DEADSOFTWARE

8df2b400683901d1f7ff64fedf827beeed961cd6
[d2df-sdl.git] / src / game / opengl / r_gui.pas
1 (* Copyright (C) Doom 2D: Forever Developers
2 *
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.
6 *
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.
11 *
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/>.
14 *)
15 {$INCLUDE ../../shared/a_modes.inc}
16 unit r_gui;
18 interface
20 uses g_gui;
22 procedure r_GUI_Load;
23 procedure r_GUI_Free;
25 procedure r_GUI_GetSize (ctrl: TGUIControl; out w, h: Integer);
26 procedure r_GUI_GetLogoSize (out w, h: WORD);
27 procedure r_GUI_GetMaxFontSize (BigFont: Boolean; out w, h: Integer);
28 procedure r_GUI_GetStringSize (BigFont: Boolean; str: String; out w, h: Integer);
30 procedure r_GUI_Draw_Window (win: TGUIWindow);
32 implementation
34 uses
35 Classes, Math,
36 MAPDEF, utils,
37 g_basic, g_base, e_input, g_options,
38 r_graphics, r_textures, r_playermodel, r_game,
39 g_game, g_menu
40 ;
42 const
43 BOX1 = 'BOX1';
44 BOX2 = 'BOX2';
45 BOX3 = 'BOX3';
46 BOX4 = 'BOX4';
47 BOX5 = 'BOX5';
48 BOX6 = 'BOX6';
49 BOX7 = 'BOX7';
50 BOX8 = 'BOX8';
51 BOX9 = 'BOX9';
53 type
54 TFontType = (Texture, Character);
56 TFont = class{$IFDEF USE_MEMPOOL}(TPoolObject){$ENDIF}
57 private
58 FID: DWORD;
59 FScale: Single;
60 FFontType: TFontType;
61 public
62 constructor Create(FontID: DWORD; FontType: TFontType);
63 destructor Destroy; override;
64 procedure Draw(X, Y: Integer; Text: string; R, G, B: Byte);
65 procedure GetTextSize(Text: string; var w, h: Word);
66 property Scale: Single read FScale write FScale;
67 property ID: DWORD read FID;
68 end;
70 var
71 Box: Array [0..8] of DWORD;
72 MarkerID: array [Boolean] of DWORD;
73 ScrollLeft, ScrollRight, ScrollMiddle, ScrollMarker: DWORD;
74 EditLeft, EditRight, EditMiddle: DWORD;
76 Font: array [boolean] of TFont; (* Small[FALSE] / Big[TRUE] *)
77 LogoTex: DWORD;
79 constructor TFont.Create (FontID: DWORD; FontType: TFontType);
80 begin
81 FID := FontID;
82 FScale := 1;
83 FFontType := FontType;
84 end;
86 destructor TFont.Destroy;
87 begin
88 inherited;
89 end;
91 procedure TFont.Draw (X, Y: Integer; Text: string; R, G, B: Byte);
92 begin
93 if FFontType = TFontType.Character then
94 e_CharFont_PrintEx(ID, X, Y, Text, _RGB(R, G, B), FScale)
95 else
96 e_TextureFontPrintEx(X, Y, Text, ID, R, G, B, FScale)
97 end;
99 procedure TFont.GetTextSize (Text: string; var w, h: Word);
100 var cw, ch: Byte;
101 begin
102 if FFontType = TFontType.Character then
103 e_CharFont_GetSize(ID, Text, w, h)
104 else
105 begin
106 e_TextureFontGetSize(ID, cw, ch);
107 w := cw * Length(Text);
108 h := ch;
109 end;
110 w := Round(w * FScale);
111 h := Round(h * FScale);
112 end;
114 procedure r_GUI_GetMaxFontSize (BigFont: Boolean; out w, h: Integer);
115 var f: TFont;
116 begin
117 f := Font[BigFont];
118 w := e_CharFont_GetMaxWidth(f.ID);
119 h := e_CharFont_GetMaxHeight(f.ID);
120 end;
122 procedure r_GUI_GetStringSize (BigFont: Boolean; str: String; out w, h: Integer);
123 var ww, hh: WORD;
124 begin
125 e_CharFont_GetSize(Font[BigFont].ID, str, ww, hh);
126 w := ww;
127 h := hh;
128 end;
130 procedure r_GUI_GetLogoSize (out w, h: WORD);
131 begin
132 w := 0;
133 h := 0;
134 if LogoTex <> 0 then
135 e_GetTextureSize(LogoTex, @w, @h);
136 end;
138 procedure r_GUI_Load;
139 begin
140 g_Texture_CreateWADEx('MAINMENU_LOGO', GameWAD + ':TEXTURES\MAINLOGO');
141 g_Texture_CreateWADEx('MAINMENU_MARKER1', GameWAD + ':TEXTURES\MARKER1');
142 g_Texture_CreateWADEx('MAINMENU_MARKER2', GameWAD + ':TEXTURES\MARKER2');
143 g_Texture_CreateWADEx('SCROLL_LEFT', GameWAD + ':TEXTURES\SLEFT');
144 g_Texture_CreateWADEx('SCROLL_RIGHT', GameWAD + ':TEXTURES\SRIGHT');
145 g_Texture_CreateWADEx('SCROLL_MIDDLE', GameWAD + ':TEXTURES\SMIDDLE');
146 g_Texture_CreateWADEx('SCROLL_MARKER', GameWAD + ':TEXTURES\SMARKER');
147 g_Texture_CreateWADEx('EDIT_LEFT', GameWAD + ':TEXTURES\ELEFT');
148 g_Texture_CreateWADEx('EDIT_RIGHT', GameWAD + ':TEXTURES\ERIGHT');
149 g_Texture_CreateWADEx('EDIT_MIDDLE', GameWAD + ':TEXTURES\EMIDDLE');
150 g_Texture_CreateWADEx('BOX1', GameWAD + ':TEXTURES\BOX1');
151 g_Texture_CreateWADEx('BOX2', GameWAD + ':TEXTURES\BOX2');
152 g_Texture_CreateWADEx('BOX3', GameWAD + ':TEXTURES\BOX3');
153 g_Texture_CreateWADEx('BOX4', GameWAD + ':TEXTURES\BOX4');
154 g_Texture_CreateWADEx('BOX5', GameWAD + ':TEXTURES\BOX5');
155 g_Texture_CreateWADEx('BOX6', GameWAD + ':TEXTURES\BOX6');
156 g_Texture_CreateWADEx('BOX7', GameWAD + ':TEXTURES\BOX7');
157 g_Texture_CreateWADEx('BOX8', GameWAD + ':TEXTURES\BOX8');
158 g_Texture_CreateWADEx('BOX9', GameWAD + ':TEXTURES\BOX9');
159 g_Texture_CreateWADEx('BSCROLL_UP_A', GameWAD + ':TEXTURES\SCROLLUPA');
160 g_Texture_CreateWADEx('BSCROLL_UP_U', GameWAD + ':TEXTURES\SCROLLUPU');
161 g_Texture_CreateWADEx('BSCROLL_DOWN_A', GameWAD + ':TEXTURES\SCROLLDOWNA');
162 g_Texture_CreateWADEx('BSCROLL_DOWN_U', GameWAD + ':TEXTURES\SCROLLDOWNU');
163 g_Texture_CreateWADEx('BSCROLL_MIDDLE', GameWAD + ':TEXTURES\SCROLLMIDDLE');
164 g_Texture_CreateWADEx('NOPIC', GameWAD + ':TEXTURES\NOPIC');
166 g_Texture_Get(MAINMENU_MARKER1, MarkerID[FALSE]);
167 g_Texture_Get(MAINMENU_MARKER2, MarkerID[TRUE]);
169 g_Texture_Get(BOX1, Box[0]);
170 g_Texture_Get(BOX2, Box[1]);
171 g_Texture_Get(BOX3, Box[2]);
172 g_Texture_Get(BOX4, Box[3]);
173 g_Texture_Get(BOX5, Box[4]);
174 g_Texture_Get(BOX6, Box[5]);
175 g_Texture_Get(BOX7, Box[6]);
176 g_Texture_Get(BOX8, Box[7]);
177 g_Texture_Get(BOX9, Box[8]);
179 g_Texture_Get(SCROLL_LEFT, ScrollLeft);
180 g_Texture_Get(SCROLL_RIGHT, ScrollRight);
181 g_Texture_Get(SCROLL_MIDDLE, ScrollMiddle);
182 g_Texture_Get(SCROLL_MARKER, ScrollMarker);
184 g_Texture_Get(EDIT_LEFT, EditLeft);
185 g_Texture_Get(EDIT_RIGHT, EditRight);
186 g_Texture_Get(EDIT_MIDDLE, EditMiddle);
188 Font[FALSE] := TFont.Create(gMenuSmallFont, TFontType.Character);
189 Font[TRUE] := TFont.Create(gMenuFont, TFontType.Character);
191 g_Texture_Get('MAINMENU_LOGO', LogoTex)
192 end;
194 procedure r_GUI_Free;
195 begin
196 g_Texture_Delete('MAINMENU_LOGO');
197 g_Texture_Delete('MAINMENU_MARKER1');
198 g_Texture_Delete('MAINMENU_MARKER2');
199 g_Texture_Delete('SCROLL_LEFT');
200 g_Texture_Delete('SCROLL_RIGHT');
201 g_Texture_Delete('SCROLL_MIDDLE');
202 g_Texture_Delete('SCROLL_MARKER');
203 g_Texture_Delete('EDIT_LEFT');
204 g_Texture_Delete('EDIT_RIGHT');
205 g_Texture_Delete('EDIT_MIDDLE');
206 g_Texture_Delete('BOX1');
207 g_Texture_Delete('BOX2');
208 g_Texture_Delete('BOX3');
209 g_Texture_Delete('BOX4');
210 g_Texture_Delete('BOX5');
211 g_Texture_Delete('BOX6');
212 g_Texture_Delete('BOX7');
213 g_Texture_Delete('BOX8');
214 g_Texture_Delete('BOX9');
215 g_Texture_Delete('BSCROLL_UP_A');
216 g_Texture_Delete('BSCROLL_UP_U');
217 g_Texture_Delete('BSCROLL_DOWN_A');
218 g_Texture_Delete('BSCROLL_DOWN_U');
219 g_Texture_Delete('BSCROLL_MIDDLE');
220 g_Texture_Delete('NOPIC');
221 end;
223 procedure r_GUI_GetSize_TextButton (ctrl: TGUITextButton; out w, h: Integer);
224 var ww, hh: WORD; f: TFont;
225 begin
226 f := Font[ctrl.BigFont];
227 f.GetTextSize(ctrl.Caption, ww, hh);
228 w := ww;
229 h := hh;
230 end;
232 procedure r_GUI_GetSize_Label (ctrl: TGUILabel; out w, h: Integer);
233 var ww, hh: WORD; f: TFont;
234 begin
235 f := Font[ctrl.BigFont];
236 f.GetTextSize(ctrl.Text, ww, hh);
237 h := hh;
238 if ctrl.FixedLength = 0 then
239 w := ww
240 else
241 w := e_CharFont_GetMaxWidth(f.ID) * ctrl.FixedLength
242 end;
244 procedure r_GUI_GetSize_Switch (ctrl: TGUISwitch; out w, h: Integer);
245 var i: Integer; ww, hh: WORD; f: TFont;
246 begin
247 w := 0;
248 h := 0;
249 if ctrl.Items <> nil then
250 begin
251 for i := 0 to High(ctrl.Items) do
252 begin
253 f := Font[ctrl.BigFont];
254 f.GetTextSize(ctrl.Items[i], ww, hh);
255 if ww > w then
256 w := ww;
257 end;
258 end;
259 end;
261 procedure r_GUI_GetSize_KeyRead (ctrl: TGUIKeyRead; out w, h: Integer);
262 var i: Integer; ww, hh: WORD; f: TFont;
263 begin
264 w := 0;
265 h := 0; // ??? always 0
266 f := Font[ctrl.BigFont];
267 for i := 0 to 255 do
268 begin
269 f.GetTextSize(e_KeyNames[i], ww, hh);
270 w := MAX(w, ww);
271 end;
272 f.GetTextSize(KEYREAD_QUERY, ww, hh);
273 if ww > w then w := ww;
274 f.GetTextSize(KEYREAD_CLEAR, ww, hh);
275 if ww > w then w := ww;
276 end;
278 procedure r_GUI_GetSize (ctrl: TGUIControl; out w, h: Integer);
279 begin
280 w := 0;
281 h := 0;
282 if ctrl is TGUITextButton then
283 r_GUI_GetSize_TextButton(ctrl as TGUITextButton, w, h)
284 else if ctrl is TGUILabel then
285 r_GUI_GetSize_Label(ctrl as TGUILabel, w, h)
286 else if ctrl is TGUIScroll then
287 w := 16 + ((ctrl as TGUIScroll).Max + 1) * 8 // ??? but h = 0
288 else if ctrl is TGUISwitch then
289 r_GUI_GetSize_Switch(ctrl as TGUISwitch, w, h)
290 else if ctrl is TGUIEdit then
291 w := 16 + (ctrl as TGUIEdit).Width * 16 // ??? but h = 0
292 else if ctrl is TGUIKeyRead then
293 r_GUI_GetSize_KeyRead(ctrl as TGUIKeyRead, w, h)
294 else if ctrl is TGUIKeyRead2 then
295 w := (ctrl as TGUIKeyRead2).MaxKeyNameWdt * 2 + 8 + 8 + 16 // ??? but h = 0
296 else if ctrl is TGUIListBox then
297 begin
298 w := 8 + ((ctrl as TGUIListBox).Width + 1) * 16; // recheck w & h
299 h := 8 + (ctrl as TGUIListBox).Height * 16;
300 end
301 else if ctrl is TGUIMemo then
302 begin
303 w := 8 + ((ctrl as TGUIMemo).Width + 1) * 16;
304 h := 8 + (ctrl as TGUIMemo).Height * 16;
305 end
306 else
307 begin
308 w := ctrl.GetWidth();
309 h := ctrl.GetHeight();
310 end;
311 end;
313 procedure r_GUI_Draw_Control (ctrl: TGUIControl); forward;
315 procedure r_GUI_Draw_TextButton (ctrl: TGUITextButton);
316 var f: TFont;
317 begin
318 f := Font[ctrl.BigFont];
319 f.Draw(ctrl.X, ctrl.Y, ctrl.Caption, ctrl.Color.R, ctrl.Color.G, ctrl.Color.B)
320 end;
322 procedure r_GUI_Draw_Label (ctrl: TGUILabel);
323 var w, h: Word; f: TFont;
324 begin
325 f := Font[ctrl.BigFont];
326 if ctrl.RightAlign then
327 begin
328 f.GetTextSize(ctrl.Text, w, h);
329 f.Draw(ctrl.X + ctrl.CMaxWidth - w, ctrl.Y, ctrl.Text, ctrl.Color.R, ctrl.Color.G, ctrl.Color.B);
330 end
331 else
332 f.Draw(ctrl.X, ctrl.Y, ctrl.Text, ctrl.Color.R, ctrl.Color.G, ctrl.Color.B);
333 end;
335 procedure r_GUI_Draw_Scroll (ctrl: TGUIScroll);
336 var a: Integer;
337 begin
338 e_Draw(ScrollLeft, ctrl.X, ctrl.Y, 0, True, False);
339 e_Draw(ScrollRight, ctrl.X + 8 + (ctrl.Max + 1) * 8, ctrl.Y, 0, True, False);
340 for a := 0 to ctrl.Max do
341 e_Draw(ScrollMiddle, ctrl.X + 8 + a * 8, ctrl.Y, 0, True, False);
342 e_Draw(ScrollMarker, ctrl.X + 8 + ctrl.Value * 8, ctrl.Y, 0, True, False);
343 end;
345 procedure r_GUI_Draw_Switch (ctrl: TGUISwitch);
346 var f: TFont;
347 begin
348 f := Font[ctrl.BigFont];
349 f.Draw(ctrl.X, ctrl.Y, ctrl.Items[ctrl.ItemIndex], ctrl.Color.R, ctrl.Color.G, ctrl.Color.B);
350 end;
352 procedure r_GUI_Draw_Edit (ctrl: TGUIEdit);
353 var c, w, h: Word; r, g, b: Byte; f: TFont;
354 begin
355 e_Draw(EditLeft, ctrl.X, ctrl.Y, 0, True, False);
356 e_Draw(EditRight, ctrl.X + 8 + ctrl.Width * 16, ctrl.Y, 0, True, False);
357 for c := 0 to ctrl.Width - 1 do
358 e_Draw(EditMiddle, ctrl.X + 8 + c * 16, ctrl.Y, 0, True, False);
359 r := ctrl.Color.R;
360 g := ctrl.Color.G;
361 b := ctrl.Color.B;
362 if ctrl.Invalid and (ctrl.Window.ActiveControl <> ctrl) then
363 begin
364 r := 128;
365 g := 128;
366 b := 128;
367 end;
368 f := Font[ctrl.BigFont];
369 f.Draw(ctrl.X + 8, ctrl.Y, ctrl.Text, r, g, b);
370 if ctrl.Window.ActiveControl = ctrl then
371 begin
372 f.GetTextSize(Copy(ctrl.Text, 1, ctrl.CaretPos), w, h);
373 h := e_CharFont_GetMaxHeight(f.ID);
374 e_DrawLine(2, ctrl.X + 8 + w, ctrl.Y + h - 3, ctrl.X + 8 + w + EDIT_CURSORLEN, ctrl.Y + h - 3, EDIT_CURSORCOLOR.R, EDIT_CURSORCOLOR.G, EDIT_CURSORCOLOR.B);
375 end;
376 end;
378 procedure r_GUI_Draw_KeyRead (ctrl: TGUIKeyRead);
379 var k: AnsiString; f: TFont;
380 begin
381 if ctrl.IsQuery then
382 k := KEYREAD_QUERY
383 else if ctrl.Key <> 0 then
384 k := e_KeyNames[ctrl.Key]
385 else
386 k := KEYREAD_CLEAR;
387 f := Font[ctrl.BigFont];
388 f.Draw(ctrl.X, ctrl.Y, k, ctrl.Color.R, ctrl.Color.G, ctrl.Color.B);
389 end;
391 procedure r_GUI_Draw_KeyRead2 (ctrl: TGUIKeyRead2);
393 procedure drawText (idx: Integer);
394 var x, y: Integer; r, g, b: Byte; kk: DWORD; str: AnsiString; f: TFont;
395 begin
396 if idx = 0 then kk := ctrl.Key0 else kk := ctrl.Key1;
397 y := ctrl.Y;
398 if idx = 0 then x := ctrl.X + 8 else x := ctrl.X + 8 + ctrl.MaxKeyNameWdt + 16;
399 r := 255;
400 g := 0;
401 b := 0;
402 if ctrl.KeyIdx = idx then
403 begin
404 r := 255; g := 255; b := 255;
405 end;
406 f := Font[ctrl.BigFont];
407 if ctrl.IsQuery and (ctrl.KeyIdx = idx) then
408 begin
409 f.Draw(x, y, KEYREAD_QUERY, r, g, b)
410 end
411 else
412 begin
413 if kk <> 0 then
414 str := e_KeyNames[kk]
415 else
416 str := KEYREAD_CLEAR;
417 f.Draw(x, y, str, r, g, b);
418 end
419 end;
421 begin
422 drawText(0);
423 drawText(1);
424 end;
426 procedure DrawBox(X, Y: Integer; Width, Height: Word);
427 begin
428 e_Draw(Box[0], X, Y, 0, False, False);
429 e_DrawFill(Box[1], X + 4, Y, Width * 4, 1, 0, False, False);
430 e_Draw(Box[2], X + 4 + Width * 16, Y, 0, False, False);
431 e_DrawFill(Box[3], X, Y + 4, 1, Height * 4, 0, False, False);
432 e_DrawFill(Box[4], X + 4, Y + 4, Width, Height, 0, False, False);
433 e_DrawFill(Box[5], X + 4 + Width * 16, Y + 4, 1, Height * 4, 0, False, False);
434 e_Draw(Box[6], X, Y + 4 + Height * 16, 0, False, False);
435 e_DrawFill(Box[7], X + 4, Y + 4 + Height * 16, Width * 4, 1, 0, False, False);
436 e_Draw(Box[8], X + 4 + Width * 16, Y + 4 + Height * 16, 0, False, False);
437 end;
439 procedure r_GUI_Draw_ModelView (ctrl: TGUIModelView);
440 begin
441 DrawBox(ctrl.X, ctrl.Y, 4, 4);
442 if ctrl.Model <> nil then
443 r_PlayerModel_Draw(ctrl.Model, ctrl.X + 4, ctrl.Y + 4);
444 end;
446 procedure r_GUI_Draw_MapPreview (ctrl: TGUIMapPreview);
447 var a: Integer; r, g, b: Byte;
448 begin
449 DrawBox(ctrl.X, ctrl.Y, MAPPREVIEW_WIDTH, MAPPREVIEW_HEIGHT);
450 if (ctrl.MapSize.X <= 0) or (ctrl.MapSize.Y <= 0) then
451 Exit;
452 e_DrawFillQuad(ctrl.X + 4, ctrl.Y + 4, ctrl.X + 4 + Trunc(ctrl.MapSize.X / ctrl.Scale) - 1, ctrl.Y + 4 + Trunc(ctrl.MapSize.Y / ctrl.Scale) - 1, 32, 32, 32, 0);
453 if ctrl.MapData <> nil then
454 for a := 0 to High(ctrl.MapData) do
455 with ctrl.MapData[a] do
456 begin
457 if X1 > MAPPREVIEW_WIDTH * 16 then Continue;
458 if Y1 > MAPPREVIEW_HEIGHT * 16 then Continue;
459 if X2 < 0 then Continue;
460 if Y2 < 0 then Continue;
461 if X2 > MAPPREVIEW_WIDTH * 16 then X2 := MAPPREVIEW_WIDTH * 16;
462 if Y2 > MAPPREVIEW_HEIGHT * 16 then Y2 := MAPPREVIEW_HEIGHT * 16;
463 if X1 < 0 then X1 := 0;
464 if Y1 < 0 then Y1 := 0;
465 case PanelType of
466 PANEL_WALL:
467 begin
468 r := 255; g := 255; b := 255;
469 end;
470 PANEL_CLOSEDOOR:
471 begin
472 r := 255; g := 255; b := 0;
473 end;
474 PANEL_WATER:
475 begin
476 r := 0; g := 0; b := 192;
477 end;
478 PANEL_ACID1:
479 begin
480 r := 0; g := 176; b := 0;
481 end;
482 PANEL_ACID2:
483 begin
484 r := 176; g := 0; b := 0;
485 end;
486 else
487 r := 128; g := 128; b := 128;
488 end;
489 if ((X2 - X1) > 0) and ((Y2 - Y1) > 0) then
490 e_DrawFillQuad(ctrl.X + 4 + X1, ctrl.Y + 4 + Y1, ctrl.X + 4 + X2 - 1, ctrl.Y + 4 + Y2 - 1, r, g, b, 0);
491 end;
492 end;
494 procedure r_GUI_Draw_Image (ctrl: TGUIImage);
495 var ID: DWORD;
496 begin
497 if ctrl.ImageRes = '' then
498 begin
499 if g_Texture_Get(ctrl.DefaultRes, ID) then
500 e_Draw(ID, ctrl.X, ctrl.Y, 0, True, False);
501 end
502 else
503 begin
504 if g_Texture_CreateWADEx(ctrl.ImageRes, ctrl.ImageRes) then
505 begin
506 if g_Texture_Get(ctrl.ImageRes, ID) then
507 e_Draw(ID, ctrl.X, ctrl.Y, 0, True, False);
508 g_Texture_Delete(ctrl.ImageRes);
509 end;
510 end;
511 end;
513 procedure DrawScroll(X, Y: Integer; Height: Word; Up, Down: Boolean);
514 var ID: DWORD;
515 begin
516 if Height < 3 then
517 Exit;
518 if Up then
519 g_Texture_Get(BSCROLL_UPA, ID)
520 else
521 g_Texture_Get(BSCROLL_UPU, ID);
522 e_Draw(ID, X, Y, 0, False, False);
523 if Down then
524 g_Texture_Get(BSCROLL_DOWNA, ID)
525 else
526 g_Texture_Get(BSCROLL_DOWNU, ID);
527 e_Draw(ID, X, Y + (Height - 1) * 16, 0, False, False);
528 g_Texture_Get(BSCROLL_MIDDLE, ID);
529 e_DrawFill(ID, X, Y + 16, 1, Height - 2, 0, False, False);
530 end;
532 procedure r_GUI_Draw_ListBox (ctrl: TGUIListBox); // + TGUIFileListBox
533 var w2, h2: Word; a: Integer; s: string; f: TFont;
534 begin
535 if ctrl.DrawBack then
536 DrawBox(ctrl.X, ctrl.Y, ctrl.Width + 1, ctrl.Height);
537 if ctrl.DrawScrollBar then
538 DrawScroll(ctrl.X + 4 + ctrl.Width * 16, ctrl.Y + 4, ctrl.Height, (ctrl.StartLine > 0) and (ctrl.Items <> nil), (ctrl.StartLine + ctrl.Height - 1 < High(ctrl.Items)) and (ctrl.Items <> nil));
539 if ctrl.Items <> nil then
540 begin
541 f := Font[ctrl.BigFont];
542 for a := ctrl.StartLine to Min(High(ctrl.Items), ctrl.StartLine + ctrl.Height - 1) do
543 begin
544 s := ctrl.Items[a];
545 f.GetTextSize(s, w2, h2);
546 while (Length(s) > 0) and (w2 > ctrl.Width * 16) do
547 begin
548 SetLength(s, Length(s) - 1);
549 f.GetTextSize(s, w2, h2);
550 end;
551 if a = ctrl.ItemIndex then
552 f.Draw(ctrl.X + 4, ctrl.Y + 4 + (a - ctrl.StartLine) * 16, s, ctrl.ActiveColor.R, ctrl.ActiveColor.G, ctrl.ActiveColor.B)
553 else
554 f.Draw(ctrl.X + 4, ctrl.Y + 4 + (a - ctrl.StartLine) * 16, s, ctrl.UnActiveColor.R, ctrl.UnActiveColor.G, ctrl.UnActiveColor.B);
555 end;
556 end;
557 end;
559 procedure r_GUI_Draw_Memo (ctrl: TGUIMemo);
560 var a: Integer; f: TFont;
561 begin
562 f := Font[ctrl.BigFont];
563 if ctrl.DrawBack then
564 DrawBox(ctrl.X, ctrl.Y, ctrl.Width + 1, ctrl.Height);
565 if ctrl.DrawScrollBar then
566 DrawScroll(ctrl.X + 4 + ctrl.Width * 16, ctrl.Y + 4, ctrl.Height, (ctrl.StartLine > 0) and (ctrl.Lines <> nil), (ctrl.StartLine + ctrl.Height - 1 < High(ctrl.Lines)) and (ctrl.Lines <> nil));
567 if ctrl.Lines <> nil then
568 for a := ctrl.StartLine to Min(High(ctrl.Lines), ctrl.StartLine + ctrl.Height - 1) do
569 f.Draw(ctrl.X + 4, ctrl.Y + 4 + (a - ctrl.StartLine) * 16, ctrl.Lines[a], ctrl.Color.R, ctrl.Color.G, ctrl.Color.B);
570 end;
572 procedure r_GUI_Draw_MainMenu (ctrl: TGUIMainMenu);
573 var a: Integer; w, h: Word; ID: DWORD;
574 begin
575 if ctrl.Header <> nil then
576 begin
577 r_GUI_Draw_Label(ctrl.Header)
578 end
579 else if LogoTex <> 0 then
580 begin
581 e_GetTextureSize(LogoTex, @w, @h);
582 e_Draw(LogoTex, ((gScreenWidth div 2) - (w div 2)), ctrl.Buttons[0].Y - ctrl.Buttons[0].GetHeight - h, 0, True, False);
583 end;
584 if ctrl.Buttons <> nil then
585 begin
586 for a := 0 to High(ctrl.Buttons) do
587 if ctrl.Buttons[a] <> nil then
588 r_GUI_Draw_TextButton(ctrl.Buttons[a]);
589 if ctrl.Index <> -1 then
590 begin
591 ID := MarkerID[ctrl.Counter DIV MAINMENU_MARKERDELAY MOD 2 <> 0];
592 e_Draw(ID, ctrl.Buttons[ctrl.Index].X - 48, ctrl.Buttons[ctrl.Index].Y, 0, True, False);
593 end
594 end;
595 end;
597 procedure r_GUI_Draw_Menu (ctrl: TGUIMenu);
598 var a, locx, locy: Integer; f: TFont;
599 begin
600 if ctrl.Header <> nil then
601 r_GUI_Draw_Label(ctrl.Header);
602 if ctrl.Items <> nil then
603 begin
604 for a := 0 to High(ctrl.Items) do
605 begin
606 if ctrl.Items[a].Text <> nil then
607 r_GUI_Draw_Control(ctrl.Items[a].Text);
608 if ctrl.Items[a].Control <> nil then
609 r_GUI_Draw_Control(ctrl.Items[a].Control);
610 end;
611 end;
612 if (ctrl.Index <> -1) and (ctrl.Counter > MENU_MARKERDELAY div 2) then
613 begin
614 locx := 0;
615 locy := 0;
616 if ctrl.Items[ctrl.Index].Text <> nil then
617 begin
618 locx := ctrl.Items[ctrl.Index].Text.X;
619 locy := ctrl.Items[ctrl.Index].Text.Y;
620 //HACK!
621 if ctrl.Items[ctrl.Index].Text.RightAlign then
622 begin
623 locx := locx + ctrl.Items[ctrl.Index].Text.CMaxWidth - ctrl.Items[ctrl.Index].Text.GetWidth;
624 end;
625 end
626 else if ctrl.Items[ctrl.Index].Control <> nil then
627 begin
628 locx := ctrl.Items[ctrl.Index].Control.X;
629 locy := ctrl.Items[ctrl.Index].Control.Y;
630 end;
631 f := Font[ctrl.BigFont];
632 locx := locx - e_CharFont_GetMaxWidth(f.ID);
633 e_CharFont_PrintEx(f.ID, locx, locy, #16, _RGB(255, 0, 0));
634 end;
635 end;
637 procedure r_GUI_Draw_Control (ctrl: TGUIControl);
638 begin
639 if ctrl is TGUITextButton then
640 r_GUI_Draw_TextButton(TGUITextButton(ctrl))
641 else if ctrl is TGUILabel then
642 r_GUI_Draw_Label(TGUILabel(ctrl))
643 else if ctrl is TGUIScroll then
644 r_GUI_Draw_Scroll(TGUIScroll(ctrl))
645 else if ctrl is TGUISwitch then
646 r_GUI_Draw_Switch(TGUISwitch(ctrl))
647 else if ctrl is TGUIEdit then
648 r_GUI_Draw_Edit(TGUIEdit(ctrl))
649 else if ctrl is TGUIKeyRead then
650 r_GUI_Draw_KeyRead(TGUIKeyRead(ctrl))
651 else if ctrl is TGUIKeyRead2 then
652 r_GUI_Draw_KeyRead2(TGUIKeyRead2(ctrl))
653 else if ctrl is TGUIModelView then
654 r_GUI_Draw_ModelView(TGUIModelView(ctrl))
655 else if ctrl is TGUIMapPreview then
656 r_GUI_Draw_MapPreview(TGUIMapPreview(ctrl))
657 else if ctrl is TGUIImage then
658 r_GUI_Draw_Image(TGUIImage(ctrl))
659 else if ctrl is TGUIListBox then
660 r_GUI_Draw_ListBox(TGUIListBox(ctrl)) // + TGUIFileListBox
661 else if ctrl is TGUIMemo then
662 r_GUI_Draw_Memo(TGUIMemo(ctrl))
663 else if ctrl is TGUIMainMenu then
664 r_GUI_Draw_MainMenu(TGUIMainMenu(ctrl))
665 else if ctrl is TGUIMenu then
666 r_GUI_Draw_Menu(TGUIMenu(ctrl))
667 else
668 Assert(False)
669 end;
671 procedure r_GUI_Draw_Window (win: TGUIWindow);
672 var i: Integer; ID: DWORD; tw, th: Word;
673 begin
674 // Here goes code duplication from g_game.pas:DrawMenuBackground()
675 if win.BackTexture <> '' then
676 if g_Texture_Get(win.BackTexture, ID) then
677 begin
678 e_Clear(0, 0, 0);
679 e_GetTextureSize(ID, @tw, @th);
680 if tw = th then
681 tw := round(tw * 1.333 * (gScreenHeight / th))
682 else
683 tw := trunc(tw * (gScreenHeight / th));
684 e_DrawSize(ID, (gScreenWidth - tw) div 2, 0, 0, False, False, tw, gScreenHeight);
685 end
686 else
687 e_Clear(0.5, 0.5, 0.5);
689 // small hack here
690 if win.Name = 'AuthorsMenu' then
691 e_DarkenQuadWH(0, 0, gScreenWidth, gScreenHeight, 150);
692 for i := 0 to High(win.Childs) do
693 if win.Childs[i] <> nil then
694 r_GUI_Draw_Control(win.Childs[i]);
695 end;
697 end.