X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;ds=sidebyside;f=src%2Fgame%2Fg_gui.pas;h=fe15869bee62b7ab781b7d04015caf5a7285c987;hb=b86d1d4b8bc50a02b7228063cb6ff0fecf545d57;hp=3181e6969102e55d77b1be621b7e46ab32158a79;hpb=d8e9a85e92260e0982cddfecb66c9dbc940f8eb1;p=d2df-sdl.git diff --git a/src/game/g_gui.pas b/src/game/g_gui.pas index 3181e69..fe15869 100644 --- a/src/game/g_gui.pas +++ b/src/game/g_gui.pas @@ -19,7 +19,7 @@ interface uses {$IFDEF USE_MEMPOOL}mempool,{$ENDIF} - e_graphics, e_input, e_log, g_playermodel, g_basic, g_touch, MAPDEF, utils; + g_base, r_graphics, e_input, e_log, g_playermodel, g_basic, MAPDEF, utils; const MAINMENU_HEADER_COLOR: TRGB = (R:255; G:255; B:255); @@ -75,6 +75,8 @@ const WM_CHAR = 102; WM_USER = 110; + MESSAGE_DIKEY = WM_USER + 1; + type TMessage = record Msg: DWORD; @@ -550,9 +552,11 @@ procedure g_GUI_LoadMenuPos(); implementation uses - {$INCLUDE ../nogl/noGLuses.inc} - g_textures, g_sound, SysUtils, e_res, - g_game, Math, StrUtils, g_player, g_options, + {$IFDEF ENABLE_TOUCH} + g_system, + {$ENDIF} + g_sound, SysUtils, e_res, r_textures, + g_game, Math, StrUtils, g_player, g_options, g_console, r_playermodel, g_map, g_weapons, xdynrec, wadreader; @@ -560,6 +564,81 @@ var Box: Array [0..8] of DWORD; Saved_Windows: SSArray; +function GetLines (text: string; FontID: DWORD; MaxWidth: Word): SSArray; + var + k: Integer = 1; + lines: Integer = 0; + i, len, lastsep: Integer; + + function PrepareStep (): Boolean; inline; + begin + // Skip leading spaces. + while PChar(text)[k-1] = ' ' do k += 1; + Result := k <= len; + i := k; + end; + + function GetLine (j: Integer; Strip: Boolean): String; inline; + begin + // Exclude trailing spaces from the line. + if Strip then + while text[j] = ' ' do j -= 1; + + Result := Copy(text, k, j-k+1); + end; + + function LineWidth (): Integer; inline; + var w, h: Word; + begin + e_CharFont_GetSize(FontID, GetLine(i, False), w, h); + Result := w; + end; + +begin + Result := nil; + len := Length(text); + //e_LogWritefln('GetLines @%s len=%s [%s]', [MaxWidth, len, text]); + + while PrepareStep() do + begin + // Get longest possible sequence (this is not constant because fonts are not monospaced). + lastsep := 0; + repeat + if text[i] in [' ', '.', ',', ':', ';'] + then lastsep := i; + i += 1; + until (i > len) or (LineWidth() > MaxWidth); + + // Do not include part of a word if possible. + if (lastsep-k > 3) and (i <= len) and (text[i] <> ' ') + then i := lastsep + 1; + + // Add line. + SetLength(Result, lines + 1); + Result[lines] := GetLine(i-1, True); + //e_LogWritefln(' -> (%s:%s::%s) [%s]', [k, i, LineWidth(), Result[lines]]); + lines += 1; + + k := i; + end; +end; + +procedure Sort(var a: SSArray); +var + i, j: Integer; + s: string; +begin + if a = nil then Exit; + + for i := High(a) downto Low(a) do + for j := Low(a) to High(a)-1 do + if LowerCase(a[j]) > LowerCase(a[j+1]) then + begin + s := a[j]; + a[j] := a[j+1]; + a[j+1] := s; + end; +end; procedure g_GUI_Init(); begin @@ -819,7 +898,7 @@ begin if FBackTexture <> '' then // Here goes code duplication from g_game.pas:DrawMenuBackground() if g_Texture_Get(FBackTexture, ID) then begin - e_Clear(GL_COLOR_BUFFER_BIT, 0, 0, 0); + e_Clear(0, 0, 0); e_GetTextureSize(ID, @tw, @th); if tw = th then tw := round(tw * 1.333 * (gScreenHeight / th)) @@ -828,7 +907,7 @@ begin e_DrawSize(ID, (gScreenWidth - tw) div 2, 0, 0, False, False, tw, gScreenHeight); end else - e_Clear(GL_COLOR_BUFFER_BIT, 0.5, 0.5, 0.5); + e_Clear(0.5, 0.5, 0.5); // small hack here if FName = 'AuthorsMenu' then @@ -2363,7 +2442,10 @@ begin end; g_GUIGrabInput := (@FOnEnterEvent = nil) and (FWindow.FActiveControl = Self); - g_Touch_ShowKeyboard(g_GUIGrabInput) + + {$IFDEF ENABLE_TOUCH} + sys_ShowKeyboard(g_GUIGrabInput) + {$ENDIF} end; procedure TGUIEdit.SetText(Text: string); @@ -2443,58 +2525,40 @@ begin with Msg do case Msg of WM_KEYDOWN: - case wParam of - VK_ESCAPE: - begin - if FIsQuery then actDefCtl(); - FIsQuery := False; - end; - IK_RETURN, IK_KPRETURN, VK_FIRE, VK_OPEN, JOY0_ATTACK, JOY1_ATTACK, JOY2_ATTACK, JOY3_ATTACK: - begin - if not FIsQuery then - begin - with FWindow do - if FActiveControl <> Self then - SetActive(Self); - - FIsQuery := True; - end - else if (wParam < VK_FIRSTKEY) and (wParam > VK_LASTKEY) then - begin - // FKey := IK_ENTER; // - FKey := wParam; - FIsQuery := False; - actDefCtl(); - end; - end; - IK_BACKSPACE: // clear keybinding if we aren't waiting for a key - begin - if not FIsQuery then + if not FIsQuery then + begin + case wParam of + IK_RETURN, IK_KPRETURN, VK_FIRE, VK_OPEN, JOY0_ATTACK, JOY1_ATTACK, JOY2_ATTACK, JOY3_ATTACK: + begin + with FWindow do + if FActiveControl <> Self then + SetActive(Self); + FIsQuery := True; + end; + IK_BACKSPACE: // clear keybinding if we aren't waiting for a key begin FKey := 0; actDefCtl(); end; - end; - end; - - MESSAGE_DIKEY: + else + FIsQuery := False; + actDefCtl(); + end; + end + else begin - if not FIsQuery and (wParam = IK_BACKSPACE) then - begin - FKey := 0; + case wParam of + VK_FIRSTKEY..VK_LASTKEY: // do not allow to bind virtual keys + begin + FIsQuery := False; + actDefCtl(); + end; + else + if (e_KeyNames[wParam] <> '') and not g_Console_MatchBind(wParam, 'togglemenu') then + FKey := wParam; + FIsQuery := False; actDefCtl(); end - else if FIsQuery then - begin - case wParam of - IK_ENTER, IK_KPRETURN, VK_FIRSTKEY..VK_LASTKEY (*, JOY0_ATTACK, JOY1_ATTACK, JOY2_ATTACK, JOY3_ATTACK*): // Not '' then - FKey := wParam; - FIsQuery := False; - actDefCtl(); - end - end; end; end; @@ -2599,72 +2663,52 @@ begin with Msg do case Msg of WM_KEYDOWN: - case wParam of - VK_ESCAPE: - begin - if FIsQuery then actDefCtl(); - FIsQuery := False; - end; - IK_RETURN, IK_KPRETURN, VK_FIRE, VK_OPEN, JOY0_ATTACK, JOY1_ATTACK, JOY2_ATTACK, JOY3_ATTACK: - begin - if not FIsQuery then - begin - with FWindow do - if FActiveControl <> Self then - SetActive(Self); - - FIsQuery := True; - end - else if (wParam < VK_FIRSTKEY) and (wParam > VK_LASTKEY) then - begin - // if (FKeyIdx = 0) then FKey0 := IK_ENTER else FKey1 := IK_ENTER; // - if (FKeyIdx = 0) then FKey0 := wParam else FKey1 := wParam; - FIsQuery := False; - actDefCtl(); - end; - end; - IK_BACKSPACE: // clear keybinding if we aren't waiting for a key - begin - if not FIsQuery then + if not FIsQuery then + begin + case wParam of + IK_RETURN, IK_KPRETURN, VK_FIRE, VK_OPEN, JOY0_ATTACK, JOY1_ATTACK, JOY2_ATTACK, JOY3_ATTACK: + begin + with FWindow do + if FActiveControl <> Self then + SetActive(Self); + FIsQuery := True; + end; + IK_BACKSPACE: // clear keybinding if we aren't waiting for a key begin if (FKeyIdx = 0) then FKey0 := 0 else FKey1 := 0; actDefCtl(); end; - end; - IK_LEFT, IK_KPLEFT, VK_LEFT, JOY0_LEFT, JOY1_LEFT, JOY2_LEFT, JOY3_LEFT: - if not FIsQuery then - begin - FKeyIdx := 0; - actDefCtl(); - end; - IK_RIGHT, IK_KPRIGHT, VK_RIGHT, JOY0_RIGHT, JOY1_RIGHT, JOY2_RIGHT, JOY3_RIGHT: - if not FIsQuery then - begin - FKeyIdx := 1; - actDefCtl(); - end; - end; - - MESSAGE_DIKEY: - begin - if not FIsQuery and (wParam = IK_BACKSPACE) then - begin - if (FKeyIdx = 0) then FKey0 := 0 else FKey1 := 0; - actDefCtl(); - end - else if FIsQuery then - begin - case wParam of - IK_ENTER, IK_KPRETURN, VK_FIRSTKEY..VK_LASTKEY (*, JOY0_ATTACK, JOY1_ATTACK, JOY2_ATTACK, JOY3_ATTACK*): // Not '' then + IK_LEFT, IK_KPLEFT, VK_LEFT, JOY0_LEFT, JOY1_LEFT, JOY2_LEFT, JOY3_LEFT: + begin + FKeyIdx := 0; + actDefCtl(); + end; + IK_RIGHT, IK_KPRIGHT, VK_RIGHT, JOY0_RIGHT, JOY1_RIGHT, JOY2_RIGHT, JOY3_RIGHT: begin - if (FKeyIdx = 0) then FKey0 := wParam else FKey1 := wParam; + FKeyIdx := 1; + actDefCtl(); end; - FIsQuery := False; - actDefCtl() - end + else + FIsQuery := False; + actDefCtl(); end; + end + else + begin + case wParam of + VK_FIRSTKEY..VK_LASTKEY: // do not allow to bind virtual keys + begin + FIsQuery := False; + actDefCtl(); + end; + else + if (e_KeyNames[wParam] <> '') and not g_Console_MatchBind(wParam, 'togglemenu') then + begin + if (FKeyIdx = 0) then FKey0 := wParam else FKey1 := wParam; + end; + FIsQuery := False; + actDefCtl() + end end; end; @@ -2694,7 +2738,8 @@ begin DrawBox(FX, FY, 4, 4); - if FModel <> nil then FModel.Draw(FX+4, FY+4); + if FModel <> nil then + r_PlayerModel_Draw(FModel, FX+4, FY+4); end; procedure TGUIModelView.NextAnim(); @@ -2984,7 +3029,7 @@ begin SetLength(FItems, Length(FItems)+1); FItems[High(FItems)] := Item; - if FSort then g_Basic.Sort(FItems); + if FSort then g_gui.Sort(FItems); end; function TGUIListBox.ItemExists (item: String): Boolean; @@ -3139,7 +3184,7 @@ begin FStartLine := 0; FIndex := -1; - if FSort then g_Basic.Sort(FItems); + if FSort then g_gui.Sort(FItems); end; procedure TGUIListBox.SelectItem(Item: String); @@ -3270,13 +3315,13 @@ begin begin if FItems[FIndex] = #29 + '..' then begin - e_LogWritefln('TGUIFileListBox: Upper dir "%s" -> "%s"', [FSubPath, e_UpperDir(FSubPath)]); + //e_LogWritefln('TGUIFileListBox: Upper dir "%s" -> "%s"', [FSubPath, e_UpperDir(FSubPath)]); FSubPath := e_UpperDir(FSubPath) end else begin s := Copy(AnsiString(FItems[FIndex]), 2); - e_LogWritefln('TGUIFileListBox: Enter dir "%s" -> "%s"', [FSubPath, e_CatPath(FSubPath, s)]); + //e_LogWritefln('TGUIFileListBox: Enter dir "%s" -> "%s"', [FSubPath, e_CatPath(FSubPath, s)]); FSubPath := e_CatPath(FSubPath, s); end; ScanDirs;