OpenClonk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
C4GuiDialogs.cpp
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 1998-2000, Matthes Bender
5  * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
6  * Copyright (c) 2009-2016, The OpenClonk Team and contributors
7  *
8  * Distributed under the terms of the ISC license; see accompanying file
9  * "COPYING" for details.
10  *
11  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
12  * See accompanying file "TRADEMARK" for details.
13  *
14  * To redistribute this file separately, substitute the full license texts
15  * for the above references.
16  */
17 // generic user interface
18 // dialog base classes and some user dialogs
19 
20 #include "C4Include.h"
22 #include "gui/C4Gui.h"
23 
24 #include "object/C4DefList.h"
25 #include "game/C4Application.h"
26 #include "game/C4Viewport.h"
27 #include "object/C4Def.h"
29 #include "graphics/C4Draw.h"
30 #include "game/C4Application.h"
31 #include "game/C4GameScript.h"
32 
33 #include "graphics/C4DrawGL.h"
34 #include "platform/StdRegistry.h"
35 
36 namespace C4GUI
37 {
38 
39 // --------------------------------------------------
40 // FrameDecoration
41 
43  {
44  pSourceDef = nullptr;
49  fctTop.Default();
51  fctRight.Default();
55  fctLeft.Default();
57  }
58 
59  bool FrameDecoration::SetFacetByAction(C4Def *pOfDef, C4TargetFacet &rfctTarget, const char *szFacetName)
60  {
61  // get action
62  StdStrBuf sActName;
63  sActName.Format("FrameDeco%s", szFacetName);
64  C4PropList *act = pOfDef->GetActionByName(sActName.getData());
65  if (!act) return false;
66  // set facet by it
67  int32_t x = act->GetPropertyInt(P_X);
68  int32_t y = act->GetPropertyInt(P_Y);
69  int32_t wdt = act->GetPropertyInt(P_Wdt);
70  int32_t hgt = act->GetPropertyInt(P_Hgt);
71  int32_t tx = act->GetPropertyInt(P_OffX);
72  int32_t ty = act->GetPropertyInt(P_OffY);
73  if (!wdt || !hgt) return false;
74  rfctTarget.Set(pOfDef->Graphics.GetBitmap(), x, y, wdt, hgt, tx, ty);
75  return true;
76  }
77 
78  bool FrameDecoration::SetByDef(C4ID idSourceDef)
79  {
80  return SetByDef(C4Id2Def(idSourceDef));
81  }
82 
84  {
85  if (!pSrcDef) return false;
86  // script compiled?
87  if (!pSrcDef->Script.IsReady()) return false;
88  // reset old
89  Clear();
90  this->pSourceDef = pSrcDef;
91  this->idSourceDef = pSrcDef->id;
92  // query values
93  dwBackClr = pSrcDef->Call(FormatString(PSF_FrameDecoration, "BackClr" ).getData()).getInt();
94  iBorderTop = pSrcDef->Call(FormatString(PSF_FrameDecoration, "BorderTop" ).getData()).getInt();
95  iBorderLeft = pSrcDef->Call(FormatString(PSF_FrameDecoration, "BorderLeft" ).getData()).getInt();
96  iBorderRight = pSrcDef->Call(FormatString(PSF_FrameDecoration, "BorderRight" ).getData()).getInt();
97  iBorderBottom = pSrcDef->Call(FormatString(PSF_FrameDecoration, "BorderBottom").getData()).getInt();
98  // get gfx
99  SetFacetByAction(pSrcDef, fctTop , "Top" );
100  SetFacetByAction(pSrcDef, fctTopRight , "TopRight" );
101  SetFacetByAction(pSrcDef, fctRight , "Right" );
102  SetFacetByAction(pSrcDef, fctBottomRight, "BottomRight");
103  SetFacetByAction(pSrcDef, fctBottom , "Bottom" );
104  SetFacetByAction(pSrcDef, fctBottomLeft , "BottomLeft" );
105  SetFacetByAction(pSrcDef, fctLeft , "Left" );
106  SetFacetByAction(pSrcDef, fctTopLeft , "TopLeft" );
107  // check for gfx outside main area
109  || (fctTopLeft.TargetX < 0) || (fctLeft.TargetX < 0) || (fctBottomLeft.TargetX < 0)
112  // k, done
113  return true;
114  }
115 
117  {
118  // simply re-set by def
119  return SetByDef(idSourceDef);
120  }
121 
123  {
124  // draw BG
125  int ox = cgo.TargetX+rcBounds.x, oy = cgo.TargetY+rcBounds.y;
126  pDraw->DrawBoxDw(cgo.Surface, ox,oy,ox+rcBounds.Wdt-1,oy+rcBounds.Hgt-1,dwBackClr);
127  // draw borders
128  int x,y,Q;
129  // top
130  if ((Q=fctTop.Wdt))
131  {
132  for (x = iBorderLeft; x < rcBounds.Wdt-iBorderRight; x += fctTop.Wdt)
133  {
134  int w = std::min<int>(fctTop.Wdt, rcBounds.Wdt-iBorderRight-x);
135  fctTop.Wdt = w;
136  fctTop.Draw(cgo.Surface, ox+x, oy+fctTop.TargetY);
137  }
138  fctTop.Wdt = Q;
139  }
140  // left
141  if ((Q=fctLeft.Hgt))
142  {
143  for (y = iBorderTop; y < rcBounds.Hgt-iBorderBottom; y += fctLeft.Hgt)
144  {
145  int h = std::min<int>(fctLeft.Hgt, rcBounds.Hgt-iBorderBottom-y);
146  fctLeft.Hgt = h;
147  fctLeft.Draw(cgo.Surface, ox+fctLeft.TargetX, oy+y);
148  }
149  fctLeft.Hgt = Q;
150  }
151  // right
152  if ((Q=fctRight.Hgt))
153  {
154  for (y = iBorderTop; y < rcBounds.Hgt-iBorderBottom; y += fctRight.Hgt)
155  {
156  int h = std::min<int>(fctRight.Hgt, rcBounds.Hgt-iBorderBottom-y);
157  fctRight.Hgt = h;
158  fctRight.Draw(cgo.Surface, ox+rcBounds.Wdt-iBorderRight+fctRight.TargetX, oy+y);
159  }
160  fctRight.Hgt = Q;
161  }
162  // bottom
163  if ((Q=fctBottom.Wdt))
164  {
165  for (x = iBorderLeft; x < rcBounds.Wdt-iBorderRight; x += fctBottom.Wdt)
166  {
167  int w = std::min<int>(fctBottom.Wdt, rcBounds.Wdt-iBorderRight-x);
168  fctBottom.Wdt = w;
169  fctBottom.Draw(cgo.Surface, ox+x, oy+rcBounds.Hgt-iBorderBottom+fctBottom.TargetY);
170  }
171  fctBottom.Wdt = Q;
172  }
173  // draw edges
178  }
179 
180 // --------------------------------------------------
181 // DialogWindow
182 
183 #ifdef USE_WIN32_WINDOWS
184 
185  C4Window * DialogWindow::Init(C4AbstractApp * pApp, const char * Title, const C4Rect &rcBounds, const char *szID)
186  {
187  C4Window * result = C4Window::Init(C4Window::W_GuiWindow, pApp, Title, &rcBounds);
188  if (result)
189  {
190  // update pos
191  if (szID && *szID)
192  RestoreWindowPosition(hWindow, FormatString("ConsoleGUI_%s", szID).getData(), Config.GetSubkeyPath("Console"), false);
193  // and show
194  ::ShowWindow(hWindow, SW_SHOW);
195  }
196  return result;
197  }
198 
199 #else
200  C4Window * DialogWindow::Init(C4AbstractApp * pApp, const char * Title, const C4Rect &rcBounds, const char *szID)
201  {
202  C4Window * result = C4Window::Init(C4Window::W_GuiWindow, pApp, Title, &rcBounds);
203  if (result)
204  {
205  // update pos
206  if (szID && *szID)
207  RestorePosition(FormatString("ConsoleGUI_%s", szID).getData(), Config.GetSubkeyPath("Console"), false);
208  else
209  SetSize(rcBounds.Wdt, rcBounds.Hgt);
210  }
211  return result;
212  }
213 #endif // _WIN32
214 
216  {
217  if (!pDialog)
218  return; // safety
219  C4Rect r;
220  GetSize(&r);
221  if (pSurface)
222  {
223  pSurface->Wdt = r.Wdt;
224  pSurface->Hgt = r.Hgt;
225 #ifndef USE_CONSOLE
227  glClear(GL_COLOR_BUFFER_BIT);
228 #endif
229  }
230  C4TargetFacet cgo;
231  cgo.Set(nullptr, 0, 0, r.Wdt, r.Hgt, 0, 0);
232  pDialog->Draw(cgo);
233  }
234 
236  {
237  // FIXME: Close the dialog of this window
238  }
239 
241  {
242 #ifdef WITH_QT_EDITOR
243  // TODO: Implement these as Qt editor windows.
244  // This currently creates an empty window in Windows and a segfault in Linux.
245  return false;
246 #endif
247  // already created?
248  if (pWindow) return true;
249  // create it!
250  pWindow = new DialogWindow();
252  {
253  delete pWindow;
254  pWindow = nullptr;
255  return false;
256  }
257  // create rendering context
259  pWindow->pDialog = this;
260  return true;
261  }
262 
264  {
265  if (pWindow)
266  {
267  delete pWindow->pSurface;
268  pWindow->Clear();
269  delete pWindow;
270  pWindow = nullptr;
271  }
272  }
273 
274  Dialog::Dialog(int32_t iWdt, int32_t iHgt, const char *szTitle, bool fViewportDlg):
275  Window(), pTitle(nullptr), pCloseBtn(nullptr), fDelOnClose(false), fViewportDlg(fViewportDlg), pWindow(nullptr), pFrameDeco(nullptr)
276  {
277  // zero fields
278  pActiveCtrl = nullptr;
279  fShow = fOK = false;
280  iFade = 100; eFade = eFadeNone;
281  // add title
282  rcBounds.Wdt = iWdt;
283  SetTitle(szTitle);
284  // set size - calcs client rect as well
285  SetBounds(C4Rect(0,0,iWdt,iHgt));
286  // create key callbacks
288  Keys.push_back(C4KeyCodeEx(K_TAB));
290  {
291  ControllerKeys::Right(Keys);
292  }
293  pKeyAdvanceControl = new C4KeyBinding(Keys, "GUIAdvanceFocus", KEYSCOPE_Gui,
295  Keys.clear();
296  Keys.push_back(C4KeyCodeEx(K_TAB, KEYS_Shift));
298  {
299  ControllerKeys::Left(Keys);
300  }
301  pKeyAdvanceControlB = new C4KeyBinding(Keys, "GUIAdvanceFocusBack", KEYSCOPE_Gui,
303  Keys.clear();
304  Keys.push_back(C4KeyCodeEx(KEY_Any, KEYS_Alt));
306  pKeyHotkey = new C4KeyBinding(Keys, "GUIHotkey", KEYSCOPE_Gui,
307  new DlgKeyCBPassKey<Dialog>(*this, &Dialog::KeyHotkey), C4CustomKey::PRIO_Ctrl);
308  Keys.clear();
309  Keys.push_back(C4KeyCodeEx(K_RETURN));
311  {
312  ControllerKeys::Ok(Keys);
313  }
314  pKeyEnter = new C4KeyBinding(Keys, "GUIDialogOkay", KEYSCOPE_Gui,
316  Keys.clear();
317  Keys.push_back(C4KeyCodeEx(K_ESCAPE));
319  {
321  }
322  pKeyEscape = new C4KeyBinding(Keys, "GUIDialogAbort", KEYSCOPE_Gui,
324  Keys.clear();
325  Keys.push_back(C4KeyCodeEx(KEY_Any));
326  Keys.push_back(C4KeyCodeEx(KEY_Any, KEYS_Shift));
327  pKeyFocusDefControl = new C4KeyBinding(Keys, "GUIFocusDefault", KEYSCOPE_Gui,
328  new DlgKeyCB<Dialog>(*this, &Dialog::KeyFocusDefault), C4CustomKey::PRIO_Dlg);
329  }
330 
332  {
333  // default title font
334  return std::min<int32_t>(::GraphicsResource.TextFont.GetLineHeight(), C4GUI_MinWoodBarHgt);
335  }
336 
337  void Dialog::SetTitle(const char *szTitle, bool fShowCloseButton)
338  {
339  // always keep local copy of title
340  TitleString.Copy(szTitle);
341  // console mode dialogs: Use window bar
343  {
344  if (pWindow) pWindow->SetTitle(szTitle ? szTitle : "");
345  return;
346  }
347  // set new
348  if (szTitle && *szTitle)
349  {
351  if (pTitle)
352  {
353  pTitle->GetBounds() = C4Rect(-GetMarginLeft(), -iTextHgt, rcBounds.Wdt, iTextHgt);
354  // noupdate if title is same - this is necessary to prevent scrolling reset when refilling internal menus
355  if (SEqual(pTitle->GetText(), szTitle)) return;
356  pTitle->SetText(szTitle);
357  }
358  else
359  AddElement(pTitle = new WoodenLabel(szTitle, C4Rect(-GetMarginLeft(), -iTextHgt, rcBounds.Wdt, iTextHgt), C4GUI_CaptionFontClr, &::GraphicsResource.TextFont, ALeft, false));
360  pTitle->SetToolTip(szTitle);
361  pTitle->SetDragTarget(this);
363  if (fShowCloseButton)
364  {
365  pTitle->SetRightIndent(20); // for close button
366  if (!pCloseBtn)
367  {
369  pCloseBtn->SetToolTip(LoadResStr("IDS_MNU_CLOSE"));
370  }
371  else
372  pCloseBtn->GetBounds() = pTitle->GetToprightCornerRect(16,16,4,4,0);
373  }
374  }
375  else
376  {
377  if (pTitle) { delete pTitle; pTitle=nullptr; }
378  if (pCloseBtn) { delete pCloseBtn; pCloseBtn = nullptr; }
379  }
380  }
381 
383  {
384  // kill key bindings
385  delete pKeyAdvanceControl;
386  delete pKeyAdvanceControlB;
387  delete pKeyHotkey;
388  delete pKeyEscape;
389  delete pKeyEnter;
390  delete pKeyFocusDefControl;
391  // clear window
393  // avoid endless delete/close-recursion
394  fDelOnClose = false;
395  // free deco
396  if (pFrameDeco) pFrameDeco->Deref();
397  }
398 
400  {
401  // update title bar position
402  if (pTitle)
403  {
405  pTitle->SetBounds(C4Rect(-GetMarginLeft(), -iTextHgt, rcBounds.Wdt, iTextHgt));
406  if (pCloseBtn) pCloseBtn->SetBounds(pTitle->GetToprightCornerRect(16,16,4,4,0));
407  }
408  // inherited
410  // update assigned window
411  if (pWindow)
412  {
413  pWindow->SetSize(rcBounds.Wdt,rcBounds.Hgt);
414  }
415  }
416 
418  {
419  // Dialogs with their own windows can only be at 0/0
420  if (pWindow)
421  {
422  rcBounds.x = 0;
423  rcBounds.y = 0;
424  }
426  }
427 
429  {
430  // inherited
431  Window::RemoveElement(pChild);
432  // clear ptr
433  if (pChild == pActiveCtrl) pActiveCtrl = nullptr;
434  }
435 
437  {
438  C4TargetFacet cgo; cgo.Set(cgo0);
439  // Dialogs with a window just ignore the cgo.
440  if (pWindow)
441  {
442  cgo.Surface = pWindow->pSurface;
443  cgo.X = 0; cgo.Y = 0; cgo.Wdt = rcBounds.Wdt; cgo.Hgt = rcBounds.Hgt;
444  }
445  Screen *pScreen;
446  // evaluate fading
447  switch (eFade)
448  {
449  case eFadeNone: break; // no fading
450  case eFadeIn:
451  // fade in
452  if ((iFade+=10) >= 100)
453  {
454  if ((pScreen = GetScreen()))
455  {
456  if (pScreen->GetTopDialog() == this)
457  pScreen->ActivateDialog(this);
458  }
459  eFade = eFadeNone;
460  }
461  break;
462  case eFadeOut:
463  // fade out
464  if ((iFade-=10) <= 0)
465  {
466  fVisible = fShow = false;
467  if ((pScreen = GetScreen()))
468  pScreen->RecheckActiveDialog();
469  eFade = eFadeNone;
470  }
471  }
472  // set fade
473  if (iFade < 100)
474  {
475  if (iFade <= 0) return;
476  pDraw->ActivateBlitModulation((iFade*255/100)<<24 | 0xffffff);
477  }
478  // separate window: Clear background
479  if (pWindow)
480  pDraw->DrawBoxDw(cgo.Surface, rcBounds.x, rcBounds.y, rcBounds.Wdt-1, rcBounds.Hgt-1, (0xff << 24) | (C4GUI_StandardBGColor & 0xffffff) );
481  // draw window + contents (evaluates IsVisible)
482  Window::Draw(cgo);
483  // reset blit modulation
485  // blit output to own window
486  if (pWindow)
487  {
488  // Draw context menu on editor window
489  ContextMenu *menu;
490  if ((menu = GetScreen()->pContext))
491  {
492  if (menu->GetTargetDialog() == this)
493  {
494  menu->Draw(cgo);
495  }
496  }
497  // Editor window: Blit to output
498  C4Rect rtSrc,rtDst;
499  rtSrc.x=rcBounds.x; rtSrc.y=rcBounds.y; rtSrc.Wdt=rcBounds.Wdt; rtSrc.Hgt=rcBounds.Hgt;
500  rtDst.x=0; rtDst.y=0; rtDst.Wdt=rcBounds.Wdt; rtDst.Hgt=rcBounds.Hgt;
501  pWindow->pSurface->PageFlip(&rtSrc, &rtDst);
502  }
503  }
504 
506  {
507  // custom border?
508  if (pFrameDeco)
509  pFrameDeco->Draw(cgo, rcBounds);
510  else
511  {
512  // standard border/bg then
513  // draw background
514  pDraw->DrawBoxDw(cgo.Surface, cgo.TargetX+rcBounds.x,cgo.TargetY+rcBounds.y,rcBounds.x+rcBounds.Wdt-1+cgo.TargetX,rcBounds.y+rcBounds.Hgt-1+cgo.TargetY,C4GUI_StandardBGColor);
515  // draw frame
516  Draw3DFrame(cgo);
517  }
518  }
519 
520  bool Dialog::CharIn(const char * c)
521  {
522  // reroute to active control
523  if (pActiveCtrl && pActiveCtrl->CharIn(c)) return true;
524  // unprocessed: Focus default control
525  // Except for space, which may have been processed as a key already
526  // (changing focus here would render buttons unusable, because they switch on KeyUp)
527  Control *pDefCtrl = GetDefaultControl();
528  if (pDefCtrl && pDefCtrl != pActiveCtrl && (!c || *c != 0x20))
529  {
530  SetFocus(pDefCtrl, false);
531  if (pActiveCtrl && pActiveCtrl->CharIn(c))
532  return true;
533  }
534  return false;
535  }
536 
537  bool Dialog::KeyHotkey(const C4KeyCodeEx &key)
538  {
539  StdStrBuf sKey = C4KeyCodeEx::KeyCode2String(key.Key, true, true);
540  // do hotkey procs for standard alphanumerics only
541  if (sKey.getLength() != 1) return false;
542  WORD wKey = WORD(*sKey.getData());
543  if (Inside<WORD>(TOUPPERIFX11(wKey), 'A', 'Z')) if (OnHotkey(char(TOUPPERIFX11(wKey)))) return true;
544  if (Inside<WORD>(TOUPPERIFX11(wKey), '0', '9')) if (OnHotkey(char(TOUPPERIFX11(wKey)))) return true;
545  return false;
546  }
547 
548  bool Dialog::KeyFocusDefault()
549  {
550  // unprocessed key: Focus default control
551  Control *pDefCtrl = GetDefaultControl();
552  if (pDefCtrl && pDefCtrl != pActiveCtrl)
553  SetFocus(pDefCtrl, false);
554  // never mark this as processed, so a later char message to the control may be sent (for deselected chat)
555  return false;
556  }
557 
558  void Dialog::MouseInput(CMouse &rMouse, int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam)
559  {
560  // inherited will do...
561  Window::MouseInput(rMouse, iButton, iX, iY, dwKeyParam);
562  }
563 
564  void Dialog::SetFocus(Control *pCtrl, bool fByMouse)
565  {
566  // no change?
567  if (pCtrl == pActiveCtrl) return;
568  // leave old focus
569  if (pActiveCtrl)
570  {
571  Control *pC = pActiveCtrl;
572  pActiveCtrl = nullptr;
573  pC->OnLooseFocus();
574  // if leaving the old focus set a new one, abort here because it looks like the control didn't want to lose focus
575  if (pActiveCtrl) return;
576  }
577  // set new
578  if ((pActiveCtrl = pCtrl)) pCtrl->OnGetFocus(fByMouse);
579  }
580 
581  void Dialog::AdvanceFocus(bool fBackwards)
582  {
583  // get element to start from
584  Element *pCurrElement = pActiveCtrl;
585  // find new control
586  for (;;)
587  {
588  // get next element
589  pCurrElement = GetNextNestedElement(pCurrElement, fBackwards);
590  // end reached: start from beginning
591  if (!pCurrElement && pActiveCtrl) if (!(pCurrElement = GetNextNestedElement(nullptr, fBackwards))) return;
592  // cycled?
593  if (pCurrElement == pActiveCtrl)
594  {
595  // but current is no longer a focus element? Then defocus it and return
596  if (pCurrElement && !pCurrElement->IsFocusElement())
597  SetFocus(nullptr, false);
598  return;
599  }
600  // for list elements, check whether the child can be selected
601  if (pCurrElement->GetParent() && !pCurrElement->GetParent()->IsSelectedChild(pCurrElement)) continue;
602  // check if this is a new control
603  Control *pFocusCtrl = pCurrElement->IsFocusElement();
604  if (pFocusCtrl && pFocusCtrl != pActiveCtrl && pFocusCtrl->IsVisible())
605  {
606  // set focus here...
607  SetFocus(pFocusCtrl, false);
608  // ...done!
609  return;
610  }
611  }
612  // never reached
613  }
614 
615  bool Dialog::Show(Screen *pOnScreen, bool fCB)
616  {
617  // already shown?
618  if (fShow) return false;
619  // default screen
620  if (!pOnScreen) if (!(pOnScreen = Screen::GetScreenS())) return false;
621  // show there
622  pOnScreen->ShowDialog(this, false);
623  fVisible = true;
624  // developer mode: Create window
626  if (!CreateConsoleWindow()) return false;
627  // CB
628  if (fCB) OnShown();
629  return true;
630  }
631 
632  void Dialog::Close(bool fOK)
633  {
634  // already closed?
635  if (!fShow) return;
636  // set OK flag
637  this->fOK = fOK;
638  // get screen
639  Screen *pScreen = GetScreen();
640  if (pScreen) pScreen->CloseDialog(this, false); else fShow = false;
641  // developer mode: Remove window
643  // do callback - last call, because it might do perilous things
644  OnClosed(fOK);
645  }
646 
647  void Dialog::OnClosed(bool fOK)
648  {
649  // developer mode: Remove window
651  // delete when closing?
652  if (fDelOnClose)
653  {
654  fDelOnClose=false;
655  delete this;
656  }
657  }
658 
660  {
661  // Cancel all dialogues if game is left (including e.g. league dialogues)
662  if (::Application.IsQuittingGame()) return false;
663  // main message loop
664  while (fShow)
665  {
666  // dialog idle proc
667  OnIdle();
668  // Modal dialogue during running game is tricky. Do not execute game!
669  bool fGameWasRunning = ::Game.IsRunning;
670  ::Game.IsRunning = false;
671  // handle messages - this may block until the next timer
672  if (!Application.ScheduleProcs())
673  return false; // game GUI and lobby will deleted in Game::Clear()
674  // reset game run state
675  if (fGameWasRunning) ::Game.IsRunning = true;
676  }
677  // return whether dlg was OK
678  return fOK;
679  }
680 
682  {
683  // process messages
684  if (!Application.ScheduleProcs(0))
685  return false;
686  // check status
687  if (!fShow) return false;
688  return true;
689  }
690 
692  {
693  // execute
694  if (Execute()) return true;
695  // delete self if closed
696  delete this;
697  return false;
698  }
699 
700  bool Dialog::IsActive(bool fForKeyboard)
701  {
702  // must be fully visible
703  if (!IsShown() || IsFading()) return false;
704  // screen-less dialogs are always inactive (not yet added)
705  Screen *pScreen = GetScreen();
706  if (!pScreen) return false;
707  // no keyboard focus if screen is in context mode
708  if (fForKeyboard && pScreen->HasContext()) return false;
709  // always okay in shared mode: all dlgs accessible by mouse
710  if (!pScreen->IsExclusive() && !fForKeyboard) return true;
711  // exclusive mode or keyboard input: Only one dlg active
712  return pScreen->pActiveDlg == this;
713  }
714 
715  bool Dialog::FadeIn(Screen *pOnScreen)
716  {
717  // default screen
718  if (!pOnScreen) pOnScreen = Screen::GetScreenS();
719  // fade in there
720  pOnScreen->ShowDialog(this, true);
721  iFade = 0;
722  eFade = eFadeIn;
723  fVisible = true;
724  OnShown();
725  // done, success
726  return true;
727  }
728 
729  void Dialog::FadeOut(bool fCloseWithOK)
730  {
731  // only if shown, or being faded in
732  if (!IsShown() && (!fVisible || eFade!=eFadeIn)) return;
733  // set OK flag
734  this->fOK = fCloseWithOK;
735  // fade out
736  Screen *pOnScreen = GetScreen();
737  if (!pOnScreen) return;
738  pOnScreen->CloseDialog(this, true);
739  eFade = eFadeOut;
740  // do callback - last call, because it might do perilous things
741  OnClosed(fCloseWithOK);
742  }
743 
744  void Dialog::ApplyElementOffset(int32_t &riX, int32_t &riY)
745  {
746  // inherited
747  Window::ApplyElementOffset(riX, riY);
748  // apply viewport offset, if a viewport is assigned
749  C4Viewport *pVP = GetViewport();
750  if (pVP)
751  {
752  C4Rect rcVP(pVP->GetOutputRect());
753  riX -= rcVP.x; riY -= rcVP.y;
754  }
755  }
756 
757  void Dialog::ApplyInvElementOffset(int32_t &riX, int32_t &riY)
758  {
759  // inherited
761  // apply viewport offset, if a viewport is assigned
762  C4Viewport *pVP = GetViewport();
763  if (pVP)
764  {
765  C4Rect rcVP(pVP->GetOutputRect());
766  riX += rcVP.x; riY += rcVP.y;
767  }
768  }
769 
770  void Dialog::SetClientSize(int32_t iToWdt, int32_t iToHgt)
771  {
772  // calc new bounds
773  iToWdt += GetMarginLeft()+GetMarginRight();
774  iToHgt += GetMarginTop()+GetMarginBottom();
775  rcBounds.x += (rcBounds.Wdt - iToWdt)/2;
776  rcBounds.y += (rcBounds.Hgt - iToHgt)/2;
777  rcBounds.Wdt = iToWdt; rcBounds.Hgt = iToHgt;
778  // reflect changes
779  UpdatePos();
780  }
781 
782 
783 // --------------------------------------------------
784 // FullscreenDialog
785 
786  FullscreenDialog::FullscreenDialog(const char *szTitle, const char *szSubtitle)
787  : Dialog(Screen::GetScreenS()->GetClientRect().Wdt, Screen::GetScreenS()->GetClientRect().Hgt, nullptr /* create own title */, false), pFullscreenTitle(nullptr)
788  {
789  // set margins
790  int32_t iScreenX = Screen::GetScreenS()->GetClientRect().Wdt;
791  int32_t iScreenY = Screen::GetScreenS()->GetClientRect().Hgt;
792  if (iScreenX < 500) iDlgMarginX = 2; else iDlgMarginX = iScreenX/50;
793  if (iScreenY < 320) iDlgMarginY = 2; else iDlgMarginY = iScreenY*2/75;
794  // set size - calcs client rect as well
795  SetBounds(C4Rect(0,0,iScreenX,iScreenY));
796  // create title
797  SetTitle(szTitle);
798  // create subtitle (only with upperboard)
799  if (szSubtitle && *szSubtitle && HasUpperBoard())
800  {
802  pSubTitle->SetToolTip(szTitle);
803  }
804  else pSubTitle = nullptr;
805  }
806 
807  void FullscreenDialog::SetTitle(const char *szTitle)
808  {
809  if (pFullscreenTitle) { delete pFullscreenTitle; pFullscreenTitle=nullptr; }
810  // change title text; creates or removes title bar if necessary
811  if (szTitle && *szTitle)
812  {
813  // not using dlg label, which is a wooden label
814  if (HasUpperBoard())
816  else
817  // non-woodbar: Title is centered and in big font
819  AddElement(pFullscreenTitle);
820  pFullscreenTitle->SetToolTip(szTitle);
821  }
822  }
823 
825  {
826  // draw upper board
827  if (HasUpperBoard())
829  }
830 
832  {
833  // inherited to update client rect
835  }
836 
838  {
839  // draw across fullscreen bounds - zoom 1px border to prevent flashing borders by blit offsets
840  rFromFct.DrawFullScreen(cgo);
841  }
842 
843 // --------------------------------------------------
844 // MessageDialog
845 
846  MessageDialog::MessageDialog(const char *szMessage, const char *szCaption, DWORD dwButtons, Icons icoIcon, DlgSize eSize, int32_t *piConfigDontShowAgainSetting, bool fDefaultNo)
847  : Dialog(eSize, 100 /* will be resized */, szCaption, false), piConfigDontShowAgainSetting(piConfigDontShowAgainSetting), pKeyCopy(nullptr), sCopyText()
848  {
850  // get positions
852  // place icon
853  C4Rect rcIcon = caMain.GetFromLeft(C4GUI_IconWdt); rcIcon.Hgt = C4GUI_IconHgt;
854  Icon *pIcon = new Icon(rcIcon, icoIcon); AddElement(pIcon);
855  // centered text for small dialogs and/or dialogs w/o much text (i.e.: no linebreaks)
856  bool fTextCentered;
857  if (eSize != dsRegular)
858  fTextCentered = true;
859  else
860  {
861  int32_t iMsgWdt=0, iMsgHgt=0;
862  rUseFont.GetTextExtent(szMessage, iMsgWdt, iMsgHgt);
863  fTextCentered = ((iMsgWdt <= caMain.GetInnerWidth() - C4GUI_IconWdt - C4GUI_DefDlgIndent*2) && iMsgHgt<=rUseFont.GetLineHeight());
864  }
865  // centered text dialog: waste some icon space on the right to balance dialog
866  if (fTextCentered) caMain.GetFromRight(C4GUI_IconWdt);
867  // place message label
868  // use text with line breaks
869  StdStrBuf sMsgBroken;
870  int iMsgHeight = rUseFont.BreakMessage(szMessage, caMain.GetInnerWidth(), &sMsgBroken, true);
871  Label *pLblMessage = new Label("", caMain.GetFromTop(iMsgHeight), fTextCentered ? ACenter : ALeft, C4GUI_MessageFontClr, &rUseFont, false);
872  pLblMessage->SetText(sMsgBroken.getData(), false);
873  AddElement(pLblMessage);
874  // place do-not-show-again-checkbox
875  if (piConfigDontShowAgainSetting)
876  {
877  int w=100,h=20;
878  const char *szCheckText = LoadResStr("IDS_MSG_DONTSHOW");
879  CheckBox::GetStandardCheckBoxSize(&w, &h, szCheckText, nullptr);
880  CheckBox *pCheck = new C4GUI::CheckBox(caMain.GetFromTop(h, w), szCheckText, !!*piConfigDontShowAgainSetting);
882  AddElement(pCheck);
883  }
884  if (!fTextCentered) caMain.ExpandLeft(C4GUI_DefDlgIndent*2 + C4GUI_IconWdt);
885  // place button(s)
886  ComponentAligner caButtonArea(caMain.GetFromTop(C4GUI_ButtonAreaHgt), 0,0);
887  int32_t iButtonCount = 0;
888  int32_t i=1; while (i) { if (dwButtons & i) ++iButtonCount; i=i<<1; }
889  fHasOK = !!(dwButtons & btnOK) || !!(dwButtons & btnYes);
890  Button *btnFocus = nullptr;
891  if (iButtonCount)
892  {
893  C4Rect rcBtn = caButtonArea.GetCentered(iButtonCount*C4GUI_DefButton2Wdt+(iButtonCount-1)*C4GUI_DefButton2HSpace, C4GUI_ButtonHgt);
894  rcBtn.Wdt = C4GUI_DefButton2Wdt;
895  // OK
896  if (dwButtons & btnOK)
897  {
898  Button *pBtnOK = new OKButton(rcBtn);
899  AddElement(pBtnOK);
901  if (!fDefaultNo) btnFocus = pBtnOK;
902  }
903  // Retry
904  if (dwButtons & btnRetry)
905  {
906  Button *pBtnRetry = new RetryButton(rcBtn);
907  AddElement(pBtnRetry);
909  if (!btnFocus) btnFocus = pBtnRetry;
910 
911  }
912  // Cancel
913  if (dwButtons & btnAbort)
914  {
915  Button *pBtnAbort = new CancelButton(rcBtn);
916  AddElement(pBtnAbort);
918  if (!btnFocus) btnFocus = pBtnAbort;
919  }
920  // Yes
921  if (dwButtons & btnYes)
922  {
923  Button *pBtnYes = new YesButton(rcBtn);
924  AddElement(pBtnYes);
926  if (!btnFocus && !fDefaultNo) btnFocus = pBtnYes;
927  }
928  // No
929  if (dwButtons & btnNo)
930  {
931  Button *pBtnNo = new NoButton(rcBtn);
932  AddElement(pBtnNo);
933  if (!btnFocus) btnFocus = pBtnNo;
934  }
935  // Reset
936  if (dwButtons & btnReset)
937  {
938  Button *pBtnReset = new ResetButton(rcBtn);
939  AddElement(pBtnReset);
941  if (!btnFocus) btnFocus = pBtnReset;
942 
943  }
944  }
945  if (btnFocus) SetFocus(btnFocus, false);
946  // resize to actually needed size
947  SetClientSize(GetClientRect().Wdt, GetClientRect().Hgt - caMain.GetHeight());
948  // Control+C copies text to clipboard
949  sCopyText = strprintf("[%s] %s", szCaption ? szCaption : "", szMessage ? szMessage : "");
950  pKeyCopy = new C4KeyBinding(C4KeyCodeEx(K_C, KEYS_Control), "GUIEditCopy", KEYSCOPE_Gui,
952  }
953 
955 {
956  delete pKeyCopy;
957 }
958 
960 {
961  // Copy text to clipboard
962  ::Application.Copy(sCopyText);
963  return true;
964 }
965 
966 
967 // --------------------------------------------------
968 // ConfirmationDialog
969 
970  ConfirmationDialog::ConfirmationDialog(const char *szMessage, const char *szCaption, BaseCallbackHandler *pCB, DWORD dwButtons, bool fSmall, Icons icoIcon)
971  : MessageDialog(szMessage, szCaption, dwButtons, icoIcon, fSmall ? MessageDialog::dsSmall : MessageDialog::dsRegular)
972  {
973  if ((this->pCB=pCB)) pCB->Ref();
974  // always log confirmation messages
975  LogSilentF("[Cnf] %s: %s", szCaption, szMessage);
976  // confirmations always get deleted on close
977  SetDelOnClose();
978  }
979 
981  {
982  // confirmed only on OK
983  BaseCallbackHandler *pStackCB = fOK ? pCB : nullptr;
984  if (pStackCB) pStackCB->Ref();
985  // caution: this will usually delete the dlg (this)
986  // so the CB-interface is backed up
988  if (pStackCB)
989  {
990  pStackCB->DoCall(nullptr);
991  pStackCB->DeRef();
992  }
993  }
994 
995 
996 // --------------------------------------------------
997 // ProgressDialog
998 
999  ProgressDialog::ProgressDialog(const char *szMessage, const char *szCaption, int32_t iMaxProgress, int32_t iInitialProgress, Icons icoIcon)
1000  : Dialog(C4GUI_ProgressDlgWdt, std::max(::GraphicsResource.TextFont.BreakMessage(szMessage, C4GUI_ProgressDlgWdt-3*C4GUI_DefDlgIndent-C4GUI_IconWdt, 0, 0, true), C4GUI_IconHgt) + C4GUI_ProgressDlgVRoom, szCaption, false)
1001  {
1002  // get positions
1004  ComponentAligner caButtonArea(caMain.GetFromBottom(C4GUI_ButtonAreaHgt), 0,0);
1005  C4Rect rtProgressBar = caMain.GetFromBottom(C4GUI_ProgressDlgPBHgt);
1006  // place icon
1007  C4Rect rcIcon = caMain.GetFromLeft(C4GUI_IconWdt); rcIcon.Hgt = C4GUI_IconHgt;
1008  Icon *pIcon = new Icon(rcIcon, icoIcon); AddElement(pIcon);
1009  // place message label
1010  // use text with line breaks
1011  StdStrBuf str;
1013  Label *pLblMessage = new Label(str.getData(), caMain.GetAll().GetMiddleX(), caMain.GetAll().y, ACenter, C4GUI_MessageFontClr, &::GraphicsResource.TextFont);
1014  AddElement(pLblMessage);
1015  // place progress bar
1016  pBar = new ProgressBar(rtProgressBar, iMaxProgress);
1017  pBar->SetProgress(iInitialProgress);
1018  pBar->SetToolTip(LoadResStr("IDS_DLGTIP_PROGRESS"));
1019  AddElement(pBar);
1020  // place abort button
1021  Button *pBtnAbort = new CancelButton(caButtonArea.GetCentered(C4GUI_DefButtonWdt, C4GUI_ButtonHgt));
1022  AddElement(pBtnAbort);
1023  }
1024 
1025 
1026 // --------------------------------------------------
1027 // Some dialog wrappers in Screen class
1028 
1029  bool Screen::ShowMessage(const char *szMessage, const char *szCaption, Icons icoIcon, int32_t *piConfigDontShowAgainSetting)
1030  {
1031  // always log messages
1032  LogSilentF("[Msg] %s: %s", szCaption, szMessage);
1033  if (piConfigDontShowAgainSetting && *piConfigDontShowAgainSetting) return true;
1034 #ifdef USE_CONSOLE
1035  // skip in console mode
1036  return true;
1037 #endif
1038  return ShowRemoveDlg(new MessageDialog(szMessage, szCaption, MessageDialog::btnOK, icoIcon, MessageDialog::dsRegular, piConfigDontShowAgainSetting));
1039  }
1040 
1041  bool Screen::ShowErrorMessage(const char *szMessage)
1042  {
1043  return ShowMessage(szMessage, LoadResStr("IDS_DLG_ERROR"), Ico_Error);
1044  }
1045 
1046  bool Screen::ShowMessageModal(const char *szMessage, const char *szCaption, DWORD dwButtons, Icons icoIcon, int32_t *piConfigDontShowAgainSetting)
1047  {
1048  // always log messages
1049  LogSilentF("[Modal] %s: %s", szCaption, szMessage);
1050  // skip if user doesn't want to see it
1051  if (piConfigDontShowAgainSetting && *piConfigDontShowAgainSetting) return true;
1052  // create message dlg and show modal
1053  return ShowModalDlg(new MessageDialog(szMessage, szCaption, dwButtons, icoIcon, MessageDialog::dsRegular, piConfigDontShowAgainSetting));
1054  }
1055 
1056  ProgressDialog *Screen::ShowProgressDlg(const char *szMessage, const char *szCaption, int32_t iMaxProgress, int32_t iInitialProgress, Icons icoIcon)
1057  {
1058  // create progress dlg
1059  ProgressDialog *pDlg = new ProgressDialog(szMessage, szCaption, iMaxProgress, iInitialProgress, icoIcon);
1060  // show it
1061  if (!pDlg->Show(this, true)) { delete pDlg; return nullptr; }
1062  // return dlg pointer
1063  return pDlg;
1064  }
1065 
1066  bool Screen::ShowModalDlg(Dialog *pDlg, bool fDestruct)
1067  {
1068 #ifdef USE_CONSOLE
1069  // no modal dialogs in console build
1070  // (there's most likely no way to close them!)
1071  if (fDestruct) delete pDlg;
1072  return true;
1073 #endif
1074  // safety
1075  if (!pDlg) return false;
1076  // show it
1077  if (!pDlg->Show(this, true)) { delete pDlg; return false; }
1078  // wait until it is closed
1079  bool fResult = pDlg->DoModal();
1080  if (fDestruct) delete pDlg;
1081  // return result
1082  return fResult;
1083  }
1084 
1086  {
1087  // safety
1088  if (!pDlg) return false;
1089  // mark removal when done
1090  pDlg->SetDelOnClose();
1091  // show it
1092  if (!pDlg->Show(this, true)) { delete pDlg; return false; }
1093  // done, success
1094  return true;
1095  }
1096 
1097 
1098 // --------------------------------------------------
1099 // InputDialog
1100 
1101  InputDialog::InputDialog(const char *szMessage, const char *szCaption, Icons icoIcon, BaseInputCallback *pCB, bool fChatLayout)
1102  : Dialog(fChatLayout ? C4GUI::GetScreenWdt()*4/5 : C4GUI_InputDlgWdt,
1103  fChatLayout ? C4GUI::Edit::GetDefaultEditHeight() + 2 :
1104  std::max(::GraphicsResource.TextFont.BreakMessage(szMessage, C4GUI_InputDlgWdt - 3 * C4GUI_DefDlgIndent - C4GUI_IconWdt, 0, 0, true),
1105  C4GUI_IconHgt) + C4GUI_InputDlgVRoom, szCaption, false),
1106  pEdit(nullptr), pCB(pCB), fChatLayout(fChatLayout), pChatLbl(nullptr)
1107  {
1108  if (fChatLayout)
1109  {
1110  // chat input layout
1112  // normal chatbox layout: Left chat label
1113  int32_t w=40,h;
1114  ::GraphicsResource.TextFont.GetTextExtent(szMessage, w,h, true);
1116  caChat.ExpandLeft(2); // undo margin
1117  rcEditBounds = caChat.GetAll();
1119  pChatLbl->SetToolTip(LoadResStr("IDS_DLGTIP_CHAT"));
1121  }
1122  else
1123  {
1124  // regular input dialog layout
1125  // get positions
1127  ComponentAligner caButtonArea(caMain.GetFromBottom(C4GUI_ButtonAreaHgt), 0,0);
1129  // place icon
1130  C4Rect rcIcon = caMain.GetFromLeft(C4GUI_IconWdt); rcIcon.Hgt = C4GUI_IconHgt;
1131  Icon *pIcon = new Icon(rcIcon, icoIcon); AddElement(pIcon);
1132  // place message label
1133  // use text with line breaks
1134  StdStrBuf str;
1136  Label *pLblMessage = new Label(str.getData(), caMain.GetAll().GetMiddleX(), caMain.GetAll().y, ACenter, C4GUI_MessageFontClr, &::GraphicsResource.TextFont);
1137  AddElement(pLblMessage);
1138  // place input edit
1139  SetCustomEdit(new Edit(rcEditBounds));
1140  // place buttons
1141  C4Rect rcBtn = caButtonArea.GetCentered(2 * C4GUI_DefButton2Wdt + C4GUI_DefButton2HSpace, C4GUI_ButtonHgt);
1142  rcBtn.Wdt = C4GUI_DefButton2Wdt;
1143  // OK
1144  Button *pBtnOK = new OKButton(rcBtn);
1145  AddElement(pBtnOK);
1146  rcBtn.x += rcBtn.Wdt + C4GUI_DefButton2HSpace;
1147  // Cancel
1148  Button *pBtnAbort = new CancelButton(rcBtn);
1149  AddElement(pBtnAbort);
1150  rcBtn.x += rcBtn.Wdt + C4GUI_DefButton2HSpace;
1151  }
1152  // input dlg always closed in the end
1153  SetDelOnClose();
1154  }
1155 
1156  void InputDialog::SetInputText(const char *szToText)
1157  {
1159  if (szToText)
1160  {
1161  pEdit->InsertText(szToText, false);
1162  pEdit->SelectAll();
1163  }
1164  }
1165 
1167  {
1168  // del old
1169  if (pEdit) delete pEdit;
1170  // add new
1171  pEdit = pCustomEdit;
1173  if (fChatLayout)
1174  {
1175  pEdit->SetToolTip(LoadResStr("IDS_DLGTIP_CHAT"));
1176  pChatLbl->SetClickFocusControl(pEdit); // 2do: to all, to allies, etc.
1177  }
1178  AddElement(pEdit);
1179  SetFocus(pEdit, false);
1180  }
1181 
1182 
1183 // --------------------------------------------------
1184 // InfoDialog
1185 
1186  InfoDialog::InfoDialog(const char *szCaption, int32_t iLineCount)
1187  : Dialog(C4GUI_InfoDlgWdt, ::GraphicsResource.TextFont.GetLineHeight()*iLineCount + C4GUI_InfoDlgVRoom, szCaption, false), iScroll(0)
1188  {
1189  // timer
1190  Application.Add(this);
1192  }
1193 
1194  InfoDialog::InfoDialog(const char *szCaption, int iLineCount, const StdStrBuf &sText)
1195  : Dialog(C4GUI_InfoDlgWdt, ::GraphicsResource.TextFont.GetLineHeight()*iLineCount + C4GUI_InfoDlgVRoom, szCaption, false), iScroll(0)
1196  {
1197  // ctor - init w/o timer
1199  // fill in initial text
1200  for (size_t i=0; i < sText.getLength(); ++i)
1201  {
1202  size_t i0 = i;
1203  while (sText[i] != '|' && sText[i]) ++i;
1204  StdStrBuf sLine = sText.copyPart(i0, i-i0);
1206  }
1208  }
1210  {
1211  Application.Remove(this);
1212  }
1213 
1215  {
1216  // get positions
1218  ComponentAligner caButtonArea(caMain.GetFromBottom(C4GUI_ButtonAreaHgt), 0,0);
1219  // place info box
1220  pTextWin = new TextWindow(caMain.GetAll(), 0, 0, 0, 100, 4096, " ", true, nullptr, 0);
1221  AddElement(pTextWin);
1222  // place close button
1223  Button *pBtnClose = new DlgCloseButton(caButtonArea.GetCentered(C4GUI_DefButtonWdt, C4GUI_ButtonHgt));
1224  AddElement(pBtnClose); pBtnClose->SetToolTip(LoadResStr("IDS_MNU_CLOSE"));
1225  }
1226 
1227  void InfoDialog::AddLine(const char *szText)
1228  {
1229  // add line to text window
1230  if (!pTextWin) return;
1232  }
1233 
1234  void InfoDialog::AddLineFmt(const char *szFmtString, ...)
1235  {
1236  // compose formatted line
1237  va_list lst; va_start(lst, szFmtString);
1238  StdStrBuf buf;
1239  buf.FormatV(szFmtString, lst);
1240  // add it
1241  AddLine(buf.getData());
1242  }
1243 
1245  {
1246  // safety
1247  if (!pTextWin) return;
1248  // backup scrolling
1249  iScroll = pTextWin->GetScrollPos();
1250  // clear text window, so new text can be added
1251  pTextWin->ClearText(false);
1252  }
1253 
1255  {
1256  // safety
1257  if (!pTextWin) return;
1258  // update text height
1260  // restore scrolling
1261  pTextWin->SetScrollPos(iScroll);
1262  }
1263 
1265  {
1266  // always update
1267  UpdateText();
1268  }
1269 
1270 } // end of namespace
1271 
const char * getData() const
Definition: StdBuf.h:450
FrameDecoration * pFrameDeco
Definition: C4Gui.h:2089
void DestroyConsoleWindow()
int32_t GetHeight() const
Definition: C4Gui.h:2801
virtual void DoCall(class Element *pElement)=0
bool IsRunning
Definition: C4Game.h:141
virtual void Draw(C4TargetFacet &cgo)
virtual void MouseInput(CMouse &rMouse, int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam)
#define C4GUI_CaptionFontClr
Definition: C4Gui.h:37
#define C4GUI_StandardBGColor
Definition: C4Gui.h:66
C4ID id
Definition: C4Def.h:103
virtual ~Dialog()
#define C4GUI_ButtonAreaHgt
Definition: C4Gui.h:113
Fade eFade
Definition: C4Gui.h:2084
virtual void OnClosed(bool fOK)
C4Config Config
Definition: C4Config.cpp:837
int GetLineHeight() const
Definition: C4FontLoader.h:132
bool GetSize(C4Rect *pRect)
Definition: C4AppT.cpp:106
float Y
Definition: C4Facet.h:120
#define C4GUI_ButtonHgt
Definition: C4Gui.h:111
void SetClientSize(int32_t iToWdt, int32_t iToHgt)
void GetAll(C4Rect &rcOut)
Definition: C4Gui.cpp:1128
bool fShow
Definition: C4Gui.h:2081
Dialog * GetTopDialog()
Definition: C4Gui.cpp:695
virtual void ApplyElementOffset(int32_t &riX, int32_t &riY)
#define C4GUI_FullscreenCaptionFontClr
Definition: C4Gui.h:161
void SetCustomEdit(Edit *pCustomEdit)
#define C4GUI_MessageFontClr
Definition: C4Gui.h:43
int Wdt
Definition: C4Surface.h:67
void DeleteSelection()
Definition: C4GuiEdit.cpp:149
Label * pFullscreenTitle
Definition: C4Gui.h:2223
C4Game Game
Definition: C4Globals.cpp:52
virtual void UpdatePos()
virtual void ApplyInvElementOffset(int32_t &riX, int32_t &riY)
#define C4GUI_MinWoodBarHgt
Definition: C4Gui.h:158
virtual void OnShown()
Definition: C4Gui.h:2208
bool IsVisible()
Definition: C4Gui.cpp:202
#define C4GUI_TitleAutoScrollTime
Definition: C4Gui.h:146
const char * GetSubkeyPath(const char *strSubkey)
Definition: C4Config.cpp:717
void DrawBackground(C4TargetFacet &cgo, C4Facet &rFromFct)
void Cancel(T &keys)
C4Surface * pSurface
Definition: C4Window.h:279
void SetToolTip(const char *szNewTooltip, bool is_immediate=false)
Definition: C4Gui.cpp:410
C4KeyShiftState
void SelectAll()
Definition: C4GuiEdit.cpp:641
void SetTitle(const char *Title)
Definition: C4AppT.cpp:112
void Draw(C4TargetFacet &cgo, C4Rect &rcDrawArea)
bool KeyEscape()
Definition: C4Gui.h:2135
#define C4GUI_InputDlgWdt
Definition: C4Gui.h:131
#define C4GUI_DefButton2HSpace
Definition: C4Gui.h:116
void Close(bool fOK)
const int ARight
Definition: C4Surface.h:43
virtual const char * GetID()
Definition: C4Gui.h:2107
bool ShowRemoveDlg(Dialog *pDlg)
Definition: C4Rect.h:29
int32_t GetScreenWdt()
Definition: C4Gui.h:2821
DialogWindow * pWindow
Definition: C4Gui.h:2088
void Draw3DFrame(C4TargetFacet &cgo, bool fUp=false, int32_t iIndent=1, BYTE byAlpha=C4GUI_BorderAlpha, bool fDrawTop=true, int32_t iTopOff=0, bool fDrawLeft=true, int32_t iLeftOff=0)
Definition: C4Gui.cpp:292
bool SetByDef(C4Def *pSrcDef)
bool GetTextExtent(const char *szText, int32_t &rsx, int32_t &rsy, bool fCheckMarkup=true)
virtual void OnIdle()
Definition: C4Gui.h:2209
void Format(const char *szFmt,...) GNUC_FORMAT_ATTRIBUTE_O
Definition: StdBuf.cpp:181
static Screen * GetScreenS()
Definition: C4Gui.h:2626
virtual C4Rect & GetClientRect()
Definition: C4Gui.h:864
C4Rect rcEditBounds
Definition: C4Gui.h:2408
void AddElement(Element *pChild)
C4Window * Init(C4AbstractApp *pApp, const char *Title, const C4Rect &rcBounds, const char *szID)
bool IsViewportDialog()
Definition: C4Gui.h:2172
static int32_t GetDefaultTitleHeight()
virtual int32_t GetMarginTop()
Definition: C4Gui.h:2246
virtual void UpdateSize()
Definition: C4Gui.cpp:186
const int C4UpperBoardHeight
Definition: C4Constants.h:59
CallbackButton< Dialog, C4GUI::IconButton > * pCloseBtn
Definition: C4Gui.h:2079
C4Rect rcClientRect
Definition: C4Gui.h:851
Control * pActiveCtrl
Definition: C4Gui.h:2080
C4Rect GetContainedClientRect()
Definition: C4Gui.h:448
ConfirmationDialog(const char *szMessage, const char *szCaption, BaseCallbackHandler *pCB, DWORD dwButtons=MessageDialog::btnOKAbort, bool fSmall=false, Icons icoIcon=Ico_Confirm)
int Hgt
Definition: C4Surface.h:67
C4GraphicsResource GraphicsResource
bool SEqual(const char *szStr1, const char *szStr2)
Definition: Standard.h:97
void Add(StdSchedulerProc *pProc)
void SetDelOnClose(bool fToVal=true)
Definition: C4Gui.h:2190
#define C4GUI_DefButton2Wdt
Definition: C4Gui.h:115
C4TargetFacet fctBottomRight
Definition: C4Gui.h:2052
void RecheckActiveDialog()
Definition: C4Gui.cpp:686
bool IsShown()
Definition: C4Gui.h:2147
bool fOK
Definition: C4Gui.h:2082
const char * LoadResStr(const char *id)
Definition: C4Language.h:83
virtual int32_t GetMarginLeft()
Definition: C4Gui.h:2141
virtual void OnLooseFocus()
Definition: C4Gui.h:1057
C4TargetFacet fctRight
Definition: C4Gui.h:2052
C4TargetFacet fctTop
Definition: C4Gui.h:2052
virtual void RemoveElement(Element *pChild)
static StdStrBuf KeyCode2String(C4KeyCode wCode, bool fHumanReadable, bool fShort)
virtual bool HasUpperBoard()
Definition: C4Gui.h:2241
#define C4GUI_InputDlgVRoom
Definition: C4Gui.h:136
int32_t Wdt
Definition: C4Rect.h:32
bool IsExclusive()
Definition: C4Gui.h:2667
#define C4GUI_InfoDlgVRoom
Definition: C4Gui.h:139
std::vector< C4KeyCodeEx > CodeList
bool Show(Screen *pOnScreen, bool fCB)
friend class TextWindow
Definition: C4Gui.h:472
void SetSize(unsigned int cx, unsigned int cy)
Definition: C4AppT.cpp:111
StdStrBuf TitleString
Definition: C4Gui.h:2086
virtual void UpdateOwnPos()
bool LogSilentF(const char *strMessage,...)
Definition: C4Log.cpp:263
bool IsFading()
Definition: C4Gui.h:2151
bool BlitSurfaceTile(C4Surface *sfcSurface, C4Surface *sfcTarget, float iToX, float iToY, float iToWdt, float iToHgt, float iOffsetX, float iOffsetY, C4ShaderCall *shader_call)
Definition: C4Draw.cpp:538
bool InsertText(const char *szText, bool fUser)
Definition: C4GuiEdit.cpp:163
bool GetFromTop(int32_t iHgt, int32_t iWdt, C4Rect &rcOut)
Definition: C4Gui.cpp:1062
static int32_t GetDefaultHeight(CStdFont *pUseFont=nullptr)
int32_t y
Definition: C4Rect.h:32
virtual C4Viewport * GetViewport()
Definition: C4Gui.h:2171
bool ShowMessageModal(const char *szMessage, const char *szCaption, DWORD dwButtons, Icons icoIcon, int32_t *piConfigDontShowAgainSetting=nullptr)
uint32_t dwBackClr
Definition: C4Gui.h:2051
virtual bool OnHotkey(uint32_t cHotkey)
#define C4GUI_IconWdt
Definition: C4Gui.h:93
const int ACenter
Definition: C4Surface.h:43
bool PageFlip(C4Rect *pSrcRt=nullptr, C4Rect *pDstRt=nullptr)
Definition: C4Surface.cpp:320
virtual void OnSec1Timer()
virtual void OnGetFocus(bool fByMouse)
Definition: C4Gui.h:1056
virtual Control * IsFocusElement()
Definition: C4Gui.h:432
C4GameControl Control
#define C4GUI_ProgressDlgPBHgt
Definition: C4Gui.h:137
void SetClickFocusControl(Control *pToCtrl)
Definition: C4Gui.h:504
bool IsReady()
Definition: C4ScriptHost.h:53
bool ShowErrorMessage(const char *szMessage)
void ExpandLeft(int32_t iByWdt)
Definition: C4Gui.h:2809
virtual void RemoveElement(Element *pChild)
C4Surface * GetBitmap(DWORD dwClr=0)
Dialog * pDialog
Definition: C4Gui.h:2032
void DrawBoxDw(C4Surface *sfcDest, int iX1, int iY1, int iX2, int iY2, DWORD dwClr)
Definition: C4Draw.cpp:849
C4Rect GetToprightCornerRect(int32_t iWidth=16, int32_t iHeight=16, int32_t iHIndent=4, int32_t iVIndent=4, int32_t iIndexX=0)
Definition: C4Gui.cpp:400
Label * pChatLbl
Definition: C4Gui.h:2410
virtual bool CharIn(const char *)
Definition: C4Gui.h:1051
static const C4ID None
Definition: C4Id.h:42
virtual void DrawElement(C4TargetFacet &cgo)
virtual int32_t GetMarginBottom()
Definition: C4Gui.h:2143
C4Rect rcBounds
Definition: C4Gui.h:385
void Set(const C4Facet &cpy)
Definition: C4Facet.h:184
InputDialog(const char *szMessage, const char *szCaption, Icons icoIcon, BaseInputCallback *pCB, bool fChatLayout=false)
virtual bool IsSelectedChild(Element *pChild)
Definition: C4Gui.h:837
#define C4GUI_IconHgt
Definition: C4Gui.h:94
int32_t GetScrollPos()
Definition: C4Gui.h:1746
void Draw(C4Facet &cgo, bool fAspect=true, int32_t iPhaseX=0, int32_t iPhaseY=0, bool fTransparent=true)
Definition: C4Facet.cpp:154
void UpdateHeight()
Definition: C4Gui.h:1750
bool RestorePosition(const char *szWindowName, const char *szSubKey, bool fHidden=false)
Definition: C4AppT.cpp:109
virtual void ApplyElementOffset(int32_t &riX, int32_t &riY)
Definition: C4Gui.h:866
Dialog * GetTargetDialog() const
Definition: C4Gui.h:1886
Container * GetParent()
Definition: C4Gui.h:429
Dialog(int32_t iWdt, int32_t iHgt, const char *szTitle, bool fViewportDlg)
Definition: C4Def.h:100
#define C4GUI_DefButtonWdt
Definition: C4Gui.h:114
C4Rect GetOutputRect()
Definition: C4Viewport.h:64
C4Draw * pDraw
Definition: C4Draw.cpp:45
virtual void PerformUpdate()
static int32_t GetDefaultEditHeight()
Definition: C4GuiEdit.cpp:113
void SetInputText(const char *szToText)
void SetScrollPos(int32_t iPos)
Definition: C4Gui.h:1748
bool KeyAdvanceFocus(bool fBackwards)
Definition: C4Gui.h:2138
virtual void ApplyInvElementOffset(int32_t &riX, int32_t &riY)
Definition: C4Gui.h:868
ProgressDialog * ShowProgressDlg(const char *szMessage, const char *szCaption, int32_t iMaxProgress=100, int32_t iInitialProgress=0, Icons icoIcon=Ico_Wait)
virtual int32_t GetMarginRight()
Definition: C4Gui.h:2142
Definition: C4Id.h:28
void FadeOut(bool fCloseWithOK)
void DrawFullScreen(C4Facet &cgo)
Definition: C4Facet.cpp:184
void OnUserClose(C4GUI::Control *btn)
Definition: C4Gui.h:2204
C4TargetFacet fctTopRight
Definition: C4Gui.h:2052
C4Rect & GetBounds()
Definition: C4Gui.h:445
std::tuple< std::string, int > BreakMessage(const char *szMsg, int iWdt, bool fCheckMarkup, float fZoom=1.0f)
Icons
Definition: C4Gui.h:637
static bool GetStandardCheckBoxSize(int *piWdt, int *piHgt, const char *szForCaptionText, CStdFont *pUseFont)
void CloseDialog(Dialog *pDlg, bool fFade)
Definition: C4Gui.cpp:666
C4KeyCode Key
StdStrBuf copyPart(size_t iStart, size_t inSize) const
Definition: StdBuf.h:643
int32_t getInt() const
Definition: C4Value.h:112
bool KeyEnter()
Definition: C4Gui.h:2133
C4PropList * GetActionByName(const char *actname)
Definition: C4Def.cpp:651
int32_t x
Definition: C4Rect.h:32
virtual void UpdateOwnPos()
void SetDragTarget(Window *pToWindow)
Definition: C4Gui.h:464
bool ShowMessage(const char *szMessage, const char *szCaption, Icons icoIcon, int32_t *piConfigDontShowAgainSetting=nullptr)
const char * GetText()
Definition: C4Gui.h:503
FullscreenDialog(const char *szTitle, const char *szSubtitle)
void SetTitle(const char *szToTitle)
void Right(T &keys)
void Remove(StdSchedulerProc *pProc)
WoodenLabel * pTitle
Definition: C4Gui.h:2078
int32_t GamepadGuiControl
Definition: C4Config.h:230
#define C4GUI_ProgressDlgWdt
Definition: C4Gui.h:130
void SetOnChecked(BaseCallbackHandler *pCB)
bool IsQuittingGame() const
Definition: C4Application.h:70
float TargetX
Definition: C4Facet.h:167
bool CreateConsoleWindow()
C4Def * C4Id2Def(C4ID id)
Definition: C4DefList.h:80
void Ok(T &keys)
void SetFocus(Control *pCtrl, bool fByMouse)
bool Copy(const std::string &text, bool fClipboard=true)
Definition: C4AppMac.mm:34
C4TargetFacet fctBottomLeft
Definition: C4Gui.h:2052
C4ConfigControls Controls
Definition: C4Config.h:260
void Default()
Definition: C4Facet.h:181
float Hgt
Definition: C4Facet.h:120
void SetBounds(const C4Rect &rcNewBound)
Definition: C4Gui.h:446
C4TargetFacet fctTopLeft
Definition: C4Gui.h:2052
void SetAutoScrollTime(uint32_t tDelay)
Definition: C4Gui.h:537
void ShowDialog(Dialog *pDlg, bool fFade)
Definition: C4Gui.cpp:614
ProgressBar * pBar
Definition: C4Gui.h:2370
bool FadeIn(Screen *pOnScreen)
bool HasContext()
Definition: C4Gui.h:2657
const int ALeft
Definition: C4Surface.h:43
virtual bool PrepareRendering(C4Surface *sfcToSurface) override
Definition: C4DrawGL.cpp:178
virtual void OnClosed(bool fOK)
bool fVisible
Definition: C4Gui.h:383
C4DefScriptHost Script
Definition: C4Def.h:184
virtual int32_t GetMarginTop()
Definition: C4Gui.h:2140
void SetTitle(const char *szToTitle, bool fShowCloseButton=true)
#define C4GUI_ProgressDlgVRoom
Definition: C4Gui.h:135
void AddLineFmt(const char *szFmtString,...) GNUC_FORMAT_ATTRIBUTE_O
#define C4GUI_DefDlgIndent
Definition: C4Gui.h:132
void FormatV(const char *szFmt, va_list args)
Definition: StdBuf.cpp:189
const C4KeyCode KEY_Any
virtual void MouseInput(CMouse &rMouse, int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam)
C4TargetFacet fctLeft
Definition: C4Gui.h:2052
void DeactivateBlitModulation()
Definition: C4Draw.h:189
virtual void Draw(C4TargetFacet &cgo)
virtual C4Window * Init(WindowKind windowKind, C4AbstractApp *pApp, const char *Title, const C4Rect *size)
Definition: C4AppT.cpp:107
int32_t GetPropertyInt(C4PropertyName k, int32_t default_val=0) const
Definition: C4PropList.cpp:863
void AddTextLine(const char *szText, CStdFont *pFont, DWORD dwClr, bool fDoUpdate, bool fMakeReadableOnBlack, CStdFont *pCaptionFont=nullptr)
Definition: C4Gui.h:1740
bool GetFromRight(int32_t iWdt, int32_t iHgt, C4Rect &rcOut)
Definition: C4Gui.cpp:1096
InfoDialog(const char *szCaption, int32_t iLineCount)
size_t getLength() const
Definition: StdBuf.h:453
C4TargetFacet fctBottom
Definition: C4Gui.h:2052
virtual void UpdatePos()
Definition: C4Gui.cpp:194
bool ShowModalDlg(Dialog *pDlg, bool fDestruct=true)
virtual Screen * GetScreen()
Definition: C4Gui.cpp:290
CStdGL * pGL
Definition: C4DrawGL.cpp:914
void SetProgress(int32_t iToProgress)
Definition: C4Gui.h:578
void ActivateBlitModulation(DWORD dwWithClr)
Definition: C4Draw.h:188
int32_t Hgt
Definition: C4Rect.h:32
bool ScheduleProcs(int iTimeout=1000/36)
void OnDontShowAgainCheck(C4GUI::Element *pCheckBox)
Definition: C4Gui.h:2344
Element * GetNextNestedElement(Element *pPrevElement, bool fBackwards)
void SetRightIndent(int32_t iNewIndent)
Definition: C4Gui.h:540
#define C4GUI_InfoDlgWdt
Definition: C4Gui.h:138
std::string strprintf(const char *format,...)
Definition: Standard.cpp:802
virtual void Close()
C4Surface * Surface
Definition: C4Facet.h:119
bool GetFromLeft(int32_t iWdt, int32_t iHgt, C4Rect &rcOut)
Definition: C4Gui.cpp:1079
TextWindow * pTextWin
Definition: C4Gui.h:2432
float TargetY
Definition: C4Facet.h:167
virtual void Clear()
Definition: C4AppT.cpp:100
void AddLine(const char *szText)
void Left(T &keys)
C4Value Call(C4PropertyName k, C4AulParSet *pPars=0, bool fPassErrors=false)
Definition: C4PropList.h:112
#define TOUPPERIFX11(key)
Dialog * pActiveDlg
Definition: C4Gui.h:2590
uint32_t DWORD
void Copy()
Definition: StdBuf.h:475
float Wdt
Definition: C4Facet.h:120
virtual void DrawElement(C4TargetFacet &cgo)
C4DefGraphics Graphics
Definition: C4Def.h:194
MessageDialog(const char *szMessage, const char *szCaption, DWORD dwButtons, Icons icoIcon, DlgSize eSize=dsRegular, int32_t *piConfigDontShowAgainSetting=nullptr, bool fDefaultNo=false)
bool IsActive(bool fForKeyboard)
float X
Definition: C4Facet.h:120
bool fHasGfxOutsideClientArea
Definition: C4Gui.h:2054
virtual void Draw(C4TargetFacet &cgo)
Definition: C4GuiMenu.cpp:462
C4Application Application
Definition: C4Globals.cpp:44
uint16_t WORD
#define PSF_FrameDecoration
Definition: C4GameScript.h:90
virtual class Control * GetDefaultControl()
Definition: C4Gui.h:2129
bool GetFromBottom(int32_t iHgt, int32_t iWdt, C4Rect &rcOut)
Definition: C4Gui.cpp:1112
ProgressDialog(const char *szMessage, const char *szCaption, int32_t iMaxProgress, int32_t iInitialProgress, Icons icoIcon)
int32_t GetInnerWidth() const
Definition: C4Gui.h:2805
virtual bool CharIn(const char *c)
virtual void UpdateSize()
void SetText(const char *szToText, bool fAllowHotkey=true)
Definition: C4GuiLabels.cpp:74
void ActivateDialog(Dialog *pDlg)
Definition: C4Gui.cpp:650
bool fDelOnClose
Definition: C4Gui.h:2085
void ClearText(bool fDoUpdate)
Definition: C4Gui.h:1744
int32_t iFade
Definition: C4Gui.h:2083
void AdvanceFocus(bool fBackwards)
StdStrBuf FormatString(const char *szFmt,...)
Definition: StdBuf.cpp:277
virtual void UpdateText()
Definition: C4Gui.h:2443