2009-05-08 13:28:41 +00:00
/*
* OpenClonk , http : //www.openclonk.org
*
2013-12-17 20:01:09 +00:00
* Copyright ( c ) 2001 - 2009 , RedWolf Design GmbH , http : //www.clonk.de/
2016-04-03 18:18:29 +00:00
* Copyright ( c ) 2009 - 2016 , The OpenClonk Team and contributors
2009-05-08 13:28:41 +00:00
*
2013-12-17 20:01:09 +00:00
* Distributed under the terms of the ISC license ; see accompanying file
* " COPYING " for details .
2009-05-08 13:28:41 +00:00
*
2013-12-17 20:01:09 +00:00
* " Clonk " is a registered trademark of Matthes Bender , used with permission .
* See accompanying file " TRADEMARK " for details .
2009-05-08 13:28:41 +00:00
*
2013-12-17 20:01:09 +00:00
* To redistribute this file separately , substitute the full license texts
* for the above references .
2009-05-08 13:28:41 +00:00
*/
// generic user interface
// defines user controls
// 2do:
// mouse wheel processing
// disabled buttons
# ifndef INC_C4Gui
# define INC_C4Gui
2016-04-03 18:07:56 +00:00
# include "graphics/C4FontLoader.h"
# include "lib/C4Rect.h"
# include "graphics/C4FacetEx.h"
# include "lib/C4LogBuf.h"
# include "gui/C4KeyboardInput.h"
# include "platform/StdScheduler.h"
# include "object/C4Id.h"
# include "platform/C4Window.h"
2009-05-08 13:28:41 +00:00
// consts (load those from a def file some time)
// font colors - alpha is font alpha, which is inversed opaque
# define C4GUI_CaptionFontClr 0xffffffff
# define C4GUI_Caption2FontClr 0xffffff00
# define C4GUI_InactCaptionFontClr 0xffafafaf
# define C4GUI_ButtonFontClr 0xffffff00
# define C4GUI_ButtonFontShadowClr 0xff000000
# define C4GUI_StatusFontClr 0xffffffff
# define C4GUI_MessageFontClr 0xffffffff
# define C4GUI_MessageFontAlpha 0xff000000
# define C4GUI_InactMessageFontClr 0xffafafaf
# define C4GUI_NotifyFontClr 0xffff0000
# define C4GUI_ComboFontClr 0xffffffff
# define C4GUI_CheckboxFontClr 0xffffffff
# define C4GUI_SmallCheckboxFontClr 0xffffffff
# define C4GUI_CheckboxDisabledFontClr 0xffafafaf
# define C4GUI_LogFontClr 0xffafafaf
# define C4GUI_LogFontClr2 0xffff1f1f
# define C4GUI_ErrorFontClr 0xffff1f1f
# define C4GUI_ProgressBarFontClr 0xffffffff
# define C4GUI_ContextFontClr 0xffffffff
# define C4GUI_GfxTabCaptActiveClr 0xff000000
# define C4GUI_GfxTabCaptInactiveClr 0xff000000
// other colors
2009-08-23 21:46:56 +00:00
# define C4GUI_ImportantBGColor 0x2f00007f
# define C4GUI_ProgressBarColor 0x4fffffff
# define C4GUI_ListBoxSelColor 0x4faf0000
# define C4GUI_ListBoxInactSelColor 0x4f7f7f7f
# define C4GUI_ContextSelColor 0x4faf0000
# define C4GUI_ContextBGColor 0xaf3f1a00
# define C4GUI_StandardBGColor 0x9f000000
2009-05-08 13:28:41 +00:00
# define C4GUI_ActiveTabBGColor C4GUI_StandardBGColor
# define C4GUI_ListBoxBarColor 0x7f772200
# define C4GUI_EditBGColor 0x7f000000
# define C4GUI_EditFontColor 0xffffffff
2009-08-23 21:46:56 +00:00
# define C4GUI_ToolTipBGColor 0xFFF1EA78
2009-05-08 13:28:41 +00:00
# define C4GUI_ToolTipFrameColor 0x7f000000
# define C4GUI_ToolTipColor 0xFF483222
// winner/loser color marking
# define C4GUI_WinningTextColor 0xffffdf00
2009-08-23 21:46:56 +00:00
# define C4GUI_WinningBackgroundColor 0xafaf7a00
2009-05-08 13:28:41 +00:00
# define C4GUI_LosingTextColor 0xffffffff
# define C4GUI_LosingBackgroundColor 0x7fafafaf
// border colors for 3D-frames
2009-08-23 21:46:56 +00:00
# define C4GUI_BorderAlpha 0x4f
2009-05-08 13:28:41 +00:00
# define C4GUI_BorderColor1 0x772200
# define C4GUI_BorderColor2 0x331100
# define C4GUI_BorderColor3 0xaa4400
# define C4GUI_BorderColorA1 (C4GUI_BorderAlpha<<24 | C4GUI_BorderColor1)
# define C4GUI_BorderColorA2 (C4GUI_BorderAlpha<<24 | C4GUI_BorderColor2)
# define C4GUI_BorderColorA3 (C4GUI_BorderAlpha<<24 | C4GUI_BorderColor3)
// GUI icon sizes
# define C4GUI_IconWdt 40
# define C4GUI_IconHgt 40
# define C4GUI_IconExWdt 64
# define C4GUI_IconExHgt 64
2016-02-19 19:17:05 +00:00
# define C4GUI_ControllerIconWdt 100
# define C4GUI_ControllerIconHgt 100
2009-05-08 13:28:41 +00:00
# define C4GUI_IconLabelSpacing 2 // space between an icon and its text
// scroll bar size
# define C4GUI_ScrollBarWdt 16
# define C4GUI_ScrollBarHgt 16
# define C4GUI_ScrollArrowHgt 16
# define C4GUI_ScrollArrowWdt 16
# define C4GUI_ScrollThumbHgt 16 // only for non-dynamic scroll thumbs
# define C4GUI_ScrollThumbWdt 16 // only for non-dynamic scroll thumbs
// button size
# define C4GUI_ButtonHgt 32 // height of buttons
# define C4GUI_BigButtonHgt 40 // height of bigger buttons (main menu)
# define C4GUI_ButtonAreaHgt 40 // height of button areas
# define C4GUI_DefButtonWdt 140 // width of default buttons
# define C4GUI_DefButton2Wdt 120 // width of default buttons if there are two of them
# define C4GUI_DefButton2HSpace 10 // horzontal space between two def dlg buttons
// default checkbox height
# define C4GUI_CheckBoxHgt 32
# define C4GUI_CheckBoxLabelSpacing 4 // pixels between checkbox box and label
// list box item spacing
# define C4GUI_DefaultListSpacing 1 // 1 px of free space between two list items
# define C4GUI_ListBoxBarIndent 10
// default dialog box sizes
# define C4GUI_MessageDlgWdt 500 // width of message dialog
# define C4GUI_MessageDlgWdtMedium 360 // width of message dialog w/o much text
# define C4GUI_MessageDlgWdtSmall 300 // width of message dialog w/o much text
# define C4GUI_ProgressDlgWdt 500 // width of progress dialog
# define C4GUI_InputDlgWdt 300
# define C4GUI_DefDlgIndent 10 // indent for default dlg items
# define C4GUI_DefDlgSmallIndent 4 // indent for dlg items that are grouped
# define C4GUI_MessageDlgVRoom 100 // height added to text height in message dialog
# define C4GUI_ProgressDlgVRoom 150 // height added to text height in progress dialog
# define C4GUI_InputDlgVRoom 150
# define C4GUI_ProgressDlgPBHgt 30 // height of progress bar in progress dlg
# define C4GUI_InfoDlgWdt 620 // width of info dialog
# define C4GUI_InfoDlgVRoom 100 // height added to text height in info dialog
# define C4GUI_MaxToolTipWdt 500 // maximum width for tooltip boxes
// time for tooltips to appear (msecs) -evaluated while drawing
# define C4GUI_ToolTipShowTime 500 // 0.5 seconds
// time for title bars to start scrolling to make longer text visible -evaluated while drawing
# define C4GUI_TitleAutoScrollTime 3000 // 3 seconds
// time interval for tab caption scrolling
# define C4GUI_TabCaptionScrollTime 500 // 0.5 seconds
// Z-ordering of dialogs
# define C4GUI_Z_CHAT +2 // chat input dialog more important than other input dialogs
# define C4GUI_Z_INPUT +1 // input dialogs on top of others
# define C4GUI_Z_DEFAULT 0 // normal placement on top of viewports
# define C4GUI_Z_PLAYERMENU -1 // inside viewport: player menu
# define C4GUI_Z_OBJECTMENU -2 // inside viewport: cursor menu
# define C4GUI_MinWoodBarHgt 23
# define C4GUI_FullscreenDlg_TitleHeight C4UpperBoardHeight // pixels reserved for top of fullscreen dialog title
# define C4GUI_FullscreenCaptionFontClr 0xffffff00
2010-03-28 17:58:21 +00:00
namespace C4GUI
{
2009-05-08 13:28:41 +00:00
// some class predefs
// C4Gui.cpp
class Element ; class Screen ; class CMouse ;
2010-06-27 00:42:48 +00:00
class ComponentAligner ;
2009-05-08 13:28:41 +00:00
// C4GuiLabels.cpp
class Label ; class WoodenLabel ; class MultilineLabel ;
class HorizontalLine ; class ProgressBar ;
class Picture ; class Icon ; class PaintBox ;
class TextWindow ;
2010-03-28 17:58:21 +00:00
// C4GuiContainers.cpp
2009-05-08 13:28:41 +00:00
class Container ; class Window ; class GroupBox ; class Control ;
class ScrollBar ; class ScrollWindow ;
// C4GuiButton.cpp
class Button ; template < class CallbackDlg , class Base > class CallbackButton ;
class IconButton ;
class CloseButton ; class OKButton ; class CancelButton ;
class CloseIconButton ; class OKIconButton ; class CancelIconButton ;
// C4GuiEdit.cpp
class Edit ;
// C4GuiCheckBox.cpp
class CheckBox ;
// C4GuiListBox.cpp
class ListBox ;
// C4GuiTabular.cpp
class Tabular ;
// C4GuiMenu.cpp
class ContextMenu ;
class ContextButton ;
// C4GUIComboBox.cpp
class ComboBox ;
// C4GuiDialog.cpp
class Dialog ; class MessageDialog ; class ProgressDialog ;
class InputDialog ; class InfoDialog ;
// inline
class MenuHandler ; class ContextHandler ;
2015-12-07 02:03:54 +00:00
// expand text like "Te&xt" to "Te<c ffff00>x</c>t". Color yellow for normal hotkey and red for tooltip.
bool ExpandHotkeyMarkup ( StdStrBuf & sText , uint32_t & rcHotkey , bool for_tooltip = false ) ;
2009-05-08 13:28:41 +00:00
// make color readable on black: max alpha to 0x1f, max color hues
DWORD MakeColorReadableOnBlack ( DWORD & rdwClr ) ;
// menu handler: generic context menu callback
class MenuHandler
2010-03-28 17:58:21 +00:00
{
public :
MenuHandler ( ) { } //ctor
virtual ~ MenuHandler ( ) { } // dtor
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual void OnOK ( Element * pTarget ) = 0 ; // menu item selected
} ;
2009-05-08 13:28:41 +00:00
// context handler: opens context menu on right-click or menu key
class ContextHandler
2010-03-28 17:58:21 +00:00
{
private :
int32_t iRefs ;
public :
ContextHandler ( ) : iRefs ( 0 ) { } //ctor
virtual ~ ContextHandler ( ) { } // dtor
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual bool OnContext ( Element * pOnElement , int32_t iX , int32_t iY ) = 0 ; // context queried - ret true if handled
virtual ContextMenu * OnSubcontext ( Element * pOnElement ) = 0 ; // subcontext queried
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
inline void Ref ( ) { + + iRefs ; }
inline void DeRef ( ) { if ( ! - - iRefs ) delete this ; }
} ;
2009-05-08 13:28:41 +00:00
// generic callback handler
class BaseCallbackHandler
2010-03-28 17:58:21 +00:00
{
private :
int32_t iRefs ;
public :
BaseCallbackHandler ( ) : iRefs ( 0 ) { }
virtual ~ BaseCallbackHandler ( ) { }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
inline void Ref ( ) { + + iRefs ; }
inline void DeRef ( ) { if ( ! - - iRefs ) delete this ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual void DoCall ( class Element * pElement ) = 0 ;
} ;
2009-05-08 13:28:41 +00:00
template < class CB > class CallbackHandler : public BaseCallbackHandler
2010-03-28 17:58:21 +00:00
{
public :
typedef void ( CB : : * Func ) ( class Element * pElement ) ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
private :
CB * pCBClass ;
Func CBFunc ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
public :
virtual void DoCall ( class Element * pElement )
{
( ( pCBClass ) - > * CBFunc ) ( pElement ) ;
}
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
CallbackHandler ( CB * pTarget , Func rFunc ) : pCBClass ( pTarget ) , CBFunc ( rFunc ) { }
} ;
2009-05-08 13:28:41 +00:00
template < class CB > class CallbackHandlerNoPar : public BaseCallbackHandler
2010-03-28 17:58:21 +00:00
{
public :
typedef void ( CB : : * Func ) ( ) ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
private :
CB * pCBClass ;
Func CBFunc ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
public :
virtual void DoCall ( class Element * pElement )
{
( ( pCBClass ) - > * CBFunc ) ( ) ;
}
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
CallbackHandlerNoPar ( CB * pTarget , Func rFunc ) : pCBClass ( pTarget ) , CBFunc ( rFunc ) { }
} ;
2009-05-08 13:28:41 +00:00
template < class CB , class ParType > class CallbackHandlerExPar : public BaseCallbackHandler
2010-03-28 17:58:21 +00:00
{
public :
typedef void ( CB : : * Func ) ( ParType ) ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
private :
CB * pCBClass ;
ParType par ;
Func CBFunc ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
public :
virtual void DoCall ( class Element * pElement )
{
( ( pCBClass ) - > * CBFunc ) ( par ) ;
}
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
CallbackHandlerExPar ( CB * pTarget , Func rFunc , ParType par ) : pCBClass ( pTarget ) , par ( par ) , CBFunc ( rFunc ) { }
} ;
2009-05-08 13:28:41 +00:00
// callback with parameter coming from calling class
template < class ParType > class BaseParCallbackHandler : public BaseCallbackHandler
2010-03-28 17:58:21 +00:00
{
protected :
virtual void DoCall ( class Element * pElement ) { assert ( false ) ; } // no-par: Not to be called
public :
BaseParCallbackHandler ( ) { }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual void DoCall ( ParType par ) = 0 ;
} ;
2009-05-08 13:28:41 +00:00
template < class CB , class ParType > class ParCallbackHandler : public BaseParCallbackHandler < ParType >
2010-03-28 17:58:21 +00:00
{
public :
typedef void ( CB : : * Func ) ( ParType par ) ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
private :
CB * pCBClass ;
Func CBFunc ;
2009-05-08 13:28:41 +00:00
2010-01-25 04:00:59 +00:00
2010-03-28 17:58:21 +00:00
protected :
// not to be called, but avoid warning for hiding base class functions
using BaseParCallbackHandler < ParType > : : DoCall ;
2010-01-25 04:00:59 +00:00
2010-03-28 17:58:21 +00:00
public :
virtual void DoCall ( ParType par ) { ( ( pCBClass ) - > * CBFunc ) ( par ) ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
ParCallbackHandler ( CB * pTarget , Func rFunc ) : pCBClass ( pTarget ) , CBFunc ( rFunc ) { }
} ;
2009-05-08 13:28:41 +00:00
// three facets for left/top, middle and right/bottom of an auto-sized bar
struct DynBarFacet
2010-03-28 17:58:21 +00:00
{
2009-05-08 13:28:41 +00:00
C4Facet fctBegin , fctMiddle , fctEnd ;
void SetHorizontal ( C4Surface & rBySfc , int iHeight = 0 , int iBorderWidth = 0 ) ;
void SetHorizontal ( C4Facet & rByFct , int32_t iBorderWidth = 0 ) ;
void Clear ( ) { fctBegin . Default ( ) ; fctMiddle . Default ( ) ; fctEnd . Default ( ) ; }
2010-03-28 17:58:21 +00:00
} ;
2009-05-08 13:28:41 +00:00
// facets used to draw a scroll bar
struct ScrollBarFacets
2010-03-28 17:58:21 +00:00
{
2009-05-08 13:28:41 +00:00
DynBarFacet barScroll ;
C4Facet fctScrollDTop , fctScrollPin , fctScrollDBottom ;
void Set ( const C4Facet & rByFct , int32_t iPinIndex = 0 ) ;
void Clear ( ) { barScroll . Clear ( ) ; fctScrollDTop . Default ( ) ; fctScrollPin . Default ( ) ; fctScrollDBottom . Default ( ) ; }
2010-03-28 17:58:21 +00:00
} ;
2009-05-08 13:28:41 +00:00
// a generic gui-element
class Element
2010-03-28 17:58:21 +00:00
{
private :
StdStrBuf ToolTip ; // MouseOver - status text
2015-12-07 02:03:54 +00:00
bool is_immediate_tooltip ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
protected :
Container * pParent ; // owning container
Element * pPrev , * pNext ; // previous and next element of same container
Window * pDragTarget ; // target that is dragged around when the user drags this element
int32_t iDragX , iDragY ; // drag start pos
bool fDragging ; // if set, mouse is down on component and dragging enabled
ContextHandler * pContextHandler ; // context handler to be called upon context menu request
public :
2014-10-05 14:46:14 +00:00
bool fVisible ; // if false, component (and subcomponents) are not drawn
2010-03-28 17:58:21 +00:00
protected :
C4Rect rcBounds ; // element bounds
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual void Draw ( C4TargetFacet & cgo ) { DrawElement ( cgo ) ; } // draw this class (this + any contents)
virtual void DrawElement ( C4TargetFacet & cgo ) { } ; // draw element itself
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual void RemoveElement ( Element * pChild ) ; // clear ptrs
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual void UpdateSize ( ) ; // called when own size changed
virtual void UpdatePos ( ) ; // called when own position changed
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
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 ) ; // draw frame around element
void DrawBar ( C4TargetFacet & cgo , DynBarFacet & rFacets ) ; // draw gfx bar within element bounds
void DrawVBar ( C4TargetFacet & cgo , DynBarFacet & rFacets ) ; // draw gfx bar within element bounds
void DrawHBarByVGfx ( C4TargetFacet & cgo , DynBarFacet & rFacets ) ; // draw horizontal gfx bar within element bounds, using gfx of vertical one
2013-12-05 03:40:17 +00:00
void DrawHVBar ( C4TargetFacet & cgo , DynBarFacet & rFacets , C4DrawTransform & trf , int32_t iMiddleLength ) ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual bool IsOwnPtrElement ( ) { return false ; } // if true is returned, item will not be deleted when container is cleared
virtual bool IsExternalDrawDialog ( ) { return false ; }
virtual bool IsMenu ( ) { return false ; }
2016-11-02 23:58:02 +00:00
virtual class DialogWindow * GetDialogWindow ( ) { return nullptr ; } // return DialogWindow if this element is a dialog
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
// for listbox-selection by character input
2011-03-28 17:31:28 +00:00
virtual bool CheckNameHotkey ( const char * ) { return false ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
public :
virtual Container * GetContainer ( ) { return pParent ; } // returns parent for elements; this for containers
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual void MouseInput ( CMouse & rMouse , int32_t iButton , int32_t iX , int32_t iY , DWORD dwKeyParam ) ; // input: mouse movement or buttons
virtual void MouseEnter ( CMouse & rMouse ) { } ; // called when mouse cursor enters element region
virtual void MouseLeave ( CMouse & rMouse ) { } ; // called when mouse cursor leaves element region
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual void StartDragging ( CMouse & rMouse , int32_t iX , int32_t iY , DWORD dwKeyParam ) ; // called by element in MouseInput: start dragging
virtual void DoDragging ( CMouse & rMouse , int32_t iX , int32_t iY , DWORD dwKeyParam ) ; // called by mouse: dragging process
virtual void StopDragging ( CMouse & rMouse , int32_t iX , int32_t iY , DWORD dwKeyParam ) ; // called by mouse: mouse released after dragging process
2009-05-08 13:28:41 +00:00
2014-03-10 23:23:24 +00:00
virtual bool OnHotkey ( uint32_t cHotkey ) { return false ; } // return true when hotkey has been processed
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
public :
bool DoContext ( ) ; // open context menu if assigned
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
public :
Element ( ) ; // ctor
virtual ~ Element ( ) ; // dtor
Container * GetParent ( ) { return pParent ; } // get owning container
virtual class Dialog * GetDlg ( ) ; // return contained dialog
virtual Screen * GetScreen ( ) ; // return contained screen
2016-11-02 23:58:02 +00:00
virtual Control * IsFocusElement ( ) { return nullptr ; } ; // return control to gain focus in search-cycle
2010-03-28 17:58:21 +00:00
virtual void UpdateOwnPos ( ) { } ; // called when element bounds were changed externally
void ScreenPos2ClientPos ( int32_t & riX , int32_t & riY ) ; // transform screen coordinates to element coordinates
void ClientPos2ScreenPos ( int32_t & riX , int32_t & riY ) ; // transform element coordinates to screen coordinates
2015-12-07 02:03:54 +00:00
void SetToolTip ( const char * szNewTooltip , bool is_immediate = false ) ; // update used tooltip
2010-03-28 17:58:21 +00:00
const char * GetToolTip ( ) ; // return tooltip const char* (own or fallback to parent)
const char * GetOwnToolTip ( ) { return ToolTip . getData ( ) ; } // return tooltip const char*, without fallback to parent
2015-12-07 02:03:54 +00:00
bool IsImmediateToolTip ( ) const { return is_immediate_tooltip ; }
2010-03-28 17:58:21 +00:00
int32_t GetWidth ( ) { return rcBounds . Wdt ; }
int32_t GetHeight ( ) { return rcBounds . Hgt ; }
C4Rect & GetBounds ( ) { return rcBounds ; }
void SetBounds ( const C4Rect & rcNewBound ) { rcBounds = rcNewBound ; UpdatePos ( ) ; UpdateSize ( ) ; }
virtual C4Rect & GetClientRect ( ) { return rcBounds ; }
C4Rect GetContainedClientRect ( ) { C4Rect rc = GetClientRect ( ) ; rc . x = rc . y = 0 ; return rc ; }
Element * GetNext ( ) const { return pNext ; }
Element * GetPrev ( ) const { return pPrev ; }
virtual Element * GetFirstNestedElement ( bool fBackwards ) { return this ; }
2016-11-02 23:58:02 +00:00
virtual Element * GetFirstContained ( ) { return nullptr ; }
2010-03-28 17:58:21 +00:00
bool IsInActiveDlg ( bool fForKeyboard ) ;
virtual bool IsParentOf ( Element * pEl ) { return false ; } // whether this is the parent container (directly or recursively) of the passed element
C4Rect GetToprightCornerRect ( int32_t iWidth = 16 , int32_t iHeight = 16 , int32_t iHIndent = 4 , int32_t iVIndent = 4 , int32_t iIndexX = 0 ) ; // get rectangle to be used for context buttons and stuff
bool IsVisible ( ) ;
virtual void SetVisibility ( bool fToValue ) ;
virtual int32_t GetListItemTopSpacing ( ) { return C4GUI_DefaultListSpacing ; }
virtual bool GetListItemTopSpacingBar ( ) { return false ; }
void SetDragTarget ( Window * pToWindow ) { pDragTarget = pToWindow ; }
void SetContextHandler ( ContextHandler * pNewHd ) // takes over ptr
{
if ( pContextHandler ) pContextHandler - > DeRef ( ) ;
if ( ( pContextHandler = pNewHd ) ) pNewHd - > Ref ( ) ;
}
virtual ContextHandler * GetContextHandler ( ) ; // get context handler to be used (own or parent)
friend class Container ; friend class TextWindow ; friend class ListBox ;
} ;
2009-05-08 13:28:41 +00:00
// a simple text label on the screen
class Label : public Element
2010-03-28 17:58:21 +00:00
{
protected :
StdStrBuf sText ; // label text
DWORD dwFgClr ; // text color
int32_t x0 , iAlign ; // x-textstart-pos; horizontal alignment
CStdFont * pFont ;
2014-03-10 23:23:24 +00:00
uint32_t cHotkey ; // hotkey for this label
2010-03-28 17:58:21 +00:00
bool fAutosize ;
bool fMarkup ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
Control * pClickFocusControl ; // control that gets focus if the label is clicked or hotkey is pressed
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual void DrawElement ( C4TargetFacet & cgo ) ; // output label
virtual void UpdateOwnPos ( ) ;
2009-05-08 13:28:41 +00:00
2014-03-10 23:23:24 +00:00
virtual bool OnHotkey ( uint32_t cHotkey ) ; // focus control on correct hotkey
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual int32_t GetLeftIndent ( ) { return 0 ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
public :
2016-11-02 23:58:02 +00:00
Label ( const char * szLblText , int32_t iX0 , int32_t iTop , int32_t iAlign = ALeft , DWORD dwFClr = 0xffffffff , CStdFont * pFont = nullptr , bool fMakeReadableOnBlack = true , bool fMarkup = true ) ; // ctor
Label ( const char * szLblText , const C4Rect & rcBounds , int32_t iAlign = ALeft , DWORD dwFClr = 0xffffffff , CStdFont * pFont = nullptr , bool fMakeReadableOnBlack = true , bool fAutosize = true , bool fMarkup = true ) ; // ctor
2010-03-28 17:58:21 +00:00
2015-09-04 02:42:29 +00:00
virtual void MouseInput ( CMouse & rMouse , int32_t iButton , int32_t iX , int32_t iY , DWORD dwKeyParam ) ; // input: mouse
2010-03-28 17:58:21 +00:00
void SetText ( const char * szToText , bool fAllowHotkey = true ) ; // update text
const char * GetText ( ) { return sText . getData ( ) ; } // retrieve current text
void SetClickFocusControl ( Control * pToCtrl ) { pClickFocusControl = pToCtrl ; }
void SetColor ( DWORD dwToClr , bool fMakeReadableOnBlack = true ) { dwFgClr = fMakeReadableOnBlack ? MakeColorReadableOnBlack ( dwToClr ) : dwToClr ; } // update label color
void SetX0 ( int32_t iToX0 ) ;
void SetAutosize ( bool fToVal ) { fAutosize = fToVal ; }
} ;
2009-05-08 13:28:41 +00:00
// a label with some wood behind
// used for captions
class WoodenLabel : public Label
2010-03-28 17:58:21 +00:00
{
private :
2013-12-07 07:04:35 +00:00
uint32_t iAutoScrollDelay ; // if set and text is longer than would fit, the label will automatically start moving if not changed and displayed for a while
2013-12-04 12:35:07 +00:00
2016-11-02 23:58:02 +00:00
// Time when the label text was changed last. nullptr if not initialized; set upon first drawing
2013-12-07 07:04:35 +00:00
C4TimeMilliseconds tLastChangeTime ;
2010-03-28 17:58:21 +00:00
int32_t iScrollPos , iScrollDir ;
int32_t iRightIndent ;
protected :
virtual void DrawElement ( C4TargetFacet & cgo ) ; // output label
C4Facet fctIcon ; // icon shown at left-side of label; if set, text is aligned to left
virtual int32_t GetLeftIndent ( ) { return fctIcon . Surface ? rcBounds . Hgt : 0 ; }
int32_t GetRightIndent ( ) const { return iRightIndent ; }
public :
2016-11-02 23:58:02 +00:00
WoodenLabel ( const char * szLblText , const C4Rect & rcBounds , DWORD dwFClr = 0xffffffff , CStdFont * pFont = nullptr , int32_t iAlign = ACenter , bool fMarkup = true ) // ctor
2013-12-07 14:27:01 +00:00
: Label ( szLblText , rcBounds , iAlign , dwFClr , pFont , true , true , fMarkup ) , iAutoScrollDelay ( 0 ) , tLastChangeTime ( C4TimeMilliseconds : : Now ( ) ) , iScrollPos ( 0 ) , iScrollDir ( 0 ) , iRightIndent ( 0 )
2010-03-28 17:58:21 +00:00
{ SetAutosize ( false ) ; this - > rcBounds = rcBounds ; } // ctor - re-sets bounds after SetText
2009-05-08 13:28:41 +00:00
2016-11-02 23:58:02 +00:00
static int32_t GetDefaultHeight ( CStdFont * pUseFont = nullptr ) ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
void SetIcon ( const C4Facet & rfctIcon ) ;
2013-12-07 07:04:35 +00:00
void SetAutoScrollTime ( uint32_t tDelay ) { iAutoScrollDelay = tDelay ; ResetAutoScroll ( ) ; }
2013-12-04 12:35:07 +00:00
void ResetAutoScroll ( ) ;
2010-03-28 17:58:21 +00:00
void SetRightIndent ( int32_t iNewIndent ) { iRightIndent = iNewIndent ; }
} ;
2009-05-08 13:28:41 +00:00
// a multiline label with automated text clipping
// used for display of log buffers
class MultilineLabel : public Element
2010-03-28 17:58:21 +00:00
{
protected :
C4LogBuffer Lines ;
bool fMarkup ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
protected :
virtual void DrawElement ( C4TargetFacet & cgo ) ; // output label
void UpdateHeight ( ) ;
virtual void UpdateSize ( ) ; // update label height
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
public :
MultilineLabel ( const C4Rect & rcBounds , int32_t iMaxLines , int32_t iMaxBuf , const char * szIndentChars , bool fAutoGrow , bool fMarkup ) ; // ctor
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
void AddLine ( const char * szLine , CStdFont * pFont , DWORD dwClr , bool fDoUpdate , bool fMakeReadableOnBlack , CStdFont * pCaptionFont ) ; // add line of text
void Clear ( bool fDoUpdate ) ; // clear lines
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
friend class TextWindow ;
} ;
2009-05-08 13:28:41 +00:00
// a bar that show progress
class ProgressBar : public Element
2010-03-28 17:58:21 +00:00
{
protected :
int32_t iProgress , iMax ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual void DrawElement ( C4TargetFacet & cgo ) ; // draw progress bar
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
public :
ProgressBar ( C4Rect & rrcBounds , int32_t iMaxProgress = 100 ) // progress bar ctor
2009-05-08 13:28:41 +00:00
: Element ( ) , iProgress ( 0 ) , iMax ( iMaxProgress )
2010-03-28 17:58:21 +00:00
{ rcBounds = rrcBounds ; UpdatePos ( ) ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
void SetProgress ( int32_t iToProgress ) { iProgress = iToProgress ; }
} ;
2009-05-08 13:28:41 +00:00
// Auxiliary design gfx: a horizontal line
class HorizontalLine : public Element
2010-03-28 17:58:21 +00:00
{
protected :
uint32_t dwClr , dwShadowClr ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual void DrawElement ( C4TargetFacet & cgo ) ; // draw horizontal line
public :
HorizontalLine ( C4Rect & rrcBounds , uint32_t dwClr = 0x000000 , uint32_t dwShadowClr = 0xaf7f7f7f )
2009-05-08 13:28:41 +00:00
: Element ( ) , dwClr ( dwClr ) , dwShadowClr ( dwShadowClr )
2010-03-28 17:58:21 +00:00
{ SetBounds ( rrcBounds ) ; }
} ;
2009-05-08 13:28:41 +00:00
// picture displaying a FacetEx
class Picture : public Element
2010-03-28 17:58:21 +00:00
{
protected :
C4FacetSurface Facet ; // picture facet
bool fAspect ; // preserve width/height-ratio when drawing
bool fCustomDrawClr ; // custom drawing color for clrbyowner-surfaces
uint32_t dwDrawClr ;
bool fAnimate ; // if true, the picture is animated. Whoaa!
int32_t iPhaseTime , iAnimationPhase , iDelay ; // current animation phase - undefined if not animated
virtual void DrawElement ( C4TargetFacet & cgo ) ; // draw the image
public :
Picture ( const C4Rect & rcBounds , bool fAspect ) ; // ctor - does not load image
const C4FacetSurface & GetFacet ( ) const { return Facet ; } // get picture facet
C4FacetSurface & GetMFacet ( ) { return Facet ; } // get picture facet
void SetFacet ( const C4Facet & fct ) { Facet . Clear ( ) ; Facet . Set ( fct ) ; }
bool EnsureOwnSurface ( ) ; // create an own surface, if it's just a link
void SetDrawColor ( uint32_t dwToClr ) { dwDrawClr = dwToClr ; fCustomDrawClr = true ; }
void SetAnimated ( bool fEnabled , int iDelay ) ; // starts/stops cycling through all phases of the specified facet
} ;
2009-05-08 13:28:41 +00:00
// picture displaying two facets
class OverlayPicture : public Picture
2010-03-28 17:58:21 +00:00
{
protected :
int iBorderSize ; // border of overlay image if not zoomed
C4Facet OverlayImage ; // image to be displayed on top of the actual picture
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual void DrawElement ( C4TargetFacet & cgo ) ; // draw the image
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
public :
OverlayPicture ( const C4Rect & rcBounds , bool fAspect , const C4Facet & rOverlayImage , int iBorderSize ) ; // ctor - does not load image
} ;
2009-05-08 13:28:41 +00:00
// icon indices
2016-02-19 19:17:05 +00:00
enum
{
Ico_Extended = 0x100 , // icon index offset for extended icons
Ico_Controller = 0x200 ,
} ;
2009-05-08 13:28:41 +00:00
enum Icons
2010-03-28 17:58:21 +00:00
{
2009-05-08 13:28:41 +00:00
Ico_Empty = - 2 , // for context menus only
Ico_None = - 1 ,
Ico_Clonk = 0 ,
Ico_Notify = 1 ,
Ico_Wait = 2 ,
Ico_NetWait = 3 ,
Ico_Host = 4 ,
Ico_Client = 5 ,
Ico_UnknownClient = 6 ,
Ico_UnknownPlayer = 7 ,
Ico_ObserverClient = 8 ,
Ico_Player = 9 ,
Ico_Resource = 10 ,
Ico_Error = 11 ,
Ico_SavegamePlayer = 12 ,
Ico_Save = 13 ,
Ico_Active = 14 ,
Ico_Options = 14 ,
2016-08-10 23:35:07 +00:00
Ico_Editor = 14 ,
2009-05-08 13:28:41 +00:00
Ico_Inactive = 15 ,
Ico_Kick = 16 ,
Ico_Loading = 17 ,
Ico_Confirm = 18 ,
Ico_Team = 19 ,
Ico_AddPlr = 20 ,
Ico_Record = 21 ,
Ico_Chart = 21 ,
Ico_Gfx = 22 ,
Ico_Sound = 23 ,
Ico_Keyboard = 24 ,
Ico_Gamepad = 25 ,
Ico_MouseOff = 26 ,
Ico_MouseOn = 27 ,
Ico_Help = 28 ,
Ico_Definition = 29 ,
Ico_GameRunning = 30 ,
2010-03-28 17:58:21 +00:00
Ico_Lobby = 31 ,
Ico_RuntimeJoin = 32 ,
Ico_Exit = 33 ,
Ico_Close = 34 ,
Ico_Rank1 = 35 ,
Ico_Rank2 = 36 ,
2009-05-08 13:28:41 +00:00
Ico_Rank3 = 37 ,
2010-03-28 17:58:21 +00:00
Ico_Rank4 = 38 ,
Ico_Rank5 = 39 ,
2009-05-08 13:28:41 +00:00
Ico_Rank6 = 40 ,
2010-03-28 17:58:21 +00:00
Ico_Rank7 = 41 ,
Ico_Rank8 = 42 ,
2009-05-08 13:28:41 +00:00
Ico_Rank9 = 43 ,
Ico_OfficialServer = 44 ,
Ico_Surrender = 45 ,
Ico_MeleeLeague = 46 ,
2010-03-28 17:58:21 +00:00
Ico_Ready = 47 ,
Ico_Star = 48 ,
2009-05-08 13:28:41 +00:00
Ico_Disconnect = 49 ,
2010-03-28 17:58:21 +00:00
Ico_View = 50 ,
2010-10-04 16:07:46 +00:00
// Ico_RegJoinOnly = 51,
2010-03-28 19:33:51 +00:00
Ico_Ignored = 52 ,
2009-05-08 13:28:41 +00:00
Ico_Ex_RecordOff = Ico_Extended + 0 ,
Ico_Ex_RecordOn = Ico_Extended + 1 ,
2010-12-10 00:06:38 +00:00
// Ico_Ex_FairCrew = Ico_Extended + 2,
2009-05-08 13:28:41 +00:00
Ico_Ex_NormalCrew = Ico_Extended + 3 ,
Ico_Ex_LeagueOff = Ico_Extended + 4 ,
Ico_Ex_LeagueOn = Ico_Extended + 5 ,
Ico_Ex_InternetOff = Ico_Extended + 6 ,
Ico_Ex_InternetOn = Ico_Extended + 7 ,
2010-03-28 17:58:21 +00:00
Ico_Ex_League = Ico_Extended + 8 ,
2010-12-10 00:06:38 +00:00
// Ico_Ex_FairCrewGray = Ico_Extended + 9,
2009-05-08 13:28:41 +00:00
Ico_Ex_NormalCrewGray = Ico_Extended + 10 ,
Ico_Ex_Locked = Ico_Extended + 11 ,
Ico_Ex_Unlocked = Ico_Extended + 12 ,
Ico_Ex_LockedFrontal = Ico_Extended + 13 ,
Ico_Ex_Update = Ico_Extended + 14 ,
Ico_Ex_Chat = Ico_Extended + 15 ,
Ico_Ex_GameList = Ico_Extended + 16 ,
2016-02-19 19:17:05 +00:00
Ico_Ex_Comment = Ico_Extended + 17 ,
Ico_Controller_A = Ico_Controller + 0 ,
Ico_Controller_B = Ico_Controller + 3 ,
Ico_Controller_X = Ico_Controller + 17 ,
Ico_Controller_Y = Ico_Controller + 18 ,
Ico_Controller_Back = Ico_Controller + 1 ,
Ico_Controller_Start = Ico_Controller + 16 ,
Ico_Controller_Dpad = Ico_Controller + 6 ,
Ico_Controller_DpadLeft = Ico_Controller + 5 ,
Ico_Controller_DpadRight = Ico_Controller + 7 ,
Ico_Controller_DpadDown = Ico_Controller + 4 ,
Ico_Controller_DpadUp = Ico_Controller + 8 ,
Ico_Controller_LeftShoulder = Ico_Controller + 9 ,
Ico_Controller_RightShoulder = Ico_Controller + 12 ,
Ico_Controller_LeftTrigger = Ico_Controller + 11 ,
Ico_Controller_RightTrigger = Ico_Controller + 14 ,
Ico_Controller_LeftStick = Ico_Controller + 10 ,
Ico_Controller_RightStick = Ico_Controller + 13 ,
2010-03-28 17:58:21 +00:00
} ;
2009-05-08 13:28:41 +00:00
// cute, litte, useless thingy
class Icon : public Picture
2010-03-28 17:58:21 +00:00
{
public :
Icon ( const C4Rect & rcBounds , Icons icoIconIndex ) ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
void SetIcon ( Icons icoNewIconIndex ) ;
static C4Facet GetIconFacet ( Icons icoIconIndex ) ;
} ;
2009-05-08 13:28:41 +00:00
// a collection of gui-elements
class Container : public Element
2010-03-28 17:58:21 +00:00
{
protected :
Element * pFirst , * pLast ; // contained elements
virtual void Draw ( C4TargetFacet & cgo ) ; // draw all elements
virtual void ElementSizeChanged ( Element * pOfElement ) { } // called when an element size is changed
virtual void ElementPosChanged ( Element * pOfElement ) { } // called when an element position is changed
virtual void AfterElementRemoval ( )
{ if ( pParent ) pParent - > AfterElementRemoval ( ) ; } // called by ScrollWindow to parent after an element has been removed
2014-03-10 23:23:24 +00:00
virtual bool OnHotkey ( uint32_t cHotkey ) ; // check all contained elements for hotkey
2010-03-28 17:58:21 +00:00
public :
Container ( ) ; // ctor
~ Container ( ) ; // dtor
void Clear ( ) ; // delete all child elements
void ClearChildren ( ) ; // delete all child elements
virtual void RemoveElement ( Element * pChild ) ; // remove child element from container
void MakeLastElement ( Element * pChild ) ; // resort to the end of the list
void AddElement ( Element * pChild ) ; // add child element to container
void ReaddElement ( Element * pChild ) ; // resort child element to end of list
void InsertElement ( Element * pChild , Element * pInsertBefore ) ; // add child element to container, ordered directly before given, other element
Element * GetNextNestedElement ( Element * pPrevElement , bool fBackwards ) ; // get next element after given, applying recursion
virtual Element * GetFirstContained ( ) { return pFirst ; }
virtual Element * GetLastContained ( ) { return pLast ; }
virtual Element * GetFirstNestedElement ( bool fBackwards ) ;
2014-10-05 14:46:14 +00:00
class Iterator
{
private :
Element * current ;
public :
Iterator ( Element * element = nullptr ) : current ( element ) { }
Element * operator * ( ) const { return current ; }
Element * operator - > ( ) const { return current ; }
void operator + + ( ) { current = current - > GetNext ( ) ; } ;
void operator + + ( int ) { operator + + ( ) ; }
bool operator = = ( const Iterator & other ) const
{
return ( current = = other . current ) ;
}
bool operator ! = ( const Iterator & other ) const
{
return ! ( * this = = other ) ;
}
} ;
class ReverseIterator
{
private :
Element * current ;
public :
ReverseIterator ( Element * element = nullptr ) : current ( element ) { }
Element * operator * ( ) const { return current ; }
Element * operator - > ( ) const { return current ; }
void operator + + ( ) { current = current - > GetPrev ( ) ; } ;
void operator + + ( int ) { operator + + ( ) ; }
bool operator = = ( const ReverseIterator & other ) const
{
return ( current = = other . current ) ;
}
bool operator ! = ( const ReverseIterator & other ) const
{
return ! ( * this = = other ) ;
}
} ;
// provide C++-style iterator interface
Iterator begin ( ) { return Iterator ( pFirst ) ; }
Iterator end ( ) { return Iterator ( nullptr ) ; }
ReverseIterator rbegin ( ) { return ReverseIterator ( pLast ) ; }
ReverseIterator rend ( ) { return ReverseIterator ( nullptr ) ; }
2010-03-28 17:58:21 +00:00
Element * GetFirst ( ) { return pFirst ; }
Element * GetLast ( ) { return pLast ; }
virtual Container * GetContainer ( ) { return this ; } // returns parent for elements; this for containers
Element * GetElementByIndex ( int32_t i ) ; // get indexed child element
int32_t GetElementCount ( ) ;
2014-10-05 14:46:14 +00:00
virtual void SetVisibility ( bool fToValue ) ;
2010-03-28 17:58:21 +00:00
virtual bool IsFocused ( Control * pCtrl ) { return pParent ? pParent - > IsFocused ( pCtrl ) : false ; }
virtual bool IsSelectedChild ( Element * pChild ) { return pParent ? pParent - > IsSelectedChild ( pChild ) : true ; } // whether the child element is selected - only false for list-box-containers which can have unselected children
virtual bool IsParentOf ( Element * pEl ) ; // whether this is the parent container (directly or recursively) of the passed element
virtual void ApplyElementOffset ( int32_t & riX , int32_t & riY ) { } // apply child drawing offset
virtual void ApplyInvElementOffset ( int32_t & riX , int32_t & riY ) { } // subtract child drawing offset
friend class Element ; friend class ScrollWindow ;
} ;
2009-05-08 13:28:41 +00:00
// a rectangled control that contains other elements
class Window : public Container
2010-03-28 17:58:21 +00:00
{
protected :
C4Rect rcClientRect ; // area for contained elements
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual void Draw ( C4TargetFacet & cgo ) ; // draw this window
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
public :
Window ( ) ; // ctor
2009-05-08 13:28:41 +00:00
2015-09-04 02:42:29 +00:00
virtual void MouseInput ( CMouse & rMouse , int32_t iButton , int32_t iX , int32_t iY , DWORD dwKeyParam ) ; // input: mouse movement or buttons
2010-03-28 17:58:21 +00:00
void SetPos ( int32_t iXPos , int32_t iYPos )
{ rcBounds . x = iXPos ; rcBounds . y = iYPos ; UpdatePos ( ) ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual void UpdateOwnPos ( ) ; // update client rect
virtual C4Rect & GetClientRect ( ) { return rcClientRect ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual void ApplyElementOffset ( int32_t & riX , int32_t & riY )
{ riX - = rcClientRect . x ; riY - = rcClientRect . y ; }
virtual void ApplyInvElementOffset ( int32_t & riX , int32_t & riY )
{ riX + = rcClientRect . x ; riY + = rcClientRect . y ; }
virtual bool IsComponentOutsideClientArea ( ) { return false ; } // if set, drawing routine of subcomponents will clip to Bounds rather than to ClientRect
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
// get margins from bounds to client rect
virtual int32_t GetMarginTop ( ) { return 0 ; }
virtual int32_t GetMarginLeft ( ) { return 0 ; }
virtual int32_t GetMarginRight ( ) { return 0 ; }
virtual int32_t GetMarginBottom ( ) { return 0 ; }
} ;
2009-05-08 13:28:41 +00:00
// a scroll bar
class ScrollBar : public Element
2010-03-28 17:58:21 +00:00
{
protected :
bool fScrolling ; // if set, scrolling is currently enabled
bool fAutoHide ; // if set, bar is made invisible if scrolling is not possible anyway
int32_t iScrollThumbSize ; // height(/width) of scroll thumb
int32_t iScrollPos ; // y(/x) offset of scroll thumb
bool fTopDown , fBottomDown ; // whether scrolling buttons are pressed
bool fHorizontal ; // if set, the scroll bar is horizontal instead of vertical
int32_t iCBMaxRange ; // range for callback class
ScrollWindow * pScrollWindow ; // associated scrolled window - may be 0 for callback scrollbars
BaseParCallbackHandler < int32_t > * pScrollCallback ; // callback called when scroll pos changes
ScrollBarFacets * pCustomGfx ;
void Update ( ) ; // update scroll bar according to window
void OnPosChanged ( ) ; // update window according to scroll bar, and/or do callbacks
virtual void DrawElement ( C4TargetFacet & cgo ) ; // draw scroll bar
// suppress scrolling pin for very narrow menus
bool HasPin ( )
{
if ( fHorizontal ) return rcBounds . Wdt > ( 2 * C4GUI_ScrollArrowWdt + C4GUI_ScrollThumbWdt ) ;
else return rcBounds . Hgt > ( 2 * C4GUI_ScrollArrowHgt + C4GUI_ScrollThumbHgt ) ;
}
int32_t GetMaxScroll ( )
{
if ( fHorizontal ) return HasPin ( ) ? GetBounds ( ) . Wdt - 2 * C4GUI_ScrollArrowWdt - iScrollThumbSize : 100 ;
else return HasPin ( ) ? GetBounds ( ) . Hgt - 2 * C4GUI_ScrollArrowHgt - iScrollThumbSize : 100 ;
}
int32_t GetScrollByPos ( int32_t iX , int32_t iY )
{
2015-02-12 22:05:55 +00:00
return Clamp < int32_t > ( ( fHorizontal ? iX - C4GUI_ScrollArrowWdt : iY - C4GUI_ScrollArrowHgt ) - iScrollThumbSize / 2 , 0 , GetMaxScroll ( ) ) ;
2010-03-28 17:58:21 +00:00
}
bool IsScrolling ( ) { return fScrolling ; }
public :
ScrollBar ( C4Rect & rcBounds , ScrollWindow * pWin ) ; // ctor for scroll window
ScrollBar ( C4Rect & rcBounds , bool fHorizontal , BaseParCallbackHandler < int32_t > * pCB , int32_t iCBMaxRange = 256 ) ; // ctor for callback
~ ScrollBar ( ) ; // dtor
2014-10-05 14:46:14 +00:00
// mouse handling
virtual void MouseInput ( CMouse & rMouse , int32_t iButton , int32_t iX , int32_t iY , DWORD dwKeyParam ) ; // input: mouse movement or buttons
virtual void DoDragging ( CMouse & rMouse , int32_t iX , int32_t iY , DWORD dwKeyParam ) ; // dragging: allow dragging of thumb
virtual void MouseLeave ( CMouse & rMouse ) ; // mouse leaves with button down: reset down state of buttons
2010-03-28 17:58:21 +00:00
// change style
void SetDecoration ( ScrollBarFacets * pToGfx , bool fAutoHide )
{ pCustomGfx = pToGfx ; this - > fAutoHide = fAutoHide ; }
// change scroll pos in a [0, iCBMaxRange-1] scale
void SetScrollPos ( int32_t iToPos ) { iScrollPos = iToPos * GetMaxScroll ( ) / ( iCBMaxRange - 1 ) ; }
friend class ScrollWindow ;
2015-01-15 20:06:58 +00:00
friend class : : C4ScriptGuiWindow ;
2010-03-28 17:58:21 +00:00
} ;
2009-05-08 13:28:41 +00:00
// a window that can be scrolled
class ScrollWindow : public Window
2010-03-28 17:58:21 +00:00
{
protected :
ScrollBar * pScrollBar ; // vertical scroll bar associated with the window
int32_t iScrollY ; // vertical scroll pos
int32_t iClientHeight ; // client rect height
bool fHasBar ;
int32_t iFrozen ; // if >0, no scrolling updates are done (used during window refill)
// pass element updates through to parent window
virtual void ElementSizeChanged ( Element * pOfElement ) // called when an element size is changed
2009-05-08 13:28:41 +00:00
{
2010-03-28 17:58:21 +00:00
Window : : ElementSizeChanged ( pOfElement ) ;
if ( pParent ) pParent - > ElementSizeChanged ( pOfElement ) ;
}
virtual void ElementPosChanged ( Element * pOfElement ) // called when an element position is changed
{
Window : : ElementPosChanged ( pOfElement ) ;
if ( pParent ) pParent - > ElementPosChanged ( pOfElement ) ;
}
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
public :
ScrollWindow ( Window * pParentWindow ) ; // create scroll window in client area of window
2016-11-02 23:58:02 +00:00
~ ScrollWindow ( ) { if ( pScrollBar ) pScrollBar - > pScrollWindow = nullptr ; }
2009-05-08 13:28:41 +00:00
2015-09-04 02:42:29 +00:00
virtual void MouseInput ( CMouse & rMouse , int32_t iButton , int32_t iX , int32_t iY , DWORD dwKeyParam ) ;
2010-03-28 17:58:21 +00:00
virtual bool IsComponentOutsideClientArea ( ) { return true ; } // always clip drawing routine of subcomponents to Bounds
void Update ( ) ; // update client rect and scroll bar according to window
virtual void UpdateOwnPos ( ) ;
void Freeze ( ) { + + iFrozen ; }
void UnFreeze ( ) { if ( ! - - iFrozen ) Update ( ) ; }
bool IsFrozen ( ) const { return ! ! iFrozen ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
void SetClientHeight ( int32_t iToHgt ) // set new client height
{ iClientHeight = iToHgt ; Update ( ) ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
// change style
void SetDecoration ( ScrollBarFacets * pToGfx , bool fAutoScroll )
{ if ( pScrollBar ) pScrollBar - > SetDecoration ( pToGfx , fAutoScroll ) ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
void SetScroll ( int32_t iToScroll ) ; // sets new scrolling; does not update scroll bar
void ScrollToBottom ( ) ; // set scrolling to bottom range; updates scroll bar
void ScrollPages ( int iPageCount ) ; // scroll down by multiples of visible height; updates scroll bar
void ScrollBy ( int iAmount ) ; // scroll down by vertical pixel amount; updates scroll bar
void ScrollRangeInView ( int32_t iY , int32_t iHgt ) ; // sets scrolling so range is in view; updates scroll bar
bool IsRangeInView ( int32_t iY , int32_t iHgt ) ; // returns whether scrolling range is in view
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
int32_t GetScrollY ( ) { return iScrollY ; }
2009-05-08 13:28:41 +00:00
2015-01-03 14:30:30 +00:00
void SetScrollBarEnabled ( bool fToVal , bool noAutomaticPositioning = false ) ;
2010-03-28 17:58:21 +00:00
bool IsScrollBarEnabled ( ) { return fHasBar ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
bool IsScrollingActive ( ) { return fHasBar & & pScrollBar & & pScrollBar - > IsScrolling ( ) ; }
bool IsScrollingNecessary ( ) { return iClientHeight > rcBounds . Hgt ; }
friend class ScrollBar ;
} ;
2009-05-08 13:28:41 +00:00
// a collection of components
class GroupBox : public Window
2010-03-28 17:58:21 +00:00
{
private :
StdStrBuf sTitle ;
CStdFont * pFont ;
uint32_t dwFrameClr , dwTitleClr , dwBackClr ;
int32_t iMargin ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
CStdFont * GetTitleFont ( ) const ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
public :
2016-11-02 23:58:02 +00:00
GroupBox ( C4Rect & rtBounds ) : Window ( ) , pFont ( nullptr ) , dwFrameClr ( 0u ) , dwTitleClr ( C4GUI_CaptionFontClr ) , dwBackClr ( 0xffffffff ) , iMargin ( 4 )
2010-03-28 17:58:21 +00:00
{
// init client rect
SetBounds ( rtBounds ) ;
} // ctor
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
void SetFont ( CStdFont * pToFont ) { pFont = pToFont ; }
void SetColors ( uint32_t dwFrameClr , uint32_t dwTitleClr , uint32_t dwBackClr = 0xffffffff ) { this - > dwFrameClr = dwFrameClr ; this - > dwTitleClr = dwTitleClr ; this - > dwBackClr = dwBackClr ; }
void SetTitle ( const char * szToTitle ) { if ( szToTitle & & * szToTitle ) sTitle . Copy ( szToTitle ) ; else sTitle . Clear ( ) ; UpdateOwnPos ( ) ; }
void SetMargin ( int32_t iNewMargin ) { iMargin = iNewMargin ; UpdateOwnPos ( ) ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
bool HasTitle ( ) const { return ! ! sTitle . getLength ( ) ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual void DrawElement ( C4TargetFacet & cgo ) ; // draw frame
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual int32_t GetMarginTop ( ) { return HasTitle ( ) ? iMargin + GetTitleFont ( ) - > GetLineHeight ( ) : iMargin ; }
virtual int32_t GetMarginLeft ( ) { return iMargin ; }
virtual int32_t GetMarginRight ( ) { return iMargin ; }
virtual int32_t GetMarginBottom ( ) { return iMargin ; }
} ;
2009-05-08 13:28:41 +00:00
// a drawing area
class PaintBox : public Window
2010-03-28 17:58:21 +00:00
{
protected :
C4FacetSurface fctPaint ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual void DrawElement ( C4TargetFacet & cgo ) ; // draw what has been painted
public :
PaintBox ( C4Rect & rtBounds , int32_t iSfcWdt = - 1 , int32_t iSfcHgt = - 1 ) ; // ctor
~ PaintBox ( ) ; // dtor
2015-09-04 02:42:29 +00:00
virtual void MouseInput ( CMouse & rMouse , int32_t iButton , int32_t iX , int32_t iY , DWORD dwKeyParam ) ; // input: mouse
2010-03-28 17:58:21 +00:00
} ;
2009-05-08 13:28:41 +00:00
// a control that may have focus
class Control : public Window
2010-03-28 17:58:21 +00:00
{
private :
class C4KeyBinding * pKeyContext ;
protected :
2011-03-28 17:31:28 +00:00
virtual bool CharIn ( const char * ) { return false ; } // input: character key pressed - should return false for none-character-inputs
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
void DisableFocus ( ) ; // called when control gets disabled: Make sure it loses focus
virtual bool IsFocusOnClick ( ) { return true ; } // defaultly, controls get focused on left-down
virtual Control * IsFocusElement ( ) { return this ; } ; // this control can gain focus
virtual void OnGetFocus ( bool fByMouse ) { } ; // callback when control gains focus
virtual void OnLooseFocus ( ) { } ; // callback when control looses focus
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
bool KeyContext ( ) { return DoContext ( ) ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
public :
Control ( const C4Rect & rtBounds ) ; // ctor
~ Control ( ) ;
2009-05-08 13:28:41 +00:00
2015-09-04 02:42:29 +00:00
virtual void MouseInput ( CMouse & rMouse , int32_t iButton , int32_t iX , int32_t iY , DWORD dwKeyParam ) ; // input: mouse. left-click sets focus
2010-03-28 17:58:21 +00:00
bool HasFocus ( ) { return pParent & & pParent - > IsFocused ( this ) ; }
bool HasDrawFocus ( ) ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
friend class Dialog ; friend class ListBox ;
} ;
2009-05-08 13:28:41 +00:00
// generic callback-functions to the dialog
template < class CallbackDlg > class DlgCallback
2010-03-28 17:58:21 +00:00
{
public :
typedef void ( CallbackDlg : : * Func ) ( Control * pFromControl ) ;
typedef bool ( CallbackDlg : : * BoolFunc ) ( Control * pFromControl ) ;
typedef bool ( CallbackDlg : : * Bool2Func ) ( Control * pFromControl , bool fBool , bool fBool2 ) ;
typedef ContextMenu * ( CallbackDlg : : * ContextFunc ) ( Element * pFromElement , int32_t iX , int32_t iY ) ;
typedef void ( CallbackDlg : : * ContextClickFunc ) ( Element * pTargetElement ) ;
} ;
2009-05-08 13:28:41 +00:00
// multi-param callback-functions to the dialog
template < class CallbackDlg , class TEx > class DlgCallbackEx
2010-03-28 17:58:21 +00:00
{
public :
typedef void ( CallbackDlg : : * ContextClickFunc ) ( Element * pTargetElement , TEx Extra ) ;
} ;
2009-05-08 13:28:41 +00:00
// a button. may be pressed.
class Button : public Control
2010-03-28 17:58:21 +00:00
{
private :
class C4KeyBinding * pKeyButton ;
DynBarFacet * pCustomGfx , * pCustomGfxDown ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
protected :
StdStrBuf sText ; // button label
2011-03-30 20:11:47 +00:00
CStdFont * pCustomFont ; // custom font (if assigned)
DWORD dwCustomFontClr ; // text font color (valid only if pCustomFont)
2010-03-28 17:58:21 +00:00
bool fDown ; // if set, button is currently held down
bool fMouseOver ; // if set, the mouse hovers over the button
2014-03-10 23:23:24 +00:00
uint32_t cHotkey ; // hotkey for this button
2010-03-28 17:58:21 +00:00
bool fEnabled ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual bool IsFocusOnClick ( ) { return false ; } // buttons don't get focus on click (for easier input, e.g. in chatbox)
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual void DrawElement ( C4TargetFacet & cgo ) ; // draw dlg bg
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual void OnPress ( ) ; // called when button is pressed
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
bool KeyButtonDown ( ) ;
bool KeyButtonUp ( ) ;
void SetDown ( ) ; // mark down and play sound
void SetUp ( bool fPress ) ; // mark up and play sound
2009-05-08 13:28:41 +00:00
2014-03-10 23:23:24 +00:00
virtual bool OnHotkey ( uint32_t cHotkey ) ; // press btn on correct hotkey
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
public :
Button ( const char * szBtnText , const C4Rect & rtBounds ) ; // ctor
~ Button ( ) ; // dtor
2009-05-08 13:28:41 +00:00
2015-09-04 02:42:29 +00:00
virtual void MouseInput ( CMouse & rMouse , int32_t iButton , int32_t iX , int32_t iY , DWORD dwKeyParam ) ; // input: mouse movement or buttons
virtual void MouseEnter ( CMouse & rMouse ) ; // mouse re-enters with button down: set button down
virtual void MouseLeave ( CMouse & rMouse ) ; // mouse leaves with button down: reset down state
2010-03-28 17:58:21 +00:00
void SetText ( const char * szToText ) ; // update button text (and hotkey)
void SetCustomGraphics ( DynBarFacet * pCustomGfx , DynBarFacet * pCustomGfxDown )
{ this - > pCustomGfx = pCustomGfx ; this - > pCustomGfxDown = pCustomGfxDown ; }
void SetEnabled ( bool fToVal ) { fEnabled = fToVal ; if ( ! fEnabled ) fDown = false ; }
2011-03-30 20:11:47 +00:00
void SetFont ( CStdFont * pFont , DWORD dwCustomFontClr = C4GUI_CaptionFontClr ) { this - > pCustomFont = pFont ; this - > dwCustomFontClr = dwCustomFontClr ; }
2010-03-28 17:58:21 +00:00
} ;
2009-05-08 13:28:41 +00:00
// button using icon image
class IconButton : public Button
2010-03-28 17:58:21 +00:00
{
protected :
C4Facet fctIcon ;
uint32_t dwClr ;
bool fHasClr ;
bool fHighlight ; // if true, the button is highlighted permanently
virtual void DrawElement ( C4TargetFacet & cgo ) ; // draw icon and highlight if necessary
public :
2016-11-02 23:58:02 +00:00
IconButton ( Icons eUseIcon , const C4Rect & rtBounds , char cHotkey = ' \0 ' , const char * tooltip_text = nullptr ) ; // ctor
2010-03-28 17:58:21 +00:00
void SetIcon ( Icons eUseIcon ) ;
void SetFacet ( const C4Facet & rCpy , uint32_t dwClr = 0u ) { fctIcon = rCpy ; }
void SetColor ( uint32_t dwClr ) { fHasClr = true ; this - > dwClr = dwClr ; }
void SetHighlight ( bool fToVal ) { fHighlight = fToVal ; }
} ;
2009-05-08 13:28:41 +00:00
// button using arrow image
class ArrowButton : public Button
2010-03-28 17:58:21 +00:00
{
public :
enum ArrowFct { Left = 0 , Right = 1 , Down = 2 } ;
protected :
ArrowFct eDir ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual void DrawElement ( C4TargetFacet & cgo ) ; // draw arrow; highlight and down if necessary
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
public :
ArrowButton ( ArrowFct eDir , const C4Rect & rtBounds , char cHotkey = 0 ) ; // ctor
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
static int32_t GetDefaultWidth ( ) ;
static int32_t GetDefaultHeight ( ) ;
} ;
2009-05-08 13:28:41 +00:00
// button using facets for highlight
class FacetButton : public Button
2010-03-28 17:58:21 +00:00
{
protected :
C4Facet fctBase , fctHighlight ;
uint32_t dwTextClrInact , dwTextClrAct ; // text colors for inactive/active button
FLOAT_RECT rcfDrawBounds ; // drawing bounds
// title drawing parameters
int32_t iTxtOffX , iTxtOffY ;
uint8_t byTxtAlign ; // ALeft, ACenter or ARight
CStdFont * pFont ; float fFontZoom ;
virtual void DrawElement ( C4TargetFacet & cgo ) ; // draw base facet or highlight facet if necessary
public :
FacetButton ( const C4Facet & rBaseFct , const C4Facet & rHighlightFct , const FLOAT_RECT & rtfBounds , char cHotkey ) ; // ctor
void SetTextColors ( uint32_t dwClrInact , uint32_t dwClrAct )
{ dwTextClrInact = dwClrInact ; dwTextClrAct = dwClrAct ; }
void SetTextPos ( int32_t iOffX , int32_t iOffY , uint8_t byAlign = ACenter )
{ iTxtOffX = iOffX ; iTxtOffY = iOffY ; byTxtAlign = byAlign ; }
void SetTextFont ( CStdFont * pFont , float fFontZoom = 1.0f )
{ this - > pFont = pFont ; this - > fFontZoom = fFontZoom ; }
} ;
2009-05-08 13:28:41 +00:00
// a button doing some callback...
template < class CallbackDlg , class Base = Button > class CallbackButton : public Base
2010-03-28 17:58:21 +00:00
{
protected :
CallbackDlg * pCB ;
typename DlgCallback < CallbackDlg > : : Func pCallbackFn ; // callback function
virtual void OnPress ( )
{
if ( pCallbackFn )
{
CallbackDlg * pC = pCB ;
if ( ! pC ) if ( ! ( pC = reinterpret_cast < CallbackDlg * > ( Base : : GetDlg ( ) ) ) ) return ;
( pC - > * pCallbackFn ) ( this ) ;
}
}
public :
2016-11-02 23:58:02 +00:00
CallbackButton ( ArrowButton : : ArrowFct eDir , const C4Rect & rtBounds , typename DlgCallback < CallbackDlg > : : Func pFn , CallbackDlg * pCB = nullptr ) // ctor
2010-01-25 04:00:59 +00:00
: Base ( eDir , rtBounds , 0 ) , pCB ( pCB ) , pCallbackFn ( pFn ) { }
2016-11-02 23:58:02 +00:00
CallbackButton ( const char * szBtnText , C4Rect & rtBounds , typename DlgCallback < CallbackDlg > : : Func pFn , CallbackDlg * pCB = nullptr ) // ctor
2010-01-25 04:00:59 +00:00
: Base ( szBtnText , rtBounds ) , pCB ( pCB ) , pCallbackFn ( pFn ) { }
2016-11-02 23:58:02 +00:00
CallbackButton ( Icons eUseIcon , const C4Rect & rtBounds , char cHotkey , typename DlgCallback < CallbackDlg > : : Func pFn , CallbackDlg * pCB = nullptr ) // ctor
2010-01-25 04:00:59 +00:00
: Base ( eUseIcon , rtBounds , cHotkey ) , pCB ( pCB ) , pCallbackFn ( pFn ) { }
2016-11-02 23:58:02 +00:00
CallbackButton ( Icons eUseIcon , const C4Rect & rtBounds , const char * tooltip_text , typename DlgCallback < CallbackDlg > : : Func pFn , CallbackDlg * pCB = nullptr ) // ctor
2015-12-07 02:03:54 +00:00
: Base ( eUseIcon , rtBounds , ' \0 ' , tooltip_text ) , pCB ( pCB ) , pCallbackFn ( pFn ) { }
2016-11-02 23:58:02 +00:00
CallbackButton ( int32_t iID , const C4Rect & rtBounds , char cHotkey , typename DlgCallback < CallbackDlg > : : Func pFn , CallbackDlg * pCB = nullptr ) // ctor
2010-01-25 04:00:59 +00:00
: Base ( iID , rtBounds , cHotkey ) , pCB ( pCB ) , pCallbackFn ( pFn ) { }
2010-03-28 17:58:21 +00:00
} ;
2009-05-08 13:28:41 +00:00
// a button doing some callback to any class
template < class CallbackDlg , class Base = Button > class CallbackButtonEx : public Base
2010-03-28 17:58:21 +00:00
{
protected :
typedef CallbackDlg * CallbackDlgPointer ;
CallbackDlgPointer pCBTarget ; // callback target
typename DlgCallback < CallbackDlg > : : Func pCallbackFn ; // callback function
virtual void OnPress ( )
{ ( pCBTarget - > * pCallbackFn ) ( this ) ; }
public :
CallbackButtonEx ( const char * szBtnText , const C4Rect & rtBounds , CallbackDlgPointer pCBTarget , typename DlgCallback < CallbackDlg > : : Func pFn ) // ctor
2009-05-08 13:28:41 +00:00
: Base ( szBtnText , rtBounds ) , pCBTarget ( pCBTarget ) , pCallbackFn ( pFn ) { }
2010-03-28 17:58:21 +00:00
CallbackButtonEx ( Icons eUseIcon , const C4Rect & rtBounds , char cHotkey , CallbackDlgPointer pCBTarget , typename DlgCallback < CallbackDlg > : : Func pFn ) // ctor
2009-05-08 13:28:41 +00:00
: Base ( eUseIcon , rtBounds , cHotkey ) , pCBTarget ( pCBTarget ) , pCallbackFn ( pFn ) { }
2010-03-28 17:58:21 +00:00
CallbackButtonEx ( const C4Facet & fctBase , const C4Facet & fctHighlight , const FLOAT_RECT & rtfBounds , char cHotkey , CallbackDlgPointer pCBTarget , typename DlgCallback < CallbackDlg > : : Func pFn ) // ctor
2009-05-08 13:28:41 +00:00
: Base ( fctBase , fctHighlight , rtfBounds , cHotkey ) , pCBTarget ( pCBTarget ) , pCallbackFn ( pFn ) { }
2010-03-28 17:58:21 +00:00
} ;
2009-05-08 13:28:41 +00:00
// an edit control to type text in
class Edit : public Control
2010-03-28 17:58:21 +00:00
{
public :
Edit ( const C4Rect & rtBounds , bool fFocusEdit = false ) ; // ctor
~ Edit ( ) ;
enum InputResult // action to be taken when text is confirmed with enter
{
IR_None = 0 , // do nothing and continue pasting
IR_CloseDlg , // stop any pastes and close parent dialog successfully
IR_CloseEdit , // stop any pastes and remove this control
IR_Abort // do nothing and stop any pastes
} ;
private :
enum CursorOperation { COP_BACK , COP_DELETE , COP_LEFT , COP_RIGHT , COP_HOME , COP_END } ;
2010-04-19 13:46:08 +00:00
static const char * CursorRepresentation ;
2010-03-28 17:58:21 +00:00
bool KeyCursorOp ( const C4KeyCodeEx & key , const CursorOperation & op ) ;
bool KeyEnter ( ) ;
bool KeyCopy ( ) { Copy ( ) ; return true ; }
bool KeyPaste ( ) { Paste ( ) ; return true ; }
bool KeyCut ( ) { Cut ( ) ; return true ; }
bool KeySelectAll ( ) { SelectAll ( ) ; return true ; }
class C4KeyBinding * RegisterCursorOp ( CursorOperation op , C4KeyCode key , const char * szName , C4CustomKey : : Priority eKeyPrio ) ;
class C4KeyBinding * pKeyCursorBack , * pKeyCursorDel , * pKeyCursorLeft , * pKeyCursorRight , * pKeyCursorHome , * pKeyCursorEnd ,
* pKeyEnter , * pKeyCopy , * pKeyPaste , * pKeyCut , * pKeySelAll ;
protected :
// context callbacks
ContextMenu * OnContext ( C4GUI : : Element * pListItem , int32_t iX , int32_t iY ) ;
void OnCtxCopy ( C4GUI : : Element * pThis ) { Copy ( ) ; } ;
void OnCtxPaste ( C4GUI : : Element * pThis ) { Paste ( ) ; } ;
void OnCtxCut ( C4GUI : : Element * pThis ) { Cut ( ) ; } ;
void OnCtxClear ( C4GUI : : Element * pThis ) { DeleteSelection ( ) ; } ;
void OnCtxSelAll ( C4GUI : : Element * pThis ) { SelectAll ( ) ; } ;
private :
void Deselect ( ) ; // clear selection range
void ClearText ( ) ; // remove all the text
public :
bool InsertText ( const char * szText , bool fUser ) ; // insert text at cursor pos (returns whether all text could be inserted)
void DeleteSelection ( ) ; // deletes the selected text. Adjust cursor position if necessary
bool SetText ( const char * szText , bool fUser ) { ClearText ( ) ; return InsertText ( szText , fUser ) ; }
void SetPasswordMask ( char cNewPasswordMask ) { cPasswordMask = cNewPasswordMask ; } // mask edit box contents using the given character
private :
int32_t GetCharPos ( int32_t iControlXPos ) ; // get character index of pixel position; always resides within current text length
void EnsureBufferSize ( int32_t iMinBufferSize ) ; // ensure buffer has desired size
void ScrollCursorInView ( ) ; // ensure cursor pos is visible in edit control
bool DoFinishInput ( bool fPasting , bool fPastingMore ) ; // do OnFinishInput callback and process result - returns whether pasting operation should be continued
bool Copy ( ) ; bool Cut ( ) ; bool Paste ( ) ; // clipboard operations
protected :
CStdFont * pFont ; // font for edit
char * Text ; // edit text
uint32_t dwBGClr , dwFontClr , dwBorderColor ; // drawing colors for edit box
int32_t iBufferSize ; // size of current buffer
int32_t iCursorPos ; // cursor position: char, before which the cursor is located
int32_t iSelectionStart , iSelectionEnd ; // selection range (start may be larger than end)
int32_t iMaxTextLength ; // maximum number of characters to be input here
2013-12-04 12:35:07 +00:00
C4TimeMilliseconds tLastInputTime ; // time of last input (for cursor flashing)
2010-03-28 17:58:21 +00:00
int32_t iXScroll ; // horizontal scrolling
char cPasswordMask ; // character to be used for masking the contents. 0 for none.
bool fLeftBtnDown ; // flag whether left mouse button is down or not
virtual bool CharIn ( const char * c ) ; // input: character key pressed - should return false for none-character-inputs
virtual void DoDragging ( CMouse & rMouse , int32_t iX , int32_t iY , DWORD dwKeyParam ) ; // dragging: allow text selection outside the component
virtual bool IsFocusOnClick ( ) { return true ; } // edit fields do get focus on click
virtual void OnGetFocus ( bool fByMouse ) ; // edit control gets focus
virtual void OnLooseFocus ( ) ; // edit control looses focus
virtual void DrawElement ( C4TargetFacet & cgo ) ; // draw edit control
// called when user presses enter in single-line edit control - closes the current dialog
virtual InputResult OnFinishInput ( bool fPasting , bool fPastingMore ) { return IR_CloseDlg ; }
virtual void OnAbortInput ( ) { }
// get margins from bounds to client rect
virtual int32_t GetMarginTop ( ) { return 2 ; }
virtual int32_t GetMarginLeft ( ) { return 4 ; }
virtual int32_t GetMarginRight ( ) { return 4 ; }
virtual int32_t GetMarginBottom ( ) { return 2 ; }
public :
2015-09-04 02:42:29 +00:00
virtual void MouseInput ( CMouse & rMouse , int32_t iButton , int32_t iX , int32_t iY , DWORD dwKeyParam ) ; // input: mouse movement or buttons
2010-03-28 17:58:21 +00:00
const char * GetText ( ) { return Text ; }
void SelectAll ( ) ; // select all the text
static int32_t GetDefaultEditHeight ( ) ;
static int32_t GetCustomEditHeight ( CStdFont * pUseFont ) ;
bool GetCurrentWord ( char * szTargetBuf , int32_t iMaxTargetBufLen ) ; // get word before cursor pos (for nick completion)
// layout
void SetFont ( CStdFont * pToFont ) { pFont = pToFont ; ScrollCursorInView ( ) ; }
void SetColors ( uint32_t dwNewBGClr , uint32_t dwNewFontClr , uint32_t dwNewBorderColor )
{ dwBGClr = dwNewBGClr ; dwFontClr = dwNewFontClr ; dwBorderColor = dwNewBorderColor ; }
void SetMaxText ( int32_t iTo ) { iMaxTextLength = iTo ; }
} ;
2009-05-08 13:28:41 +00:00
// an edit doing some callback
template < class CallbackCtrl > class CallbackEdit : public Edit
2010-03-28 17:58:21 +00:00
{
private :
CallbackCtrl * pCBCtrl ;
protected :
typedef InputResult ( CallbackCtrl : : * CBFunc ) ( Edit * , bool , bool ) ;
typedef void ( CallbackCtrl : : * CBAbortFunc ) ( ) ;
CBFunc pCBFunc ; CBAbortFunc pCBAbortFunc ;
virtual InputResult OnFinishInput ( bool fPasting , bool fPastingMore )
{ if ( pCBFunc & & pCBCtrl ) return ( pCBCtrl - > * pCBFunc ) ( this , fPasting , fPastingMore ) ; else return IR_CloseDlg ; }
virtual void OnAbortInput ( )
{ if ( pCBAbortFunc & & pCBCtrl ) ( pCBCtrl - > * pCBAbortFunc ) ( ) ; }
public :
2016-11-02 23:58:02 +00:00
CallbackEdit ( const C4Rect & rtBounds , CallbackCtrl * pCBCtrl , CBFunc pCBFunc , CBAbortFunc pCBAbortFunc = nullptr ) // ctor
2009-05-08 13:28:41 +00:00
: Edit ( rtBounds ) , pCBCtrl ( pCBCtrl ) , pCBFunc ( pCBFunc ) , pCBAbortFunc ( pCBAbortFunc ) { }
2010-03-28 17:58:21 +00:00
} ;
2009-05-08 13:28:41 +00:00
// an edit control that renames a label - some less decoration; abort on Escape and focus loss
class RenameEdit : public Edit
2010-03-28 17:58:21 +00:00
{
private :
C4KeyBinding * pKeyAbort ; // key bindings
bool fFinishing ; // set during deletion process
Label * pForLabel ; // label that is being renamed
Control * pPrevFocusCtrl ; // previous focus element to be restored after rename
public :
enum RenameResult
2009-05-08 13:28:41 +00:00
{
2010-03-28 17:58:21 +00:00
RR_Invalid = 0 , // rename not accepted; continue editing
RR_Accepted , // rename accepted; delete control
RR_Deleted // control deleted - leave everything
} ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
public :
RenameEdit ( Label * pLabel ) ; // ctor - construct for label; add element; set focus
virtual ~ RenameEdit ( ) ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
void Abort ( ) ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
private :
void FinishRename ( ) ; // renaming aborted or finished - remove this element and restore label
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
protected :
bool KeyAbort ( ) { Abort ( ) ; return true ; }
virtual InputResult OnFinishInput ( bool fPasting , bool fPastingMore ) ; // forward last input to OnOKRename
virtual void OnLooseFocus ( ) ; // callback when control looses focus: OK input
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual void OnCancelRename ( ) { } // renaming was aborted
virtual RenameResult OnOKRename ( const char * szNewName ) = 0 ; // rename performed - return whether name was accepted
} ;
2009-05-08 13:28:41 +00:00
template < class CallbackDlg , class ParType > class CallbackRenameEdit : public RenameEdit
2010-03-28 17:58:21 +00:00
{
public :
protected :
typedef void ( CallbackDlg : : * CBCancelFunc ) ( ParType ) ;
typedef RenameResult ( CallbackDlg : : * CBOKFunc ) ( ParType , const char * ) ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
CBCancelFunc pCBCancelFunc ; CBOKFunc pCBOKFunc ;
CallbackDlg * pDlg ; ParType par ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual void OnCancelRename ( ) { if ( pDlg & & pCBCancelFunc ) ( pDlg - > * pCBCancelFunc ) ( par ) ; }
virtual RenameResult OnOKRename ( const char * szNewName ) { return ( pDlg & & pCBOKFunc ) ? ( pDlg - > * pCBOKFunc ) ( par , szNewName ) : RR_Accepted ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
public :
CallbackRenameEdit ( Label * pForLabel , CallbackDlg * pDlg , const ParType & par , CBOKFunc pCBOKFunc , CBCancelFunc pCBCancelFunc ) // ctor
2010-01-25 04:00:59 +00:00
: RenameEdit ( pForLabel ) , pCBCancelFunc ( pCBCancelFunc ) , pCBOKFunc ( pCBOKFunc ) , pDlg ( pDlg ) , par ( par ) { }
2010-03-28 17:58:21 +00:00
} ;
2009-05-08 13:28:41 +00:00
// editbox below descriptive label sharing one window for common tooltip
class LabeledEdit : public C4GUI : : Window
2010-03-28 17:58:21 +00:00
{
public :
2016-11-02 23:58:02 +00:00
LabeledEdit ( const C4Rect & rcBounds , const char * szName , bool fMultiline , const char * szPrefText = nullptr , CStdFont * pUseFont = nullptr , uint32_t dwTextClr = C4GUI_CaptionFontClr ) ;
2010-03-28 17:58:21 +00:00
private :
C4GUI : : Edit * pEdit ;
public :
const char * GetText ( ) const { return pEdit - > GetText ( ) ; }
C4GUI : : Edit * GetEdit ( ) const { return pEdit ; }
static bool GetControlSize ( int * piWdt , int * piHgt , const char * szForText , CStdFont * pForFont , bool fMultiline ) ;
} ;
2009-05-08 13:28:41 +00:00
// checkbox with a text label right of it
class CheckBox : public Control
2010-03-28 17:58:21 +00:00
{
private :
bool fChecked ;
class C4KeyBinding * pKeyCheck ;
StdStrBuf sCaption ;
bool fMouseOn ;
BaseCallbackHandler * pCBHandler ; // callback handler called if check state changes
bool fEnabled ;
CStdFont * pFont ;
uint32_t dwEnabledClr , dwDisabledClr ;
2014-03-10 23:23:24 +00:00
uint32_t cHotkey ;
2010-03-28 17:58:21 +00:00
public :
CheckBox ( const C4Rect & rtBounds , const char * szCaption , bool fChecked ) ; // ctor
~ CheckBox ( ) ;
private :
bool KeyCheck ( ) { ToggleCheck ( true ) ; return true ; }
public :
void ToggleCheck ( bool fByUser ) ; // check on/off; do callback
protected :
virtual void UpdateOwnPos ( ) ;
virtual bool IsFocusOnClick ( ) { return false ; } // just check/uncheck on click; do not gain keyboard focus as well
2016-11-02 23:58:02 +00:00
virtual Control * IsFocusElement ( ) { return fEnabled ? Control : : IsFocusElement ( ) : nullptr ; } ; // this control can gain focus if enabled
2010-03-28 17:58:21 +00:00
virtual void DrawElement ( C4TargetFacet & cgo ) ; // draw checkbox
2014-03-10 23:23:24 +00:00
virtual bool OnHotkey ( uint32_t cHotkey ) ; // return true when hotkey has been processed
2010-03-28 17:58:21 +00:00
public :
2015-09-04 02:42:29 +00:00
virtual void MouseInput ( CMouse & rMouse , int32_t iButton , int32_t iX , int32_t iY , DWORD dwKeyParam ) ; // input: mouse movement or buttons
virtual void MouseEnter ( CMouse & rMouse ) ;
virtual void MouseLeave ( CMouse & rMouse ) ;
2010-03-28 17:58:21 +00:00
void SetChecked ( bool fToVal ) { fChecked = fToVal ; } // set w/o callback
bool GetChecked ( ) const { return fChecked ; }
void SetOnChecked ( BaseCallbackHandler * pCB ) ;
void SetEnabled ( bool fToVal ) { if ( ! ( fEnabled = fToVal ) ) DisableFocus ( ) ; }
const char * GetText ( ) { return sCaption . getData ( ) ; }
void SetFont ( CStdFont * pFont , uint32_t dwEnabledClr , uint32_t dwDisabledClr )
{ this - > pFont = pFont ; this - > dwEnabledClr = dwEnabledClr ; this - > dwDisabledClr = dwDisabledClr ; }
static bool GetStandardCheckBoxSize ( int * piWdt , int * piHgt , const char * szForCaptionText , CStdFont * pUseFont ) ; // get needed size to construct a checkbox
} ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
// a vertical list of elements
class ListBox : public Control
{
private :
class C4KeyBinding * pKeyContext , * pKeyUp , * pKeyDown , * pKeyPageUp , * pKeyPageDown , * pKeyHome , * pKeyEnd , * pKeyActivate , * pKeyLeft , * pKeyRight ;
bool KeyContext ( ) ;
bool KeyUp ( ) ;
bool KeyDown ( ) ;
bool KeyLeft ( ) ;
bool KeyRight ( ) ;
bool KeyPageUp ( ) ;
bool KeyPageDown ( ) ;
bool KeyHome ( ) ;
bool KeyEnd ( ) ;
bool KeyActivate ( ) ;
protected :
int32_t iMultiColItemWidth ; // if nonzero, the listbox is multicolumn and the column count depends on how many items fit in
int32_t iColCount ; // number of columns (usually 1)
ScrollWindow * pClientWindow ; // client scrolling window
Element * pSelectedItem ; // selected list item
BaseCallbackHandler * pSelectionChangeHandler , * pSelectionDblClickHandler ;
bool fDrawBackground ; // whether darker background is to be drawn
bool fDrawBorder ; // whether 3D frame around box shall be drawn or nay
bool fSelectionDisabled ; // if set, no entries can be selected
virtual void DrawElement ( C4TargetFacet & cgo ) ; // draw listbox
virtual bool IsFocused ( Control * pCtrl )
{
// subcontrol also counts as focused if the list has focus and the subcontrol is selected
return Control : : IsFocused ( pCtrl ) | | ( HasFocus ( ) & & pSelectedItem = = pCtrl ) ;
}
virtual bool IsFocusOnClick ( ) { return true ; } // list boxes do get focus on click
virtual Control * IsFocusElement ( ) { return this ; } ; // this control can gain focus
virtual void OnGetFocus ( bool fByMouse ) ; // callback when control gains focus - select a list item if none are selected
virtual bool CharIn ( const char * c ) ; // character input for direct list element selection
virtual void AfterElementRemoval ( )
{ Container : : AfterElementRemoval ( ) ; UpdateElementPositions ( ) ; } // called by ScrollWindow to parent after an element has been removed
void UpdateColumnCount ( ) ;
public :
ListBox ( const C4Rect & rtBounds , int32_t iMultiColItemWidth = 0 ) ; // ctor
virtual ~ ListBox ( ) ; // dtor
2015-09-04 02:42:29 +00:00
virtual void MouseInput ( CMouse & rMouse , int32_t iButton , int32_t iX , int32_t iY , DWORD dwKeyParam ) ; // input: mouse movement or buttons
2010-03-28 17:58:21 +00:00
virtual void RemoveElement ( Element * pChild ) ; // remove child component
bool AddElement ( Element * pChild , int32_t iIndent = 0 ) ; // add element and adjust its pos
bool InsertElement ( Element * pChild , Element * pInsertBefore , int32_t iIndent = 0 ) ; // insert element and adjust its pos
virtual void ElementSizeChanged ( Element * pOfElement ) ; // called when an element size is changed
virtual void ElementPosChanged ( Element * pOfElement ) ; // called when an element position is changed
int32_t GetItemWidth ( ) { return iMultiColItemWidth ? iMultiColItemWidth : pClientWindow - > GetClientRect ( ) . Wdt ; }
void SelectionChanged ( bool fByUser ) ; // pSelectedItem changed: sound, tooltip, etc.
void SetSelectionChangeCallbackFn ( BaseCallbackHandler * pToHandler ) // update selection change handler
{
if ( pSelectionChangeHandler ) pSelectionChangeHandler - > DeRef ( ) ;
if ( ( pSelectionChangeHandler = pToHandler ) ) pToHandler - > Ref ( ) ;
}
void SetSelectionDblClickFn ( BaseCallbackHandler * pToHandler ) // update selection doubleclick handler
{
if ( pSelectionDblClickHandler ) pSelectionDblClickHandler - > DeRef ( ) ;
if ( ( pSelectionDblClickHandler = pToHandler ) ) pSelectionDblClickHandler - > Ref ( ) ;
}
void ScrollToBottom ( ) // set scrolling to bottom range
{ if ( pClientWindow ) pClientWindow - > ScrollToBottom ( ) ; }
void ScrollItemInView ( Element * pItem ) ; // set scrolling so a specific item is visible
void FreezeScrolling ( ) { pClientWindow - > Freeze ( ) ; }
void UnFreezeScrolling ( ) { pClientWindow - > UnFreeze ( ) ; }
// change style
void SetDecoration ( bool fDrawBG , ScrollBarFacets * pToGfx , bool fAutoScroll , bool fDrawBorder = false )
{ fDrawBackground = fDrawBG ; this - > fDrawBorder = fDrawBorder ; if ( pClientWindow ) pClientWindow - > SetDecoration ( pToGfx , fAutoScroll ) ; }
void SetSelectionDiabled ( bool fToVal = true ) { fSelectionDisabled = fToVal ; }
// get head and tail list items
2016-11-02 23:58:02 +00:00
Element * GetFirst ( ) { return pClientWindow ? pClientWindow - > GetFirst ( ) : nullptr ; }
Element * GetLast ( ) { return pClientWindow ? pClientWindow - > GetLast ( ) : nullptr ; }
2010-03-28 17:58:21 +00:00
// get margins from bounds to client rect
virtual int32_t GetMarginTop ( ) { return 3 ; }
virtual int32_t GetMarginLeft ( ) { return 3 ; }
virtual int32_t GetMarginRight ( ) { return 3 ; }
virtual int32_t GetMarginBottom ( ) { return 3 ; }
Element * GetSelectedItem ( ) { return pSelectedItem ; } // get focused listbox item
bool IsScrollingActive ( ) { return pClientWindow & & pClientWindow - > IsScrollingActive ( ) ; }
bool IsScrollingNecessary ( ) { return pClientWindow & & pClientWindow - > IsScrollingNecessary ( ) ; }
void SelectEntry ( Element * pNewSel , bool fByUser ) ;
void SelectFirstEntry ( bool fByUser ) { SelectEntry ( GetFirst ( ) , fByUser ) ; }
2016-11-02 23:58:02 +00:00
void SelectNone ( bool fByUser ) { SelectEntry ( nullptr , fByUser ) ; }
2010-03-28 17:58:21 +00:00
bool IsMultiColumn ( ) const { return iColCount > 1 ; }
int32_t ContractToElementHeight ( ) ; // make smaller if elements don't use up all of the available height. Return amount by which list box got contracted
void UpdateElementPositions ( ) ; // reposition list items so they are stacked vertically
void UpdateElementPosition ( Element * pOfElement , int32_t iIndent ) ; // update pos for one specific element
virtual void UpdateSize ( ) { Control : : UpdateSize ( ) ; if ( pClientWindow ) { pClientWindow - > UpdateSize ( ) ; UpdateElementPositions ( ) ; } }
virtual bool IsSelectedChild ( Element * pChild ) { return pChild = = pSelectedItem | | ( pSelectedItem & & pSelectedItem - > IsParentOf ( pChild ) ) ; }
typedef int32_t ( * SortFunction ) ( const Element * pEl1 , const Element * pEl2 , void * par ) ;
void SortElements ( SortFunction SortFunc , void * par ) ; // sort list items
} ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
// tabbing panel
class Tabular : public Control
{
public :
// sheet covering the client area of a tabular
class Sheet : public Window
{
2009-05-08 13:28:41 +00:00
protected :
2010-03-28 17:58:21 +00:00
StdStrBuf sTitle ; // sheet label
int32_t icoTitle ; // sheet label icon
2014-03-10 23:23:24 +00:00
uint32_t cHotkey ;
2010-03-28 17:58:21 +00:00
uint32_t dwCaptionClr ; // caption color - default if 0
bool fHasCloseButton , fCloseButtonHighlighted ;
bool fTitleMarkup ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
Sheet ( const char * szTitle , const C4Rect & rcBounds , int32_t icoTitle = Ico_None , bool fHasCloseButton = false , bool fTitleMarkup = true ) ; // ctor; expands hotkey markup in title
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
void DrawCaption ( C4TargetFacet & cgo , int32_t x , int32_t y , int32_t iMaxWdt , bool fLarge , bool fActive , bool fFocus , C4Facet * pfctClip , C4Facet * pfctIcon , CStdFont * pUseFont ) ;
void GetCaptionSize ( int32_t * piWdt , int32_t * piHgt , bool fLarge , bool fActive , C4Facet * pfctClip , C4Facet * pfctIcon , CStdFont * pUseFont ) ;
virtual void OnShown ( bool fByUser ) { } // calklback from tabular after sheet has been made visible
void SetCloseButtonHighlight ( bool fToVal ) { fCloseButtonHighlighted = fToVal ; }
bool IsPosOnCloseButton ( int32_t x , int32_t y , int32_t iCaptWdt , int32_t iCaptHgt , bool fLarge ) ;
bool IsActiveSheet ( ) ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
public :
const char * GetTitle ( ) { return sTitle . getData ( ) ; }
char GetHotkey ( ) { return cHotkey ; }
void SetTitle ( const char * szNewTitle ) ;
void SetCaptionColor ( uint32_t dwNewClr = 0 ) { dwCaptionClr = dwNewClr ; }
virtual void UserClose ( ) { delete this ; } // user pressed close button
bool HasCloseButton ( ) const { return fHasCloseButton ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
friend class Tabular ;
2009-05-08 13:28:41 +00:00
} ;
2010-03-28 17:58:21 +00:00
enum TabPosition
2009-05-08 13:28:41 +00:00
{
2010-03-28 17:58:21 +00:00
tbNone = 0 , // no tabs
tbTop , // tabs on top
tbLeft // tabs to the left
2009-05-08 13:28:41 +00:00
} ;
2010-03-28 17:58:21 +00:00
private :
Sheet * pActiveSheet ; // currently selected sheet
TabPosition eTabPos ; // whither tabs shalt be shown or nay, en where art thy shown?
int32_t iMaxTabWidth ; // maximum tab length; used when tabs are positioned left and do not have gfx
int32_t iSheetSpacing , iSheetOff ; // distances of sheet captions
int32_t iCaptionLengthTotal , iCaptionScrollPos ; // scrolling in captions (top only)
bool fScrollingLeft , fScrollingRight , fScrollingLeftDown , fScrollingRightDown ; // scrolling in captions (top only)
2013-12-04 12:35:07 +00:00
C4TimeMilliseconds tLastScrollTime ; // set when fScrollingLeftDown or fScrollingRightDown are true: Time for next scrolling if mouse is held down
2010-03-28 17:58:21 +00:00
int iSheetMargin ;
bool fDrawSelf ; // if border and bg shall be drawn
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
C4Facet * pfctBack , * pfctClip , * pfctIcons ; // set for tabulars that have custom gfx
2016-11-02 23:58:02 +00:00
CStdFont * pSheetCaptionFont ; // font to be used for caption drawing; nullptr if default GUI font is to be used
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
C4KeyBinding * pKeySelUp , * pKeySelDown , * pKeySelUp2 , * pKeySelDown2 , * pKeyCloseTab ; // key bindings
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
void SelectionChanged ( bool fByUser ) ; // pActiveSheet changed: sound, tooltip, etc.
void SheetsChanged ( ) ; // update iMaxTabWidth by new set of sheet labels
void UpdateScrolling ( ) ;
void DoCaptionScroll ( int32_t iDir ) ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
private :
bool HasGfx ( ) { return pfctBack & & pfctClip & & pfctIcons ; } // whether the control uses custom graphics
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
protected :
bool KeySelUp ( ) ; // keyboard callback: Select previous sheet
bool KeySelDown ( ) ; // keyboard callback: Select next sheet
bool KeyCloseTab ( ) ; // keyboard callback: Close current sheet if possible
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual void DrawElement ( C4TargetFacet & cgo ) ;
void MouseLeaveCaptionArea ( ) ;
virtual void MouseLeave ( CMouse & rMouse ) ;
virtual void OnGetFocus ( bool fByMouse ) ;
2009-05-08 13:28:41 +00:00
2016-11-02 23:58:02 +00:00
virtual Control * IsFocusElement ( ) { return eTabPos ? this : nullptr ; } ; // this control can gain focus only if tabs are enabled only
2010-03-28 17:58:21 +00:00
virtual bool IsFocusOnClick ( ) { return false ; } // but never get focus on single mouse click, because this would de-focus any contained controls!
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
int32_t GetTopSize ( ) { return ( eTabPos = = tbTop ) ? 20 : 0 ; } // vertical size of tab selection bar
int32_t GetLeftSize ( ) { return ( eTabPos = = tbLeft ) ? ( HasGfx ( ) ? GetLeftClipSize ( pfctClip ) : 20 + iMaxTabWidth ) : 0 ; } // horizontal size of tab selection bar
bool HasLargeCaptions ( ) { return eTabPos = = tbLeft ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual int32_t GetMarginTop ( ) { return iSheetMargin + GetTopSize ( ) + ( HasGfx ( ) ? ( rcBounds . Hgt - GetTopSize ( ) ) * 30 / 483 : 0 ) ; }
virtual int32_t GetMarginLeft ( ) { return iSheetMargin + GetLeftSize ( ) + ( HasGfx ( ) ? ( rcBounds . Wdt - GetLeftSize ( ) ) * 13 / 628 : 0 ) ; }
virtual int32_t GetMarginRight ( ) { return iSheetMargin + ( HasGfx ( ) ? ( rcBounds . Wdt - GetLeftSize ( ) ) * 30 / 628 : 0 ) ; }
virtual int32_t GetMarginBottom ( ) { return iSheetMargin + ( HasGfx ( ) ? ( rcBounds . Hgt - GetTopSize ( ) ) * 32 / 483 : 0 ) ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual void UpdateSize ( ) ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual bool IsSelectedChild ( Element * pChild ) { return pChild = = pActiveSheet | | ( pActiveSheet & & pActiveSheet - > IsParentOf ( pChild ) ) ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
public :
Tabular ( C4Rect & rtBounds , TabPosition eTabPos ) ; // ctor
~ Tabular ( ) ; // dtor
2009-05-08 13:28:41 +00:00
2015-09-04 02:42:29 +00:00
virtual void MouseInput ( CMouse & rMouse , int32_t iButton , int32_t iX , int32_t iY , DWORD dwKeyParam ) ;
2010-03-28 17:58:21 +00:00
virtual void RemoveElement ( Element * pChild ) ; // clear ptr
Sheet * AddSheet ( const char * szTitle , int32_t icoTitle = Ico_None ) ;
void AddCustomSheet ( Sheet * pAddSheet ) ;
void ClearSheets ( ) ; // del all sheets
void SelectSheet ( int32_t iIndex , bool fByUser ) ;
void SelectSheet ( Sheet * pSelSheet , bool fByUser ) ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
Sheet * GetSheet ( int32_t iIndex ) { return ( Sheet * ) GetElementByIndex ( iIndex ) ; }
Sheet * GetActiveSheet ( ) { return pActiveSheet ; }
int32_t GetActiveSheetIndex ( ) ;
int32_t GetSheetCount ( ) { return GetElementCount ( ) ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
void SetGfx ( C4Facet * pafctBack , C4Facet * pafctClip , C4Facet * pafctIcons , CStdFont * paSheetCaptionFont , bool fResizeByAspect ) ;
static int32_t GetLeftClipSize ( C4Facet * pfctForClip ) { return pfctForClip - > Wdt * 95 / 120 ; } // left clip area size by gfx
void SetSheetMargin ( int32_t iMargin ) { iSheetMargin = iMargin ; UpdateOwnPos ( ) ; }
void SetDrawDecoration ( bool fToVal ) { fDrawSelf = fToVal ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
friend class Sheet ;
} ;
2009-05-08 13:28:41 +00:00
// scrollable text box
class TextWindow : public Control
2010-03-28 17:58:21 +00:00
{
protected :
ScrollWindow * pClientWindow ; // client scrolling window
Picture * pTitlePicture ; // [optional]: Picture shown atop the text
MultilineLabel * pLogBuffer ; // buffer holding text data
bool fDrawBackground , fDrawFrame ; // whether dark background should be drawn (default true)
size_t iPicPadding ;
virtual void DrawElement ( C4TargetFacet & cgo ) ; // draw text window
virtual void ElementSizeChanged ( Element * pOfElement ) ; // called when an element size is changed
virtual void ElementPosChanged ( Element * pOfElement ) ; // called when an element position is changed
virtual void UpdateSize ( ) ;
2016-11-02 23:58:02 +00:00
virtual Control * IsFocusElement ( ) { return nullptr ; } ; // no focus element for now, because there's nothing to do (2do: scroll?)
2010-03-28 17:58:21 +00:00
public :
2016-11-02 23:58:02 +00:00
TextWindow ( C4Rect & rtBounds , size_t iPicWdt = 0 , size_t iPicHgt = 0 , size_t iPicPadding = 0 , size_t iMaxLines = 100 , size_t iMaxTextLen = 4096 , const char * szIndentChars = " " , bool fAutoGrow = false , const C4Facet * pOverlayPic = nullptr , int iOverlayBorder = 0 , bool fMarkup = false ) ; // ctor
2010-03-28 17:58:21 +00:00
2016-11-02 23:58:02 +00:00
void AddTextLine ( const char * szText , CStdFont * pFont , DWORD dwClr , bool fDoUpdate , bool fMakeReadableOnBlack , CStdFont * pCaptionFont = nullptr ) // add text in a new line
2010-03-28 17:58:21 +00:00
{ if ( pLogBuffer ) pLogBuffer - > AddLine ( szText , pFont , dwClr , fDoUpdate , fMakeReadableOnBlack , pCaptionFont ) ; }
void ScrollToBottom ( ) // set scrolling to bottom range
{ if ( pClientWindow ) pClientWindow - > ScrollToBottom ( ) ; }
void ClearText ( bool fDoUpdate )
{ if ( pLogBuffer ) pLogBuffer - > Clear ( fDoUpdate ) ; }
int32_t GetScrollPos ( )
{ return pClientWindow ? pClientWindow - > GetScrollY ( ) : 0 ; }
void SetScrollPos ( int32_t iPos )
{ if ( pClientWindow ) pClientWindow - > ScrollRangeInView ( iPos , 0 ) ; }
void UpdateHeight ( )
{ if ( pLogBuffer ) pLogBuffer - > UpdateHeight ( ) ; }
void SetDecoration ( bool fDrawBG , bool fDrawFrame , ScrollBarFacets * pToGfx , bool fAutoScroll )
{ fDrawBackground = fDrawBG ; this - > fDrawFrame = fDrawFrame ; if ( pClientWindow ) pClientWindow - > SetDecoration ( pToGfx , fAutoScroll ) ; }
void SetPicture ( const C4Facet & rNewPic ) ;
// get margins from bounds to client rect
virtual int32_t GetMarginTop ( ) { return 8 ; }
virtual int32_t GetMarginLeft ( ) { return 10 ; }
virtual int32_t GetMarginRight ( ) { return 5 ; }
virtual int32_t GetMarginBottom ( ) { return 8 ; }
} ;
2009-05-08 13:28:41 +00:00
// context menu opened on right-click
class ContextMenu : public Window
2010-03-28 17:58:21 +00:00
{
private :
// key bindings
class C4KeyBinding * pKeySelUp , * pKeySelDown , * pKeySubmenu , * pKeyBack , * pKeyAbort , * pKeyConfirm , * pKeyHotkey ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
bool KeySelUp ( ) ;
bool KeySelDown ( ) ;
bool KeySubmenu ( ) ;
bool KeyBack ( ) ;
bool KeyAbort ( ) ;
bool KeyConfirm ( ) ;
bool KeyHotkey ( const C4KeyCodeEx & key ) ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
private :
static int32_t iGlobalMenuIndex ;
int32_t iMenuIndex ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
void UpdateElementPositions ( ) ; // stack all menu elements
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
// element adding made private: May only add entries
bool AddElement ( Element * pChild ) ;
bool InsertElement ( Element * pChild , Element * pInsertBefore ) ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
public :
// one text entry (icon+text+eventually right-arrow)
class Entry : public Element
{
private :
int32_t GetIconIndent ( ) { return ( icoIcon = = - 1 ) ? 0 : rcBounds . Hgt + 2 ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
protected :
StdStrBuf sText ; // entry text
2014-03-10 23:23:24 +00:00
uint32_t cHotkey ; // entry hotkey
2010-03-28 17:58:21 +00:00
Icons icoIcon ; // icon to be drawn left of text
MenuHandler * pMenuHandler ; // callback when item is selected
ContextHandler * pSubmenuHandler ; // callback when submenu is opened
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
protected :
virtual void DrawElement ( C4TargetFacet & cgo ) ; // draw element
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
MenuHandler * GetAndZeroCallback ( )
2016-11-02 23:58:02 +00:00
{ MenuHandler * pMH = pMenuHandler ; pMenuHandler = nullptr ; return pMH ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual void MouseLeave ( CMouse & rMouse )
{ if ( GetParent ( ) ) ( ( ContextMenu * ) GetParent ( ) ) - > MouseLeaveEntry ( rMouse , this ) ; }
2009-05-08 13:28:41 +00:00
2014-03-10 23:23:24 +00:00
virtual bool OnHotkey ( uint32_t cKey ) { return cKey = = cHotkey ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual bool IsMenu ( ) { return true ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
public :
2016-11-02 23:58:02 +00:00
Entry ( const char * szText , Icons icoIcon = Ico_None , MenuHandler * pMenuHandler = nullptr , ContextHandler * pSubmenuHandler = nullptr ) ; // ctor
2010-03-28 17:58:21 +00:00
~ Entry ( )
{
if ( pMenuHandler ) delete pMenuHandler ;
if ( pSubmenuHandler ) delete pSubmenuHandler ;
}
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
const char * GetText ( ) { return sText . getData ( ) ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
friend class ContextMenu ;
} ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
protected :
Element * pTarget ; // target element; close menu if this is lost
Element * pSelectedItem ; // currently highlighted menu item
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
ContextMenu * pSubmenu ; // currently open submenu
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
// mouse movement or buttons forwarded from screen:
// Check bounds and forward as MouseInput to context menu or submenus
// return whether inside context menu bounds
bool CtxMouseInput ( CMouse & rMouse , int32_t iButton , int32_t iScreenX , int32_t iScreenY , DWORD dwKeyParam ) ;
virtual void RemoveElement ( Element * pChild ) ; // clear ptr - abort menu if target is destroyed
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual bool CharIn ( const char * c ) ; // input: character key pressed - should return false for none-character-inputs
void MouseLeaveEntry ( CMouse & rMouse , Entry * pOldEntry ) ; // callback: mouse leaves - deselect menu item if no submenu is open (callback done by menu item)
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual void DrawElement ( C4TargetFacet & cgo ) ; // draw BG
virtual void Draw ( C4TargetFacet & cgo ) ; // draw inherited (element+contents) plus submenu
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual bool IsMenu ( ) { return true ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual Screen * GetScreen ( ) ; // return screen by static var
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual int32_t GetMarginTop ( ) { return 5 ; }
virtual int32_t GetMarginLeft ( ) { return 5 ; }
virtual int32_t GetMarginRight ( ) { return 5 ; }
virtual int32_t GetMarginBottom ( ) { return 5 ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
void SelectionChanged ( bool fByUser ) ; // other item selected: Close any submenu; do callbacks
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual void ElementSizeChanged ( Element * pOfElement ) ; // called when an element size is changed
virtual void ElementPosChanged ( Element * pOfElement ) ; // called when an element position is changed
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
void CheckOpenSubmenu ( ) ; // open submenu if present for selected item
bool IsSubmenu ( ) ; // return whether it's a submenu
void DoOK ( ) ; // do OK for selected item
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
public :
ContextMenu ( ) ; // ctor
~ ContextMenu ( ) ; // dtor
2009-05-08 13:28:41 +00:00
2015-09-04 02:42:29 +00:00
virtual void MouseInput ( CMouse & rMouse , int32_t iButton , int32_t iX , int32_t iY , DWORD dwKeyParam ) ; // input: mouse movement or buttons
2010-03-28 17:58:21 +00:00
void Open ( Element * pTarget , int32_t iScreenX , int32_t iScreenY ) ;
void Abort ( bool fByUser ) ;
2009-05-08 13:28:41 +00:00
2016-11-02 23:58:02 +00:00
void AddItem ( const char * szText , const char * szToolTip = nullptr , Icons icoIcon = Ico_None , MenuHandler * pMenuHandler = nullptr , ContextHandler * pSubmenuHandler = nullptr )
2010-03-28 17:58:21 +00:00
{
Element * pNew = new ContextMenu : : Entry ( szText , icoIcon , pMenuHandler , pSubmenuHandler ) ;
AddElement ( pNew ) ; pNew - > SetToolTip ( szToolTip ) ;
}
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
Entry * GetIndexedEntry ( int32_t iIndex ) { return static_cast < Entry * > ( GetElementByIndex ( iIndex ) ) ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
void SelectItem ( int32_t iIndex ) ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
int32_t GetMenuIndex ( ) { return iMenuIndex ; }
static int32_t GetLastMenuIndex ( ) { return iGlobalMenuIndex ; }
2009-05-08 13:28:41 +00:00
2016-11-02 23:58:02 +00:00
Dialog * GetTargetDialog ( ) const { return pTarget ? pTarget - > GetDlg ( ) : nullptr ; }
2015-09-12 06:51:55 +00:00
friend class Screen ; friend class Entry ; friend class Dialog ;
2010-03-28 17:58:21 +00:00
} ;
2009-05-08 13:28:41 +00:00
// a button to open a context menu
class ContextButton : public Control
2010-03-28 17:58:21 +00:00
{
private :
C4KeyBinding * pKeyContext ;
int32_t iOpenMenu ; // associated menu (used to flag button down)
bool fMouseOver ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
public :
ContextButton ( C4Rect & rtBounds ) ; // ctor
ContextButton ( Element * pForEl , bool fAdd , int32_t iHIndent = 4 , int32_t iVIndent = 4 ) ; // ctor creating at topright pos of element
~ ContextButton ( ) ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
private :
bool DoContext ( int32_t iX = - 1 , int32_t iY = - 1 ) ; // open context menu
bool KeyContext ( ) { return DoContext ( ) ; }
void RegisterContextKey ( ) ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
protected :
virtual void DrawElement ( C4TargetFacet & cgo ) ; // draw btn
2009-05-08 13:28:41 +00:00
2015-09-04 02:42:29 +00:00
virtual bool IsFocusOnClick ( ) { return false ; } // don't select control on click
public :
2010-03-28 17:58:21 +00:00
virtual void MouseInput ( CMouse & rMouse , int32_t iButton , int32_t iX , int32_t iY , DWORD dwKeyParam ) ; // input: mouse. left-click opens menu
virtual void MouseEnter ( CMouse & rMouse ) ;
virtual void MouseLeave ( CMouse & rMouse ) ;
} ;
2009-05-08 13:28:41 +00:00
// combo box filler
// should be ComboBox::FillCB; but nested class will cause internal compiler faults
class ComboBox_FillCB
2010-03-28 17:58:21 +00:00
{
private :
ComboBox * pCombo ;
ContextMenu * pDrop ;
public :
virtual ~ ComboBox_FillCB ( ) { }
void FillDropDown ( ComboBox * pComboBox , ContextMenu * pDropdownList )
{ pCombo = pComboBox ; pDrop = pDropdownList ; FillDropDownCB ( ) ; }
virtual void FillDropDownCB ( ) = 0 ;
virtual bool OnComboSelChange ( ComboBox * pForCombo , int32_t idNewSelection ) = 0 ;
// to be used in fill-callback only (crash otherwise!)
void AddEntry ( const char * szText , int32_t id ) ;
bool FindEntry ( const char * szText ) ;
void ClearEntries ( ) ;
void SelectEntry ( int32_t iEntry ) ; // select entry by index
} ;
2009-05-08 13:28:41 +00:00
template < class CB > class ComboBox_FillCallback : public ComboBox_FillCB
2010-03-28 17:58:21 +00:00
{
public :
typedef void ( CB : : * ComboFillFunc ) ( ComboBox_FillCB * pFiller ) ;
typedef bool ( CB : : * ComboSelFunc ) ( ComboBox * pForCombo , int32_t idNewSelection ) ;
private :
CB * pCBClass ;
ComboFillFunc FillFunc ;
ComboSelFunc SelFunc ;
protected :
virtual void FillDropDownCB ( )
{ if ( pCBClass & & FillFunc ) ( pCBClass - > * FillFunc ) ( this ) ; }
virtual bool OnComboSelChange ( ComboBox * pForCombo , int32_t idNewSelection )
{ if ( pCBClass & & SelFunc ) return ( pCBClass - > * SelFunc ) ( pForCombo , idNewSelection ) ; else return false ; }
public :
ComboBox_FillCallback ( CB * pCBClass , ComboFillFunc FillFunc , ComboSelFunc SelFunc ) :
pCBClass ( pCBClass ) , FillFunc ( FillFunc ) , SelFunc ( SelFunc ) { }
} ;
2009-05-08 13:28:41 +00:00
// dropdown box to select elements from a list
class ComboBox : public Control
2010-03-28 17:58:21 +00:00
{
public :
struct ComboMenuCBStruct // struct used as menu callback parameter for dropdown menu
{
StdCopyStrBuf sText ;
int32_t id ;
ComboMenuCBStruct ( ) : sText ( ) , id ( 0 ) { }
ComboMenuCBStruct ( const char * szText , int32_t id ) : sText ( szText ) , id ( id ) { }
} ;
private :
class C4KeyBinding * pKeyOpenCombo , * pKeyCloseCombo ;
private :
int32_t iOpenMenu ; // associated menu (used to flag dropped down)
ComboBox_FillCB * pFillCallback ; // callback used to display the dropdown
char Text [ C4MaxTitle + 1 ] ; // currently selected item
bool fReadOnly ; // merely a label in ReadOnly-mode
bool fSimple ; // combo without border and stuff
bool fMouseOver ; // mouse hovering over this?
CStdFont * pUseFont ; // font used to draw this control
uint32_t dwFontClr , dwBGClr , dwBorderClr ; // colors used to draw this control
C4Facet * pFctSideArrow ; // arrow gfx used to start combo-dropdown
private :
bool DoDropdown ( ) ; // open dropdown menu (context menu)
bool KeyDropDown ( ) { return DoDropdown ( ) ; }
bool KeyAbortDropDown ( ) { return AbortDropdown ( true ) ; }
bool AbortDropdown ( bool fByUser ) ; // abort dropdown menu, if it's open
protected :
virtual void DrawElement ( C4TargetFacet & cgo ) ; // draw combo box
virtual bool IsFocusOnClick ( ) { return false ; } // don't select control on click
2016-11-02 23:58:02 +00:00
virtual Control * IsFocusElement ( ) { return fReadOnly ? nullptr : this ; } ; // this control can gain focus if not readonly
2010-03-28 17:58:21 +00:00
void OnCtxComboSelect ( C4GUI : : Element * pListItem , const ComboMenuCBStruct & rNewSel ) ;
public :
ComboBox ( const C4Rect & rtBounds ) ;
~ ComboBox ( ) ;
2015-09-04 02:42:29 +00:00
virtual void MouseInput ( CMouse & rMouse , int32_t iButton , int32_t iX , int32_t iY , DWORD dwKeyParam ) ; // input: mouse. left-click opens menu
virtual void MouseEnter ( CMouse & rMouse ) ; // called when mouse cursor enters element region
virtual void MouseLeave ( CMouse & rMouse ) ; // called when mouse cursor leaves element region
2010-03-28 17:58:21 +00:00
void SetComboCB ( ComboBox_FillCB * pNewFillCallback ) ;
static int32_t GetDefaultHeight ( ) ;
void SetText ( const char * szToText ) ;
void SetReadOnly ( bool fToVal ) { if ( ( fReadOnly = fToVal ) ) AbortDropdown ( false ) ; }
void SetSimple ( bool fToVal ) { fSimple = fToVal ; }
const StdStrBuf GetText ( ) { return StdStrBuf ( Text , false ) ; }
void SetFont ( CStdFont * pToFont ) { pUseFont = pToFont ; }
void SetColors ( uint32_t dwFontClr , uint32_t dwBGClr , uint32_t dwBorderClr )
{ this - > dwFontClr = dwFontClr ; this - > dwBGClr = dwBGClr ; this - > dwBorderClr = dwBorderClr ; }
void SetDecoration ( C4Facet * pFctSideArrow )
{ this - > pFctSideArrow = pFctSideArrow ; }
friend class ComboBox_FillCB ;
} ;
2009-05-08 13:28:41 +00:00
2010-12-11 18:50:38 +00:00
class Dialog ;
2009-05-08 13:28:41 +00:00
// EM window class
2012-04-11 02:15:33 +00:00
class DialogWindow : public C4Window
2010-03-28 17:58:21 +00:00
{
public :
2010-12-11 18:50:38 +00:00
Dialog * pDialog ;
2016-11-02 23:58:02 +00:00
DialogWindow ( ) : C4Window ( ) , pDialog ( nullptr ) { }
2011-08-27 21:12:01 +00:00
using C4Window : : Init ;
2012-04-01 20:16:59 +00:00
C4Window * Init ( C4AbstractApp * pApp , const char * Title , const C4Rect & rcBounds , const char * szID ) ;
2010-03-28 17:58:21 +00:00
virtual void Close ( ) ;
2010-12-11 18:50:38 +00:00
virtual void PerformUpdate ( ) ;
2010-03-28 17:58:21 +00:00
} ;
2009-05-08 13:28:41 +00:00
// information on how to draw dialog borders and face
class FrameDecoration
2010-03-28 17:58:21 +00:00
{
private :
int iRefCount ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
bool SetFacetByAction ( C4Def * pOfDef , class C4TargetFacet & rfctTarget , const char * szFacetName ) ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
public :
2014-10-23 21:29:14 +00:00
C4Def * pSourceDef ;
2010-03-28 17:58:21 +00:00
C4ID idSourceDef ;
uint32_t dwBackClr ; // background face color
C4TargetFacet fctTop , fctTopRight , fctRight , fctBottomRight , fctBottom , fctBottomLeft , fctLeft , fctTopLeft ;
int iBorderTop , iBorderLeft , iBorderRight , iBorderBottom ;
bool fHasGfxOutsideClientArea ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
FrameDecoration ( ) : iRefCount ( 0 ) { Clear ( ) ; }
void Clear ( ) ; // zero data
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
// create from ActMap and graphics of a definition (does some script callbacks to get parameters)
2014-08-13 09:28:22 +00:00
bool SetByDef ( C4Def * pSrcDef ) ;
bool SetByDef ( C4ID idSourceDef ) ; // a wrapper for the above method
2010-03-28 17:58:21 +00:00
bool UpdateGfx ( ) ; // update Surface, e.g. after def reload
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
void Ref ( ) { + + iRefCount ; }
void Deref ( ) { if ( ! - - iRefCount ) delete this ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
void Draw ( C4TargetFacet & cgo , C4Rect & rcDrawArea ) ; // draw deco for given rect (rect includes border)
} ;
2009-05-08 13:28:41 +00:00
// a dialog
2010-12-11 18:50:38 +00:00
class Dialog : public Window
2010-03-28 17:58:21 +00:00
{
private :
enum Fade { eFadeNone = 0 , eFadeOut , eFadeIn } ;
C4KeyBinding * pKeyAdvanceControl , * pKeyAdvanceControlB , * pKeyHotkey , * pKeyEnter , * pKeyEscape , * pKeyFocusDefControl ;
protected :
WoodenLabel * pTitle ; // title bar text
CallbackButton < Dialog , C4GUI : : IconButton > * pCloseBtn ;
Control * pActiveCtrl ; // control that has focus
bool fShow ; // if set, the dlg is shown
bool fOK ; // if set, the user pressed OK
int32_t iFade ; // dlg fade (percent)
Fade eFade ; // fading mode
bool fDelOnClose ; // auto-delete when closing
StdStrBuf TitleString ;
bool fViewportDlg ; // set in ctor: if true, dlg is not independant, but drawn ad controlled within viewports
DialogWindow * pWindow ; // window in console mode
FrameDecoration * pFrameDeco ;
bool CreateConsoleWindow ( ) ;
void DestroyConsoleWindow ( ) ;
virtual void UpdateSize ( ) ; // called when own size changed - update assigned pWindow
virtual void UpdatePos ( ) ; // Dialogs with their own windows can only be at 0/0
public :
Dialog ( int32_t iWdt , int32_t iHgt , const char * szTitle , bool fViewportDlg ) ; // ctor
virtual ~ Dialog ( ) ; // dtor
virtual void RemoveElement ( Element * pChild ) ; // clear ptr
virtual void Draw ( C4TargetFacet & cgo ) ; // render dialog (published)
virtual void DrawElement ( C4TargetFacet & cgo ) ; // draw dlg bg
virtual bool IsComponentOutsideClientArea ( ) { return ! ! pTitle ; } // pTitle lies outside client area
2016-11-02 23:58:02 +00:00
virtual const char * GetID ( ) { return nullptr ; }
2010-03-28 17:58:21 +00:00
// special handling for viewport dialogs
virtual void ApplyElementOffset ( int32_t & riX , int32_t & riY ) ;
virtual void ApplyInvElementOffset ( int32_t & riX , int32_t & riY ) ;
virtual bool IsFocused ( Control * pCtrl ) { return pCtrl = = pActiveCtrl ; }
void SetFocus ( Control * pCtrl , bool fByMouse ) ;
Control * GetFocus ( ) { return pActiveCtrl ; }
virtual Dialog * GetDlg ( ) { return this ; } // this is the dialog
2010-12-11 18:50:38 +00:00
virtual DialogWindow * GetDialogWindow ( ) { return pWindow ; }
2010-03-28 17:58:21 +00:00
virtual bool CharIn ( const char * c ) ; // input: character key pressed - should return false for none-character-inputs (forward to focused control)
private :
bool KeyHotkey ( const C4KeyCodeEx & key ) ;
bool KeyFocusDefault ( ) ;
public :
2015-09-04 02:42:29 +00:00
virtual void MouseInput ( CMouse & rMouse , int32_t iButton , int32_t iX , int32_t iY , DWORD dwKeyParam ) ; // input: mouse. forwards to child controls
2010-03-28 17:58:21 +00:00
// default control to be set if unprocessed keyboard input has been detected
2016-11-02 23:58:02 +00:00
virtual class Control * GetDefaultControl ( ) { return nullptr ; }
2010-03-28 17:58:21 +00:00
// default dlg actions for enter/escape
virtual bool OnEnter ( ) { UserClose ( true ) ; return true ; }
bool KeyEnter ( ) { return OnEnter ( ) ; }
virtual bool OnEscape ( ) { UserClose ( false ) ; return true ; }
bool KeyEscape ( ) { return OnEscape ( ) ; }
void AdvanceFocus ( bool fBackwards ) ; // change focus to next component
bool KeyAdvanceFocus ( bool fBackwards ) { AdvanceFocus ( fBackwards ) ; return true ; }
virtual int32_t GetMarginTop ( ) { return ( pTitle ? pTitle - > GetBounds ( ) . Hgt : 0 ) + ( pFrameDeco ? pFrameDeco - > iBorderTop : Window : : GetMarginTop ( ) ) ; }
virtual int32_t GetMarginLeft ( ) { return pFrameDeco ? pFrameDeco - > iBorderLeft : Window : : GetMarginLeft ( ) ; }
virtual int32_t GetMarginRight ( ) { return pFrameDeco ? pFrameDeco - > iBorderRight : Window : : GetMarginRight ( ) ; }
virtual int32_t GetMarginBottom ( ) { return pFrameDeco ? pFrameDeco - > iBorderBottom : Window : : GetMarginBottom ( ) ; }
static int32_t GetDefaultTitleHeight ( ) ;
bool IsShown ( ) { return fShow ; } // returns whether dlg is on screen (may be invisible)
bool IsOK ( ) { return fOK ; } // returns whether user pressed OK
bool IsAborted ( ) { return ! fShow & & ! fOK ; } // returns whether dialog has been aborted
bool IsActive ( bool fForKeyboard ) ; // return whether dlg has mouse control focus
bool IsFading ( ) { return eFade ! = eFadeNone ; }
virtual bool IsFullscreenDialog ( ) { return false ; }
virtual bool HasBackground ( ) { return false ; } // true if dlg draws screen background (fullscreen dialogs only)
// true for dialogs that should span the whole screen
// not just the mouse-viewport
virtual bool IsFreePlaceDialog ( ) { return false ; }
// true for dialogs that should be placed at the bottom of the screen (chat)
virtual bool IsBottomPlacementDialog ( ) { return false ; }
// true for dialogs that receive full keyboard and mouse input even in shared mode
virtual bool IsExclusiveDialog ( ) { return false ; }
// some dialogs, like menus or chat control, don't really need a mouse
// so do not enable it for those in shared mode if mouse control is disabled
virtual bool IsMouseControlled ( ) { return true ; }
// For dialogs associated to a viewport: Return viewport (for placement)
2016-11-02 23:58:02 +00:00
virtual C4Viewport * GetViewport ( ) { return nullptr ; }
2010-03-28 17:58:21 +00:00
bool IsViewportDialog ( ) { return fViewportDlg ; }
// for custom placement procedures; should call SetPos
virtual bool DoPlacement ( Screen * pOnScreen , const C4Rect & rPreferredDlgRect ) { return false ; }
// true for dialogs drawn externally
virtual bool IsExternalDrawDialog ( ) { return false ; }
// z-ordering used for dialog placement
virtual int32_t GetZOrdering ( ) { return C4GUI_Z_DEFAULT ; }
bool Show ( Screen * pOnScreen , bool fCB ) ; // show dialog on screen - default to last created screen
void Close ( bool fOK ) ; // close dlg
bool FadeIn ( Screen * pOnScreen ) ; // fade dlg into screen
void FadeOut ( bool fCloseWithOK ) ; // fade out dlg
bool DoModal ( ) ; // execute message loop until dlg is closed (or GUI destructed) - returns whether dlg was OK
bool Execute ( ) ; // execute dialog - does message handling, gfx output and idle proc; return false if dlg got closed or GUI deleted
bool Execute2 ( ) ; // execute dialog - does message handling, gfx output and idle proc; return false and deletes self if dlg got closed or GUI deleted
void SetDelOnClose ( bool fToVal = true ) { fDelOnClose = fToVal ; } // dialog will delete itself when closed
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
void SetTitle ( const char * szToTitle , bool fShowCloseButton = true ) ; // change title text; creates or removes title bar if necessary
void SetFrameDeco ( FrameDecoration * pNewDeco ) // change border decoration
{
if ( pFrameDeco ) pFrameDeco - > Deref ( ) ;
if ( ( pFrameDeco = pNewDeco ) ) pNewDeco - > Ref ( ) ;
UpdateOwnPos ( ) ; // margin may have changed; might need to reposition stuff
}
void ClearFrameDeco ( ) / / clear border decoration ; no own pos update !
2016-11-02 23:58:02 +00:00
{ if ( pFrameDeco ) pFrameDeco - > Deref ( ) ; pFrameDeco = nullptr ; }
2010-03-28 17:58:21 +00:00
FrameDecoration * GetFrameDecoration ( ) const { return pFrameDeco ; }
void SetClientSize ( int32_t iToWdt , int32_t iToHgt ) ; // resize dialog so its client area has the specified size
void OnUserClose ( C4GUI : : Control * btn ) // user presses close btn: Usually close dlg with abort
{ UserClose ( false ) ; }
virtual void UserClose ( bool fOK ) { Close ( fOK ) ; }
virtual void OnClosed ( bool fOK ) ; // callback when dlg got closed
virtual void OnShown ( ) { } // callback when shown - should not delete the dialog
virtual void OnIdle ( ) { } // idle proc in DoModal
virtual ContextHandler * GetContextHandler ( ) // always use own context handler only (no fall-through to screen)
{ return pContextHandler ; }
2009-05-08 13:28:41 +00:00
# ifdef _WIN32
2010-03-28 17:58:21 +00:00
static bool RegisterWindowClass ( HINSTANCE hInst ) ; // registers WNDCLASS for console mode dialogs
2009-05-08 13:28:41 +00:00
# endif
2010-03-28 17:58:21 +00:00
friend class Screen ;
} ;
2009-05-08 13:28:41 +00:00
// a dialog covering the whole screen (using UpperBoard-caption)
class FullscreenDialog : public Dialog
2010-03-28 17:58:21 +00:00
{
protected :
Label * pFullscreenTitle , * pSubTitle ; // subtitle to be put in upper-right corner
int32_t iDlgMarginX , iDlgMarginY ; // dialog margin set by screen size
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual const char * GetID ( ) { return 0 ; } // no ID needed, because it's never created as a window
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
public :
FullscreenDialog ( const char * szTitle , const char * szSubtitle ) ; // ctor
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
void SetTitle ( const char * szToTitle ) ; // change title text; creates or removes title bar if necessary
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
protected :
virtual void DrawElement ( C4TargetFacet & cgo ) ; // draw dlg bg
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
// fullscreen dialogs are not closed on Enter
virtual bool OnEnter ( ) { return false ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual bool IsComponentOutsideClientArea ( ) { return true ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual bool HasUpperBoard ( ) { return false ; } // standard fullscreen dialog: UpperBoard no longer present
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual bool IsFullscreenDialog ( ) { return true ; }
virtual bool DoPlacement ( Screen * pOnScreen , const C4Rect & rPreferredDlgRect ) { return true ; } // fullscreen dlg already placed
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual int32_t GetMarginTop ( ) { return ( HasUpperBoard ( ) ? C4UpperBoardHeight : C4GUI_FullscreenDlg_TitleHeight ) + iDlgMarginY ; }
virtual int32_t GetMarginLeft ( ) { return iDlgMarginX ; }
virtual int32_t GetMarginRight ( ) { return iDlgMarginX ; }
virtual int32_t GetMarginBottom ( ) { return iDlgMarginY ; }
virtual void UpdateOwnPos ( ) ; // called when element bounds were changed externally
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
// helper func: draw facet to screen background
void DrawBackground ( C4TargetFacet & cgo , C4Facet & rFromFct ) ;
} ;
2009-05-08 13:28:41 +00:00
// a button closing the Dlg
class CloseButton : public Button
2010-03-28 17:58:21 +00:00
{
protected :
bool fCloseResult ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual void OnPress ( )
{ Dialog * pDlg ; if ( ( pDlg = GetDlg ( ) ) ) pDlg - > UserClose ( fCloseResult ) ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
public :
CloseButton ( const char * szBtnText , const C4Rect & rtBounds , bool fResult ) // ctor
2009-05-08 13:28:41 +00:00
: Button ( szBtnText , rtBounds ) , fCloseResult ( fResult ) { }
2010-03-28 17:58:21 +00:00
} ;
2009-05-08 13:28:41 +00:00
class CloseIconButton : public IconButton
2010-03-28 17:58:21 +00:00
{
protected :
bool fCloseResult ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual void OnPress ( )
{ Dialog * pDlg ; if ( ( pDlg = GetDlg ( ) ) ) pDlg - > UserClose ( fCloseResult ) ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
public :
CloseIconButton ( const C4Rect & rtBounds , Icons eIcon , bool fResult ) // ctor
2009-05-08 13:28:41 +00:00
: IconButton ( eIcon , rtBounds , 0 ) , fCloseResult ( fResult ) { }
2010-03-28 17:58:21 +00:00
} ;
2009-05-08 13:28:41 +00:00
// OK button
2010-03-28 17:58:21 +00:00
class OKButton : public CloseButton
{
public : OKButton ( const C4Rect & rtBounds ) // ctor
2009-05-08 13:28:41 +00:00
: CloseButton ( LoadResStr ( " IDS_DLG_OK " ) , rtBounds , true ) { } } ;
2010-03-28 17:58:21 +00:00
class OKIconButton : public CloseIconButton
{
public : OKIconButton ( const C4Rect & rtBounds , Icons eIcon ) // ctor
2009-05-08 13:28:41 +00:00
: CloseIconButton ( rtBounds , eIcon , true ) { } } ;
// cancel button
2010-03-28 17:58:21 +00:00
class CancelButton : public CloseButton
{
public : CancelButton ( const C4Rect & rtBounds ) // ctor
2009-05-08 13:28:41 +00:00
: CloseButton ( LoadResStr ( " IDS_DLG_CANCEL " ) , rtBounds , false ) { } } ;
2010-03-28 17:58:21 +00:00
class CancelIconButton : public CloseIconButton
{
public : CancelIconButton ( const C4Rect & rtBounds , Icons eIcon ) // ctor
2009-05-08 13:28:41 +00:00
: CloseIconButton ( rtBounds , eIcon , false ) { } } ;
// regular close button
2010-03-28 17:58:21 +00:00
class DlgCloseButton : public CloseButton
{
public : DlgCloseButton ( const C4Rect & rtBounds ) // ctor
2009-05-08 13:28:41 +00:00
: CloseButton ( LoadResStr ( " IDS_DLG_CLOSE " ) , rtBounds , true ) { } } ;
// Yes button
2010-03-28 17:58:21 +00:00
class YesButton : public CloseButton
{
public : YesButton ( const C4Rect & rtBounds ) // ctor
2009-05-08 13:28:41 +00:00
: CloseButton ( LoadResStr ( " IDS_DLG_YES " ) , rtBounds , true ) { } } ;
// No button
2010-03-28 17:58:21 +00:00
class NoButton : public CloseButton
{
public : NoButton ( const C4Rect & rtBounds ) // ctor
2009-05-08 13:28:41 +00:00
: CloseButton ( LoadResStr ( " IDS_DLG_NO " ) , rtBounds , false ) { } } ;
// Retry button
2010-03-28 17:58:21 +00:00
class RetryButton : public CloseButton
{
public : RetryButton ( const C4Rect & rtBounds ) // ctor
2009-05-08 13:28:41 +00:00
: CloseButton ( LoadResStr ( " IDS_BTN_RETRY " ) , rtBounds , true ) { } } ;
2011-03-30 20:11:47 +00:00
// Reset button
class ResetButton : public CloseButton
{
public : ResetButton ( const C4Rect & rtBounds ) // ctor
2012-10-07 16:45:50 +00:00
: CloseButton ( LoadResStr ( " IDS_BTN_RESET " ) , rtBounds , true ) { } } ;
2009-05-08 13:28:41 +00:00
// a simple message dialog
class MessageDialog : public Dialog
2010-03-28 17:58:21 +00:00
{
private :
bool fHasOK ;
int32_t * piConfigDontShowAgainSetting ;
2013-09-22 14:30:55 +00:00
class C4KeyBinding * pKeyCopy ;
StdCopyStrBuf sCopyText ; // text that goes into clipboard if user presses Ctrl+C on this window
2010-03-28 17:58:21 +00:00
public :
2011-03-30 20:11:47 +00:00
enum Buttons { btnOK = 1 , btnAbort = 2 , btnYes = 4 , btnNo = 8 , btnRetry = 16 , btnReset = 32 ,
2010-03-28 17:58:21 +00:00
btnOKAbort = btnOK | btnAbort , btnYesNo = btnYes | btnNo , btnRetryAbort = btnRetry | btnAbort
} ;
enum DlgSize { dsRegular = C4GUI_MessageDlgWdt , dsMedium = C4GUI_MessageDlgWdtMedium , dsSmall = C4GUI_MessageDlgWdtSmall } ;
2016-11-02 23:58:02 +00:00
MessageDialog ( const char * szMessage , const char * szCaption , DWORD dwButtons , Icons icoIcon , DlgSize eSize = dsRegular , int32_t * piConfigDontShowAgainSetting = nullptr , bool fDefaultNo = false ) ;
2013-09-22 14:30:55 +00:00
~ MessageDialog ( ) ;
2010-03-28 17:58:21 +00:00
protected :
virtual bool OnEnter ( ) { if ( ! fHasOK ) return false ; Close ( true ) ; return true ; }
void OnDontShowAgainCheck ( C4GUI : : Element * pCheckBox )
{ if ( piConfigDontShowAgainSetting ) * piConfigDontShowAgainSetting = static_cast < C4GUI : : CheckBox * > ( pCheckBox ) - > GetChecked ( ) ; }
2013-09-22 14:30:55 +00:00
bool KeyCopy ( ) ;
2010-03-28 17:58:21 +00:00
virtual const char * GetID ( ) { return " MessageDialog " ; }
virtual int32_t GetZOrdering ( ) { return C4GUI_Z_INPUT ; }
} ;
2009-05-08 13:28:41 +00:00
// a confirmation dialog, which performs a callback after confirmation
class ConfirmationDialog : public MessageDialog
2010-03-28 17:58:21 +00:00
{
private :
BaseCallbackHandler * pCB ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
public :
ConfirmationDialog ( const char * szMessage , const char * szCaption , BaseCallbackHandler * pCB , DWORD dwButtons = MessageDialog : : btnOKAbort , bool fSmall = false , Icons icoIcon = Ico_Confirm ) ;
~ ConfirmationDialog ( ) { if ( pCB ) pCB - > DeRef ( ) ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
protected :
virtual void OnClosed ( bool fOK ) ; // callback when dlg got closed
} ;
2009-05-08 13:28:41 +00:00
// a simple progress dialog
class ProgressDialog : public Dialog
2010-03-28 17:58:21 +00:00
{
protected :
ProgressBar * pBar ; // progress bar component
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual const char * GetID ( ) { return " ProgressDialog " ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
public :
ProgressDialog ( const char * szMessage , const char * szCaption , int32_t iMaxProgress , int32_t iInitialProgress , Icons icoIcon ) ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
void SetProgress ( int32_t iToProgress ) { pBar - > SetProgress ( iToProgress ) ; } // change progress
virtual bool OnEnter ( ) { return false ; } // don't close on Enter!
} ;
2009-05-08 13:28:41 +00:00
class BaseInputCallback
2010-03-28 17:58:21 +00:00
{
public :
virtual void OnOK ( const StdStrBuf & sText ) = 0 ;
virtual ~ BaseInputCallback ( ) { }
} ;
2009-05-08 13:28:41 +00:00
template < class T > class InputCallback : public BaseInputCallback
2010-03-28 17:58:21 +00:00
{
public :
typedef void ( T : : * CBFunc ) ( const StdStrBuf & ) ;
private :
T * pTarget ;
CBFunc pCBFunc ;
public :
InputCallback ( T * pTarget , CBFunc pCBFunc ) : pTarget ( pTarget ) , pCBFunc ( pCBFunc ) { }
virtual void OnOK ( const StdStrBuf & sText ) { ( pTarget - > * pCBFunc ) ( sText ) ; }
} ;
2009-05-08 13:28:41 +00:00
// a dialog for a one-line text input; contains OK and cancel button
class InputDialog : public Dialog
2010-03-28 17:58:21 +00:00
{
protected :
Edit * pEdit ; // edit for text input
BaseInputCallback * pCB ;
C4Rect rcEditBounds ;
bool fChatLayout ;
Label * pChatLbl ;
virtual const char * GetID ( ) { return " InputDialog " ; }
public :
InputDialog ( const char * szMessage , const char * szCaption , Icons icoIcon , BaseInputCallback * pCB , bool fChatLayout = false ) ;
~ InputDialog ( ) { if ( pCB ) delete pCB ; }
virtual void OnClosed ( bool fOK ) { if ( pCB & & fOK ) pCB - > OnOK ( StdStrBuf ( pEdit - > GetText ( ) ) ) ; Dialog : : OnClosed ( fOK ) ; } // close CB
void SetMaxText ( int32_t iMaxLen ) { pEdit - > SetMaxText ( iMaxLen ) ; }
void SetInputText ( const char * szToText ) ;
const char * GetInputText ( ) { return pEdit - > GetText ( ) ; }
void SetCustomEdit ( Edit * pCustomEdit ) ;
} ;
2009-05-08 13:28:41 +00:00
// a dialog showing some information text
class InfoDialog : public Dialog , private C4ApplicationSec1Timer
2010-03-28 17:58:21 +00:00
{
private :
int32_t iScroll ; // current scroll pos; backup for text update
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
protected :
TextWindow * pTextWin ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
void CreateSubComponents ( ) ; // ctor func
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
// add text to the info window
void AddLine ( const char * szText ) ;
void AddLineFmt ( const char * szFmtString , . . . ) GNUC_FORMAT_ATTRIBUTE_O ;
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
void BeginUpdateText ( ) ; // backup scrolling and clear text window
void EndUpdateText ( ) ; // restore scroll pos; set last update time
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual void UpdateText ( ) { } ; // function to be overwritten for timed dlgs: Update window text
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual void OnSec1Timer ( ) ; // idle proc: update text if necessary
public :
InfoDialog ( const char * szCaption , int32_t iLineCount ) ; // ctor
InfoDialog ( const char * szCaption , int iLineCount , const StdStrBuf & sText ) ; // ctor - init w/o timer
2015-01-02 20:13:20 +00:00
~ InfoDialog ( ) ;
2010-03-28 17:58:21 +00:00
} ;
2009-05-08 13:28:41 +00:00
// a keyboard event that's only executed if the dialog is activated
template < class TargetClass > class DlgKeyCB : public C4KeyCB < TargetClass >
2010-03-28 17:58:21 +00:00
{
private :
typedef C4KeyCB < TargetClass > Base ;
typedef bool ( TargetClass : : * CallbackFunc ) ( ) ;
public :
2016-11-02 23:58:02 +00:00
DlgKeyCB ( TargetClass & rTarget , CallbackFunc pFuncDown , CallbackFunc pFuncUp = nullptr , CallbackFunc pFuncPressed = nullptr )
2010-03-28 17:58:21 +00:00
: Base ( rTarget , pFuncDown , pFuncUp , pFuncPressed ) { }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual bool CheckCondition ( ) { return Base : : rTarget . IsInActiveDlg ( true ) & & Base : : rTarget . IsVisible ( ) ; }
} ;
2009-05-08 13:28:41 +00:00
template < class TargetClass > class DlgKeyCBPassKey : public C4KeyCBPassKey < TargetClass >
2010-03-28 17:58:21 +00:00
{
private :
typedef C4KeyCBPassKey < TargetClass > Base ;
typedef bool ( TargetClass : : * CallbackFunc ) ( const C4KeyCodeEx & key ) ;
public :
2016-11-02 23:58:02 +00:00
DlgKeyCBPassKey ( TargetClass & rTarget , CallbackFunc pFuncDown , CallbackFunc pFuncUp = nullptr , CallbackFunc pFuncPressed = nullptr )
2010-03-28 17:58:21 +00:00
: Base ( rTarget , pFuncDown , pFuncUp , pFuncPressed ) { }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual bool CheckCondition ( ) { return Base : : rTarget . IsInActiveDlg ( true ) & & Base : : rTarget . IsVisible ( ) ; }
} ;
2009-05-08 13:28:41 +00:00
template < class TargetClass , class ParameterType > class DlgKeyCBEx : public C4KeyCBEx < TargetClass , ParameterType >
2010-03-28 17:58:21 +00:00
{
private :
typedef C4KeyCBEx < TargetClass , ParameterType > Base ;
typedef bool ( TargetClass : : * CallbackFunc ) ( ParameterType par ) ;
public :
2016-11-02 23:58:02 +00:00
DlgKeyCBEx ( TargetClass & rTarget , const ParameterType & par , CallbackFunc pFuncDown , CallbackFunc pFuncUp = nullptr , CallbackFunc pFuncPressed = nullptr )
2010-03-28 17:58:21 +00:00
: Base ( rTarget , par , pFuncDown , pFuncUp , pFuncPressed ) { }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual bool CheckCondition ( ) { return Base : : rTarget . IsInActiveDlg ( true ) & & Base : : rTarget . IsVisible ( ) ; }
} ;
2009-05-08 13:28:41 +00:00
// a keyboard event that's only executed if the control has focus
template < class TargetClass > class ControlKeyCB : public C4KeyCB < TargetClass >
2010-03-28 17:58:21 +00:00
{
private :
typedef C4KeyCB < TargetClass > Base ;
typedef bool ( TargetClass : : * CallbackFunc ) ( ) ;
public :
2016-11-02 23:58:02 +00:00
ControlKeyCB ( TargetClass & rTarget , CallbackFunc pFuncDown , CallbackFunc pFuncUp = nullptr , CallbackFunc pFuncPressed = nullptr )
2010-03-28 17:58:21 +00:00
: Base ( rTarget , pFuncDown , pFuncUp , pFuncPressed ) { }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual bool CheckCondition ( ) { return Base : : rTarget . HasDrawFocus ( ) ; }
} ;
2009-05-08 13:28:41 +00:00
template < class TargetClass , class ParameterType > class ControlKeyCBExPassKey : public C4KeyCBExPassKey < TargetClass , ParameterType >
2010-03-28 17:58:21 +00:00
{
private :
typedef C4KeyCBExPassKey < TargetClass , ParameterType > Base ;
typedef bool ( TargetClass : : * CallbackFunc ) ( const C4KeyCodeEx & key , const ParameterType & par ) ;
public :
2016-11-02 23:58:02 +00:00
ControlKeyCBExPassKey ( TargetClass & rTarget , const ParameterType & rPar , CallbackFunc pFuncDown , CallbackFunc pFuncUp = nullptr , CallbackFunc pFuncPressed = nullptr )
2010-03-28 17:58:21 +00:00
: Base ( rTarget , rPar , pFuncDown , pFuncUp , pFuncPressed ) { }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual bool CheckCondition ( ) { return Base : : rTarget . HasDrawFocus ( ) ; }
} ;
2009-05-08 13:28:41 +00:00
// key event that checks whether a control is active, but forwards to the dialog
template < class TargetClass > class ControlKeyDlgCB : public C4KeyCB < TargetClass >
2010-03-28 17:58:21 +00:00
{
private :
class Control * pCtrl ;
typedef C4KeyCB < TargetClass > Base ;
typedef bool ( TargetClass : : * CallbackFunc ) ( ) ;
public :
2016-11-02 23:58:02 +00:00
ControlKeyDlgCB ( Control * pCtrl , TargetClass & rTarget , CallbackFunc pFuncDown , CallbackFunc pFuncUp = nullptr , CallbackFunc pFuncPressed = nullptr )
2010-03-28 17:58:21 +00:00
: Base ( rTarget , pFuncDown , pFuncUp , pFuncPressed ) , pCtrl ( pCtrl ) { }
virtual bool CheckCondition ( ) { return pCtrl & & pCtrl - > IsInActiveDlg ( true ) & & pCtrl - > IsVisible ( ) ; }
} ;
2009-05-08 13:28:41 +00:00
// mouse cursor control
class CMouse
2010-03-28 17:58:21 +00:00
{
public :
int32_t x , y ; // cursor position
bool LDown , MDown , RDown ; // mouse button states
int32_t LDownX , LDownY ; // position where left button was pressed last
DWORD dwKeys ; // shift, ctrl, etc.
bool fActive ;
2013-12-07 14:27:01 +00:00
C4TimeMilliseconds tLastMovementTime ; // C4TimeMilliseconds::Now() when the mouse pos changed last
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
// whether last input was done by mouse
// set to true whenever mouse pos changes or buttons are pressed
// reset by keyboard actions to avoid tooltips where the user isn't even doing anything
bool fActiveInput ;
2009-05-08 13:28:41 +00:00
2015-12-07 02:03:54 +00:00
enum TooltipShowState
{
TTST_None = 0 , // show no tooltips
TTST_Immediate = 1 , // show only tooltips of elements that require immediate show (i.e. otherwise unlabeled buttons)
TTST_All = 2 , // show all tooltips (mouse hovered on same element for some time)
} ;
2010-03-28 17:58:21 +00:00
public :
Element * pMouseOverElement , * pPrevMouseOverElement ; // elements at mouse position (after and before processing of mouse event)
Element * pDragElement ; // element at pos where left mouse button was clicked last
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
public :
CMouse ( int32_t iX , int32_t iY ) ; // ctor
~ CMouse ( ) ; // dtor
2009-05-08 13:28:41 +00:00
2015-12-07 02:03:54 +00:00
void Draw ( C4TargetFacet & cgo , TooltipShowState draw_tool_tips ) ; // draw cursor
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
void Input ( int32_t iButton , int32_t iX , int32_t iY , DWORD dwKeyParam ) ; // process mouse input
bool IsLDown ( ) { return LDown ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
void GetLastXY ( int32_t & rX , int32_t & rY , DWORD & rdwKeys ) { rX = x ; rY = y ; rdwKeys = dwKeys ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
void ResetElements ( ) // reset MouseOver/etc.-controls
2016-11-02 23:58:02 +00:00
{ pMouseOverElement = pPrevMouseOverElement = pDragElement = nullptr ; }
2010-03-28 17:58:21 +00:00
void ReleaseElements ( ) ; // reset MouseOver/etc.-controls, doing the appropriate callbacks
void OnElementGetsInvisible ( Element * pChild ) ; // clear ptr
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
void RemoveElement ( Element * pChild ) ; // clear ptr
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
void SetOwnedMouse ( bool fToVal ) { fActive = fToVal ; }
2009-05-08 13:28:41 +00:00
2013-12-07 14:27:01 +00:00
void ResetToolTipTime ( ) { tLastMovementTime = C4TimeMilliseconds : : Now ( ) ; }
bool IsMouseStill ( ) { return C4TimeMilliseconds : : Now ( ) - tLastMovementTime > = C4GUI_ToolTipShowTime ; }
2010-03-28 17:58:21 +00:00
void ResetActiveInput ( ) { fActiveInput = false ; }
bool IsActiveInput ( ) { return fActiveInput ; }
void ReleaseButtons ( ) { LDown = RDown = MDown = false ; }
} ;
2009-05-08 13:28:41 +00:00
// the dialog client area
class Screen : public Window
2010-03-28 17:58:21 +00:00
{
public :
CMouse Mouse ;
protected :
Dialog * pActiveDlg ; // current, active dialog
ContextMenu * pContext ; // currently opened context menu (lowest submenu)
bool fExclusive ; // default true. if false, input is shared with the game
C4Rect PreferredDlgRect ; // rectangle in which dialogs should be placed
float fZoom ;
static Screen * pScreen ; // static singleton var
public :
virtual void RemoveElement ( Element * pChild ) ; // clear ptr
const C4Rect & GetPreferredDlgRect ( ) { return PreferredDlgRect ; }
protected :
using Window : : Draw ;
virtual void Draw ( C4TargetFacet & cgo , bool fDoBG ) ; // draw screen contents
virtual void ElementPosChanged ( Element * pOfElement ) ; // called when a dialog is moved
public :
void ShowDialog ( Dialog * pDlg , bool fFade ) ; // present dialog to user
void CloseDialog ( Dialog * pDlg , bool fFade ) ; // hide dialog from user
void ActivateDialog ( Dialog * pDlg ) ; // set dlg as active
void RecheckActiveDialog ( ) ;
Dialog * GetTopDialog ( ) ; // get topmost dlg
public :
2010-10-29 23:19:54 +00:00
Screen ( ) ;
~ Screen ( ) ;
void Init ( int32_t tx , int32_t ty , int32_t twdt , int32_t thgt ) ;
void Clear ( ) ;
2010-03-28 17:58:21 +00:00
2011-10-03 14:30:18 +00:00
void Render ( bool fDoBG ) ; // render to pDraw
2010-03-28 17:58:21 +00:00
void RenderMouse ( C4TargetFacet & cgo ) ; // draw mouse only
virtual Screen * GetScreen ( ) { return this ; } ; // return contained screen
static Screen * GetScreenS ( ) { return pScreen ; } // get global screen
float GetZoom ( ) const { return fZoom ; } ; // get GUI zoom
bool IsActive ( ) { return ! ! GetTopDialog ( ) ; } // return whether GUI is active
bool KeyAny ( ) ; // to be called on keystrokes; resets some tooltip-times
virtual bool CharIn ( const char * c ) ; // input: character key pressed - should return false for none-character-inputs
2015-09-04 03:04:26 +00:00
using Window : : MouseInput ;
2010-03-28 17:58:21 +00:00
bool MouseInput ( int32_t iButton , int32_t iX , int32_t iY , DWORD dwKeyParam , Dialog * pDlg , class C4Viewport * pVP ) ; // input: mouse movement or buttons; sends MouseEnter/Leave; return whether inside dialog
2010-09-29 21:58:59 +00:00
void MouseMove ( int32_t iButton , int32_t iX , int32_t iY , DWORD dwKeyParam , class C4Viewport * pVP ) ; // pVP specified for console mode viewports only
void SetMouseInGUI ( bool fInGUI , bool fByMouse ) ;
2010-03-28 17:58:21 +00:00
bool RecheckMouseInput ( ) ; // do mouse movement iusing last input flags
2016-11-02 23:58:02 +00:00
bool ShowMessage ( const char * szMessage , const char * szCaption , Icons icoIcon , int32_t * piConfigDontShowAgainSetting = nullptr ) ; // show message
2010-03-28 17:58:21 +00:00
bool ShowErrorMessage ( const char * szMessage ) ; // show message: Error caption and icon
2016-11-02 23:58:02 +00:00
bool ShowMessageModal ( const char * szMessage , const char * szCaption , DWORD dwButtons , Icons icoIcon , int32_t * piConfigDontShowAgainSetting = nullptr ) ; // show modal message dlg
2010-03-28 17:58:21 +00:00
ProgressDialog * ShowProgressDlg ( const char * szMessage , const char * szCaption , int32_t iMaxProgress = 100 , int32_t iInitialProgress = 0 , Icons icoIcon = Ico_Wait ) ; // create and show a progress dialog
bool ShowModalDlg ( Dialog * pDlg , bool fDestruct = true ) ; // show any dialog modal and destruct it afterwards
bool ShowRemoveDlg ( Dialog * pDlg ) ; // show dialog, and flag it to delete itself when closed; return immediately
void CloseAllDialogs ( bool fWithOK ) ; // close all dialogs on the screen; top dlgs first
void SetPreferredDlgRect ( const C4Rect & rtNewPref ) { PreferredDlgRect = rtNewPref ; }
2012-03-23 21:53:56 +00:00
# ifdef USE_WIN32_WINDOWS
2010-03-28 17:58:21 +00:00
Dialog * GetDialog ( HWND hWindow ) ; // get console dialog
2009-05-08 13:28:41 +00:00
# endif
2011-08-27 21:12:01 +00:00
Dialog * GetDialog ( C4Window * pWindow ) ; // get console dialog
2010-03-28 17:58:21 +00:00
void DoContext ( ContextMenu * pNewCtx , Element * pAtElement , int32_t iX , int32_t iY ) ; // open context menu (closes any other contextmenu)
void AbortContext ( bool fByUser ) { if ( pContext ) pContext - > Abort ( fByUser ) ; } // close context menu
int32_t GetContextMenuIndex ( ) { return pContext ? pContext - > GetMenuIndex ( ) : 0 ; } // get current context-menu (lowest level)
int32_t GetLastContextMenuIndex ( ) { return ContextMenu : : GetLastMenuIndex ( ) ; } // get last opened context-menu (lowest level)
bool HasContext ( ) { return ! ! pContext ; }
bool HasFullscreenDialog ( bool fIncludeFading ) ; // true if on fullscreen dialog is visible
Dialog * GetFullscreenDialog ( bool fIncludeFading ) ; // return dlg pointer to first found fullscreen dialog
// callback from C4Game from message-handling of WM_TIMER; forwards to dialog-timer
void OnSec1Timer ( ) ;
// exclusive
void SetExclusive ( bool fToState ) { fExclusive = fToState ; Mouse . SetOwnedMouse ( fExclusive ) ; UpdateMouseFocus ( ) ; }
bool IsExclusive ( ) { return fExclusive ; }
bool HasKeyboardFocus ( )
{
// always hook keyboard in exclusive mode; only on exclusive top dialogs in shared mode
if ( IsExclusive ( ) ) return true ;
Dialog * pDlg = GetTopDialog ( ) ;
return pDlg & & pDlg - > IsExclusiveDialog ( ) ;
}
bool HasMouseFocus ( ) // return whether mouse controls GUI only
{ return HasKeyboardFocus ( ) ; }
int32_t GetMouseControlledDialogCount ( ) ; // count dlgs with that flag set
void UpdateMouseFocus ( ) ; // when exclusive mode has changed: Make sure mouse clip is correct
// draw a tooltip in a box
static void DrawToolTip ( const char * szTip , C4TargetFacet & cgo , float guix , float guiy ) ;
// gamepad
void UpdateGamepadGUIControlEnabled ( ) ; // callback when gamepad gui option changed
friend class Dialog ; friend class ContextMenu ;
} ;
2009-05-08 13:28:41 +00:00
// menu handler bound to member functions of another class
template < class CBClass > class CBMenuHandler : public MenuHandler
2010-03-28 17:58:21 +00:00
{
private :
CBClass * pCBTarget ; // callback target
typename DlgCallback < CBClass > : : ContextClickFunc pCallbackFn ; // callback function
public :
// ctor
CBMenuHandler < CBClass > ( CBClass * pCBTarget , typename DlgCallback < CBClass > : : ContextClickFunc pCallbackFn , int32_t iaExtra = 0 )
2009-05-08 13:28:41 +00:00
: MenuHandler ( ) , pCBTarget ( pCBTarget ) , pCallbackFn ( pCallbackFn ) { }
2010-03-28 17:58:21 +00:00
virtual void OnOK ( Element * pTargetElement )
{
if ( ! pCBTarget /* || !pCallbackFn */ ) return ;
// do callback
( pCBTarget - > * pCallbackFn ) ( pTargetElement ) ;
}
} ;
2009-05-08 13:28:41 +00:00
// menu handler bound to member functions of another class, providing extra storage for parameters
template < class CBClass , class TEx > class CBMenuHandlerEx : public MenuHandler
2010-03-28 17:58:21 +00:00
{
private :
CBClass * pCBTarget ; // callback target
typename DlgCallbackEx < CBClass , const TEx & > : : ContextClickFunc pCallbackFn ; // callback function
TEx Extra ; // extra data
public :
// ctor
CBMenuHandlerEx < CBClass , TEx > ( CBClass * pCBTarget , typename DlgCallbackEx < CBClass , const TEx & > : : ContextClickFunc pCallbackFn , TEx aExtra )
2009-05-08 13:28:41 +00:00
: MenuHandler ( ) , pCBTarget ( pCBTarget ) , pCallbackFn ( pCallbackFn ) , Extra ( aExtra ) { }
2010-03-28 17:58:21 +00:00
CBMenuHandlerEx < CBClass , TEx > ( CBClass * pCBTarget , typename DlgCallbackEx < CBClass , const TEx & > : : ContextClickFunc pCallbackFn )
2009-05-08 13:28:41 +00:00
: MenuHandler ( ) , pCBTarget ( pCBTarget ) , pCallbackFn ( pCallbackFn ) , Extra ( ) { }
2010-03-28 17:58:21 +00:00
const TEx & GetExtra ( ) const { return Extra ; }
void SetExtra ( const TEx & e ) { Extra = e ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
virtual void OnOK ( Element * pTargetElement )
{
if ( ! pCBTarget | | ! pCallbackFn ) return ;
// do callback
( pCBTarget - > * pCallbackFn ) ( pTargetElement , Extra ) ;
}
} ;
2009-05-08 13:28:41 +00:00
// context handler bound to member functions of another class
template < class CBClass > class CBContextHandler : public ContextHandler
2010-03-28 17:58:21 +00:00
{
private :
CBClass * pCBTarget ; // callback target
typename DlgCallback < CBClass > : : ContextFunc pCallbackFn ; // callback function
public :
// ctor
CBContextHandler < CBClass > ( CBClass * pCBTarget , typename DlgCallback < CBClass > : : ContextFunc pCallbackFn )
2009-05-08 13:28:41 +00:00
: ContextHandler ( ) , pCBTarget ( pCBTarget ) , pCallbackFn ( pCallbackFn ) { }
2010-03-28 17:58:21 +00:00
virtual bool OnContext ( Element * pOnElement , int32_t iX , int32_t iY )
{
DlgCallback < CBClass > ( ) ;
if ( ! pCBTarget ) return false ;
// if (!pCallbackFn) return false;
Screen * pScreen = pOnElement - > GetScreen ( ) ;
if ( ! pScreen ) return false ;
// let CB func create context menu
ContextMenu * pNewMenu = ( pCBTarget - > * pCallbackFn ) ( pOnElement , iX , iY ) ;
if ( ! pNewMenu ) return false ;
// open it on screen
pScreen - > DoContext ( pNewMenu , pOnElement , iX , iY ) ;
// done, success
return true ;
}
virtual C4GUI : : ContextMenu * OnSubcontext ( Element * pOnElement )
{
// query directly
return ( pCBTarget - > * pCallbackFn ) ( pOnElement , 0 , 0 ) ;
}
friend class Dialog ;
} ;
2009-05-08 13:28:41 +00:00
// a helper used to align elements
class ComponentAligner
2010-03-28 17:58:21 +00:00
{
protected :
C4Rect rcClientArea ; // free client area
int32_t iMarginX , iMarginY ; // horizontal and vertical margins of components
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
static C4Rect rcTemp ; // temp rect
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
public :
ComponentAligner ( const C4Rect & rcArea , int32_t iMarginX , int32_t iMarginY , bool fZeroAreaXY = false ) // ctor
2009-05-08 13:28:41 +00:00
: rcClientArea ( rcArea ) , iMarginX ( iMarginX ) , iMarginY ( iMarginY )
2010-03-28 17:58:21 +00:00
{ if ( fZeroAreaXY ) rcClientArea . x = rcClientArea . y = 0 ; }
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
bool GetFromTop ( int32_t iHgt , int32_t iWdt , C4Rect & rcOut ) ; // get a portion from the top
bool GetFromLeft ( int32_t iWdt , int32_t iHgt , C4Rect & rcOut ) ; // get a portion from the left
bool GetFromRight ( int32_t iWdt , int32_t iHgt , C4Rect & rcOut ) ; // get a portion from the right
bool GetFromBottom ( int32_t iHgt , int32_t iWdt , C4Rect & rcOut ) ; // get a portion from the bottom
void GetAll ( C4Rect & rcOut ) ; // get remaining client area
bool GetCentered ( int32_t iWdt , int32_t iHgt , C4Rect & rcOut ) ; // get centered subregion within area
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
C4Rect & GetFromTop ( int32_t iHgt , int32_t iWdt = - 1 ) { GetFromTop ( iHgt , iWdt , rcTemp ) ; return rcTemp ; } // get a portion from the top
C4Rect & GetFromLeft ( int32_t iWdt , int32_t iHgt = - 1 ) { GetFromLeft ( iWdt , iHgt , rcTemp ) ; return rcTemp ; } // get a portion from the left
C4Rect & GetFromRight ( int32_t iWdt , int32_t iHgt = - 1 ) { GetFromRight ( iWdt , iHgt , rcTemp ) ; return rcTemp ; } // get a portion from the right
C4Rect & GetFromBottom ( int32_t iHgt , int32_t iWdt = - 1 ) { GetFromBottom ( iHgt , iWdt , rcTemp ) ; return rcTemp ; } // get a portion from the bottom
C4Rect & GetAll ( ) { GetAll ( rcTemp ) ; return rcTemp ; } // get remaining client are
C4Rect & GetCentered ( int32_t iWdt , int32_t iHgt ) { GetCentered ( iWdt , iHgt , rcTemp ) ; return rcTemp ; } // get centered subregion within area (w/o size checks)
2009-05-08 13:28:41 +00:00
2010-03-28 17:58:21 +00:00
C4Rect & GetGridCell ( int32_t iSectX , int32_t iSectXMax , int32_t iSectY , int32_t iSectYMax , int32_t iSectSizeX = - 1 , int32_t iSectSizeY = - 1 , bool fCenterPos = false , int32_t iSectNumX = 1 , int32_t iSectNumY = 1 ) ;
int32_t GetWidth ( ) const { return rcClientArea . Wdt ; }
int32_t GetHeight ( ) const { return rcClientArea . Hgt ; }
int32_t GetHMargin ( ) const { return iMarginX ; }
int32_t GetVMargin ( ) const { return iMarginY ; }
int32_t GetInnerWidth ( ) const { return rcClientArea . Wdt - 2 * iMarginX ; }
int32_t GetInnerHeight ( ) const { return rcClientArea . Hgt - 2 * iMarginY ; }
void ExpandTop ( int32_t iByHgt ) { rcClientArea . y - = iByHgt ; rcClientArea . Hgt + = iByHgt ; } // enlarge client rect
void ExpandLeft ( int32_t iByWdt ) { rcClientArea . x - = iByWdt ; rcClientArea . Wdt + = iByWdt ; } // enlarge client rect
void ExpandRight ( int32_t iByWdt ) { rcClientArea . Wdt + = iByWdt ; } // enlarge client rect
void ExpandBottom ( int32_t iByHgt ) { rcClientArea . Hgt + = iByHgt ; } // enlarge client rect
void LogIt ( const char * szName ) ;
} ;
2009-05-08 13:28:41 +00:00
// shortcut for check whether GUI is active
2010-10-30 00:08:58 +00:00
inline bool IsActive ( ) { return Screen : : GetScreenS ( ) - > IsActive ( ) ; }
inline bool IsExclusive ( ) { return Screen : : GetScreenS ( ) - > IsExclusive ( ) ; }
2009-05-08 13:28:41 +00:00
// shortcut for GUI screen size
2010-10-30 00:08:58 +00:00
inline int32_t GetScreenWdt ( ) { return Screen : : GetScreenS ( ) - > GetBounds ( ) . Wdt ; }
inline int32_t GetScreenHgt ( ) { return Screen : : GetScreenS ( ) - > GetBounds ( ) . Hgt ; }
2009-05-08 13:28:41 +00:00
// sound effect in GUI: Only if enabled
void GUISound ( const char * szSound ) ;
// Zoom
2010-10-30 00:08:58 +00:00
inline float GetZoom ( ) { return Screen : : GetScreenS ( ) - > GetZoom ( ) ; }
2010-09-29 21:58:59 +00:00
inline void MouseMove ( int32_t iButton , int32_t iX , int32_t iY , DWORD dwKeyParam , class C4Viewport * pVP ) // pVP specified for console mode viewports only
2010-10-30 00:08:58 +00:00
{ Screen : : GetScreenS ( ) - > MouseMove ( iButton , iX , iY , dwKeyParam , pVP ) ; }
2009-05-08 13:28:41 +00:00
2010-10-29 23:19:54 +00:00
extern Screen TheScreen ;
2010-03-28 17:58:21 +00:00
} // end of namespace
2009-05-08 13:28:41 +00:00
typedef C4GUI : : Screen C4GUIScreen ;
2009-06-05 16:53:56 +00:00
extern C4GUIScreen * pGUI ;
2009-05-08 13:28:41 +00:00
# endif