forked from Mirrors/openclonk
348 lines
10 KiB
C++
348 lines
10 KiB
C++
/*
|
|
* OpenClonk, http://www.openclonk.org
|
|
*
|
|
* Copyright (c) 2003-2008 Sven Eberhardt
|
|
* Copyright (c) 2007-2008, 2010 Günther Brammer
|
|
* Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de
|
|
*
|
|
* Portions might be copyrighted by other authors who have contributed
|
|
* to OpenClonk.
|
|
*
|
|
* Permission to use, copy, modify, and/or distribute this software for any
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
* copyright notice and this permission notice appear in all copies.
|
|
* See isc_license.txt for full license and disclaimer.
|
|
*
|
|
* "Clonk" is a registered trademark of Matthes Bender.
|
|
* See clonk_trademark_license.txt for full license.
|
|
*/
|
|
// generic user interface
|
|
// that which can be pressed
|
|
|
|
#include <C4Include.h>
|
|
#include <C4Gui.h>
|
|
|
|
#include <C4FullScreen.h>
|
|
#include <C4LoaderScreen.h>
|
|
#include <C4Application.h>
|
|
#include <C4MouseControl.h>
|
|
#include <C4GraphicsResource.h>
|
|
#include <StdDDraw2.h>
|
|
|
|
namespace C4GUI
|
|
{
|
|
|
|
|
|
// --------------------------------------------------
|
|
// Button
|
|
|
|
Button::Button(const char *szBtnText, const C4Rect &rtBounds)
|
|
: Control(rtBounds), pCustomGfx(NULL), pCustomGfxDown(NULL), fDown(false), fMouseOver(false), fEnabled(true),
|
|
dwCustomFontClr(0), pCustomFont(NULL)
|
|
{
|
|
// key callbacks
|
|
C4CustomKey::CodeList keys;
|
|
keys.push_back(C4KeyCodeEx(K_SPACE));
|
|
keys.push_back(C4KeyCodeEx(K_RETURN));
|
|
if (Config.Controls.GamepadGuiControl)
|
|
keys.push_back(C4KeyCodeEx(KEY_Gamepad(0, KEY_JOY_AnyLowButton)));
|
|
pKeyButton = new C4KeyBinding(keys, "GUIButtonPress", KEYSCOPE_Gui,
|
|
new ControlKeyCB<Button>(*this, &Button::KeyButtonDown, &Button::KeyButtonUp), C4CustomKey::PRIO_Ctrl);
|
|
sText = "";
|
|
// set new button text
|
|
SetText(szBtnText);
|
|
}
|
|
|
|
Button::~Button()
|
|
{
|
|
delete pKeyButton;
|
|
}
|
|
|
|
void Button::SetText(const char *szToText)
|
|
{
|
|
// set new button text
|
|
if (szToText)
|
|
{
|
|
sText.Copy(szToText);
|
|
// expand hotkey markup
|
|
ExpandHotkeyMarkup(sText, cHotkey);
|
|
}
|
|
else
|
|
{
|
|
sText="";
|
|
cHotkey=0;
|
|
}
|
|
}
|
|
|
|
bool Button::OnHotkey(char cHotkey)
|
|
{
|
|
// if hotkey matches, press the button
|
|
if (this->cHotkey == cHotkey && fEnabled)
|
|
{
|
|
OnPress();
|
|
return true;
|
|
}
|
|
else return false;
|
|
}
|
|
|
|
void Button::DrawElement(C4TargetFacet &cgo)
|
|
{
|
|
// draw base
|
|
if (fDown)
|
|
// pressed
|
|
DrawBar(cgo, pCustomGfxDown ? *pCustomGfxDown : ::GraphicsResource.barButtonD);
|
|
else
|
|
// released
|
|
DrawBar(cgo, pCustomGfx ? *pCustomGfx : ::GraphicsResource.barButton);
|
|
// get text pos
|
|
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;
|
|
int32_t iTxtOff = fDown ? 1 : 0;
|
|
// draw selection highlight
|
|
if (fEnabled) if (HasDrawFocus() || (fMouseOver && IsInActiveDlg(false)))
|
|
{
|
|
pDraw->SetBlitMode(C4GFXBLIT_ADDITIVE);
|
|
::GraphicsResource.fctButtonHighlight.DrawX(cgo.Surface, x0+5, y0+3, rcBounds.Wdt-10, rcBounds.Hgt-6);
|
|
pDraw->ResetBlitMode();
|
|
}
|
|
// draw text
|
|
int32_t iTextHgt = rcBounds.Hgt-2;
|
|
CStdFont &rUseFont =
|
|
(::GraphicsResource.TitleFont.GetLineHeight() > iTextHgt ?
|
|
(::GraphicsResource.CaptionFont.GetLineHeight() > iTextHgt ?
|
|
::GraphicsResource.TextFont :
|
|
::GraphicsResource.CaptionFont) :
|
|
::GraphicsResource.TitleFont);
|
|
iTextHgt = rUseFont.GetLineHeight();
|
|
//CStdFont &rShadowFont = GetRes()->MiniFont;
|
|
//pDraw->TextOut(Text, rShadowFont, (float) iTextHgt/rShadowFont.GetLineHeight(), cgo.Surface, (x0+x1)/2 + iTxtOff, (y0+y1-iTextHgt)/2 + iTxtOff, C4GUI_ButtonFontShadowClr, ACenter, true);
|
|
pDraw->TextOut(sText.getData(), rUseFont, 1.0f, cgo.Surface, (x0+x1)/2 + iTxtOff, (y0+y1-iTextHgt)/2 + iTxtOff, C4GUI_ButtonFontClr, ACenter, true);
|
|
}
|
|
|
|
bool Button::KeyButtonDown()
|
|
{
|
|
// not on disabled
|
|
if (!fEnabled) return false;
|
|
// space downs button
|
|
SetDown();
|
|
return true;
|
|
}
|
|
|
|
bool Button::KeyButtonUp()
|
|
{
|
|
// space press activates button
|
|
if (!fDown) return false;
|
|
SetUp(true);
|
|
if (fEnabled) OnPress();
|
|
return true;
|
|
}
|
|
|
|
void Button::MouseInput(CMouse &rMouse, int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam)
|
|
{
|
|
// inherited
|
|
Control::MouseInput(rMouse, iButton, iX, iY, dwKeyParam);
|
|
// process left down and up
|
|
if (fEnabled) switch (iButton)
|
|
{
|
|
case C4MC_Button_LeftDown:
|
|
|
|
// mark button as being down
|
|
SetDown();
|
|
// remember drag target
|
|
// no dragging movement will be done w/o drag component assigned
|
|
// but it should be remembered if the user leaves the button with the mouse down
|
|
// and then re-enters w/o having released the button
|
|
if (!rMouse.pDragElement) rMouse.pDragElement = this;
|
|
break;
|
|
|
|
case C4MC_Button_LeftUp:
|
|
// only if button was down... (might have dragged here)
|
|
if (fDown)
|
|
{
|
|
// it's now up :)
|
|
SetUp(true);
|
|
// process event
|
|
OnPress();
|
|
}
|
|
break;
|
|
};
|
|
}
|
|
|
|
void Button::MouseEnter(CMouse &rMouse)
|
|
{
|
|
Control::MouseEnter(rMouse);
|
|
// remember mouse state for button highlight
|
|
fMouseOver = true;
|
|
// mouse re-enters with left button down?
|
|
if (rMouse.pDragElement == this) if (fEnabled) SetDown();
|
|
}
|
|
|
|
void Button::MouseLeave(CMouse &rMouse)
|
|
{
|
|
Control::MouseLeave(rMouse);
|
|
// mouse left
|
|
fMouseOver = false;
|
|
// reset down-state if mouse leves with button down
|
|
if (rMouse.pDragElement == this) if (fEnabled) SetUp(false);
|
|
}
|
|
|
|
void Button::OnPress()
|
|
{
|
|
// nothing in base
|
|
}
|
|
|
|
void Button::SetDown()
|
|
{
|
|
// already down?
|
|
if (fDown) return;
|
|
// play sound
|
|
GUISound("ArrowHit");
|
|
// set down
|
|
fDown = true;
|
|
}
|
|
|
|
void Button::SetUp(bool fPress)
|
|
{
|
|
// already up?
|
|
if (!fDown) return;
|
|
// play sound
|
|
GUISound(fPress ? "Click" : "ArrowHit");
|
|
// set up
|
|
fDown = false;
|
|
}
|
|
|
|
|
|
// --------------------------------------------------------
|
|
// IconButton
|
|
|
|
void IconButton::DrawElement(C4TargetFacet &cgo)
|
|
{
|
|
// get drawing bounds
|
|
int32_t x0 = cgo.TargetX + rcBounds.x, y0 = cgo.TargetY + rcBounds.y;
|
|
// draw selection highlight
|
|
if (fEnabled) if (fHighlight || HasDrawFocus() || (fMouseOver && IsInActiveDlg(false)))
|
|
{
|
|
pDraw->SetBlitMode(C4GFXBLIT_ADDITIVE);
|
|
::GraphicsResource.fctButtonHighlightRound.DrawX(cgo.Surface, x0, y0, rcBounds.Wdt, rcBounds.Hgt);
|
|
pDraw->ResetBlitMode();
|
|
}
|
|
// draw the icon
|
|
if (fHasClr && fctIcon.Surface) fctIcon.Surface->SetClr(dwClr);
|
|
fctIcon.DrawX(cgo.Surface, x0, y0, rcBounds.Wdt, rcBounds.Hgt);
|
|
// "button" down?
|
|
if (fEnabled) if (fDown || fHighlight)
|
|
{
|
|
pDraw->SetBlitMode(C4GFXBLIT_ADDITIVE);
|
|
::GraphicsResource.fctButtonHighlightRound.DrawX(cgo.Surface, x0, y0, rcBounds.Wdt, rcBounds.Hgt);
|
|
pDraw->ResetBlitMode();
|
|
}
|
|
// some icon buttons have captions. draw caption below button
|
|
if (sText.getLength())
|
|
{
|
|
CStdFont &rUseFont = pCustomFont ? *pCustomFont : ::GraphicsResource.TextFont;
|
|
pDraw->TextOut(sText.getData(), rUseFont, 1.0f, cgo.Surface, x0+rcBounds.Wdt/2, y0+rcBounds.Hgt-rUseFont.GetLineHeight()*4/5, pCustomFont ? dwCustomFontClr : C4GUI_CaptionFontClr, ACenter);
|
|
}
|
|
}
|
|
|
|
IconButton::IconButton(Icons eUseIcon, const C4Rect &rtBounds, char caHotkey)
|
|
: Button("", rtBounds), dwClr(0u), fHasClr(false), fHighlight(false)
|
|
{
|
|
// ctor
|
|
cHotkey = caHotkey;
|
|
SetIcon(eUseIcon);
|
|
}
|
|
|
|
void IconButton::SetIcon(Icons eUseIcon)
|
|
{
|
|
if (eUseIcon>=0) fctIcon = Icon::GetIconFacet(eUseIcon); else fctIcon.Surface=NULL;
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------
|
|
// ArrowButton
|
|
|
|
ArrowButton::ArrowButton(ArrowFct eDir, const C4Rect &rtBounds, char cHotkey)
|
|
: Button("", rtBounds), eDir(eDir)
|
|
{
|
|
// ctor
|
|
this->cHotkey = cHotkey;
|
|
}
|
|
|
|
void ArrowButton::DrawElement(C4TargetFacet &cgo)
|
|
{
|
|
// get drawing bounds
|
|
int32_t x0 = cgo.TargetX + rcBounds.x, y0 = cgo.TargetY + rcBounds.y;
|
|
// draw selection highlight
|
|
if (fEnabled) if (HasDrawFocus() || (fMouseOver && IsInActiveDlg(false)))
|
|
{
|
|
pDraw->SetBlitMode(C4GFXBLIT_ADDITIVE);
|
|
::GraphicsResource.fctButtonHighlightRound.DrawX(cgo.Surface, x0, y0, rcBounds.Wdt, rcBounds.Hgt);
|
|
pDraw->ResetBlitMode();
|
|
}
|
|
// draw the arrow - down if pressed
|
|
int32_t iFctIdx = eDir;
|
|
if (fDown) iFctIdx += Down;
|
|
::GraphicsResource.fctBigArrows.GetPhase(iFctIdx).DrawX(cgo.Surface, x0, y0, rcBounds.Wdt, rcBounds.Hgt);
|
|
}
|
|
|
|
|
|
int32_t ArrowButton::GetDefaultWidth()
|
|
{
|
|
// default by gfx size
|
|
return ::GraphicsResource.fctBigArrows.Wdt;
|
|
}
|
|
|
|
int32_t ArrowButton::GetDefaultHeight()
|
|
{
|
|
// default by gfx size
|
|
return ::GraphicsResource.fctBigArrows.Hgt;
|
|
}
|
|
|
|
|
|
// --------------------------------------------------------
|
|
// FacetButton
|
|
|
|
FacetButton::FacetButton(const C4Facet &rBaseFct, const C4Facet &rHighlightFct, const FLOAT_RECT &rtfBounds, char cHotkey)
|
|
: Button("", C4Rect(rtfBounds)), fctBase(rBaseFct), fctHighlight(rHighlightFct), dwTextClrInact(0x7f000000), dwTextClrAct(0xff000000), rcfDrawBounds(rtfBounds), pFont(NULL), fFontZoom(1.0f)
|
|
{
|
|
// ctor
|
|
this->cHotkey = cHotkey;
|
|
iTxtOffX=iTxtOffY=0;
|
|
byTxtAlign=ALeft;
|
|
}
|
|
|
|
void FacetButton::DrawElement(C4TargetFacet &cgo)
|
|
{
|
|
// get drawing bounds
|
|
float x0 = rcfDrawBounds.left + cgo.TargetX, y0 = rcfDrawBounds.top + cgo.TargetY;
|
|
// draw button or highlight facet
|
|
uint32_t dwTextClr;
|
|
if ((HasDrawFocus() || (fMouseOver && IsInActiveDlg(false))) && fEnabled)
|
|
{
|
|
fctHighlight.DrawXFloat(cgo.Surface, x0, y0, rcfDrawBounds.right-rcfDrawBounds.left, rcfDrawBounds.bottom-rcfDrawBounds.top);
|
|
dwTextClr = dwTextClrAct;
|
|
}
|
|
else
|
|
{
|
|
fctBase.DrawXFloat(cgo.Surface, x0, y0, rcfDrawBounds.right-rcfDrawBounds.left, rcfDrawBounds.bottom-rcfDrawBounds.top);
|
|
dwTextClr = dwTextClrInact;
|
|
}
|
|
// draw caption text
|
|
if (sText.getLength()>0)
|
|
{
|
|
CStdFont *pUseFont = pFont ? pFont : &(::GraphicsResource.GetFontByHeight(rcBounds.Hgt, &fFontZoom));
|
|
pDraw->TextOut(sText.getData(), *pUseFont, fFontZoom, cgo.Surface, (int)(x0+iTxtOffX), (int)(y0+iTxtOffY), dwTextClr, byTxtAlign, true);
|
|
}
|
|
/*
|
|
if (fEnabled) if (fMouseOver && IsInActiveDlg(false))
|
|
{
|
|
pDraw->SetBlitMode(C4GFXBLIT_ADDITIVE);
|
|
GetRes()->fctButtonHighlight.DrawXFloat(cgo.Surface, x0, y0, rcfDrawBounds.right-rcfDrawBounds.left, rcfDrawBounds.bottom-rcfDrawBounds.top);
|
|
pDraw->ResetBlitMode();
|
|
}*/
|
|
}
|
|
|
|
|
|
} // end of namespace
|
|
|