OpenClonk
C4GuiButton.cpp
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
5  * Copyright (c) 2009-2016, The OpenClonk Team and contributors
6  *
7  * Distributed under the terms of the ISC license; see accompanying file
8  * "COPYING" for details.
9  *
10  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
11  * See accompanying file "TRADEMARK" for details.
12  *
13  * To redistribute this file separately, substitute the full license texts
14  * for the above references.
15  */
16 // generic user interface
17 // that which can be pressed
18 
19 #include "C4Include.h"
20 #include "gui/C4Gui.h"
21 
22 #include "graphics/C4Draw.h"
24 #include "gui/C4MouseControl.h"
25 
26 namespace C4GUI
27 {
28 
29 
30 // --------------------------------------------------
31 // Button
32 
33  Button::Button(const char *szBtnText, const C4Rect &rtBounds)
34  : Control(rtBounds), pCustomGfx(nullptr), pCustomGfxDown(nullptr), fDown(false), fMouseOver(false), fEnabled(true),
35  dwCustomFontClr(0), pCustomFont(nullptr)
36  {
37  // key callbacks
39  keys.emplace_back(K_SPACE);
40  keys.emplace_back(K_RETURN);
42  ControllerKeys::Ok(keys);
43  pKeyButton = new C4KeyBinding(keys, "GUIButtonPress", KEYSCOPE_Gui,
45  sText = "";
46  // set new button text
47  SetText(szBtnText);
48  }
49 
51  {
52  delete pKeyButton;
53  }
54 
55  void Button::SetText(const char *szToText)
56  {
57  // set new button text
58  if (szToText)
59  {
60  sText.Copy(szToText);
61  // expand hotkey markup
63  }
64  else
65  {
66  sText="";
67  cHotkey=0;
68  }
69  }
70 
71  bool Button::OnHotkey(uint32_t cHotkey)
72  {
73  // if hotkey matches, press the button
74  if (this->cHotkey == cHotkey && fEnabled)
75  {
76  OnPress();
77  return true;
78  }
79  else return false;
80  }
81 
83  {
84  // draw base
85  if (fDown)
86  // pressed
87  DrawBar(cgo, pCustomGfxDown ? *pCustomGfxDown : ::GraphicsResource.barButtonD);
88  else
89  // released
90  DrawBar(cgo, pCustomGfx ? *pCustomGfx : ::GraphicsResource.barButton);
91  // get text pos
92  int32_t x0 = cgo.TargetX + rcBounds.x, y0 = cgo.TargetY + rcBounds.y, x1 = cgo.TargetX + rcBounds.x + rcBounds.Wdt - 1, y1 = cgo.TargetY + rcBounds.y + rcBounds.Hgt - 1;
93  int32_t iTxtOff = fDown ? 1 : 0;
94  // draw selection highlight
95  if (fEnabled) if (HasDrawFocus() || (fMouseOver && IsInActiveDlg(false)))
96  {
100  }
101  // draw text
102  int32_t iTextHgt = rcBounds.Hgt-2;
103  CStdFont &rUseFont =
109  iTextHgt = rUseFont.GetLineHeight();
110  pDraw->TextOut(sText.getData(), rUseFont, 1.0f, cgo.Surface, (x0+x1)/2 + iTxtOff, (y0+y1-iTextHgt)/2 + iTxtOff, C4GUI_ButtonFontClr, ACenter, true);
111  }
112 
114 {
115  // not on disabled
116  if (!fEnabled) return false;
117  // space downs button
118  SetDown();
119  return true;
120  }
121 
123  {
124  // space press activates button
125  if (!fDown) return false;
126  SetUp(true);
127  if (fEnabled) OnPress();
128  return true;
129  }
130 
131  void Button::MouseInput(CMouse &rMouse, int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam)
132  {
133  // inherited
134  Control::MouseInput(rMouse, iButton, iX, iY, dwKeyParam);
135  // process left down and up
136  if (fEnabled) switch (iButton)
137  {
139 
140  // mark button as being down
141  SetDown();
142  // remember drag target
143  // no dragging movement will be done w/o drag component assigned
144  // but it should be remembered if the user leaves the button with the mouse down
145  // and then re-enters w/o having released the button
146  if (!rMouse.pDragElement) rMouse.pDragElement = this;
147  break;
148 
149  case C4MC_Button_LeftUp:
150  // only if button was down... (might have dragged here)
151  if (fDown)
152  {
153  // it's now up :)
154  SetUp(true);
155  // process event
156  OnPress();
157  }
158  break;
159  };
160  }
161 
163  {
164  Control::MouseEnter(rMouse);
165  // remember mouse state for button highlight
166  fMouseOver = true;
167  // mouse re-enters with left button down?
168  if (rMouse.pDragElement == this) if (fEnabled) SetDown();
169  }
170 
172  {
173  Control::MouseLeave(rMouse);
174  // mouse left
175  fMouseOver = false;
176  // reset down-state if mouse leves with button down
177  if (rMouse.pDragElement == this) if (fEnabled) SetUp(false);
178  }
179 
181  {
182  // nothing in base
183  }
184 
186  {
187  // already down?
188  if (fDown) return;
189  // play sound
190  GUISound("UI::Tick");
191  // set down
192  fDown = true;
193  }
194 
195  void Button::SetUp(bool fPress)
196  {
197  // already up?
198  if (!fDown) return;
199  // play sound
200  GUISound(fPress ? "UI::Click" : "UI::Tick");
201  // set up
202  fDown = false;
203  }
204 
205 
206 // --------------------------------------------------------
207 // IconButton
208 
210  {
211  // get drawing bounds
212  int32_t x0 = cgo.TargetX + rcBounds.x, y0 = cgo.TargetY + rcBounds.y;
213  // draw selection highlight
214  if (fEnabled) if (fHighlight || HasDrawFocus() || (fMouseOver && IsInActiveDlg(false)))
215  {
218  pDraw->ResetBlitMode();
219  }
220  // draw the icon
222  fctIcon.DrawX(cgo.Surface, x0, y0, rcBounds.Wdt, rcBounds.Hgt);
223  // "button" down?
224  if (fEnabled) if (fDown || fHighlight)
225  {
228  pDraw->ResetBlitMode();
229  }
230  // some icon buttons have captions. draw caption below button
231  if (sText.getLength())
232  {
235  }
236  }
237 
238  IconButton::IconButton(Icons eUseIcon, const C4Rect &rtBounds, char caHotkey, const char *tooltip_text)
239  : Button("", rtBounds), dwClr(0u), fHasClr(false), fHighlight(false)
240  {
241  // ctor
242  cHotkey = caHotkey;
243  SetIcon(eUseIcon);
244  // set tooltip and expand hotkey
245  if (tooltip_text)
246  {
247  StdStrBuf tooltip_text_buf(tooltip_text);
248  if (!cHotkey) ExpandHotkeyMarkup(tooltip_text_buf, cHotkey, true);
249  SetToolTip(tooltip_text_buf.getData(), true);
250  }
251  }
252 
253  void IconButton::SetIcon(Icons eUseIcon)
254  {
255  if (eUseIcon>=0) fctIcon = Icon::GetIconFacet(eUseIcon); else fctIcon.Surface=nullptr;
256  }
257 
258 
259 
260 // --------------------------------------------------------
261 // ArrowButton
262 
263  ArrowButton::ArrowButton(ArrowFct eDir, const C4Rect &rtBounds, char cHotkey)
264  : Button("", rtBounds), eDir(eDir)
265  {
266  // ctor
267  this->cHotkey = cHotkey;
268  }
269 
271  {
272  // get drawing bounds
273  int32_t x0 = cgo.TargetX + rcBounds.x, y0 = cgo.TargetY + rcBounds.y;
274  // draw selection highlight
275  if (fEnabled) if (HasDrawFocus() || (fMouseOver && IsInActiveDlg(false)))
276  {
279  pDraw->ResetBlitMode();
280  }
281  // draw the arrow - down if pressed
282  int32_t iFctIdx = eDir;
283  if (fDown) iFctIdx += Down;
285  }
286 
287 
289  {
290  // default by gfx size
292  }
293 
295  {
296  // default by gfx size
298  }
299 
300 
301 // --------------------------------------------------------
302 // FacetButton
303 
304  FacetButton::FacetButton(const C4Facet &rBaseFct, const C4Facet &rHighlightFct, const FLOAT_RECT &rtfBounds, char cHotkey)
305  : Button("", C4Rect(rtfBounds)), fctBase(rBaseFct), fctHighlight(rHighlightFct), dwTextClrInact(0x7f000000), dwTextClrAct(0xff000000), rcfDrawBounds(rtfBounds), pFont(nullptr), fFontZoom(1.0f)
306  {
307  // ctor
308  this->cHotkey = cHotkey;
309  iTxtOffX=iTxtOffY=0;
311  }
312 
314  {
315  // get drawing bounds
316  float x0 = rcfDrawBounds.left + cgo.TargetX, y0 = rcfDrawBounds.top + cgo.TargetY;
317  // draw button or highlight facet
318  uint32_t dwTextClr;
319  if ((HasDrawFocus() || (fMouseOver && IsInActiveDlg(false))) && fEnabled)
320  {
322  dwTextClr = dwTextClrAct;
323  }
324  else
325  {
327  dwTextClr = dwTextClrInact;
328  }
329  // draw caption text
330  if (sText.getLength()>0)
331  {
333  pDraw->TextOut(sText.getData(), *pUseFont, fFontZoom, cgo.Surface, (int)(x0+iTxtOffX), (int)(y0+iTxtOffY), dwTextClr, byTxtAlign, true);
334  }
335  /*
336  if (fEnabled) if (fMouseOver && IsInActiveDlg(false))
337  {
338  pDraw->SetBlitMode(C4GFXBLIT_ADDITIVE);
339  GetRes()->fctButtonHighlight.DrawXFloat(cgo.Surface, x0, y0, rcfDrawBounds.right-rcfDrawBounds.left, rcfDrawBounds.bottom-rcfDrawBounds.top);
340  pDraw->ResetBlitMode();
341  }*/
342  }
343 
344 
345 } // end of namespace
346 
C4Config Config
Definition: C4Config.cpp:930
C4Draw * pDraw
Definition: C4Draw.cpp:42
C4GraphicsResource GraphicsResource
#define C4GUI_ButtonFontClr
Definition: C4Gui.h:40
#define C4GUI_CaptionFontClr
Definition: C4Gui.h:37
@ KEYSCOPE_Gui
const int32_t C4MC_Button_LeftUp
const int32_t C4MC_Button_LeftDown
float bottom
Definition: C4Rect.h:25
float top
Definition: C4Rect.h:25
float right
Definition: C4Rect.h:25
float left
Definition: C4Rect.h:25
const int ALeft
Definition: C4Surface.h:41
#define C4GFXBLIT_ADDITIVE
Definition: C4Surface.h:26
const int ACenter
Definition: C4Surface.h:41
uint32_t DWORD
int32_t GamepadGuiControl
Definition: C4Config.h:233
C4ConfigControls Controls
Definition: C4Config.h:263
std::vector< C4KeyCodeEx > CodeList
void SetBlitMode(DWORD dwBlitMode)
Definition: C4Draw.h:191
void ResetBlitMode()
Definition: C4Draw.h:192
bool TextOut(const char *szText, CStdFont &rFont, float fZoom, C4Surface *sfcDest, float iTx, float iTy, DWORD dwFCol=0xffffffff, BYTE byForm=ALeft, bool fDoMarkup=true)
Definition: C4Draw.cpp:561
C4Surface * Surface
Definition: C4Facet.h:117
C4Facet GetPhase(int iPhaseX=0, int iPhaseY=0)
Definition: C4Facet.cpp:59
float Hgt
Definition: C4Facet.h:118
float Wdt
Definition: C4Facet.h:118
void DrawX(C4Surface *sfcTarget, float iX, float iY, float iWdt, float iHgt, int32_t iPhaseX=0, int32_t iPhaseY=0) const
Definition: C4Facet.cpp:358
void DrawXFloat(C4Surface *sfcTarget, float fX, float fY, float fWdt, float fHgt) const
Definition: C4Facet.cpp:368
ArrowButton(ArrowFct eDir, const C4Rect &rtBounds, char cHotkey=0)
ArrowFct eDir
Definition: C4Gui.h:1161
static int32_t GetDefaultHeight()
static int32_t GetDefaultWidth()
void DrawElement(C4TargetFacet &cgo) override
void MouseEnter(CMouse &rMouse) override
bool KeyButtonUp()
void MouseLeave(CMouse &rMouse) override
bool KeyButtonDown()
StdStrBuf sText
Definition: C4Gui.h:1099
virtual void OnPress()
bool fDown
Definition: C4Gui.h:1102
void MouseInput(CMouse &rMouse, int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam) override
CStdFont * pCustomFont
Definition: C4Gui.h:1100
bool OnHotkey(uint32_t cHotkey) override
Definition: C4GuiButton.cpp:71
void SetUp(bool fPress)
Button(const char *szBtnText, const C4Rect &rtBounds)
Definition: C4GuiButton.cpp:33
void DrawElement(C4TargetFacet &cgo) override
Definition: C4GuiButton.cpp:82
bool fEnabled
Definition: C4Gui.h:1105
bool fMouseOver
Definition: C4Gui.h:1103
uint32_t cHotkey
Definition: C4Gui.h:1104
~Button() override
Definition: C4GuiButton.cpp:50
DWORD dwCustomFontClr
Definition: C4Gui.h:1101
void SetText(const char *szToText)
Definition: C4GuiButton.cpp:55
Element * pDragElement
Definition: C4Gui.h:2556
void MouseInput(CMouse &rMouse, int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam) override
C4Rect rcBounds
Definition: C4Gui.h:385
bool IsInActiveDlg(bool fForKeyboard)
Definition: C4Gui.cpp:435
void DrawBar(C4TargetFacet &cgo, DynBarFacet &rFacets)
Definition: C4Gui.cpp:308
virtual void MouseEnter(CMouse &rMouse)
Definition: C4Gui.h:413
void SetToolTip(const char *szNewTooltip, bool is_immediate=false)
Definition: C4Gui.cpp:409
virtual void MouseLeave(CMouse &rMouse)
Definition: C4Gui.h:414
uint32_t dwTextClrInact
Definition: C4Gui.h:1177
C4Facet fctHighlight
Definition: C4Gui.h:1176
void DrawElement(C4TargetFacet &cgo) override
uint32_t dwTextClrAct
Definition: C4Gui.h:1177
int32_t iTxtOffX
Definition: C4Gui.h:1181
CStdFont * pFont
Definition: C4Gui.h:1183
FLOAT_RECT rcfDrawBounds
Definition: C4Gui.h:1178
FacetButton(const C4Facet &rBaseFct, const C4Facet &rHighlightFct, const FLOAT_RECT &rtfBounds, char cHotkey)
uint8_t byTxtAlign
Definition: C4Gui.h:1182
C4Facet fctBase
Definition: C4Gui.h:1176
int32_t iTxtOffY
Definition: C4Gui.h:1181
C4Facet fctIcon
Definition: C4Gui.h:1139
void SetIcon(Icons eUseIcon)
uint32_t dwClr
Definition: C4Gui.h:1140
void DrawElement(C4TargetFacet &cgo) override
IconButton(Icons eUseIcon, const C4Rect &rtBounds, char cHotkey='\0', const char *tooltip_text=nullptr)
static C4Facet GetIconFacet(Icons icoIconIndex)
CStdFont & GetFontByHeight(int32_t iHgt, float *pfZoom=nullptr)
C4GUI::DynBarFacet barButton
C4FacetID fctButtonHighlightRound
C4GUI::DynBarFacet barButtonD
Definition: C4Rect.h:28
int32_t y
Definition: C4Rect.h:30
int32_t Hgt
Definition: C4Rect.h:30
int32_t Wdt
Definition: C4Rect.h:30
int32_t x
Definition: C4Rect.h:30
void SetClr(DWORD toClr)
Definition: C4Surface.h:132
float TargetY
Definition: C4Facet.h:165
float TargetX
Definition: C4Facet.h:165
int GetLineHeight() const
Definition: C4FontLoader.h:125
const char * getData() const
Definition: StdBuf.h:442
void Copy()
Definition: StdBuf.h:467
size_t getLength() const
Definition: StdBuf.h:445
Icons
Definition: C4Gui.h:638
bool ExpandHotkeyMarkup(StdStrBuf &sText, uint32_t &rcHotkey, bool for_tooltip)
Definition: C4Gui.cpp:38
void GUISound(const char *szSound)
Definition: C4Gui.cpp:1175
void Ok(T &keys)