1 (* Copyright (C) Doom 2D: Forever Developers
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, version 3 of the License ONLY.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 {$INCLUDE ../shared/a_modes.inc}
21 {$IFDEF USE_MEMPOOL}mempool
,{$ENDIF}
22 e_graphics
, e_input
, e_log
, g_playermodel
, g_basic
, g_touch
, MAPDEF
, utils
;
25 MAINMENU_HEADER_COLOR
: TRGB
= (R
:255; G
:255; B
:255);
26 MAINMENU_ITEMS_COLOR
: TRGB
= (R
:255; G
:255; B
:255);
27 MAINMENU_UNACTIVEITEMS_COLOR
: TRGB
= (R
:192; G
:192; B
:192);
28 MAINMENU_CLICKSOUND
= 'MENU_SELECT';
29 MAINMENU_CHANGESOUND
= 'MENU_CHANGE';
31 MAINMENU_MARKER1
= 'MAINMENU_MARKER1';
32 MAINMENU_MARKER2
= 'MAINMENU_MARKER2';
33 MAINMENU_MARKERDELAY
= 24;
34 WINDOW_CLOSESOUND
= 'MENU_CLOSE';
35 MENU_HEADERCOLOR
: TRGB
= (R
:255; G
:255; B
:255);
36 MENU_ITEMSTEXT_COLOR
: TRGB
= (R
:255; G
:255; B
:255);
37 MENU_UNACTIVEITEMS_COLOR
: TRGB
= (R
:128; G
:128; B
:128);
38 MENU_ITEMSCTRL_COLOR
: TRGB
= (R
:255; G
:0; B
:0);
41 MENU_CLICKSOUND
= 'MENU_SELECT';
42 MENU_CHANGESOUND
= 'MENU_CHANGE';
43 MENU_MARKERDELAY
= 24;
44 SCROLL_LEFT
= 'SCROLL_LEFT';
45 SCROLL_RIGHT
= 'SCROLL_RIGHT';
46 SCROLL_MIDDLE
= 'SCROLL_MIDDLE';
47 SCROLL_MARKER
= 'SCROLL_MARKER';
48 SCROLL_ADDSOUND
= 'SCROLL_ADD';
49 SCROLL_SUBSOUND
= 'SCROLL_SUB';
50 EDIT_LEFT
= 'EDIT_LEFT';
51 EDIT_RIGHT
= 'EDIT_RIGHT';
52 EDIT_MIDDLE
= 'EDIT_MIDDLE';
53 EDIT_CURSORCOLOR
: TRGB
= (R
:200; G
:0; B
:0);
55 KEYREAD_QUERY
= '<...>';
56 KEYREAD_CLEAR
= '???';
59 MAPPREVIEW_HEIGHT
= 8;
69 BSCROLL_UPA
= 'BSCROLL_UP_A';
70 BSCROLL_UPU
= 'BSCROLL_UP_U';
71 BSCROLL_DOWNA
= 'BSCROLL_DOWN_A';
72 BSCROLL_DOWNU
= 'BSCROLL_DOWN_U';
73 BSCROLL_MIDDLE
= 'BSCROLL_MIDDLE';
85 TFontType
= (Texture
, Character
);
87 TFont
= class{$IFDEF USE_MEMPOOL}(TPoolObject
){$ENDIF}
93 constructor Create(FontID
: DWORD
; FontType
: TFontType
);
94 procedure Draw(X
, Y
: Integer; Text: string; R
, G
, B
: Byte);
95 procedure GetTextSize(Text: string; var w
, h
: Word);
96 property Scale
: Single read FScale write FScale
;
102 TOnKeyDownEvent
= procedure(Key
: Byte);
103 TOnKeyDownEventEx
= procedure(win
: TGUIWindow
; Key
: Byte);
104 TOnCloseEvent
= procedure;
105 TOnShowEvent
= procedure;
106 TOnClickEvent
= procedure;
107 TOnChangeEvent
= procedure(Sender
: TGUIControl
);
108 TOnEnterEvent
= procedure(Sender
: TGUIControl
);
110 TGUIControl
= class{$IFDEF USE_MEMPOOL}(TPoolObject
){$ENDIF}
114 FWindow
: TGUIWindow
;
117 FRightAlign
: Boolean; //HACK! this works only for "normal" menus, only for menu text labels, and generally sux. sorry.
118 FMaxWidth
: Integer; //HACK! used for right-aligning labels
121 procedure OnMessage(var Msg
: TMessage
); virtual;
122 procedure Update
; virtual;
123 procedure Draw
; virtual;
124 function GetWidth(): Integer; virtual;
125 function GetHeight(): Integer; virtual;
126 function WantActivationKey (key
: LongInt): Boolean; virtual;
127 property X
: Integer read FX write FX
;
128 property Y
: Integer read FY write FY
;
129 property Enabled
: Boolean read FEnabled write FEnabled
;
130 property Name
: string read FName write FName
;
131 property UserData
: Pointer read FUserData write FUserData
;
132 property RightAlign
: Boolean read FRightAlign write FRightAlign
; // for menu
135 TGUIWindow
= class{$IFDEF USE_MEMPOOL}(TPoolObject
){$ENDIF}
137 FActiveControl
: TGUIControl
;
139 FPrevWindow
: TGUIWindow
;
141 FBackTexture
: string;
142 FMainWindow
: Boolean;
143 FOnKeyDown
: TOnKeyDownEvent
;
144 FOnKeyDownEx
: TOnKeyDownEventEx
;
145 FOnCloseEvent
: TOnCloseEvent
;
146 FOnShowEvent
: TOnShowEvent
;
149 Childs
: array of TGUIControl
;
150 constructor Create(Name
: string);
151 destructor Destroy
; override;
152 function AddChild(Child
: TGUIControl
): TGUIControl
;
153 procedure OnMessage(var Msg
: TMessage
);
156 procedure SetActive(Control
: TGUIControl
);
157 function GetControl(Name
: string): TGUIControl
;
158 property OnKeyDown
: TOnKeyDownEvent read FOnKeyDown write FOnKeyDown
;
159 property OnKeyDownEx
: TOnKeyDownEventEx read FOnKeyDownEx write FOnKeyDownEx
;
160 property OnClose
: TOnCloseEvent read FOnCloseEvent write FOnCloseEvent
;
161 property OnShow
: TOnShowEvent read FOnShowEvent write FOnShowEvent
;
162 property Name
: string read FName
;
163 property DefControl
: string read FDefControl write FDefControl
;
164 property BackTexture
: string read FBackTexture write FBackTexture
;
165 property MainWindow
: Boolean read FMainWindow write FMainWindow
;
166 property UserData
: Pointer read FUserData write FUserData
;
169 TGUITextButton
= class(TGUIControl
)
178 ProcEx
: procedure (sender
: TGUITextButton
);
179 constructor Create(aProc
: Pointer; FontID
: DWORD
; Text: string);
180 destructor Destroy(); override;
181 procedure OnMessage(var Msg
: TMessage
); override;
182 procedure Draw(); override;
183 function GetWidth(): Integer; override;
184 function GetHeight(): Integer; override;
185 procedure Click(Silent
: Boolean = False);
186 property Caption
: string read FText write FText
;
187 property Color
: TRGB read FColor write FColor
;
188 property Font
: TFont read FFont write FFont
;
189 property ShowWindow
: string read FShowWindow write FShowWindow
;
192 TGUILabel
= class(TGUIControl
)
198 FOnClickEvent
: TOnClickEvent
;
200 constructor Create(Text: string; FontID
: DWORD
);
201 destructor Destroy(); override;
202 procedure OnMessage(var Msg
: TMessage
); override;
203 procedure Draw
; override;
204 function GetWidth
: Integer; override;
205 function GetHeight
: Integer; override;
206 property OnClick
: TOnClickEvent read FOnClickEvent write FOnClickEvent
;
207 property FixedLength
: Word read FFixedLen write FFixedLen
;
208 property Text: string read FText write FText
;
209 property Color
: TRGB read FColor write FColor
;
210 property Font
: TFont read FFont write FFont
;
213 TGUIScroll
= class(TGUIControl
)
221 FOnChangeEvent
: TOnChangeEvent
;
222 procedure FSetValue(a
: Integer);
224 constructor Create();
225 procedure OnMessage(var Msg
: TMessage
); override;
226 procedure Draw
; override;
227 function GetWidth(): Integer; override;
228 property OnChange
: TOnChangeEvent read FOnChangeEvent write FOnChangeEvent
;
229 property Max
: Word read FMax write FMax
;
230 property Value
: Integer read FValue write FSetValue
;
233 TGUISwitch
= class(TGUIControl
)
236 FItems
: array of string;
239 FOnChangeEvent
: TOnChangeEvent
;
241 constructor Create(FontID
: DWORD
);
242 destructor Destroy(); override;
243 procedure OnMessage(var Msg
: TMessage
); override;
244 procedure AddItem(Item
: string);
245 procedure Draw
; override;
246 function GetWidth(): Integer; override;
247 function GetText
: string;
248 property ItemIndex
: Integer read FIndex write FIndex
;
249 property Color
: TRGB read FColor write FColor
;
250 property Font
: TFont read FFont write FFont
;
251 property OnChange
: TOnChangeEvent read FOnChangeEvent write FOnChangeEvent
;
254 TGUIEdit
= class(TGUIControl
)
262 FOnlyDigits
: Boolean;
266 FOnChangeEvent
: TOnChangeEvent
;
267 FOnEnterEvent
: TOnEnterEvent
;
269 procedure SetText(Text: string);
271 constructor Create(FontID
: DWORD
);
272 destructor Destroy(); override;
273 procedure OnMessage(var Msg
: TMessage
); override;
274 procedure Draw
; override;
275 function GetWidth(): Integer; override;
276 property OnChange
: TOnChangeEvent read FOnChangeEvent write FOnChangeEvent
;
277 property OnEnter
: TOnEnterEvent read FOnEnterEvent write FOnEnterEvent
;
278 property Width
: Word read FWidth write FWidth
;
279 property MaxLength
: Word read FMaxLength write FMaxLength
;
280 property OnlyDigits
: Boolean read FOnlyDigits write FOnlyDigits
;
281 property Text: string read FText write SetText
;
282 property Color
: TRGB read FColor write FColor
;
283 property Font
: TFont read FFont write FFont
;
284 property Invalid
: Boolean read FInvalid write FInvalid
;
287 TGUIKeyRead
= class(TGUIControl
)
294 constructor Create(FontID
: DWORD
);
295 destructor Destroy(); override;
296 procedure OnMessage(var Msg
: TMessage
); override;
297 procedure Draw
; override;
298 function GetWidth(): Integer; override;
299 function WantActivationKey (key
: LongInt): Boolean; override;
300 property Key
: Word read FKey write FKey
;
301 property Color
: TRGB read FColor write FColor
;
302 property Font
: TFont read FFont write FFont
;
306 TGUIKeyRead2
= class(TGUIControl
)
311 FKey0
, FKey1
: Word; // this should be an array. sorry.
314 FMaxKeyNameWdt
: Integer;
316 constructor Create(FontID
: DWORD
);
317 destructor Destroy(); override;
318 procedure OnMessage(var Msg
: TMessage
); override;
319 procedure Draw
; override;
320 function GetWidth(): Integer; override;
321 function WantActivationKey (key
: LongInt): Boolean; override;
322 property Key0
: Word read FKey0 write FKey0
;
323 property Key1
: Word read FKey1 write FKey1
;
324 property Color
: TRGB read FColor write FColor
;
325 property Font
: TFont read FFont write FFont
;
328 TGUIModelView
= class(TGUIControl
)
330 FModel
: TPlayerModel
;
334 destructor Destroy
; override;
335 procedure SetModel(ModelName
: string);
336 procedure SetColor(Red
, Green
, Blue
: Byte);
337 procedure NextAnim();
338 procedure NextWeapon();
339 procedure Update
; override;
340 procedure Draw
; override;
341 property Model
: TPlayerModel read FModel
;
344 TPreviewPanel
= record
345 X1
, Y1
, X2
, Y2
: Integer;
349 TGUIMapPreview
= class(TGUIControl
)
351 FMapData
: array of TPreviewPanel
;
355 constructor Create();
356 destructor Destroy(); override;
357 procedure SetMap(Res
: string);
358 procedure ClearMap();
359 procedure Draw(); override;
360 function GetScaleStr
: String;
363 TGUIImage
= class(TGUIControl
)
368 constructor Create();
369 procedure SetImage(Res
: string);
370 procedure ClearImage();
371 procedure Draw(); override;
372 property DefaultRes
: string read FDefaultRes write FDefaultRes
;
375 TGUIListBox
= class(TGUIControl
)
379 FUnActiveColor
: TRGB
;
387 FDrawScroll
: Boolean;
388 FOnChangeEvent
: TOnChangeEvent
;
390 procedure FSetItems(Items
: SSArray
);
391 procedure FSetIndex(aIndex
: Integer);
394 constructor Create(FontID
: DWORD
; Width
, Height
: Word);
395 destructor Destroy(); override;
396 procedure OnMessage(var Msg
: TMessage
); override;
397 procedure Draw(); override;
398 procedure AddItem(Item
: String);
399 function ItemExists (item
: String): Boolean;
400 procedure SelectItem(Item
: String);
402 function GetWidth(): Integer; override;
403 function GetHeight(): Integer; override;
404 function SelectedItem(): String;
406 property OnChange
: TOnChangeEvent read FOnChangeEvent write FOnChangeEvent
;
407 property Sort
: Boolean read FSort write FSort
;
408 property ItemIndex
: Integer read FIndex write FSetIndex
;
409 property Items
: SSArray read FItems write FSetItems
;
410 property DrawBack
: Boolean read FDrawBack write FDrawBack
;
411 property DrawScrollBar
: Boolean read FDrawScroll write FDrawScroll
;
412 property ActiveColor
: TRGB read FActiveColor write FActiveColor
;
413 property UnActiveColor
: TRGB read FUnActiveColor write FUnActiveColor
;
414 property Font
: TFont read FFont write FFont
;
417 TGUIFileListBox
= class(TGUIListBox
)
422 FBaseList
: SSArray
; // highter index have highter priority
427 procedure OnMessage (var Msg
: TMessage
); override;
428 procedure SetBase (dirs
: SSArray
; path
: String = '');
429 function SelectedItem(): String;
430 procedure UpdateFileList();
432 property Dirs
: Boolean read FDirs write FDirs
;
433 property FileMask
: String read FFileMask write FFileMask
;
436 TGUIMemo
= class(TGUIControl
)
445 FDrawScroll
: Boolean;
447 constructor Create(FontID
: DWORD
; Width
, Height
: Word);
448 destructor Destroy(); override;
449 procedure OnMessage(var Msg
: TMessage
); override;
450 procedure Draw
; override;
452 function GetWidth(): Integer; override;
453 function GetHeight(): Integer; override;
454 procedure SetText(Text: string);
455 property DrawBack
: Boolean read FDrawBack write FDrawBack
;
456 property DrawScrollBar
: Boolean read FDrawScroll write FDrawScroll
;
457 property Color
: TRGB read FColor write FColor
;
458 property Font
: TFont read FFont write FFont
;
461 TGUIMainMenu
= class(TGUIControl
)
463 FButtons
: array of TGUITextButton
;
472 constructor Create(FontID
: DWORD
; Logo
, Header
: string);
473 destructor Destroy
; override;
474 procedure OnMessage(var Msg
: TMessage
); override;
475 function AddButton(fProc
: Pointer; Caption
: string; ShowWindow
: string = ''): TGUITextButton
;
476 function GetButton(aName
: string): TGUITextButton
;
477 procedure EnableButton(aName
: string; e
: Boolean);
478 procedure AddSpace();
479 procedure Update
; override;
480 procedure Draw
; override;
483 TControlType
= class of TGUIControl
;
485 PMenuItem
= ^TMenuItem
;
488 ControlType
: TControlType
;
489 Control
: TGUIControl
;
492 TGUIMenu
= class(TGUIControl
)
494 FItems
: array of TMenuItem
;
502 function NewItem(): Integer;
504 constructor Create(HeaderFont
, ItemsFont
: DWORD
; Header
: string);
505 destructor Destroy
; override;
506 procedure OnMessage(var Msg
: TMessage
); override;
507 procedure AddSpace();
508 procedure AddLine(fText
: string);
509 procedure AddText(fText
: string; MaxWidth
: Word);
510 function AddLabel(fText
: string): TGUILabel
;
511 function AddButton(Proc
: Pointer; fText
: string; _ShowWindow
: string = ''): TGUITextButton
;
512 function AddScroll(fText
: string): TGUIScroll
;
513 function AddSwitch(fText
: string): TGUISwitch
;
514 function AddEdit(fText
: string): TGUIEdit
;
515 function AddKeyRead(fText
: string): TGUIKeyRead
;
516 function AddKeyRead2(fText
: string): TGUIKeyRead2
;
517 function AddList(fText
: string; Width
, Height
: Word): TGUIListBox
;
518 function AddFileList(fText
: string; Width
, Height
: Word): TGUIFileListBox
;
519 function AddMemo(fText
: string; Width
, Height
: Word): TGUIMemo
;
521 function GetControl(aName
: string): TGUIControl
;
522 function GetControlsText(aName
: string): TGUILabel
;
523 procedure Draw
; override;
524 procedure Update
; override;
525 procedure UpdateIndex();
526 property Align
: Boolean read FAlign write FAlign
;
527 property Left
: Integer read FLeft write FLeft
;
528 property YesNo
: Boolean read FYesNo write FYesNo
;
532 g_GUIWindows
: array of TGUIWindow
;
533 g_ActiveWindow
: TGUIWindow
= nil;
534 g_GUIGrabInput
: Boolean = False;
536 procedure g_GUI_Init();
537 function g_GUI_AddWindow(Window
: TGUIWindow
): TGUIWindow
;
538 function g_GUI_GetWindow(Name
: string): TGUIWindow
;
539 procedure g_GUI_ShowWindow(Name
: string);
540 procedure g_GUI_HideWindow(PlaySound
: Boolean = True);
541 function g_GUI_Destroy(): Boolean;
542 procedure g_GUI_SaveMenuPos();
543 procedure g_GUI_LoadMenuPos();
549 {$INCLUDE ../nogl/noGLuses.inc}
550 {$IFDEF ENABLE_SOUND}
553 g_textures
, SysUtils
, e_res
,
554 g_game
, Math
, StrUtils
, g_player
, g_options
, g_console
,
555 g_map
, g_weapons
, xdynrec
, wadreader
, Generics
.Collections
, Generics
.Defaults
;
559 Box
: array[0..8] of DWORD
;
560 Saved_Windows
: SSArray
;
563 procedure g_GUI_Init();
565 g_Texture_Get(BOX1
, Box
[0]);
566 g_Texture_Get(BOX2
, Box
[1]);
567 g_Texture_Get(BOX3
, Box
[2]);
568 g_Texture_Get(BOX4
, Box
[3]);
569 g_Texture_Get(BOX5
, Box
[4]);
570 g_Texture_Get(BOX6
, Box
[5]);
571 g_Texture_Get(BOX7
, Box
[6]);
572 g_Texture_Get(BOX8
, Box
[7]);
573 g_Texture_Get(BOX9
, Box
[8]);
576 function g_GUI_Destroy(): Boolean;
580 Result
:= (Length(g_GUIWindows
) > 0);
582 for i
:= 0 to High(g_GUIWindows
) do
583 g_GUIWindows
[i
].Free();
586 g_ActiveWindow
:= nil;
589 function g_GUI_AddWindow(Window
: TGUIWindow
): TGUIWindow
;
591 SetLength(g_GUIWindows
, Length(g_GUIWindows
)+1);
592 g_GUIWindows
[High(g_GUIWindows
)] := Window
;
597 function g_GUI_GetWindow(Name
: string): TGUIWindow
;
603 if g_GUIWindows
<> nil then
604 for i
:= 0 to High(g_GUIWindows
) do
605 if g_GUIWindows
[i
].FName
= Name
then
607 Result
:= g_GUIWindows
[i
];
611 Assert(Result
<> nil, 'GUI_Window "'+Name
+'" not found');
614 procedure g_GUI_ShowWindow(Name
: string);
618 if g_GUIWindows
= nil then
621 for i
:= 0 to High(g_GUIWindows
) do
622 if g_GUIWindows
[i
].FName
= Name
then
624 g_GUIWindows
[i
].FPrevWindow
:= g_ActiveWindow
;
625 g_ActiveWindow
:= g_GUIWindows
[i
];
627 if g_ActiveWindow
.MainWindow
then
628 g_ActiveWindow
.FPrevWindow
:= nil;
630 if g_ActiveWindow
.FDefControl
<> '' then
631 g_ActiveWindow
.SetActive(g_ActiveWindow
.GetControl(g_ActiveWindow
.FDefControl
))
633 g_ActiveWindow
.SetActive(nil);
635 if @g_ActiveWindow
.FOnShowEvent
<> nil then
636 g_ActiveWindow
.FOnShowEvent();
642 procedure g_GUI_HideWindow(PlaySound
: Boolean = True);
644 if g_ActiveWindow
<> nil then
646 if @g_ActiveWindow
.OnClose
<> nil then
647 g_ActiveWindow
.OnClose();
648 g_ActiveWindow
:= g_ActiveWindow
.FPrevWindow
;
649 {$IFDEF ENABLE_SOUND}
651 g_Sound_PlayEx(WINDOW_CLOSESOUND
);
656 procedure g_GUI_SaveMenuPos();
661 SetLength(Saved_Windows
, 0);
662 win
:= g_ActiveWindow
;
666 len
:= Length(Saved_Windows
);
667 SetLength(Saved_Windows
, len
+ 1);
669 Saved_Windows
[len
] := win
.Name
;
671 if win
.MainWindow
then
674 win
:= win
.FPrevWindow
;
678 procedure g_GUI_LoadMenuPos();
680 i
, j
, k
, len
: Integer;
683 g_ActiveWindow
:= nil;
684 len
:= Length(Saved_Windows
);
689 // Îêíî ñ ãëàâíûì ìåíþ:
690 g_GUI_ShowWindow(Saved_Windows
[len
-1]);
692 // Íå ïåðåêëþ÷èëîñü (èëè íåêóäà äàëüøå):
693 if (len
= 1) or (g_ActiveWindow
= nil) then
696 // Èùåì êíîïêè â îñòàëüíûõ îêíàõ:
697 for k
:= len
-1 downto 1 do
701 for i
:= 0 to Length(g_ActiveWindow
.Childs
)-1 do
703 if g_ActiveWindow
.Childs
[i
] is TGUIMainMenu
then
704 begin // GUI_MainMenu
705 with TGUIMainMenu(g_ActiveWindow
.Childs
[i
]) do
706 for j
:= 0 to Length(FButtons
)-1 do
707 if FButtons
[j
].ShowWindow
= Saved_Windows
[k
-1] then
709 FButtons
[j
].Click(True);
715 if g_ActiveWindow
.Childs
[i
] is TGUIMenu
then
716 with TGUIMenu(g_ActiveWindow
.Childs
[i
]) do
717 for j
:= 0 to Length(FItems
)-1 do
718 if FItems
[j
].ControlType
= TGUITextButton
then
719 if TGUITextButton(FItems
[j
].Control
).ShowWindow
= Saved_Windows
[k
-1] then
721 TGUITextButton(FItems
[j
].Control
).Click(True);
732 (g_ActiveWindow
.Name
= Saved_Windows
[k
]) then
737 procedure DrawBox(X
, Y
: Integer; Width
, Height
: Word);
739 e_Draw(Box
[0], X
, Y
, 0, False, False);
740 e_DrawFill(Box
[1], X
+4, Y
, Width
*4, 1, 0, False, False);
741 e_Draw(Box
[2], X
+4+Width
*16, Y
, 0, False, False);
742 e_DrawFill(Box
[3], X
, Y
+4, 1, Height
*4, 0, False, False);
743 e_DrawFill(Box
[4], X
+4, Y
+4, Width
, Height
, 0, False, False);
744 e_DrawFill(Box
[5], X
+4+Width
*16, Y
+4, 1, Height
*4, 0, False, False);
745 e_Draw(Box
[6], X
, Y
+4+Height
*16, 0, False, False);
746 e_DrawFill(Box
[7], X
+4, Y
+4+Height
*16, Width
*4, 1, 0, False, False);
747 e_Draw(Box
[8], X
+4+Width
*16, Y
+4+Height
*16, 0, False, False);
750 procedure DrawScroll(X
, Y
: Integer; Height
: Word; Up
, Down
: Boolean);
754 if Height
< 3 then Exit
;
757 g_Texture_Get(BSCROLL_UPA
, ID
)
759 g_Texture_Get(BSCROLL_UPU
, ID
);
760 e_Draw(ID
, X
, Y
, 0, False, False);
763 g_Texture_Get(BSCROLL_DOWNA
, ID
)
765 g_Texture_Get(BSCROLL_DOWNU
, ID
);
766 e_Draw(ID
, X
, Y
+(Height
-1)*16, 0, False, False);
768 g_Texture_Get(BSCROLL_MIDDLE
, ID
);
769 e_DrawFill(ID
, X
, Y
+16, 1, Height
-2, 0, False, False);
774 constructor TGUIWindow
.Create(Name
: string);
777 FActiveControl
:= nil;
781 FOnCloseEvent
:= nil;
785 destructor TGUIWindow
.Destroy
;
792 for i
:= 0 to High(Childs
) do
796 function TGUIWindow
.AddChild(Child
: TGUIControl
): TGUIControl
;
798 Child
.FWindow
:= Self
;
800 SetLength(Childs
, Length(Childs
) + 1);
801 Childs
[High(Childs
)] := Child
;
806 procedure TGUIWindow
.Update
;
810 for i
:= 0 to High(Childs
) do
811 if Childs
[i
] <> nil then Childs
[i
].Update
;
814 procedure TGUIWindow
.Draw
;
820 if FBackTexture
<> '' then // Here goes code duplication from g_game.pas:DrawMenuBackground()
821 if g_Texture_Get(FBackTexture
, ID
) then
823 e_Clear(GL_COLOR_BUFFER_BIT
, 0, 0, 0);
824 e_GetTextureSize(ID
, @tw
, @th
);
826 tw
:= round(tw
* 1.333 * (gScreenHeight
/ th
))
828 tw
:= trunc(tw
* (gScreenHeight
/ th
));
829 e_DrawSize(ID
, (gScreenWidth
- tw
) div 2, 0, 0, False, False, tw
, gScreenHeight
);
832 e_Clear(GL_COLOR_BUFFER_BIT
, 0.5, 0.5, 0.5);
835 if FName
= 'AuthorsMenu' then
836 e_DarkenQuadWH(0, 0, gScreenWidth
, gScreenHeight
, 150);
838 for i
:= 0 to High(Childs
) do
839 if Childs
[i
] <> nil then Childs
[i
].Draw
;
842 procedure TGUIWindow
.OnMessage(var Msg
: TMessage
);
844 if FActiveControl
<> nil then FActiveControl
.OnMessage(Msg
);
845 if @FOnKeyDown
<> nil then FOnKeyDown(Msg
.wParam
);
846 if @FOnKeyDownEx
<> nil then FOnKeyDownEx(self
, Msg
.wParam
);
848 if Msg
.Msg
= WM_KEYDOWN
then
860 procedure TGUIWindow
.SetActive(Control
: TGUIControl
);
862 FActiveControl
:= Control
;
865 function TGUIWindow
.GetControl(Name
: String): TGUIControl
;
871 if Childs
<> nil then
872 for i
:= 0 to High(Childs
) do
873 if Childs
[i
] <> nil then
874 if LowerCase(Childs
[i
].FName
) = LowerCase(Name
) then
880 Assert(Result
<> nil, 'Window Control "'+Name
+'" not Found!');
885 constructor TGUIControl
.Create();
891 FRightAlign
:= false;
895 procedure TGUIControl
.OnMessage(var Msg
: TMessage
);
901 procedure TGUIControl
.Update();
905 procedure TGUIControl
.Draw();
909 function TGUIControl
.WantActivationKey (key
: LongInt): Boolean;
914 function TGUIControl
.GetWidth(): Integer;
919 function TGUIControl
.GetHeight(): Integer;
926 procedure TGUITextButton
.Click(Silent
: Boolean = False);
928 {$IFDEF ENABLE_SOUND}
929 if (FSound
<> '') and (not Silent
) then g_Sound_PlayEx(FSound
);
932 if @Proc
<> nil then Proc();
933 if @ProcEx
<> nil then ProcEx(self
);
935 if FShowWindow
<> '' then g_GUI_ShowWindow(FShowWindow
);
938 constructor TGUITextButton
.Create(aProc
: Pointer; FontID
: DWORD
; Text: string);
945 FFont
:= TFont
.Create(FontID
, TFontType
.Character
);
950 destructor TGUITextButton
.Destroy
;
956 procedure TGUITextButton
.Draw
;
958 FFont
.Draw(FX
, FY
, FText
, FColor
.R
, FColor
.G
, FColor
.B
)
961 function TGUITextButton
.GetHeight
: Integer;
965 FFont
.GetTextSize(FText
, w
, h
);
969 function TGUITextButton
.GetWidth
: Integer;
973 FFont
.GetTextSize(FText
, w
, h
);
977 procedure TGUITextButton
.OnMessage(var Msg
: TMessage
);
979 if not FEnabled
then Exit
;
986 IK_RETURN
, IK_KPRETURN
, IK_SELECT
,
988 JOY0_ATTACK
, JOY1_ATTACK
, JOY2_ATTACK
, JOY3_ATTACK
: Click();
995 constructor TFont
.Create(FontID
: DWORD
; FontType
: TFontType
);
1000 FFontType
:= FontType
;
1003 procedure TFont
.Draw(X
, Y
: Integer; Text: string; R
, G
, B
: Byte);
1005 if FFontType
= TFontType
.Character
1006 then e_CharFont_PrintEx(ID
, X
, Y
, Text, _RGB(R
, G
, B
), FScale
)
1007 else e_TextureFontPrintEx(X
, Y
, Text, ID
, R
, G
, B
, FScale
);
1010 procedure TFont
.GetTextSize(Text: string; var w
, h
: Word);
1014 if FFontType
= TFontType
.Character
then
1015 e_CharFont_GetSize(ID
, Text, w
, h
)
1018 e_TextureFontGetSize(ID
, cw
, ch
);
1019 w
:= cw
*Length(Text);
1023 w
:= Round(w
*FScale
);
1024 h
:= Round(h
*FScale
);
1029 function TGUIMainMenu
.AddButton(fProc
: Pointer; Caption
: string; ShowWindow
: string = ''): TGUITextButton
;
1037 SetLength(FButtons
, Length(FButtons
)+1);
1038 FButtons
[High(FButtons
)] := TGUITextButton
.Create(fProc
, FFontID
, Caption
);
1039 FButtons
[High(FButtons
)].ShowWindow
:= ShowWindow
;
1040 with FButtons
[High(FButtons
)] do
1042 if (fProc
<> nil) or (ShowWindow
<> '') then FColor
:= MAINMENU_ITEMS_COLOR
1043 else FColor
:= MAINMENU_UNACTIVEITEMS_COLOR
;
1044 FSound
:= MAINMENU_CLICKSOUND
;
1047 _x
:= gScreenWidth
div 2;
1049 for a
:= 0 to High(FButtons
) do
1050 if FButtons
[a
] <> nil then
1051 _x
:= Min(_x
, (gScreenWidth
div 2)-(FButtons
[a
].GetWidth
div 2));
1053 if FLogo
<> 0 then e_GetTextureSize(FLogo
, nil, @lh
);
1054 hh
:= FButtons
[High(FButtons
)].GetHeight
;
1056 if FLogo
<> 0 then h
:= lh
+ hh
* (1 + Length(FButtons
)) + MAINMENU_SPACE
* (Length(FButtons
) - 1)
1057 else h
:= hh
* (2 + Length(FButtons
)) + MAINMENU_SPACE
* (Length(FButtons
) - 1);
1058 h
:= (gScreenHeight
div 2) - (h
div 2);
1060 if FHeader
<> nil then with FHeader
do
1066 if FLogo
<> 0 then Inc(h
, lh
)
1069 for a
:= 0 to High(FButtons
) do
1071 if FButtons
[a
] <> nil then
1078 Inc(h
, hh
+MAINMENU_SPACE
);
1081 Result
:= FButtons
[High(FButtons
)];
1084 procedure TGUIMainMenu
.AddSpace
;
1086 SetLength(FButtons
, Length(FButtons
)+1);
1087 FButtons
[High(FButtons
)] := nil;
1090 constructor TGUIMainMenu
.Create(FontID
: DWORD
; Logo
, Header
: string);
1096 FCounter
:= MAINMENU_MARKERDELAY
;
1098 g_Texture_Get(MAINMENU_MARKER1
, FMarkerID1
);
1099 g_Texture_Get(MAINMENU_MARKER2
, FMarkerID2
);
1101 if not g_Texture_Get(Logo
, FLogo
) then
1103 FHeader
:= TGUILabel
.Create(Header
, FFontID
);
1106 FColor
:= MAINMENU_HEADER_COLOR
;
1107 FX
:= (gScreenWidth
div 2)-(GetWidth
div 2);
1108 FY
:= (gScreenHeight
div 2)-(GetHeight
div 2);
1113 destructor TGUIMainMenu
.Destroy
;
1117 if FButtons
<> nil then
1118 for a
:= 0 to High(FButtons
) do
1126 procedure TGUIMainMenu
.Draw
;
1134 if FHeader
<> nil then FHeader
.Draw
1136 e_GetTextureSize(FLogo
, @w
, @h
);
1137 e_Draw(FLogo
, ((gScreenWidth
div 2) - (w
div 2)), FButtons
[0].FY
- FButtons
[0].GetHeight
- h
, 0, True, False);
1140 if FButtons
<> nil then
1142 for a
:= 0 to High(FButtons
) do
1143 if FButtons
[a
] <> nil then FButtons
[a
].Draw
;
1145 if FIndex
<> -1 then
1146 e_Draw(FMarkerID1
, FButtons
[FIndex
].FX
-48, FButtons
[FIndex
].FY
, 0, True, False);
1150 procedure TGUIMainMenu
.EnableButton(aName
: string; e
: Boolean);
1154 if FButtons
= nil then Exit
;
1156 for a
:= 0 to High(FButtons
) do
1157 if (FButtons
[a
] <> nil) and (FButtons
[a
].Name
= aName
) then
1159 if e
then FButtons
[a
].FColor
:= MAINMENU_ITEMS_COLOR
1160 else FButtons
[a
].FColor
:= MAINMENU_UNACTIVEITEMS_COLOR
;
1161 FButtons
[a
].Enabled
:= e
;
1166 function TGUIMainMenu
.GetButton(aName
: string): TGUITextButton
;
1172 if FButtons
= nil then Exit
;
1174 for a
:= 0 to High(FButtons
) do
1175 if (FButtons
[a
] <> nil) and (FButtons
[a
].Name
= aName
) then
1177 Result
:= FButtons
[a
];
1182 procedure TGUIMainMenu
.OnMessage(var Msg
: TMessage
);
1187 if not FEnabled
then Exit
;
1191 if FButtons
= nil then Exit
;
1194 for a
:= 0 to High(FButtons
) do
1195 if FButtons
[a
] <> nil then
1201 if not ok
then Exit
;
1206 IK_UP
, IK_KPUP
, VK_UP
, JOY0_UP
, JOY1_UP
, JOY2_UP
, JOY3_UP
:
1210 if FIndex
< 0 then FIndex
:= High(FButtons
);
1211 until FButtons
[FIndex
] <> nil;
1213 {$IFDEF ENABLE_SOUND}
1214 g_Sound_PlayEx(MENU_CHANGESOUND
);
1217 IK_DOWN
, IK_KPDOWN
, VK_DOWN
, JOY0_DOWN
, JOY1_DOWN
, JOY2_DOWN
, JOY3_DOWN
:
1221 if FIndex
> High(FButtons
) then FIndex
:= 0;
1222 until FButtons
[FIndex
] <> nil;
1224 {$IFDEF ENABLE_SOUND}
1225 g_Sound_PlayEx(MENU_CHANGESOUND
);
1228 IK_RETURN
, IK_KPRETURN
, IK_SELECT
,
1229 VK_FIRE
, VK_OPEN
, JOY0_ATTACK
,
1230 JOY1_ATTACK
, JOY2_ATTACK
, JOY3_ATTACK
:
1231 if (FIndex
<> -1) and FButtons
[FIndex
].FEnabled
then
1232 FButtons
[FIndex
].Click
;
1237 procedure TGUIMainMenu
.Update
;
1243 if FCounter
= 0 then
1246 FMarkerID1
:= FMarkerID2
;
1249 FCounter
:= MAINMENU_MARKERDELAY
;
1250 end else Dec(FCounter
);
1255 constructor TGUILabel
.Create(Text: string; FontID
: DWORD
);
1259 FFont
:= TFont
.Create(FontID
, TFontType
.Character
);
1263 FOnClickEvent
:= nil;
1266 destructor TGUILabel
.Destroy();
1272 procedure TGUILabel
.Draw
;
1278 FFont
.GetTextSize(FText
, w
, h
);
1279 FFont
.Draw(FX
+FMaxWidth
-w
, FY
, FText
, FColor
.R
, FColor
.G
, FColor
.B
);
1283 FFont
.Draw(FX
, FY
, FText
, FColor
.R
, FColor
.G
, FColor
.B
);
1287 function TGUILabel
.GetHeight
: Integer;
1291 FFont
.GetTextSize(FText
, w
, h
);
1295 function TGUILabel
.GetWidth
: Integer;
1299 if FFixedLen
= 0 then
1300 FFont
.GetTextSize(FText
, w
, h
)
1302 w
:= e_CharFont_GetMaxWidth(FFont
.ID
)*FFixedLen
;
1306 procedure TGUILabel
.OnMessage(var Msg
: TMessage
);
1308 if not FEnabled
then Exit
;
1315 IK_RETURN
, IK_KPRETURN
, IK_SELECT
,
1317 JOY0_ATTACK
, JOY1_ATTACK
, JOY2_ATTACK
, JOY3_ATTACK
:
1318 if @FOnClickEvent
<> nil then
1326 function TGUIMenu
.AddButton(Proc
: Pointer; fText
: string; _ShowWindow
: string = ''): TGUITextButton
;
1333 Control
:= TGUITextButton
.Create(Proc
, FFontID
, fText
);
1334 with TGUITextButton(Control
) do
1336 ShowWindow
:= _ShowWindow
;
1337 FColor
:= MENU_ITEMSCTRL_COLOR
;
1342 ControlType
:= TGUITextButton
;
1343 Result
:= TGUITextButton(Control
);
1346 if FIndex
= -1 then FIndex
:= i
;
1351 procedure TGUIMenu
.AddLine(fText
: string);
1358 Text := TGUILabel
.Create(fText
, FFontID
);
1361 FColor
:= MENU_ITEMSTEXT_COLOR
;
1370 procedure TGUIMenu
.AddText(fText
: string; MaxWidth
: Word);
1375 l
:= GetLines(fText
, FFontID
, MaxWidth
);
1377 if l
= nil then Exit
;
1379 for a
:= 0 to High(l
) do
1384 Text := TGUILabel
.Create(l
[a
], FFontID
);
1387 with Text do begin FColor
:= _RGB(255, 0, 0); end;
1391 with Text do begin FColor
:= MENU_ITEMSTEXT_COLOR
; end;
1401 procedure TGUIMenu
.AddSpace
;
1415 constructor TGUIMenu
.Create(HeaderFont
, ItemsFont
: DWORD
; Header
: string);
1421 FFontID
:= ItemsFont
;
1422 FCounter
:= MENU_MARKERDELAY
;
1426 FHeader
:= TGUILabel
.Create(Header
, HeaderFont
);
1429 FX
:= (gScreenWidth
div 2)-(GetWidth
div 2);
1431 FColor
:= MAINMENU_HEADER_COLOR
;
1435 destructor TGUIMenu
.Destroy
;
1439 if FItems
<> nil then
1440 for a
:= 0 to High(FItems
) do
1454 procedure TGUIMenu
.Draw
;
1456 a
, locx
, locy
: Integer;
1460 if FHeader
<> nil then FHeader
.Draw
;
1462 if FItems
<> nil then
1463 for a
:= 0 to High(FItems
) do
1465 if FItems
[a
].Text <> nil then FItems
[a
].Text.Draw
;
1466 if FItems
[a
].Control
<> nil then FItems
[a
].Control
.Draw
;
1469 if (FIndex
<> -1) and (FCounter
> MENU_MARKERDELAY
div 2) then
1474 if FItems
[FIndex
].Text <> nil then
1476 locx
:= FItems
[FIndex
].Text.FX
;
1477 locy
:= FItems
[FIndex
].Text.FY
;
1479 if FItems
[FIndex
].Text.RightAlign
then
1481 locx
:= locx
+FItems
[FIndex
].Text.FMaxWidth
-FItems
[FIndex
].Text.GetWidth
;
1484 else if FItems
[FIndex
].Control
<> nil then
1486 locx
:= FItems
[FIndex
].Control
.FX
;
1487 locy
:= FItems
[FIndex
].Control
.FY
;
1490 locx
:= locx
-e_CharFont_GetMaxWidth(FFontID
);
1492 e_CharFont_PrintEx(FFontID
, locx
, locy
, #16, _RGB(255, 0, 0));
1496 function TGUIMenu
.GetControl(aName
: String): TGUIControl
;
1502 if FItems
<> nil then
1503 for a
:= 0 to High(FItems
) do
1504 if FItems
[a
].Control
<> nil then
1505 if LowerCase(FItems
[a
].Control
.Name
) = LowerCase(aName
) then
1507 Result
:= FItems
[a
].Control
;
1511 Assert(Result
<> nil, 'GUI control "'+aName
+'" not found!');
1514 function TGUIMenu
.GetControlsText(aName
: String): TGUILabel
;
1520 if FItems
<> nil then
1521 for a
:= 0 to High(FItems
) do
1522 if FItems
[a
].Control
<> nil then
1523 if LowerCase(FItems
[a
].Control
.Name
) = LowerCase(aName
) then
1525 Result
:= FItems
[a
].Text;
1529 Assert(Result
<> nil, 'GUI control''s text "'+aName
+'" not found!');
1532 function TGUIMenu
.NewItem
: Integer;
1534 SetLength(FItems
, Length(FItems
)+1);
1535 Result
:= High(FItems
);
1538 procedure TGUIMenu
.OnMessage(var Msg
: TMessage
);
1543 if not FEnabled
then Exit
;
1547 if FItems
= nil then Exit
;
1550 for a
:= 0 to High(FItems
) do
1551 if FItems
[a
].Control
<> nil then
1557 if not ok
then Exit
;
1559 if (Msg
.Msg
= WM_KEYDOWN
) and (FIndex
<> -1) and (FItems
[FIndex
].Control
<> nil) and
1560 (FItems
[FIndex
].Control
.WantActivationKey(Msg
.wParam
)) then
1562 FItems
[FIndex
].Control
.OnMessage(Msg
);
1563 {$IFDEF ENABLE_SOUND}
1564 g_Sound_PlayEx(MENU_CLICKSOUND
);
1573 IK_UP
, IK_KPUP
, VK_UP
,JOY0_UP
, JOY1_UP
, JOY2_UP
, JOY3_UP
:
1578 if c
> Length(FItems
) then
1585 if FIndex
< 0 then FIndex
:= High(FItems
);
1586 until (FItems
[FIndex
].Control
<> nil) and
1587 (FItems
[FIndex
].Control
.Enabled
);
1591 {$IFDEF ENABLE_SOUND}
1592 g_Sound_PlayEx(MENU_CHANGESOUND
);
1596 IK_DOWN
, IK_KPDOWN
, VK_DOWN
, JOY0_DOWN
, JOY1_DOWN
, JOY2_DOWN
, JOY3_DOWN
:
1601 if c
> Length(FItems
) then
1608 if FIndex
> High(FItems
) then FIndex
:= 0;
1609 until (FItems
[FIndex
].Control
<> nil) and
1610 (FItems
[FIndex
].Control
.Enabled
);
1614 {$IFDEF ENABLE_SOUND}
1615 g_Sound_PlayEx(MENU_CHANGESOUND
);
1619 IK_LEFT
, IK_RIGHT
, IK_KPLEFT
, IK_KPRIGHT
, VK_LEFT
, VK_RIGHT
,
1620 JOY0_LEFT
, JOY1_LEFT
, JOY2_LEFT
, JOY3_LEFT
,
1621 JOY0_RIGHT
, JOY1_RIGHT
, JOY2_RIGHT
, JOY3_RIGHT
:
1623 if FIndex
<> -1 then
1624 if FItems
[FIndex
].Control
<> nil then
1625 FItems
[FIndex
].Control
.OnMessage(Msg
);
1627 IK_RETURN
, IK_KPRETURN
, IK_SELECT
,
1629 JOY0_ATTACK
, JOY1_ATTACK
, JOY2_ATTACK
, JOY3_ATTACK
:
1631 if FIndex
<> -1 then
1633 if FItems
[FIndex
].Control
<> nil then FItems
[FIndex
].Control
.OnMessage(Msg
);
1635 {$IFDEF ENABLE_SOUND}
1636 g_Sound_PlayEx(MENU_CLICKSOUND
);
1641 if FYesNo
and (length(FItems
) > 1) then
1643 Msg
.wParam
:= IK_RETURN
; // to register keypress
1644 FIndex
:= High(FItems
)-1;
1645 if FItems
[FIndex
].Control
<> nil then FItems
[FIndex
].Control
.OnMessage(Msg
);
1648 if FYesNo
and (length(FItems
) > 1) then
1650 Msg
.wParam
:= IK_RETURN
; // to register keypress
1651 FIndex
:= High(FItems
);
1652 if FItems
[FIndex
].Control
<> nil then FItems
[FIndex
].Control
.OnMessage(Msg
);
1659 procedure TGUIMenu
.ReAlign();
1661 a
, tx
, cx
, w
, h
: Integer;
1662 cww
: array of Integer; // cached widths
1665 if FItems
= nil then Exit
;
1667 SetLength(cww
, length(FItems
));
1669 for a
:= 0 to High(FItems
) do
1671 if FItems
[a
].Text <> nil then
1673 cww
[a
] := FItems
[a
].Text.GetWidth
;
1674 if maxcww
< cww
[a
] then maxcww
:= cww
[a
];
1685 for a
:= 0 to High(FItems
) do
1688 if FItems
[a
].Text <> nil then w
:= FItems
[a
].Text.GetWidth
;
1689 if FItems
[a
].Control
<> nil then
1692 if FItems
[a
].ControlType
= TGUILabel
then w
+= TGUILabel(FItems
[a
].Control
).GetWidth
1693 else if FItems
[a
].ControlType
= TGUITextButton
then w
+= TGUITextButton(FItems
[a
].Control
).GetWidth
1694 else if FItems
[a
].ControlType
= TGUIScroll
then w
+= TGUIScroll(FItems
[a
].Control
).GetWidth
1695 else if FItems
[a
].ControlType
= TGUISwitch
then w
+= TGUISwitch(FItems
[a
].Control
).GetWidth
1696 else if FItems
[a
].ControlType
= TGUIEdit
then w
+= TGUIEdit(FItems
[a
].Control
).GetWidth
1697 else if FItems
[a
].ControlType
= TGUIKeyRead
then w
+= TGUIKeyRead(FItems
[a
].Control
).GetWidth
1698 else if FItems
[a
].ControlType
= TGUIKeyRead2
then w
+= TGUIKeyRead2(FItems
[a
].Control
).GetWidth
1699 else if FItems
[a
].ControlType
= TGUIListBox
then w
+= TGUIListBox(FItems
[a
].Control
).GetWidth
1700 else if FItems
[a
].ControlType
= TGUIFileListBox
then w
+= TGUIFileListBox(FItems
[a
].Control
).GetWidth
1701 else if FItems
[a
].ControlType
= TGUIMemo
then w
+= TGUIMemo(FItems
[a
].Control
).GetWidth
;
1703 tx
:= Min(tx
, (gScreenWidth
div 2)-(w
div 2));
1708 for a
:= 0 to High(FItems
) do
1712 if (Text <> nil) and (Control
= nil) then Continue
;
1714 if Text <> nil then w
:= tx
+Text.GetWidth
;
1715 if w
> cx
then cx
:= w
;
1721 h
:= FHeader
.GetHeight
*2+MENU_VSPACE
*(Length(FItems
)-1);
1723 for a
:= 0 to High(FItems
) do
1727 if (ControlType
= TGUIListBox
) or (ControlType
= TGUIFileListBox
) then
1728 h
+= (FItems
[a
].Control
as TGUIListBox
).GetHeight() // FIXME: possible mistyping?..
1730 h
+= e_CharFont_GetMaxHeight(FFontID
);
1734 h
:= (gScreenHeight
div 2)-(h
div 2);
1738 FX
:= (gScreenWidth
div 2)-(GetWidth
div 2);
1741 Inc(h
, GetHeight
*2);
1744 for a
:= 0 to High(FItems
) do
1756 if Text.RightAlign
and (length(cww
) > a
) then
1758 //Text.FX := Text.FX+maxcww;
1759 Text.FMaxWidth
:= maxcww
;
1763 if Control
<> nil then
1781 if (ControlType
= TGUIListBox
) or (ControlType
= TGUIFileListBox
) then
1782 h
+= (Control
as TGUIListBox
).GetHeight
// FIXME: possible mistyping?..
1783 else if ControlType
= TGUIMemo
then
1784 h
+= TGUIMemo(Control
).GetHeight
1786 h
+= e_CharFont_GetMaxHeight(FFontID
);
1790 // another ugly hack
1791 if FYesNo
and (length(FItems
) > 1) then
1794 for a
:= High(FItems
)-1 to High(FItems
) do
1796 if (FItems
[a
].Control
<> nil) and (FItems
[a
].ControlType
= TGUITextButton
) then
1798 cx
:= TGUITextButton(FItems
[a
].Control
).GetWidth
;
1799 if cx
> w
then w
:= cx
;
1804 for a
:= High(FItems
)-1 to High(FItems
) do
1806 if (FItems
[a
].Control
<> nil) and (FItems
[a
].ControlType
= TGUITextButton
) then
1808 FItems
[a
].Control
.FX
:= (gScreenWidth
-w
) div 2;
1815 function TGUIMenu
.AddScroll(fText
: string): TGUIScroll
;
1822 Control
:= TGUIScroll
.Create();
1824 Text := TGUILabel
.Create(fText
, FFontID
);
1825 Text.FColor
:= MENU_ITEMSTEXT_COLOR
;
1827 ControlType
:= TGUIScroll
;
1828 Result
:= TGUIScroll(Control
);
1831 if FIndex
= -1 then FIndex
:= i
;
1836 function TGUIMenu
.AddSwitch(fText
: string): TGUISwitch
;
1843 Control
:= TGUISwitch
.Create(FFontID
);
1844 TGUISwitch(Control
).FColor
:= MENU_ITEMSCTRL_COLOR
;
1846 Text := TGUILabel
.Create(fText
, FFontID
);
1847 Text.FColor
:= MENU_ITEMSTEXT_COLOR
;
1849 ControlType
:= TGUISwitch
;
1850 Result
:= TGUISwitch(Control
);
1853 if FIndex
= -1 then FIndex
:= i
;
1858 function TGUIMenu
.AddEdit(fText
: string): TGUIEdit
;
1865 Control
:= TGUIEdit
.Create(FFontID
);
1866 with TGUIEdit(Control
) do
1868 FWindow
:= Self
.FWindow
;
1869 FColor
:= MENU_ITEMSCTRL_COLOR
;
1872 if fText
= '' then Text := nil else
1874 Text := TGUILabel
.Create(fText
, FFontID
);
1875 Text.FColor
:= MENU_ITEMSTEXT_COLOR
;
1878 ControlType
:= TGUIEdit
;
1879 Result
:= TGUIEdit(Control
);
1882 if FIndex
= -1 then FIndex
:= i
;
1887 procedure TGUIMenu
.Update
;
1893 if FCounter
= 0 then FCounter
:= MENU_MARKERDELAY
else Dec(FCounter
);
1895 if FItems
<> nil then
1896 for a
:= 0 to High(FItems
) do
1897 if FItems
[a
].Control
<> nil then
1898 (FItems
[a
].Control
as FItems
[a
].ControlType
).Update
; // FIXME: improper polymorphism.
1901 function TGUIMenu
.AddKeyRead(fText
: string): TGUIKeyRead
;
1908 Control
:= TGUIKeyRead
.Create(FFontID
);
1909 with TGUIKeyRead(Control
) do
1911 FWindow
:= Self
.FWindow
;
1912 FColor
:= MENU_ITEMSCTRL_COLOR
;
1915 Text := TGUILabel
.Create(fText
, FFontID
);
1916 Text.FColor
:= MENU_ITEMSTEXT_COLOR
;
1918 ControlType
:= TGUIKeyRead
;
1919 Result
:= TGUIKeyRead(Control
);
1922 if FIndex
= -1 then FIndex
:= i
;
1927 function TGUIMenu
.AddKeyRead2(fText
: string): TGUIKeyRead2
;
1934 Control
:= TGUIKeyRead2
.Create(FFontID
);
1935 with TGUIKeyRead2(Control
) do
1937 FWindow
:= Self
.FWindow
;
1938 FColor
:= MENU_ITEMSCTRL_COLOR
;
1941 Text := TGUILabel
.Create(fText
, FFontID
);
1944 FColor
:= MENU_ITEMSCTRL_COLOR
; //MENU_ITEMSTEXT_COLOR;
1948 ControlType
:= TGUIKeyRead2
;
1949 Result
:= TGUIKeyRead2(Control
);
1952 if FIndex
= -1 then FIndex
:= i
;
1957 function TGUIMenu
.AddList(fText
: string; Width
, Height
: Word): TGUIListBox
;
1964 Control
:= TGUIListBox
.Create(FFontID
, Width
, Height
);
1965 with TGUIListBox(Control
) do
1967 FWindow
:= Self
.FWindow
;
1968 FActiveColor
:= MENU_ITEMSCTRL_COLOR
;
1969 FUnActiveColor
:= MENU_ITEMSTEXT_COLOR
;
1972 Text := TGUILabel
.Create(fText
, FFontID
);
1973 Text.FColor
:= MENU_ITEMSTEXT_COLOR
;
1975 ControlType
:= TGUIListBox
;
1976 Result
:= TGUIListBox(Control
);
1979 if FIndex
= -1 then FIndex
:= i
;
1984 function TGUIMenu
.AddFileList(fText
: string; Width
, Height
: Word): TGUIFileListBox
;
1991 Control
:= TGUIFileListBox
.Create(FFontID
, Width
, Height
);
1992 with TGUIFileListBox(Control
) do
1994 FWindow
:= Self
.FWindow
;
1995 FActiveColor
:= MENU_ITEMSCTRL_COLOR
;
1996 FUnActiveColor
:= MENU_ITEMSTEXT_COLOR
;
1999 if fText
= '' then Text := nil else
2001 Text := TGUILabel
.Create(fText
, FFontID
);
2002 Text.FColor
:= MENU_ITEMSTEXT_COLOR
;
2005 ControlType
:= TGUIFileListBox
;
2006 Result
:= TGUIFileListBox(Control
);
2009 if FIndex
= -1 then FIndex
:= i
;
2014 function TGUIMenu
.AddLabel(fText
: string): TGUILabel
;
2021 Control
:= TGUILabel
.Create('', FFontID
);
2022 with TGUILabel(Control
) do
2024 FWindow
:= Self
.FWindow
;
2025 FColor
:= MENU_ITEMSCTRL_COLOR
;
2028 Text := TGUILabel
.Create(fText
, FFontID
);
2029 Text.FColor
:= MENU_ITEMSTEXT_COLOR
;
2031 ControlType
:= TGUILabel
;
2032 Result
:= TGUILabel(Control
);
2035 if FIndex
= -1 then FIndex
:= i
;
2040 function TGUIMenu
.AddMemo(fText
: string; Width
, Height
: Word): TGUIMemo
;
2047 Control
:= TGUIMemo
.Create(FFontID
, Width
, Height
);
2048 with TGUIMemo(Control
) do
2050 FWindow
:= Self
.FWindow
;
2051 FColor
:= MENU_ITEMSTEXT_COLOR
;
2054 if fText
= '' then Text := nil else
2056 Text := TGUILabel
.Create(fText
, FFontID
);
2057 Text.FColor
:= MENU_ITEMSTEXT_COLOR
;
2060 ControlType
:= TGUIMemo
;
2061 Result
:= TGUIMemo(Control
);
2064 if FIndex
= -1 then FIndex
:= i
;
2069 procedure TGUIMenu
.UpdateIndex();
2077 if (FIndex
< 0) or (FIndex
> High(FItems
)) then
2083 if FItems
[FIndex
].Control
.Enabled
then
2092 constructor TGUIScroll
.Create
;
2097 FOnChangeEvent
:= nil;
2099 g_Texture_Get(SCROLL_LEFT
, FLeftID
);
2100 g_Texture_Get(SCROLL_RIGHT
, FRightID
);
2101 g_Texture_Get(SCROLL_MIDDLE
, FMiddleID
);
2102 g_Texture_Get(SCROLL_MARKER
, FMarkerID
);
2105 procedure TGUIScroll
.Draw
;
2111 e_Draw(FLeftID
, FX
, FY
, 0, True, False);
2112 e_Draw(FRightID
, FX
+8+(FMax
+1)*8, FY
, 0, True, False);
2114 for a
:= 0 to FMax
do
2115 e_Draw(FMiddleID
, FX
+8+a
*8, FY
, 0, True, False);
2117 e_Draw(FMarkerID
, FX
+8+FValue
*8, FY
, 0, True, False);
2120 procedure TGUIScroll
.FSetValue(a
: Integer);
2122 if a
> FMax
then FValue
:= FMax
else FValue
:= a
;
2125 function TGUIScroll
.GetWidth
: Integer;
2127 Result
:= 16+(FMax
+1)*8;
2130 procedure TGUIScroll
.OnMessage(var Msg
: TMessage
);
2132 if not FEnabled
then Exit
;
2140 IK_LEFT
, IK_KPLEFT
, VK_LEFT
, JOY0_LEFT
, JOY1_LEFT
, JOY2_LEFT
, JOY3_LEFT
:
2144 {$IFDEF ENABLE_SOUND}
2145 g_Sound_PlayEx(SCROLL_SUBSOUND
);
2147 if @FOnChangeEvent
<> nil then FOnChangeEvent(Self
);
2149 IK_RIGHT
, IK_KPRIGHT
, VK_RIGHT
, JOY0_RIGHT
, JOY1_RIGHT
, JOY2_RIGHT
, JOY3_RIGHT
:
2150 if FValue
< FMax
then
2153 {$IFDEF ENABLE_SOUND}
2154 g_Sound_PlayEx(SCROLL_ADDSOUND
);
2156 if @FOnChangeEvent
<> nil then FOnChangeEvent(Self
);
2165 procedure TGUISwitch
.AddItem(Item
: string);
2167 SetLength(FItems
, Length(FItems
)+1);
2168 FItems
[High(FItems
)] := Item
;
2170 if FIndex
= -1 then FIndex
:= 0;
2173 constructor TGUISwitch
.Create(FontID
: DWORD
);
2179 FFont
:= TFont
.Create(FontID
, TFontType
.Character
);
2182 destructor TGUISwitch
.Destroy();
2188 procedure TGUISwitch
.Draw
;
2192 FFont
.Draw(FX
, FY
, FItems
[FIndex
], FColor
.R
, FColor
.G
, FColor
.B
);
2195 function TGUISwitch
.GetText
: string;
2197 if FIndex
<> -1 then Result
:= FItems
[FIndex
]
2201 function TGUISwitch
.GetWidth
: Integer;
2208 if FItems
= nil then Exit
;
2210 for a
:= 0 to High(FItems
) do
2212 FFont
.GetTextSize(FItems
[a
], w
, h
);
2213 if w
> Result
then Result
:= w
;
2217 procedure TGUISwitch
.OnMessage(var Msg
: TMessage
);
2219 if not FEnabled
then Exit
;
2223 if FItems
= nil then Exit
;
2228 IK_RETURN
, IK_KPRETURN
, IK_RIGHT
, IK_KPRIGHT
, IK_SELECT
,
2229 VK_FIRE
, VK_OPEN
, VK_RIGHT
,
2230 JOY0_RIGHT
, JOY1_RIGHT
, JOY2_RIGHT
, JOY3_RIGHT
,
2231 JOY0_ATTACK
, JOY1_ATTACK
, JOY2_ATTACK
, JOY3_ATTACK
:
2233 if FIndex
< High(FItems
) then
2238 {$IFDEF ENABLE_SOUND}
2239 g_Sound_PlayEx(SCROLL_ADDSOUND
);
2242 if @FOnChangeEvent
<> nil then
2243 FOnChangeEvent(Self
);
2246 IK_LEFT
, IK_KPLEFT
, VK_LEFT
,
2247 JOY0_LEFT
, JOY1_LEFT
, JOY2_LEFT
, JOY3_LEFT
:
2252 FIndex
:= High(FItems
);
2254 {$IFDEF ENABLE_SOUND}
2255 g_Sound_PlayEx(SCROLL_SUBSOUND
);
2258 if @FOnChangeEvent
<> nil then
2259 FOnChangeEvent(Self
);
2267 constructor TGUIEdit
.Create(FontID
: DWORD
);
2271 FFont
:= TFont
.Create(FontID
, TFontType
.Character
);
2277 g_Texture_Get(EDIT_LEFT
, FLeftID
);
2278 g_Texture_Get(EDIT_RIGHT
, FRightID
);
2279 g_Texture_Get(EDIT_MIDDLE
, FMiddleID
);
2282 destructor TGUIEdit
.Destroy();
2288 procedure TGUIEdit
.Draw
;
2295 e_Draw(FLeftID
, FX
, FY
, 0, True, False);
2296 e_Draw(FRightID
, FX
+8+FWidth
*16, FY
, 0, True, False);
2298 for c
:= 0 to FWidth
-1 do
2299 e_Draw(FMiddleID
, FX
+8+c
*16, FY
, 0, True, False);
2304 if FInvalid
and (FWindow
.FActiveControl
<> self
) then begin r
:= 128; g
:= 128; b
:= 128; end;
2305 FFont
.Draw(FX
+8, FY
, FText
, r
, g
, b
);
2307 if (FWindow
.FActiveControl
= self
) then
2309 FFont
.GetTextSize(Copy(FText
, 1, FCaretPos
), w
, h
);
2310 h
:= e_CharFont_GetMaxHeight(FFont
.ID
);
2311 e_DrawLine(2, FX
+8+w
, FY
+h
-3, FX
+8+w
+EDIT_CURSORLEN
, FY
+h
-3,
2312 EDIT_CURSORCOLOR
.R
, EDIT_CURSORCOLOR
.G
, EDIT_CURSORCOLOR
.B
);
2316 function TGUIEdit
.GetWidth
: Integer;
2318 Result
:= 16+FWidth
*16;
2321 procedure TGUIEdit
.OnMessage(var Msg
: TMessage
);
2323 if not FEnabled
then Exit
;
2332 if (wParam
in [48..57]) and (Chr(wParam
) <> '`') then
2333 if Length(Text) < FMaxLength
then
2335 Insert(Chr(wParam
), FText
, FCaretPos
+ 1);
2341 if (wParam
in [32..255]) and (Chr(wParam
) <> '`') then
2342 if Length(Text) < FMaxLength
then
2344 Insert(Chr(wParam
), FText
, FCaretPos
+ 1);
2352 Delete(FText
, FCaretPos
, 1);
2353 if FCaretPos
> 0 then Dec(FCaretPos
);
2355 IK_DELETE
: Delete(FText
, FCaretPos
+ 1, 1);
2356 IK_END
, IK_KPEND
: FCaretPos
:= Length(FText
);
2357 IK_HOME
, IK_KPHOME
: FCaretPos
:= 0;
2358 IK_LEFT
, IK_KPLEFT
, VK_LEFT
, JOY0_LEFT
, JOY1_LEFT
, JOY2_LEFT
, JOY3_LEFT
: if FCaretPos
> 0 then Dec(FCaretPos
);
2359 IK_RIGHT
, IK_KPRIGHT
, VK_RIGHT
, JOY0_RIGHT
, JOY1_RIGHT
, JOY2_RIGHT
, JOY3_RIGHT
: if FCaretPos
< Length(FText
) then Inc(FCaretPos
);
2360 IK_RETURN
, IK_KPRETURN
, IK_SELECT
,
2362 JOY0_ATTACK
, JOY1_ATTACK
, JOY2_ATTACK
, JOY3_ATTACK
:
2365 if FActiveControl
<> Self
then
2368 if @FOnEnterEvent
<> nil then FOnEnterEvent(Self
);
2372 if FDefControl
<> '' then SetActive(GetControl(FDefControl
))
2373 else SetActive(nil);
2374 if @FOnChangeEvent
<> nil then FOnChangeEvent(Self
);
2380 g_GUIGrabInput
:= (@FOnEnterEvent
= nil) and (FWindow
.FActiveControl
= Self
);
2381 g_Touch_ShowKeyboard(g_GUIGrabInput
)
2384 procedure TGUIEdit
.SetText(Text: string);
2386 if Length(Text) > FMaxLength
then SetLength(Text, FMaxLength
);
2388 FCaretPos
:= Length(FText
);
2393 constructor TGUIKeyRead
.Create(FontID
: DWORD
);
2399 FFont
:= TFont
.Create(FontID
, TFontType
.Character
);
2402 destructor TGUIKeyRead
.Destroy();
2408 procedure TGUIKeyRead
.Draw
;
2412 FFont
.Draw(FX
, FY
, IfThen(FIsQuery
, KEYREAD_QUERY
, IfThen(FKey
<> 0, e_KeyNames
[FKey
], KEYREAD_CLEAR
)),
2413 FColor
.R
, FColor
.G
, FColor
.B
);
2416 function TGUIKeyRead
.GetWidth
: Integer;
2423 for a
:= 0 to 255 do
2425 FFont
.GetTextSize(e_KeyNames
[a
], w
, h
);
2426 Result
:= Max(Result
, w
);
2429 FFont
.GetTextSize(KEYREAD_QUERY
, w
, h
);
2430 if w
> Result
then Result
:= w
;
2432 FFont
.GetTextSize(KEYREAD_CLEAR
, w
, h
);
2433 if w
> Result
then Result
:= w
;
2436 function TGUIKeyRead
.WantActivationKey (key
: LongInt): Boolean;
2439 (key
= IK_BACKSPACE
) or
2443 procedure TGUIKeyRead
.OnMessage(var Msg
: TMessage
);
2444 procedure actDefCtl ();
2447 if FDefControl
<> '' then
2448 SetActive(GetControl(FDefControl
))
2456 if not FEnabled
then
2462 if not FIsQuery
then
2465 IK_RETURN
, IK_KPRETURN
, IK_SELECT
,
2467 JOY0_ATTACK
, JOY1_ATTACK
, JOY2_ATTACK
, JOY3_ATTACK
:
2470 if FActiveControl
<> Self
then
2474 IK_BACKSPACE
: // clear keybinding if we aren't waiting for a key
2487 VK_FIRSTKEY
..VK_LASTKEY
: // do not allow to bind virtual keys
2493 if (e_KeyNames
[wParam
] <> '') and not g_Console_MatchBind(wParam
, 'togglemenu') then
2501 g_GUIGrabInput
:= FIsQuery
2506 constructor TGUIKeyRead2
.Create(FontID
: DWORD
);
2519 FFont
:= TFont
.Create(FontID
, TFontType
.Character
);
2521 FMaxKeyNameWdt
:= 0;
2522 for a
:= 0 to 255 do
2524 FFont
.GetTextSize(e_KeyNames
[a
], w
, h
);
2525 FMaxKeyNameWdt
:= Max(FMaxKeyNameWdt
, w
);
2528 FMaxKeyNameWdt
:= FMaxKeyNameWdt
-(FMaxKeyNameWdt
div 3);
2530 FFont
.GetTextSize(KEYREAD_QUERY
, w
, h
);
2531 if w
> FMaxKeyNameWdt
then FMaxKeyNameWdt
:= w
;
2533 FFont
.GetTextSize(KEYREAD_CLEAR
, w
, h
);
2534 if w
> FMaxKeyNameWdt
then FMaxKeyNameWdt
:= w
;
2537 destructor TGUIKeyRead2
.Destroy();
2543 procedure TGUIKeyRead2
.Draw
;
2544 procedure drawText (idx
: Integer);
2550 if idx
= 0 then kk
:= FKey0
else kk
:= FKey1
;
2552 if idx
= 0 then x
:= FX
+8 else x
:= FX
+8+FMaxKeyNameWdt
+16;
2556 if FKeyIdx
= idx
then begin r
:= 255; g
:= 255; b
:= 255; end;
2557 if FIsQuery
and (FKeyIdx
= idx
) then
2558 FFont
.Draw(x
, y
, KEYREAD_QUERY
, r
, g
, b
)
2560 FFont
.Draw(x
, y
, IfThen(kk
<> 0, e_KeyNames
[kk
], KEYREAD_CLEAR
), r
, g
, b
);
2566 //FFont.Draw(FX+8, FY, IfThen(FIsQuery and (FKeyIdx = 0), KEYREAD_QUERY, IfThen(FKey0 <> 0, e_KeyNames[FKey0], KEYREAD_CLEAR)), FColor.R, FColor.G, FColor.B);
2567 //FFont.Draw(FX+8+FMaxKeyNameWdt+16, FY, IfThen(FIsQuery and (FKeyIdx = 1), KEYREAD_QUERY, IfThen(FKey1 <> 0, e_KeyNames[FKey1], KEYREAD_CLEAR)), FColor.R, FColor.G, FColor.B);
2572 function TGUIKeyRead2
.GetWidth
: Integer;
2574 Result
:= FMaxKeyNameWdt
*2+8+8+16;
2577 function TGUIKeyRead2
.WantActivationKey (key
: LongInt): Boolean;
2580 IK_BACKSPACE
, IK_LEFT
, IK_RIGHT
, IK_KPLEFT
, IK_KPRIGHT
, VK_LEFT
, VK_RIGHT
,
2581 JOY0_LEFT
, JOY1_LEFT
, JOY2_LEFT
, JOY3_LEFT
,
2582 JOY0_RIGHT
, JOY1_RIGHT
, JOY2_RIGHT
, JOY3_RIGHT
:
2589 procedure TGUIKeyRead2
.OnMessage(var Msg
: TMessage
);
2590 procedure actDefCtl ();
2593 if FDefControl
<> '' then
2594 SetActive(GetControl(FDefControl
))
2602 if not FEnabled
then
2608 if not FIsQuery
then
2611 IK_RETURN
, IK_KPRETURN
, IK_SELECT
,
2613 JOY0_ATTACK
, JOY1_ATTACK
, JOY2_ATTACK
, JOY3_ATTACK
:
2616 if FActiveControl
<> Self
then
2620 IK_BACKSPACE
: // clear keybinding if we aren't waiting for a key
2622 if (FKeyIdx
= 0) then FKey0
:= 0 else FKey1
:= 0;
2625 IK_LEFT
, IK_KPLEFT
, VK_LEFT
, JOY0_LEFT
, JOY1_LEFT
, JOY2_LEFT
, JOY3_LEFT
:
2630 IK_RIGHT
, IK_KPRIGHT
, VK_RIGHT
, JOY0_RIGHT
, JOY1_RIGHT
, JOY2_RIGHT
, JOY3_RIGHT
:
2643 VK_FIRSTKEY
..VK_LASTKEY
: // do not allow to bind virtual keys
2649 if (e_KeyNames
[wParam
] <> '') and not g_Console_MatchBind(wParam
, 'togglemenu') then
2651 if (FKeyIdx
= 0) then FKey0
:= wParam
else FKey1
:= wParam
;
2659 g_GUIGrabInput
:= FIsQuery
2665 constructor TGUIModelView
.Create
;
2672 destructor TGUIModelView
.Destroy
;
2679 procedure TGUIModelView
.Draw
;
2683 DrawBox(FX
, FY
, 4, 4);
2685 if FModel
<> nil then FModel
.Draw(FX
+4, FY
+4);
2688 procedure TGUIModelView
.NextAnim();
2690 if FModel
= nil then
2693 if FModel
.Animation
< A_PAIN
then
2694 FModel
.ChangeAnimation(FModel
.Animation
+1, True)
2696 FModel
.ChangeAnimation(A_STAND
, True);
2699 procedure TGUIModelView
.NextWeapon();
2701 if FModel
= nil then
2704 if FModel
.Weapon
< WP_LAST
2705 then FModel
.SetWeapon(FModel
.Weapon
+1)
2706 else FModel
.SetWeapon(WEAPON_IRONFIST
);
2709 procedure TGUIModelView
.SetColor(Red
, Green
, Blue
: Byte);
2711 if FModel
<> nil then FModel
.SetColor(Red
, Green
, Blue
);
2714 procedure TGUIModelView
.SetModel(ModelName
: string);
2718 FModel
:= g_PlayerModel_Get(ModelName
);
2721 procedure TGUIModelView
.Update
;
2728 if FModel
<> nil then FModel
.Update
;
2733 constructor TGUIMapPreview
.Create();
2739 destructor TGUIMapPreview
.Destroy();
2745 procedure TGUIMapPreview
.Draw();
2752 DrawBox(FX
, FY
, MAPPREVIEW_WIDTH
, MAPPREVIEW_HEIGHT
);
2754 if (FMapSize
.X
<= 0) or (FMapSize
.Y
<= 0) then
2757 e_DrawFillQuad(FX
+4, FY
+4,
2758 FX
+4 + Trunc(FMapSize
.X
/ FScale
) - 1,
2759 FY
+4 + Trunc(FMapSize
.Y
/ FScale
) - 1,
2762 if FMapData
<> nil then
2763 for a
:= 0 to High(FMapData
) do
2766 if X1
> MAPPREVIEW_WIDTH
*16 then Continue
;
2767 if Y1
> MAPPREVIEW_HEIGHT
*16 then Continue
;
2769 if X2
< 0 then Continue
;
2770 if Y2
< 0 then Continue
;
2772 if X2
> MAPPREVIEW_WIDTH
*16 then X2
:= MAPPREVIEW_WIDTH
*16;
2773 if Y2
> MAPPREVIEW_HEIGHT
*16 then Y2
:= MAPPREVIEW_HEIGHT
*16;
2775 if X1
< 0 then X1
:= 0;
2776 if Y1
< 0 then Y1
:= 0;
2817 if ((X2
-X1
) > 0) and ((Y2
-Y1
) > 0) then
2818 e_DrawFillQuad(FX
+4 + X1
, FY
+4 + Y1
,
2819 FX
+4 + X2
- 1, FY
+4 + Y2
- 1, r
, g
, b
, 0);
2823 procedure TGUIMapPreview
.SetMap(Res
: string);
2828 //header: TMapHeaderRec_1;
2833 map
: TDynRecord
= nil;
2840 FileName
:= g_ExtractWadName(Res
);
2842 WAD
:= TWADFile
.Create();
2843 if not WAD
.ReadFile(FileName
) then
2849 //k8: ignores path again
2850 if not WAD
.GetMapResource(g_ExtractFileName(Res
), Data
, Len
) then
2859 map
:= g_Map_ParseMap(Data
, Len
);
2869 if (map
= nil) then exit
;
2872 panlist
:= map
.field
['panel'];
2873 //header := GetMapHeader(map);
2875 FMapSize
.X
:= map
.Width
div 16;
2876 FMapSize
.Y
:= map
.Height
div 16;
2878 rX
:= Ceil(map
.Width
/ (MAPPREVIEW_WIDTH
*256.0));
2879 rY
:= Ceil(map
.Height
/ (MAPPREVIEW_HEIGHT
*256.0));
2880 FScale
:= max(rX
, rY
);
2884 if (panlist
<> nil) then
2886 for pan
in panlist
do
2888 if (pan
.PanelType
and (PANEL_WALL
or PANEL_CLOSEDOOR
or
2889 PANEL_STEP
or PANEL_WATER
or
2890 PANEL_ACID1
or PANEL_ACID2
)) <> 0 then
2892 SetLength(FMapData
, Length(FMapData
)+1);
2893 with FMapData
[High(FMapData
)] do
2898 X2
:= (pan
.X
+ pan
.Width
) div 16;
2899 Y2
:= (pan
.Y
+ pan
.Height
) div 16;
2901 X1
:= Trunc(X1
/FScale
+ 0.5);
2902 Y1
:= Trunc(Y1
/FScale
+ 0.5);
2903 X2
:= Trunc(X2
/FScale
+ 0.5);
2904 Y2
:= Trunc(Y2
/FScale
+ 0.5);
2906 if (X1
<> X2
) or (Y1
<> Y2
) then
2914 PanelType
:= pan
.PanelType
;
2920 //writeln('freeing map');
2925 procedure TGUIMapPreview
.ClearMap();
2927 SetLength(FMapData
, 0);
2934 function TGUIMapPreview
.GetScaleStr(): String;
2936 if FScale
> 0.0 then
2938 Result
:= FloatToStrF(FScale
*16.0, ffFixed
, 3, 3);
2939 while (Result
[Length(Result
)] = '0') do
2940 Delete(Result
, Length(Result
), 1);
2941 if (Result
[Length(Result
)] = ',') or (Result
[Length(Result
)] = '.') then
2942 Delete(Result
, Length(Result
), 1);
2943 Result
:= '1 : ' + Result
;
2951 procedure TGUIListBox
.AddItem(Item
: string);
2953 SetLength(FItems
, Length(FItems
)+1);
2954 FItems
[High(FItems
)] := Item
;
2957 specialize TArrayHelper
<ShortString
>.Sort(FItems
,
2958 specialize TComparer
<ShortString
>.Construct(@ShortCompareText
));
2961 function TGUIListBox
.ItemExists (item
: String): Boolean;
2965 while (i
<= High(FItems
)) and (FItems
[i
] <> item
) do Inc(i
);
2966 result
:= i
<= High(FItems
)
2969 procedure TGUIListBox
.Clear
;
2977 constructor TGUIListBox
.Create(FontID
: DWORD
; Width
, Height
: Word);
2981 FFont
:= TFont
.Create(FontID
, TFontType
.Character
);
2986 FOnChangeEvent
:= nil;
2988 FDrawScroll
:= True;
2991 destructor TGUIListBox
.Destroy();
2997 procedure TGUIListBox
.Draw
;
3005 if FDrawBack
then DrawBox(FX
, FY
, FWidth
+1, FHeight
);
3007 DrawScroll(FX
+4+FWidth
*16, FY
+4, FHeight
, (FStartLine
> 0) and (FItems
<> nil),
3008 (FStartLine
+FHeight
-1 < High(FItems
)) and (FItems
<> nil));
3010 if FItems
<> nil then
3011 for a
:= FStartLine
to Min(High(FItems
), FStartLine
+FHeight
-1) do
3015 FFont
.GetTextSize(s
, w2
, h2
);
3016 while (Length(s
) > 0) and (w2
> FWidth
*16) do
3018 SetLength(s
, Length(s
)-1);
3019 FFont
.GetTextSize(s
, w2
, h2
);
3023 FFont
.Draw(FX
+4, FY
+4+(a
-FStartLine
)*16, s
, FActiveColor
.R
, FActiveColor
.G
, FActiveColor
.B
)
3025 FFont
.Draw(FX
+4, FY
+4+(a
-FStartLine
)*16, s
, FUnActiveColor
.R
, FUnActiveColor
.G
, FUnActiveColor
.B
);
3029 function TGUIListBox
.GetHeight
: Integer;
3031 Result
:= 8+FHeight
*16;
3034 function TGUIListBox
.GetWidth
: Integer;
3036 Result
:= 8+(FWidth
+1)*16;
3039 procedure TGUIListBox
.OnMessage(var Msg
: TMessage
);
3043 if not FEnabled
then Exit
;
3047 if FItems
= nil then Exit
;
3060 FIndex
:= High(FItems
);
3061 FStartLine
:= Max(High(FItems
)-FHeight
+1, 0);
3063 IK_UP
, IK_LEFT
, IK_KPUP
, IK_KPLEFT
, VK_LEFT
, JOY0_LEFT
, JOY1_LEFT
, JOY2_LEFT
, JOY3_LEFT
:
3067 if FIndex
< FStartLine
then Dec(FStartLine
);
3068 if @FOnChangeEvent
<> nil then FOnChangeEvent(Self
);
3070 IK_DOWN
, IK_RIGHT
, IK_KPDOWN
, IK_KPRIGHT
, VK_RIGHT
, JOY0_RIGHT
, JOY1_RIGHT
, JOY2_RIGHT
, JOY3_RIGHT
:
3071 if FIndex
< High(FItems
) then
3074 if FIndex
> FStartLine
+FHeight
-1 then Inc(FStartLine
);
3075 if @FOnChangeEvent
<> nil then FOnChangeEvent(Self
);
3077 IK_RETURN
, IK_KPRETURN
, IK_SELECT
,
3079 JOY0_ATTACK
, JOY1_ATTACK
, JOY2_ATTACK
, JOY3_ATTACK
:
3082 if FActiveControl
<> Self
then SetActive(Self
)
3084 if FDefControl
<> '' then SetActive(GetControl(FDefControl
))
3085 else SetActive(nil);
3089 for a
:= 0 to High(FItems
) do
3090 if (Length(FItems
[a
]) > 0) and (LowerCase(FItems
[a
][1]) = LowerCase(Chr(wParam
))) then
3093 FStartLine
:= Min(Max(FIndex
-1, 0), Length(FItems
)-FHeight
);
3094 if @FOnChangeEvent
<> nil then FOnChangeEvent(Self
);
3100 function TGUIListBox
.SelectedItem(): String;
3104 if (FIndex
< 0) or (FItems
= nil) or
3105 (FIndex
> High(FItems
)) then
3108 Result
:= FItems
[FIndex
];
3111 procedure TGUIListBox
.FSetItems(Items
: SSArray
);
3113 if FItems
<> nil then
3122 specialize TArrayHelper
<ShortString
>.Sort(FItems
,
3123 specialize TComparer
<ShortString
>.Construct(@ShortCompareText
));
3126 procedure TGUIListBox
.SelectItem(Item
: String);
3130 if FItems
= nil then
3134 Item
:= LowerCase(Item
);
3136 for a
:= 0 to High(FItems
) do
3137 if LowerCase(FItems
[a
]) = Item
then
3143 if FIndex
< FHeight
then
3146 FStartLine
:= Min(FIndex
, Length(FItems
)-FHeight
);
3149 procedure TGUIListBox
.FSetIndex(aIndex
: Integer);
3151 if FItems
= nil then
3154 if (aIndex
< 0) or (aIndex
> High(FItems
)) then
3159 if FIndex
<= FHeight
then
3162 FStartLine
:= Min(FIndex
, Length(FItems
)-FHeight
);
3167 procedure TGUIFileListBox
.OnMessage(var Msg
: TMessage
);
3169 a
, b
: Integer; s
: AnsiString
;
3171 if not FEnabled
then
3174 if FItems
= nil then
3185 if @FOnChangeEvent
<> nil then
3186 FOnChangeEvent(Self
);
3191 FIndex
:= High(FItems
);
3192 FStartLine
:= Max(High(FItems
)-FHeight
+1, 0);
3193 if @FOnChangeEvent
<> nil then
3194 FOnChangeEvent(Self
);
3197 IK_PAGEUP
, IK_KPPAGEUP
:
3200 then FIndex
-= FHeight
3203 if FStartLine
> FHeight
3204 then FStartLine
-= FHeight
3205 else FStartLine
:= 0;
3208 IK_PAGEDN
, IK_KPPAGEDN
:
3210 if FIndex
< High(FItems
)-FHeight
3211 then FIndex
+= FHeight
3212 else FIndex
:= High(FItems
);
3214 if FStartLine
< High(FItems
)-FHeight
3215 then FStartLine
+= FHeight
3216 else FStartLine
:= High(FItems
)-FHeight
+1;
3219 IK_UP
, IK_LEFT
, IK_KPUP
, IK_KPLEFT
, VK_UP
, VK_LEFT
, JOY0_LEFT
, JOY1_LEFT
, JOY2_LEFT
, JOY3_LEFT
:
3223 if FIndex
< FStartLine
then
3225 if @FOnChangeEvent
<> nil then
3226 FOnChangeEvent(Self
);
3229 IK_DOWN
, IK_RIGHT
, IK_KPDOWN
, IK_KPRIGHT
, VK_DOWN
, VK_RIGHT
, JOY0_RIGHT
, JOY1_RIGHT
, JOY2_RIGHT
, JOY3_RIGHT
:
3230 if FIndex
< High(FItems
) then
3233 if FIndex
> FStartLine
+FHeight
-1 then
3235 if @FOnChangeEvent
<> nil then
3236 FOnChangeEvent(Self
);
3239 IK_RETURN
, IK_KPRETURN
, IK_SELECT
,
3241 JOY0_ATTACK
, JOY1_ATTACK
, JOY2_ATTACK
, JOY3_ATTACK
:
3244 if FActiveControl
<> Self
then
3248 if FItems
[FIndex
][1] = #29 then // Ïàïêà
3250 if FItems
[FIndex
] = #29 + '..' then
3252 //e_LogWritefln('TGUIFileListBox: Upper dir "%s" -> "%s"', [FSubPath, e_UpperDir(FSubPath)]);
3253 FSubPath
:= e_UpperDir(FSubPath
)
3257 s
:= Copy(AnsiString(FItems
[FIndex
]), 2);
3258 //e_LogWritefln('TGUIFileListBox: Enter dir "%s" -> "%s"', [FSubPath, e_CatPath(FSubPath, s)]);
3260 // FIXME: hack for improper ConcatPaths(); see commit.
3263 else FSubPath
:= ConcatPaths([FSubPath
, s
]);
3270 if FDefControl
<> ''
3271 then SetActive(GetControl(FDefControl
))
3272 else SetActive(nil);
3278 for b
:= FIndex
+ 1 to High(FItems
) + FIndex
do
3280 a
:= b
mod Length(FItems
);
3281 if ( (Length(FItems
[a
]) > 0) and
3282 (LowerCase(FItems
[a
][1]) = LowerCase(Chr(wParam
))) ) or
3283 ( (Length(FItems
[a
]) > 1) and
3284 (FItems
[a
][1] = #29) and // Ïàïêà
3285 (LowerCase(FItems
[a
][2]) = LowerCase(Chr(wParam
))) ) then
3288 FStartLine
:= Min(Max(FIndex
-1, 0), Length(FItems
)-FHeight
);
3289 if @FOnChangeEvent
<> nil then
3290 FOnChangeEvent(Self
);
3297 procedure TGUIFileListBox
.ScanDirs();
3306 i
:= High(FBaseList
);
3309 // FIXME: hack for improper ConcatPaths(); see commit.
3310 path
:= AnsiString(FBaseList
[i
]);
3312 then path
:= FSubPath
3313 else path
:= ConcatPaths([path
, FSubPath
]);
3317 if FindFirst(path
+ '/' + '*', faDirectory
, SR
) = 0 then
3319 if LongBool(SR
.Attr
and faDirectory
) then
3320 if (SR
.Name
<> '.') and ((FSubPath
<> '') or (SR
.Name
<> '..')) then
3321 if not Self
.ItemExists(#1 + SR
.Name
) then
3322 Self
.AddItem(#1 + SR
.Name
);
3323 until FindNext(SR
) <> 0;
3329 i
:= High(FBaseList
);
3332 // FIXME: hack for improper ConcatPaths(); see commit.
3333 path
:= AnsiString(FBaseList
[i
]);
3335 then path
:= FSubPath
3336 else path
:= ConcatPaths([path
, FSubPath
]);
3343 j
:= Length(sm
) + 1;
3344 sc
:= Copy(sm
, 1, j
- 1);
3346 if FindFirst(path
+ '/' + sc
, faAnyFile
, SR
) = 0 then
3348 if not Self
.ItemExists(SR
.Name
) then
3350 until FindNext(SR
) <> 0;
3356 for i
:= 0 to High(FItems
) do
3357 if FItems
[i
][1] = #1 then
3358 FItems
[i
][1] := #29;
3361 procedure TGUIFileListBox
.SetBase (dirs
: SSArray
; path
: String);
3368 function TGUIFileListBox
.SelectedItem (): String;
3373 if (FIndex
>= 0) and (FIndex
<= High(FItems
)) and (FItems
[FIndex
][1] <> '/') and (FItems
[FIndex
][1] <> '\') then
3375 // FIXME: hack for improper ConcatPaths(); see commit.
3377 then s
:= FItems
[FIndex
]
3378 else s
:= ConcatPaths([FSubPath
, FItems
[FIndex
]]);
3380 if e_FindResource(FBaseList
, s
) then
3381 Result
:= ExpandFileName(s
)
3383 e_LogWritefln('TGUIFileListBox.SelectedItem -> "%s"', [Result
]);
3386 procedure TGUIFileListBox
.UpdateFileList();
3390 if (FIndex
= -1) or (FItems
= nil) or
3391 (FIndex
> High(FItems
)) or
3392 (FItems
[FIndex
][1] = '/') or
3393 (FItems
[FIndex
][1] = '\') then
3396 fn
:= FItems
[FIndex
];
3407 procedure TGUIMemo
.Clear
;
3413 constructor TGUIMemo
.Create(FontID
: DWORD
; Width
, Height
: Word);
3417 FFont
:= TFont
.Create(FontID
, TFontType
.Character
);
3422 FDrawScroll
:= True;
3425 destructor TGUIMemo
.Destroy();
3431 procedure TGUIMemo
.Draw
;
3437 if FDrawBack
then DrawBox(FX
, FY
, FWidth
+1, FHeight
);
3439 DrawScroll(FX
+4+FWidth
*16, FY
+4, FHeight
, (FStartLine
> 0) and (FLines
<> nil),
3440 (FStartLine
+FHeight
-1 < High(FLines
)) and (FLines
<> nil));
3442 if FLines
<> nil then
3443 for a
:= FStartLine
to Min(High(FLines
), FStartLine
+FHeight
-1) do
3444 FFont
.Draw(FX
+4, FY
+4+(a
-FStartLine
)*16, FLines
[a
], FColor
.R
, FColor
.G
, FColor
.B
);
3447 function TGUIMemo
.GetHeight
: Integer;
3449 Result
:= 8+FHeight
*16;
3452 function TGUIMemo
.GetWidth
: Integer;
3454 Result
:= 8+(FWidth
+1)*16;
3457 procedure TGUIMemo
.OnMessage(var Msg
: TMessage
);
3459 if not FEnabled
then Exit
;
3463 if FLines
= nil then Exit
;
3469 IK_UP
, IK_LEFT
, IK_KPUP
, IK_KPLEFT
, VK_UP
, VK_LEFT
, JOY0_LEFT
, JOY1_LEFT
, JOY2_LEFT
, JOY3_LEFT
:
3470 if FStartLine
> 0 then
3472 IK_DOWN
, IK_RIGHT
, IK_KPDOWN
, IK_KPRIGHT
, VK_DOWN
, VK_RIGHT
, JOY0_RIGHT
, JOY1_RIGHT
, JOY2_RIGHT
, JOY3_RIGHT
:
3473 if FStartLine
< Length(FLines
)-FHeight
then
3475 IK_RETURN
, IK_KPRETURN
, IK_SELECT
,
3477 JOY0_ATTACK
, JOY1_ATTACK
, JOY2_ATTACK
, JOY3_ATTACK
:
3480 if FActiveControl
<> Self
then
3486 if FDefControl
<> '' then SetActive(GetControl(FDefControl
))
3487 else SetActive(nil);
3493 procedure TGUIMemo
.SetText(Text: string);
3496 FLines
:= GetLines(Text, FFont
.ID
, FWidth
*16);
3501 procedure TGUIimage
.ClearImage();
3503 if FImageRes
= '' then Exit
;
3505 g_Texture_Delete(FImageRes
);
3509 constructor TGUIimage
.Create();
3516 procedure TGUIimage
.Draw();
3524 then Res
:= FDefaultRes
3525 else Res
:= FImageRes
;
3527 if g_Texture_Get(Res
, ID
) then
3528 e_Draw(ID
, FX
, FY
, 0, True, False);
3531 procedure TGUIimage
.SetImage(Res
: string);
3535 if g_Texture_CreateWADEx(Res
, Res
) then FImageRes
:= Res
;