1# -*-python-*-
2# GemRB - Infinity Engine Emulator
3# Copyright (C) 2003-2005 The GemRB Project
4#
5# This program is free software; you can redistribute it and/or
6# modify it under the terms of the GNU General Public License
7# as published by the Free Software Foundation; either version 2
8# of the License, or (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
17# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18#
19
20# MessageWindow.py - scripts and GUI for the main (walk) window
21
22###################################################
23
24import GemRB
25import GameCheck
26import GUICommon
27import GUICommonWindows
28
29from GUIDefines import *
30
31def OnLoad():
32	# just load the medium window always. we can shrink/expand it, but it is the one with both controls
33	# this saves us from haveing to bend over backwards to load the new window and move the text to it (its also shorter code)
34	# for reference: medium = 12 = guiwdmb8, large = 7 = guwbtp38, small = 4 = guwbtp28
35	MessageWindow = GemRB.LoadWindow(12, GUICommon.GetWindowPack(), WINDOW_BOTTOM|WINDOW_HCENTER)
36	MessageWindow.SetFlags(WF_BORDERLESS|IE_GUI_VIEW_IGNORE_EVENTS, OP_OR)
37	MessageWindow.AddAlias("MSGWIN")
38	MessageWindow.AddAlias("HIDE_CUT", 0)
39
40	TMessageTA = MessageWindow.GetControl(1)
41	TMessageTA.SetFlags(IE_GUI_TEXTAREA_AUTOSCROLL|IE_GUI_TEXTAREA_HISTORY)
42	TMessageTA.SetResizeFlags(IE_GUI_VIEW_RESIZE_ALL)
43	TMessageTA.AddAlias("MsgSys", 0)
44	TMessageTA.SetColor({'r' : 255, 'g' : 0, 'b' : 0}, TA_COLOR_OPTIONS)
45	TMessageTA.SetColor({'r' : 255, 'g' : 255, 'b' : 255}, TA_COLOR_HOVER)
46
47	sbar = MessageWindow.GetControl(2)
48	sbar.SetResizeFlags(IE_GUI_VIEW_RESIZE_VERTICAL)
49
50	ActionsWindow = GemRB.LoadWindow(3, GUICommon.GetWindowPack(), WINDOW_BOTTOM|WINDOW_HCENTER)
51	GUICommonWindows.OpenActionsWindowControls (ActionsWindow)
52	ActionsWindow.SetFlags(WF_BORDERLESS|IE_GUI_VIEW_IGNORE_EVENTS, OP_OR)
53	ActionsWindow.AddAlias("ACTWIN")
54	ActionsWindow.AddAlias("HIDE_CUT", 1)
55	ActionsWindow.AddAlias("NOT_DLG", 0)
56
57	aFrame = ActionsWindow.GetFrame()
58	mFrame = MessageWindow.GetFrame()
59	MessageWindow.SetPos(mFrame['x'], mFrame['y'] - aFrame['h'])
60
61	Button = ActionsWindow.GetControl(60)
62	if Button:
63		Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, lambda: ToggleWindowMinimize(OptionsWindow, GS_OPTIONPANE))
64		Button = ActionsWindow.GetControl(61)
65		Button.SetEvent(IE_GUI_BUTTON_ON_PRESS, lambda: ToggleWindowMinimize(PortraitWindow, GS_PORTRAITPANE))
66
67	if GameCheck.HasHOW():
68		OptionsWindow = GemRB.LoadWindow(25, GUICommon.GetWindowPack(), WINDOW_LEFT|WINDOW_VCENTER)
69	else:
70		OptionsWindow = GemRB.LoadWindow(0, GUICommon.GetWindowPack(), WINDOW_LEFT|WINDOW_VCENTER)
71	OptionsWindow.SetFlags(WF_BORDERLESS|IE_GUI_VIEW_IGNORE_EVENTS, OP_OR)
72	OptionsWindow.AddAlias("OPTWIN")
73	OptionsWindow.AddAlias("HIDE_CUT", 2)
74	OptionsWindow.AddAlias("NOT_DLG", 1)
75
76	GUICommonWindows.SetupMenuWindowControls (OptionsWindow, 1, None)
77	PortraitWindow = GUICommonWindows.OpenPortraitWindow(1)
78	PortraitWindow.AddAlias("HIDE_CUT", 3)
79	PortraitWindow.AddAlias("NOT_DLG", 2)
80
81	# 1280 and higher don't have this control
82	Button = OptionsWindow.GetControl (10)
83	if Button:
84		Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, lambda: ToggleWindowMinimize(OptionsWindow, GS_OPTIONPANE))
85		Button = PortraitWindow.GetControl (8)
86		Button.SetEvent (IE_GUI_BUTTON_ON_PRESS, lambda: ToggleWindowMinimize(PortraitWindow, GS_PORTRAITPANE))
87
88	UpdateControlStatus(True)
89
90# or if we are going to do this a lot maybe add a view flag for automatically resizing to the assigned background
91# TODO: add a GUIScript function to return a dict with a CObject<Sprite2D> + dimensions for a given resref
92WinSizes = {GS_SMALLDIALOG : 45,
93			GS_MEDIUMDIALOG : 109,
94			GS_LARGEDIALOG : 237}
95
96def MWinBG(size, width=None):
97	if width is None:
98		width = GemRB.GetSystemVariable (SV_WIDTH)
99
100	bg = None
101	if size == GS_SMALLDIALOG:
102		if width == 640:
103			bg = "guiwbtp2"
104		else:
105			bg = "guwbtp2"
106	elif size == GS_MEDIUMDIALOG:
107		bg = "guiwdmb"
108	elif size == GS_LARGEDIALOG:
109		if width == 640:
110			bg = "guiwbtp3"
111		else:
112			bg = "guwbtp3"
113	else:
114		raise ValueError('Invalid size for MWinBG')
115
116	if width >= 800 and width < 1024:
117		bg = bg + "8"
118	elif width >= 1024:
119		bg = bg + "0"
120
121	# FIXME: infinite recursion possible
122	from ie_restype import RES_MOS
123	if not GemRB.HasResource(bg, RES_MOS):
124		if GameCheck.IsBG2() or GameCheck.IsIWD2():
125			return MWinBG(size, 800)
126		else:
127			return MWinBG(size, 640)
128
129	return bg
130
131MinimizedWindows = {}
132def ToggleWindowMinimize(win, GSFlag = 0):
133	key = win.ID
134	maximize = True if key in MinimizedWindows else False
135	if maximize:
136		# restore to original size
137		win.SetSize(*MinimizedWindows[key])
138		del MinimizedWindows[key]
139
140		if GSFlag: # stored in save
141			GemRB.GameSetScreenFlags(GSFlag, OP_NAND)
142
143	else: # minimize
144		size = win.GetSize()
145		MinimizedWindows[key] = size
146		win.SetSize(size[0], 5)
147		win.ScrollTo(0,0)
148
149		if GSFlag: # stored in save
150			GemRB.GameSetScreenFlags(GSFlag, OP_OR)
151
152	if key == GemRB.GetView("OPTWIN").ID:
153		ToggleActionbarClock(not maximize)
154
155def ToggleActionbarClock(show):
156	actwin = GemRB.GetView("ACTWIN")
157	clock = actwin.GetControl (62)
158	if clock:
159		clock.SetVisible(show)
160
161MTARestoreSize = None
162def UpdateControlStatus(init = False):
163	MessageWindow = GemRB.GetView("MSGWIN")
164
165	if not MessageWindow:
166		# exit if we get called from core without the right window pack being loaded
167		return
168
169	ExpandButton = MessageWindow.GetControl(0)
170	ExpandButton.SetDisabled(False)
171	ExpandButton.SetResizeFlags(IE_GUI_VIEW_RESIZE_TOP)
172	ExpandButton.SetHotKey(chr(0x8d), 0, True) # GEM_PGUP
173
174	ContractButton = MessageWindow.GetControl(3)
175	ContractButton.SetFlags(IE_GUI_VIEW_INVISIBLE|IE_GUI_VIEW_DISABLED, OP_NAND)
176	ContractButton.SetResizeFlags(IE_GUI_VIEW_RESIZE_BOTTOM)
177	ContractButton.SetHotKey(chr(0x8e), 0, True) # GEM_PGDOWN
178
179	def GetGSFlags():
180		GSFlags = GemRB.GetGUIFlags()
181		Expand = GSFlags&GS_DIALOGMASK
182		GSFlags = GSFlags-Expand
183		return (GSFlags, Expand)
184
185	def SetMWSize(size, GSFlags):
186		if size not in WinSizes:
187			return
188
189		frame = ContractButton.GetFrame()
190		if size != GS_SMALLDIALOG:
191			frame['y'] -= (frame['h'] + 6)
192		ExpandButton.SetFrame(frame)
193
194		frame = MessageWindow.GetFrame()
195		diff = frame['h'] - WinSizes[size]
196		frame['y'] += diff
197		frame['h'] = WinSizes[size]
198		MessageWindow.SetFrame(frame)
199		MessageWindow.SetBackground(MWinBG(size))
200
201		GemRB.GameSetScreenFlags(size + GSFlags, OP_SET)
202
203	def OnIncreaseSize():
204		GSFlags, Expand = GetGSFlags()
205		Expand = (Expand + 1)*2 # next size up
206
207		SetMWSize(Expand, GSFlags)
208
209	def OnDecreaseSize():
210		GSFlags, Expand = GetGSFlags()
211		Expand = Expand // 2 - 1 # next size down: 6->2, 2->0
212
213		SetMWSize(Expand, GSFlags)
214
215	global MTARestoreSize
216	ContractButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, OnDecreaseSize)
217	ExpandButton.SetEvent(IE_GUI_BUTTON_ON_PRESS, OnIncreaseSize)
218
219	GSFlags, Expand = GetGSFlags()
220	if init:
221		SetMWSize(Expand, GSFlags)
222		if GSFlags&GS_OPTIONPANE:
223			win = GemRB.GetView("OPTWIN")
224			ToggleWindowMinimize(win)
225		else:
226			ToggleActionbarClock(False)
227		if GSFlags&GS_PORTRAITPANE:
228			win = GemRB.GetView("PORTWIN")
229			ToggleWindowMinimize(win)
230	else:
231		if Expand == GS_LARGEDIALOG:
232			if MTARestoreSize is not None and (GSFlags&GS_DIALOG) == 0:
233				SetMWSize(MTARestoreSize, GSFlags)
234				MTARestoreSize = None
235			else:
236				ExpandButton.SetDisabled(True)
237
238		elif (GSFlags&GS_DIALOG):
239			MTARestoreSize = Expand
240			#a dialogue is running, setting messagewindow size to maximum
241			SetMWSize(GS_LARGEDIALOG, GSFlags)
242
243		elif Expand == GS_SMALLDIALOG:
244			ContractButton.SetFlags(IE_GUI_VIEW_INVISIBLE|IE_GUI_VIEW_DISABLED, OP_OR)
245
246	return
247