1#-*-python-*- 2#GemRB - Infinity Engine Emulator 3#Copyright (C) 2009 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 20import _GemRB 21import GameCheck 22 23from GUIDefines import * 24from MetaClasses import metaIDWrapper, add_metaclass 25from GemRB import GetView, CreateView, RemoveView, RemoveScriptingRef 26 27def CreateScrollbarARGs(bam = None): 28 bamframes = list(range(6)) 29 30 if GameCheck.IsBG2(): 31 bam = bam if bam else 'GUISCRCW' 32 bamframes = [0,1,2,3,5,4] 33 elif GameCheck.IsPST(): 34 bam = bam if bam else 'CGSCRL1' 35 elif GameCheck.IsIWD2(): 36 bam = bam if bam else 'GBTNSCRL' 37 elif GameCheck.IsBG1(): 38 bam = bam if bam else 'GUIWSBR' 39 bamframes = [0,1,2,3,6,7] 40 elif GameCheck.IsIWD1(): 41 bam = bam if bam else 'GUISBR' 42 else: # demo 43 bam = bam if bam else 'scrlbar1' 44 bamframes = [0,1,2,3,5,4] 45 46 return (bam, bamframes) 47 48@add_metaclass(metaIDWrapper) 49class GTable: 50 methods = { 51 'GetValue': _GemRB.Table_GetValue, 52 'FindValue': _GemRB.Table_FindValue, 53 'GetRowIndex': _GemRB.Table_GetRowIndex, 54 'GetRowName': _GemRB.Table_GetRowName, 55 'GetColumnIndex': _GemRB.Table_GetColumnIndex, 56 'GetColumnName': _GemRB.Table_GetColumnName, 57 'GetRowCount': _GemRB.Table_GetRowCount, 58 'GetColumnCount': _GemRB.Table_GetColumnCount 59 } 60 61 def __bool__(self): 62 return self.ID != -1 63 64@add_metaclass(metaIDWrapper) 65class GSymbol: 66 methods = { 67 'GetValue': _GemRB.Symbol_GetValue, 68 'Unload': _GemRB.Symbol_Unload 69 } 70 71class Scrollable(object): 72 def Scroll(self, x, y, relative = True): 73 _GemRB.Scrollable_Scroll(self, x, y, relative) 74 75 def ScrollTo(self, x, y): 76 self.Scroll(x, y, False) 77 78 def ScrollDelta(self, x, y): 79 self.Scroll(x, y, True) 80 81@add_metaclass(metaIDWrapper) 82class GView: 83 methods = { 84 'AddAlias': _GemRB.View_AddAlias, 85 'AddSubview': _GemRB.View_AddSubview, 86 'SetEventProxy': _GemRB.View_SetEventProxy, 87 'GetFrame': _GemRB.View_GetFrame, 88 'SetFrame': _GemRB.View_SetFrame, 89 'SetBackground': _GemRB.View_SetBackground, 90 'SetFlags': _GemRB.View_SetFlags, 91 'SetResizeFlags': _GemRB.View_SetResizeFlags, 92 'SetTooltip': _GemRB.View_SetTooltip, 93 'Focus': _GemRB.View_Focus 94 } 95 96 __slots__ = ['SCRIPT_GROUP', 'Flags'] 97 98 def __eq__(self, rhs): 99 if rhs == None: 100 return self.ID == -1 101 return self.ID == rhs.ID and self.SCRIPT_GROUP == rhs.SCRIPT_GROUP 102 103 def __hash__(self): 104 return self.SCRIPT_GROUP + str(self.ID) 105 106 def __bool__(self): 107 return self.ID != -1 108 109 def GetSize(self): 110 frame = self.GetFrame() 111 return (frame['w'], frame['h']) 112 113 def GetPos(self): 114 frame = self.GetFrame() 115 return (frame['x'], frame['y']) 116 117 def SetSize(self, w, h): 118 r = self.GetFrame() 119 r['w'] = w 120 r['h'] = h 121 self.SetFrame(r); 122 123 def SetPos(self, x, y): 124 r = self.GetFrame() 125 r['x'] = x 126 r['y'] = y 127 self.SetFrame(r); 128 129 def GetInsetFrame(self, l = 0, r = None, t = None, b = None): 130 r = r if r is not None else l 131 t = t if t is not None else l 132 b = b if b is not None else t 133 134 frame = self.GetFrame() 135 frame['x'] = l 136 frame['y'] = b 137 frame['w'] -= (l + r) 138 frame['h'] -= (b + t) 139 return frame 140 141 def SetVisible(self, visible): 142 self.SetFlags(IE_GUI_VIEW_INVISIBLE, OP_NAND if visible else OP_OR) 143 144 def IsVisible(self): 145 return not (self.Flags & IE_GUI_VIEW_INVISIBLE) 146 147 def SetDisabled(self, disable): 148 self.SetFlags(IE_GUI_VIEW_DISABLED, OP_OR if disable else OP_NAND) 149 150 def CreateControl(self, newID, ctype, x, y, w, h, *args): # backwards compatibility 151 frame = {"x" : x, "y" : y, "w" : w, "h" : h} 152 return self.CreateSubview(newID, ctype, frame, *args) 153 154 def ReplaceSubview(self, subview, ctype, *args): 155 if isinstance(subview, int): 156 subview = self.GetControl (subview) 157 newID = subview.ID & 0x00000000ffffffff 158 frame = subview.GetFrame() 159 RemoveView(subview, True) 160 161 return self.CreateSubview(newID, ctype, frame, args) 162 163 def CreateSubview(self, newID, ctype, frame, *args): 164 view = CreateView(newID, ctype, frame, *args) # this will create an entry in the generic 'control' group 165 created = self.AddSubview(view) # this will move the reference into the our window's group 166 RemoveScriptingRef(view) # destroy the old reference just in case something tries to recycle the id while 'created' is still valid 167 return created 168 169 def RemoveSubview(self, view, delete=False): 170 return RemoveView(view, delete) 171 172 def CreateWorldMapControl(self, control, *args): 173 return self.CreateControl(control, IE_GUI_WORLDMAP, args[0], args[1], args[2], args[3], args[4:]) 174 175 def CreateMapControl(self, control, *args): 176 return self.CreateControl(control, IE_GUI_MAP, args[0], args[1], args[2], args[3], args[4:]) 177 178 def CreateLabel(self, control, *args): 179 return self.CreateControl(control, IE_GUI_LABEL, args[0], args[1], args[2], args[3], args[4:]) 180 181 def CreateButton(self, control, *args): 182 return self.CreateControl(control, IE_GUI_BUTTON, args[0], args[1], args[2], args[3], args[4:]) 183 184 def CreateScrollBar(self, control, frame, bam=None): 185 view = CreateView (control, IE_GUI_SCROLLBAR, frame, CreateScrollbarARGs(bam)) 186 return self.AddSubview (view) 187 188 def CreateTextArea(self, control, *args): 189 return self.CreateControl(control, IE_GUI_TEXTAREA, args[0], args[1], args[2], args[3], args[4:]) 190 191 def CreateTextEdit(self, control, *args): 192 return self.CreateControl(control, IE_GUI_EDIT, args[0], args[1], args[2], args[3], args[4:]) 193 194class GWindow(GView, Scrollable): 195 methods = { 196 'SetupEquipmentIcons': _GemRB.Window_SetupEquipmentIcons, 197 'SetupControls': _GemRB.Window_SetupControls, 198 'Focus': _GemRB.Window_Focus, 199 'ShowModal': _GemRB.Window_ShowModal, 200 'SetAction': _GemRB.Window_SetAction 201 } 202 203 __slots__ = ['HasFocus'] 204 205 def DeleteControl(self, view): # backwards compatibility 206 if type(view) == int: 207 view = self.GetControl (view) 208 RemoveView (view, True) 209 210 def GetControl(self, newID): # backwards compatibility 211 return GetView(self, newID) 212 213 def AliasControls (self, map): 214 for alias, cid in map.items(): 215 control = self.GetControl(cid) 216 if control: 217 control.AddAlias(alias, self.ID) 218 else: 219 print("no control with id=" + str(cid)) 220 221 def GetControlAlias(self, alias): # see AliasControls() 222 return GetView(alias, self.ID) 223 224 def ReparentSubview(self, view, newparent): 225 # reparenting assumes within the same window 226 newID = view.ID & 0x00000000ffffffff 227 view = self.RemoveSubview(view) 228 229 parentFrame = newparent.GetFrame() 230 frame = view.GetFrame() 231 frame['x'] -= parentFrame['x'] 232 frame['y'] -= parentFrame['y'] 233 view.SetFrame(frame) 234 return newparent.AddSubview(view, None, newID) 235 236 def Unload(self): # backwards compatibility 237 self.Close() 238 239 def Close(self): 240 RemoveView(self, False) 241 242class GControl(GView): 243 methods = { 244 'HasAnimation': _GemRB.Control_HasAnimation, 245 'SetVarAssoc': _GemRB.Control_SetVarAssoc, 246 'SetAnimationPalette': _GemRB.Control_SetAnimationPalette, 247 'SetAnimation': _GemRB.Control_SetAnimation, 248 'QueryText': _GemRB.Control_QueryText, 249 'SetText': _GemRB.Control_SetText, 250 'SetAction': _GemRB.Control_SetAction, 251 'SetActionInterval': _GemRB.Control_SetActionInterval, 252 'SetStatus': _GemRB.Control_SetStatus 253 } 254 255 __slots__ = ['ControlID', 'VarName', 'Value'] 256 257 # backwards compatibility 258 # map old event identifiers to new action system 259 EventMap = { 260 IE_GUI_BUTTON_ON_PRESS: lambda control, handler: control.SetAction(handler, IE_ACT_MOUSE_PRESS, GEM_MB_ACTION, 0, 1), 261 IE_GUI_MOUSE_ENTER_BUTTON: lambda control, handler: control.SetAction(handler, IE_ACT_MOUSE_ENTER), 262 IE_GUI_MOUSE_LEAVE_BUTTON: lambda control, handler: control.SetAction(handler, IE_ACT_MOUSE_LEAVE), 263 IE_GUI_BUTTON_ON_SHIFT_PRESS: lambda control, handler: control.SetAction(handler, IE_ACT_MOUSE_PRESS, GEM_MB_ACTION, 1, 1), 264 IE_GUI_BUTTON_ON_RIGHT_PRESS: lambda control, handler: control.SetAction(handler, IE_ACT_MOUSE_PRESS, GEM_MB_MENU, 0, 1), 265 IE_GUI_BUTTON_ON_DOUBLE_PRESS: lambda control, handler: control.SetAction(handler, IE_ACT_MOUSE_PRESS, GEM_MB_ACTION, 0, 2), 266 IE_GUI_PROGRESS_END_REACHED: lambda control, handler: control.SetAction(handler, IE_GUI_PROGRESS_END_REACHED), 267 IE_GUI_SLIDER_ON_CHANGE: lambda control, handler: control.SetAction(handler, IE_ACT_VALUE_CHANGE), 268 IE_GUI_EDIT_ON_CHANGE: lambda control, handler: control.SetAction(handler, IE_ACT_VALUE_CHANGE), 269 IE_GUI_EDIT_ON_DONE: lambda control, handler: control.SetAction(handler, IE_ACT_CUSTOM), 270 IE_GUI_EDIT_ON_CANCEL: lambda control, handler: control.SetAction(handler, IE_ACT_CUSTOM+1), 271 IE_GUI_TEXTAREA_ON_CHANGE: lambda control, handler: control.SetAction(handler, IE_ACT_VALUE_CHANGE), 272 IE_GUI_TEXTAREA_ON_SELECT: lambda control, handler: control.SetAction(handler, IE_GUI_TEXTAREA_ON_SELECT), 273 IE_GUI_LABEL_ON_PRESS: lambda control, handler: control.SetAction(handler, IE_ACT_MOUSE_PRESS, GEM_MB_ACTION, 0, 1), 274 IE_GUI_SCROLLBAR_ON_CHANGE: lambda control, handler: control.SetAction(handler, IE_ACT_VALUE_CHANGE), 275 IE_GUI_WORLDMAP_ON_PRESS: lambda control, handler: control.SetAction(handler, IE_ACT_MOUSE_PRESS, GEM_MB_ACTION, 0, 1), 276 IE_GUI_MAP_ON_PRESS: lambda control, handler: control.SetAction(handler, IE_ACT_MOUSE_PRESS, GEM_MB_ACTION, 0, 1), 277 IE_GUI_MAP_ON_RIGHT_PRESS: lambda control, handler: control.SetAction(handler, IE_ACT_MOUSE_PRESS, GEM_MB_MENU, 0, 1) 278 } 279 280 def SetEvent(self, event, handler): 281 GControl.EventMap[event](self, handler) 282 283 def QueryInteger(self): 284 return int("0"+self.QueryText()) 285 286class GLabel(GControl): 287 methods = { 288 'SetFont': _GemRB.Label_SetFont, 289 'SetTextColor': _GemRB.Label_SetTextColor 290 } 291 292class GTextArea(GControl, Scrollable): 293 methods = { 294 'ChapterText': _GemRB.TextArea_SetChapterText, 295 'Append': _GemRB.TextArea_Append, 296 'SetColor': _GemRB.TextArea_SetColor 297 } 298 __slots__ = ['DefaultText'] 299 300 def ListResources(self, what, opts=0): 301 _GemRB.TextArea_SetColor(self, ColorWhitish, TA_COLOR_OPTIONS) 302 return _GemRB.TextArea_ListResources(self, what, opts) 303 304 def Clear(self): 305 self.SetText("") 306 307 def SetOptions(self, optList, varname=None, val=0): 308 _GemRB.TextArea_SetOptions(self, optList) 309 if varname: 310 self.SetVarAssoc(varname, val) 311 312class GTextEdit(GControl): 313 methods = { 314 'SetBufferLength': _GemRB.TextEdit_SetBufferLength, 315 } 316 317class GScrollBar(GControl, Scrollable): 318 def SetVarAssoc(self, varname, val, rangeMin = 0, rangeMax = None): 319 rangeMax = val if rangeMax is None else rangeMax 320 super(GScrollBar, self).SetVarAssoc(varname, val, rangeMin, rangeMax) 321 322class GButton(GControl): 323 methods = { 324 'SetSprites': _GemRB.Button_SetSprites, 325 'SetOverlay': _GemRB.Button_SetOverlay, 326 'SetBorder': _GemRB.Button_SetBorder, 327 'EnableBorder': _GemRB.Button_EnableBorder, 328 'SetFont': _GemRB.Button_SetFont, 329 'SetHotKey': _GemRB.Button_SetHotKey, 330 'SetAnchor': _GemRB.Button_SetAnchor, 331 'SetPushOffset': _GemRB.Button_SetPushOffset, 332 'SetTextColor': _GemRB.Button_SetTextColor, 333 'SetState': _GemRB.Button_SetState, 334 'SetPictureClipping': _GemRB.Button_SetPictureClipping, 335 'SetPicture': _GemRB.Button_SetPicture, 336 'SetPLT': _GemRB.Button_SetPLT, 337 'SetBAM': _GemRB.Button_SetBAM, 338 'SetSpellIcon': _GemRB.Button_SetSpellIcon, 339 'SetItemIcon': _GemRB.Button_SetItemIcon, 340 'SetActionIcon': _GemRB.Button_SetActionIcon 341 } 342 343 def MakeDefault(self, glob=False): 344 # return key 345 return self.SetHotKey(chr(0x86), 0, glob) 346 347 def MakeEscape(self, glob=False): 348 # escape key 349 return self.SetHotKey(chr(0x8c), 0, glob) 350 351 def SetMOS(self, mos): 352 self.SetPicture(mos) # backwards compatibility 353 354 def SetSprite2D(self, spr): 355 self.SetPicture(spr) # backwards compatibility 356 357 def CreateLabel(self, labelid, *args): 358 frame = self.GetFrame() 359 return self.CreateControl(labelid, IE_GUI_LABEL, 0, 0, frame['w'], frame['h'], args) 360 361class GWorldMap(GControl, Scrollable): 362 methods = { 363 'GetDestinationArea': _GemRB.WorldMap_GetDestinationArea 364 } 365 366@add_metaclass(metaIDWrapper) 367class GSaveGame: 368 methods = { 369 'GetDate': _GemRB.SaveGame_GetDate, 370 'GetGameDate': _GemRB.SaveGame_GetGameDate, 371 'GetName': _GemRB.SaveGame_GetName, 372 'GetPortrait': _GemRB.SaveGame_GetPortrait, 373 'GetPreview': _GemRB.SaveGame_GetPreview, 374 'GetSaveID': _GemRB.SaveGame_GetSaveID, 375 } 376 377@add_metaclass(metaIDWrapper) 378class GSprite2D: 379 methods = {} 380