2013-05-02 22:21:39 +00:00
# pragma once
2013-10-23 11:55:11 +00:00
// More traditional UI framework than ui/ui.h.
2013-05-02 22:21:39 +00:00
// Still very simple to use.
// Works very similarly to Android, there's a Measure pass and a Layout pass which you don't
// really need to care about if you just use the standard containers and widgets.
2013-05-25 14:52:27 +00:00
# include <cmath>
2013-06-04 12:50:22 +00:00
# include <cstdio>
2016-10-12 09:32:24 +00:00
# include <functional>
# include <map>
2015-09-19 08:21:42 +00:00
# include <memory>
2016-10-12 09:32:24 +00:00
# include <string>
# include <vector>
2013-05-02 22:21:39 +00:00
2020-10-04 21:24:14 +00:00
# include "Common/Render/TextureAtlas.h"
2020-10-03 22:25:21 +00:00
# include "Common/Math/lin/matrix4x4.h"
# include "Common/Math/math_util.h"
# include "Common/Math/geom2d.h"
2023-05-26 16:40:13 +00:00
# include "Common/Input/KeyCodes.h"
2013-05-02 22:21:39 +00:00
2020-09-29 10:44:47 +00:00
# include "Common/Common.h"
2013-10-18 17:45:05 +00:00
# undef small
2013-07-08 10:34:39 +00:00
struct KeyInput ;
2013-05-02 22:21:39 +00:00
struct TouchInput ;
2013-08-12 21:07:27 +00:00
struct AxisInput ;
2013-05-02 22:21:39 +00:00
2020-02-29 20:51:14 +00:00
struct ImageID ;
2013-05-02 22:21:39 +00:00
class DrawBuffer ;
2013-06-08 20:41:17 +00:00
class Texture ;
2013-05-27 22:32:00 +00:00
class UIContext ;
2013-05-02 22:21:39 +00:00
2016-12-25 17:18:19 +00:00
namespace Draw {
2018-03-27 21:10:33 +00:00
class DrawContext ;
2016-12-25 19:54:37 +00:00
class Texture ;
2016-12-25 17:18:19 +00:00
}
2014-08-17 19:28:34 +00:00
2013-05-02 22:21:39 +00:00
// I don't generally like namespaces but I think we do need one for UI, so many potentially-clashing names.
namespace UI {
2013-05-25 10:40:57 +00:00
class View ;
2013-05-02 22:21:39 +00:00
enum DrawableType {
DRAW_NOTHING ,
DRAW_SOLID_COLOR ,
DRAW_4GRID ,
2013-06-08 20:41:17 +00:00
DRAW_STRETCH_IMAGE ,
2013-05-02 22:21:39 +00:00
} ;
2013-06-02 21:44:28 +00:00
enum Visibility {
V_VISIBLE ,
V_INVISIBLE , // Keeps position, not drawn or interacted with
V_GONE , // Does not participate in layout
} ;
2013-05-02 22:21:39 +00:00
struct Drawable {
2020-02-29 20:51:14 +00:00
Drawable ( ) : type ( DRAW_NOTHING ) , image ( ImageID : : invalid ( ) ) , color ( 0xFFFFFFFF ) { }
explicit Drawable ( uint32_t col ) : type ( DRAW_SOLID_COLOR ) , image ( ImageID : : invalid ( ) ) , color ( col ) { }
Drawable ( DrawableType t , ImageID img , uint32_t col = 0xFFFFFFFF ) : type ( t ) , image ( img ) , color ( col ) { }
2013-05-02 22:21:39 +00:00
DrawableType type ;
2020-02-29 20:51:14 +00:00
ImageID image ;
2013-06-08 20:41:17 +00:00
uint32_t color ;
2013-05-02 22:21:39 +00:00
} ;
struct Style {
2020-02-29 20:51:14 +00:00
Style ( ) : fgColor ( 0xFFFFFFFF ) , background ( 0xFF303030 ) , image ( ImageID : : invalid ( ) ) { }
2013-05-02 22:21:39 +00:00
uint32_t fgColor ;
2013-06-08 20:41:17 +00:00
Drawable background ;
2020-02-29 20:51:14 +00:00
ImageID image ; // where applicable.
2013-05-02 22:21:39 +00:00
} ;
2013-08-30 12:44:23 +00:00
struct FontStyle {
2021-10-16 23:47:24 +00:00
FontStyle ( ) { }
FontStyle ( FontID atlasFnt , const char * name , int size ) : atlasFont ( atlasFnt ) , fontName ( name ) , sizePts ( size ) { }
2013-08-30 12:44:23 +00:00
2021-10-16 23:47:24 +00:00
FontID atlasFont { nullptr } ;
2013-08-30 12:44:23 +00:00
// For native fonts:
std : : string fontName ;
2021-10-16 23:47:24 +00:00
int sizePts = 0 ;
int flags = 0 ;
2013-08-30 12:44:23 +00:00
} ;
2013-05-02 22:21:39 +00:00
// To use with an UI atlas.
struct Theme {
2013-08-30 12:44:23 +00:00
FontStyle uiFont ;
FontStyle uiFontSmall ;
FontStyle uiFontSmaller ;
2020-02-29 20:51:14 +00:00
ImageID checkOn ;
ImageID checkOff ;
ImageID sliderKnob ;
ImageID whiteImage ;
ImageID dropShadow4Grid ;
2013-05-25 10:40:57 +00:00
2013-06-08 20:41:17 +00:00
Style itemStyle ;
2013-05-25 14:52:27 +00:00
Style itemDownStyle ;
Style itemFocusedStyle ;
2013-08-16 14:47:25 +00:00
Style itemDisabledStyle ;
Style headerStyle ;
2017-03-26 15:57:04 +00:00
Style infoStyle ;
2013-08-14 21:29:27 +00:00
2017-03-26 15:57:04 +00:00
Style popupStyle ;
2022-02-18 20:02:07 +00:00
uint32_t backgroundColor ;
2013-05-25 10:40:57 +00:00
} ;
// The four cardinal directions should be enough, plus Prev/Next in "element order".
enum FocusDirection {
FOCUS_UP ,
FOCUS_DOWN ,
FOCUS_LEFT ,
FOCUS_RIGHT ,
FOCUS_NEXT ,
FOCUS_PREV ,
2021-08-08 20:38:19 +00:00
FOCUS_FIRST ,
FOCUS_LAST ,
FOCUS_PREV_PAGE ,
FOCUS_NEXT_PAGE ,
2013-05-02 22:21:39 +00:00
} ;
2022-11-12 18:27:19 +00:00
typedef float Size ; // can also be WRAP_CONTENT or FILL_PARENT.
static constexpr Size WRAP_CONTENT = - 1.0f ;
static constexpr Size FILL_PARENT = - 2.0f ;
2013-05-02 22:21:39 +00:00
// Gravity
enum Gravity {
G_LEFT = 0 ,
G_RIGHT = 1 ,
G_HCENTER = 2 ,
G_HORIZMASK = 3 ,
G_TOP = 0 ,
G_BOTTOM = 4 ,
G_VCENTER = 8 ,
G_TOPLEFT = G_TOP | G_LEFT ,
G_TOPRIGHT = G_TOP | G_RIGHT ,
G_BOTTOMLEFT = G_BOTTOM | G_LEFT ,
G_BOTTOMRIGHT = G_BOTTOM | G_RIGHT ,
2014-12-31 14:28:14 +00:00
G_CENTER = G_HCENTER | G_VCENTER ,
2013-05-02 22:21:39 +00:00
G_VERTMASK = 3 < < 2 ,
} ;
2021-09-28 00:42:47 +00:00
enum Borders {
BORDER_NONE = 0 ,
BORDER_TOP = 0x0001 ,
BORDER_LEFT = 0x0002 ,
BORDER_BOTTOM = 0x0004 ,
BORDER_RIGHT = 0x0008 ,
BORDER_HORIZ = BORDER_LEFT | BORDER_RIGHT ,
BORDER_VERT = BORDER_TOP | BORDER_BOTTOM ,
BORDER_ALL = BORDER_TOP | BORDER_LEFT | BORDER_BOTTOM | BORDER_RIGHT ,
} ;
enum class BorderStyle {
HEADER_FG ,
ITEM_DOWN_BG ,
} ;
2013-05-02 22:21:39 +00:00
enum Orientation {
ORIENT_HORIZONTAL ,
ORIENT_VERTICAL ,
} ;
2013-06-10 20:05:58 +00:00
inline Orientation Opposite ( Orientation o ) {
if ( o = = ORIENT_HORIZONTAL ) return ORIENT_VERTICAL ; else return ORIENT_HORIZONTAL ;
}
2013-07-15 17:56:36 +00:00
inline FocusDirection Opposite ( FocusDirection d ) {
switch ( d ) {
case FOCUS_UP : return FOCUS_DOWN ;
case FOCUS_DOWN : return FOCUS_UP ;
case FOCUS_LEFT : return FOCUS_RIGHT ;
case FOCUS_RIGHT : return FOCUS_LEFT ;
case FOCUS_PREV : return FOCUS_NEXT ;
case FOCUS_NEXT : return FOCUS_PREV ;
2021-08-08 20:38:19 +00:00
case FOCUS_FIRST : return FOCUS_LAST ;
case FOCUS_LAST : return FOCUS_FIRST ;
case FOCUS_PREV_PAGE : return FOCUS_NEXT_PAGE ;
case FOCUS_NEXT_PAGE : return FOCUS_PREV_PAGE ;
2013-07-15 17:56:36 +00:00
}
2013-07-15 22:25:08 +00:00
return d ;
2013-07-15 17:56:36 +00:00
}
2013-05-02 22:21:39 +00:00
enum MeasureSpecType {
UNSPECIFIED ,
EXACTLY ,
AT_MOST ,
} ;
2013-10-13 18:33:42 +00:00
// I hope I can find a way to simplify this one day.
2013-05-02 22:21:39 +00:00
enum EventReturn {
2013-10-13 18:33:42 +00:00
EVENT_DONE , // Return this when no other view may process this event, for example if you changed the view hierarchy
EVENT_SKIPPED , // Return this if you ignored an event
2013-10-13 18:49:10 +00:00
EVENT_CONTINUE , // Return this if it's safe to send this event to further listeners. This should normally be the default choice but often EVENT_DONE is necessary.
2013-05-02 22:21:39 +00:00
} ;
2013-07-15 15:51:12 +00:00
enum FocusFlags {
FF_LOSTFOCUS = 1 ,
FF_GOTFOCUS = 2
} ;
2016-01-23 06:40:16 +00:00
enum PersistStatus {
PERSIST_SAVE ,
PERSIST_RESTORE ,
} ;
2013-05-02 22:21:39 +00:00
2016-01-23 06:40:16 +00:00
typedef std : : vector < int > PersistBuffer ;
typedef std : : map < std : : string , UI : : PersistBuffer > PersistMap ;
class ViewGroup ;
2013-05-02 22:21:39 +00:00
struct MeasureSpec {
MeasureSpec ( MeasureSpecType t , float s = 0.0f ) : type ( t ) , size ( s ) { }
MeasureSpec ( ) : type ( UNSPECIFIED ) , size ( 0 ) { }
MeasureSpec operator - ( float amount ) {
// TODO: Check type
return MeasureSpec ( type , size - amount ) ;
}
MeasureSpecType type ;
float size ;
} ;
// Should cover all bases.
struct EventParams {
View * v ;
uint32_t a , b , x , y ;
2013-12-02 15:50:03 +00:00
float f ;
2013-06-10 20:05:58 +00:00
std : : string s ;
2013-05-02 22:21:39 +00:00
} ;
struct HandlerRegistration {
2013-06-02 12:25:57 +00:00
std : : function < EventReturn ( EventParams & ) > func ;
2013-05-02 22:21:39 +00:00
} ;
class Event {
public :
2013-06-27 14:20:18 +00:00
Event ( ) { }
2019-06-23 18:13:14 +00:00
~ Event ( ) ;
2013-05-02 22:21:39 +00:00
// Call this from input thread or whatever, it doesn't matter
2013-06-01 16:59:03 +00:00
void Trigger ( EventParams & e ) ;
2013-05-02 22:21:39 +00:00
// Call this from UI thread
2013-07-15 17:56:36 +00:00
EventReturn Dispatch ( EventParams & e ) ;
2013-05-02 22:21:39 +00:00
2013-06-09 09:18:57 +00:00
// This is suggested for use in most cases. Autobinds, allowing for neat syntax.
2013-12-06 15:44:39 +00:00
template < class T >
2013-06-09 10:40:53 +00:00
T * Handle ( T * thiz , EventReturn ( T : : * theCallback ) ( EventParams & e ) ) {
2016-10-12 09:32:24 +00:00
Add ( std : : bind ( theCallback , thiz , std : : placeholders : : _1 ) ) ;
2013-06-09 10:40:53 +00:00
return thiz ;
2013-06-04 21:53:41 +00:00
}
2013-06-09 09:18:57 +00:00
// Sometimes you have an already-bound function<>, just use this then.
2013-06-04 21:53:41 +00:00
void Add ( std : : function < EventReturn ( EventParams & ) > func ) ;
2013-06-09 09:18:57 +00:00
private :
2013-05-02 22:21:39 +00:00
std : : vector < HandlerRegistration > handlers_ ;
DISALLOW_COPY_AND_ASSIGN ( Event ) ;
} ;
struct Margins {
Margins ( ) : top ( 0 ) , bottom ( 0 ) , left ( 0 ) , right ( 0 ) { }
2013-08-19 22:34:54 +00:00
explicit Margins ( int8_t all ) : top ( all ) , bottom ( all ) , left ( all ) , right ( all ) { }
Margins ( int8_t horiz , int8_t vert ) : top ( vert ) , bottom ( vert ) , left ( horiz ) , right ( horiz ) { }
Margins ( int8_t l , int8_t t , int8_t r , int8_t b ) : top ( t ) , bottom ( b ) , left ( l ) , right ( r ) { }
2013-06-08 20:41:17 +00:00
2016-08-08 00:35:41 +00:00
int horiz ( ) const {
2016-08-07 18:56:08 +00:00
return left + right ;
}
2016-08-08 00:35:41 +00:00
int vert ( ) const {
2016-08-07 18:56:08 +00:00
return top + bottom ;
}
2022-12-07 23:01:46 +00:00
void SetAll ( float f ) {
int8_t i = ( int ) f ;
top = i ;
bottom = i ;
left = i ;
right = i ;
}
2016-08-07 18:56:08 +00:00
2013-08-19 22:34:54 +00:00
int8_t top ;
int8_t bottom ;
int8_t left ;
int8_t right ;
2013-05-02 22:21:39 +00:00
} ;
2016-08-07 18:39:15 +00:00
struct Padding {
Padding ( ) : top ( 0 ) , bottom ( 0 ) , left ( 0 ) , right ( 0 ) { }
explicit Padding ( float all ) : top ( all ) , bottom ( all ) , left ( all ) , right ( all ) { }
Padding ( float horiz , float vert ) : top ( vert ) , bottom ( vert ) , left ( horiz ) , right ( horiz ) { }
Padding ( float l , float t , float r , float b ) : top ( t ) , bottom ( b ) , left ( l ) , right ( r ) { }
2016-08-08 00:35:41 +00:00
float horiz ( ) const {
2016-08-07 18:39:15 +00:00
return left + right ;
}
2016-08-08 00:35:41 +00:00
float vert ( ) const {
2016-08-07 18:39:15 +00:00
return top + bottom ;
}
float top ;
float bottom ;
float left ;
float right ;
} ;
2013-06-09 11:01:36 +00:00
enum LayoutParamsType {
LP_PLAIN = 0 ,
LP_LINEAR = 1 ,
LP_ANCHOR = 2 ,
2021-08-29 21:10:14 +00:00
LP_GRID = 3 ,
2013-06-09 11:01:36 +00:00
} ;
2013-05-02 22:21:39 +00:00
// Need a virtual destructor so vtables are created, otherwise RTTI can't work
class LayoutParams {
public :
2013-06-09 11:01:36 +00:00
LayoutParams ( LayoutParamsType type = LP_PLAIN )
2013-06-11 18:33:41 +00:00
: width ( WRAP_CONTENT ) , height ( WRAP_CONTENT ) , type_ ( type ) { }
2013-06-09 11:01:36 +00:00
LayoutParams ( Size w , Size h , LayoutParamsType type = LP_PLAIN )
: width ( w ) , height ( h ) , type_ ( type ) { }
2013-05-02 22:21:39 +00:00
virtual ~ LayoutParams ( ) { }
Size width ;
Size height ;
2013-06-09 11:01:36 +00:00
// Fake RTTI
bool Is ( LayoutParamsType type ) const { return type_ = = type ; }
2015-12-23 04:07:37 +00:00
template < typename T >
T * As ( ) {
if ( Is ( T : : StaticType ( ) ) ) {
return static_cast < T * > ( this ) ;
}
return nullptr ;
}
template < typename T >
const T * As ( ) const {
if ( Is ( T : : StaticType ( ) ) ) {
return static_cast < const T * > ( this ) ;
}
return nullptr ;
}
static LayoutParamsType StaticType ( ) {
return LP_PLAIN ;
}
2013-06-09 11:01:36 +00:00
private :
LayoutParamsType type_ ;
2013-05-02 22:21:39 +00:00
} ;
View * GetFocusedView ( ) ;
2017-12-03 18:40:09 +00:00
class Tween ;
2017-12-10 08:17:35 +00:00
class CallbackColorTween ;
2017-12-03 18:40:09 +00:00
2013-05-02 22:21:39 +00:00
class View {
public :
2022-12-15 08:30:47 +00:00
View ( LayoutParams * layoutParams = 0 ) : layoutParams_ ( layoutParams ) {
2013-05-02 22:21:39 +00:00
if ( ! layoutParams )
layoutParams_ . reset ( new LayoutParams ( ) ) ;
}
2013-10-13 18:33:42 +00:00
virtual ~ View ( ) ;
2013-05-02 22:21:39 +00:00
// Please note that Touch is called ENTIRELY asynchronously from drawing!
// Can even be called on a different thread! This is to really minimize latency, and decouple
2013-08-27 17:43:40 +00:00
// touch response from the frame rate. Same with Key and Axis.
2015-02-02 23:10:38 +00:00
virtual bool Key ( const KeyInput & input ) { return false ; }
2022-11-27 15:15:16 +00:00
virtual bool Touch ( const TouchInput & input ) { return true ; }
2013-08-12 21:07:27 +00:00
virtual void Axis ( const AxisInput & input ) { }
2017-12-03 18:40:09 +00:00
virtual void Update ( ) ;
2013-05-02 22:21:39 +00:00
2018-03-27 21:10:33 +00:00
virtual void DeviceLost ( ) { }
virtual void DeviceRestored ( Draw : : DrawContext * draw ) { }
2015-10-31 12:43:33 +00:00
// If this view covers these coordinates, it should add itself and its children to the list.
virtual void Query ( float x , float y , std : : vector < View * > & list ) ;
2021-02-21 20:42:56 +00:00
virtual std : : string DescribeLog ( ) const ;
2021-02-22 00:38:02 +00:00
// Accessible/searchable description.
virtual std : : string DescribeText ( ) const { return " " ; }
2015-10-31 12:43:33 +00:00
2013-07-15 15:51:12 +00:00
virtual void FocusChanged ( int focusFlags ) { }
2016-01-23 09:59:25 +00:00
virtual void PersistData ( PersistStatus status , std : : string anonId , PersistMap & storage ) ;
2013-07-15 15:51:12 +00:00
2013-05-02 22:21:39 +00:00
void Move ( Bounds bounds ) {
bounds_ = bounds ;
}
2013-11-04 12:34:15 +00:00
2013-05-02 22:21:39 +00:00
// Views don't do anything here in Layout, only containers implement this.
2013-05-27 22:32:00 +00:00
virtual void Measure ( const UIContext & dc , MeasureSpec horiz , MeasureSpec vert ) ;
2013-05-02 22:21:39 +00:00
virtual void Layout ( ) { }
2013-05-27 22:32:00 +00:00
virtual void Draw ( UIContext & dc ) { }
2013-05-02 22:21:39 +00:00
virtual float GetMeasuredWidth ( ) const { return measuredWidth_ ; }
virtual float GetMeasuredHeight ( ) const { return measuredHeight_ ; }
// Override this for easy standard behaviour. No need to override Measure.
2013-05-27 22:32:00 +00:00
virtual void GetContentDimensions ( const UIContext & dc , float & w , float & h ) const ;
2016-08-07 20:34:47 +00:00
virtual void GetContentDimensionsBySpec ( const UIContext & dc , MeasureSpec horiz , MeasureSpec vert , float & w , float & h ) const ;
2013-05-02 22:21:39 +00:00
// Called when the layout is done.
void SetBounds ( Bounds bounds ) { bounds_ = bounds ; }
virtual const LayoutParams * GetLayoutParams ( ) const { return layoutParams_ . get ( ) ; }
2013-06-08 20:41:17 +00:00
virtual void ReplaceLayoutParams ( LayoutParams * newLayoutParams ) { layoutParams_ . reset ( newLayoutParams ) ; }
2013-05-02 22:21:39 +00:00
const Bounds & GetBounds ( ) const { return bounds_ ; }
2014-03-03 11:33:57 +00:00
virtual bool SetFocus ( ) ;
2013-05-26 22:54:02 +00:00
2013-05-02 22:21:39 +00:00
virtual bool CanBeFocused ( ) const { return true ; }
2013-05-27 19:39:56 +00:00
virtual bool SubviewFocused ( View * view ) { return false ; }
2015-09-17 18:29:37 +00:00
2013-05-25 10:40:57 +00:00
bool HasFocus ( ) const {
2013-05-02 22:21:39 +00:00
return GetFocusedView ( ) = = this ;
}
2020-03-22 01:33:54 +00:00
void SetEnabled ( bool enabled ) {
enabledFunc_ = nullptr ;
enabledPtr_ = nullptr ;
enabled_ = enabled ;
enabledMeansDisabled_ = false ;
}
2013-10-29 09:11:41 +00:00
bool IsEnabled ( ) const {
2020-03-22 01:33:54 +00:00
if ( enabledFunc_ )
return enabledFunc_ ( ) ! = enabledMeansDisabled_ ;
2013-10-29 09:11:41 +00:00
if ( enabledPtr_ )
2014-07-09 06:37:51 +00:00
return * enabledPtr_ ! = enabledMeansDisabled_ ;
2020-03-22 01:33:54 +00:00
return enabled_ ! = enabledMeansDisabled_ ;
}
void SetEnabledFunc ( std : : function < bool ( ) > func ) {
enabledFunc_ = func ;
enabledPtr_ = nullptr ;
enabledMeansDisabled_ = false ;
}
void SetEnabledPtr ( bool * enabled ) {
enabledFunc_ = nullptr ;
enabledPtr_ = enabled ;
enabledMeansDisabled_ = false ;
}
void SetDisabledPtr ( bool * disabled ) {
enabledFunc_ = nullptr ;
enabledPtr_ = disabled ;
enabledMeansDisabled_ = true ;
2013-10-29 09:11:41 +00:00
}
2013-06-02 21:44:28 +00:00
2016-01-23 17:12:56 +00:00
virtual void SetVisibility ( Visibility visibility ) { visibility_ = visibility ; }
2013-06-02 21:44:28 +00:00
Visibility GetVisibility ( ) const { return visibility_ ; }
2013-06-01 16:59:03 +00:00
2013-06-08 20:41:17 +00:00
const std : : string & Tag ( ) const { return tag_ ; }
void SetTag ( const std : : string & str ) { tag_ = str ; }
2013-06-09 11:01:36 +00:00
// Fake RTTI
virtual bool IsViewGroup ( ) const { return false ; }
2021-08-08 21:46:05 +00:00
virtual bool ContainsSubview ( const View * view ) const { return false ; }
2013-06-09 11:01:36 +00:00
2023-12-20 15:20:26 +00:00
virtual Point GetFocusPosition ( FocusDirection dir ) const ;
2013-07-15 17:56:36 +00:00
2017-12-03 18:40:09 +00:00
template < class T >
T * AddTween ( T * t ) {
tweens_ . push_back ( t ) ;
return t ;
}
2013-05-02 22:21:39 +00:00
protected :
// Inputs to layout
2015-09-19 08:21:42 +00:00
std : : unique_ptr < LayoutParams > layoutParams_ ;
2013-06-08 20:41:17 +00:00
std : : string tag_ ;
2022-12-15 08:30:47 +00:00
Visibility visibility_ = V_VISIBLE ;
2013-06-01 16:59:03 +00:00
2013-05-02 22:21:39 +00:00
// Results of measure pass. Set these in Measure.
2022-12-15 08:30:47 +00:00
float measuredWidth_ = 0.0f ;
float measuredHeight_ = 0.0f ;
2013-05-02 22:21:39 +00:00
// Outputs of layout. X/Y are absolute screen coordinates, hierarchy is "gone" here.
2022-12-15 08:30:47 +00:00
Bounds bounds_ { } ;
2013-05-02 22:21:39 +00:00
2017-12-03 18:40:09 +00:00
std : : vector < Tween * > tweens_ ;
2013-05-02 22:21:39 +00:00
private :
2020-03-22 01:33:54 +00:00
std : : function < bool ( ) > enabledFunc_ ;
2022-12-15 08:30:47 +00:00
bool * enabledPtr_ = nullptr ;
bool enabled_ = true ;
bool enabledMeansDisabled_ = false ;
2013-10-29 09:11:41 +00:00
2013-05-02 22:21:39 +00:00
DISALLOW_COPY_AND_ASSIGN ( View ) ;
} ;
// These don't do anything when touched.
class InertView : public View {
public :
InertView ( LayoutParams * layoutParams )
: View ( layoutParams ) { }
2015-02-02 23:10:38 +00:00
bool Key ( const KeyInput & input ) override { return false ; }
2022-11-27 15:15:16 +00:00
bool Touch ( const TouchInput & input ) override { return false ; }
2015-02-02 23:10:38 +00:00
bool CanBeFocused ( ) const override { return false ; }
2013-05-02 22:21:39 +00:00
} ;
// All these light up their background when touched, or have focus.
class Clickable : public View {
public :
2017-12-10 08:17:35 +00:00
Clickable ( LayoutParams * layoutParams ) ;
2013-05-02 22:21:39 +00:00
2015-02-02 23:10:38 +00:00
bool Key ( const KeyInput & input ) override ;
2022-11-27 15:15:16 +00:00
bool Touch ( const TouchInput & input ) override ;
2013-05-02 22:21:39 +00:00
2015-02-02 23:10:38 +00:00
void FocusChanged ( int focusFlags ) override ;
2013-07-15 15:51:12 +00:00
2013-05-02 22:21:39 +00:00
Event OnClick ;
protected :
// Internal method that fires on a click. Default behaviour is to trigger
// the event.
// Use it for checking/unchecking checkboxes, etc.
virtual void Click ( ) ;
2017-12-10 08:17:35 +00:00
void DrawBG ( UIContext & dc , const Style & style ) ;
2013-05-02 22:21:39 +00:00
2017-12-10 08:17:35 +00:00
CallbackColorTween * bgColor_ = nullptr ;
2017-12-10 20:21:57 +00:00
float bgColorLast_ = 0.0f ;
2017-12-10 08:17:35 +00:00
int downCountDown_ = 0 ;
bool dragging_ = false ;
bool down_ = false ;
2013-05-02 22:21:39 +00:00
} ;
2021-09-19 13:54:01 +00:00
// TODO: Very similar to Choice, should probably merge them.
// Right now more flexible image support though.
2013-05-02 22:21:39 +00:00
class Button : public Clickable {
public :
Button ( const std : : string & text , LayoutParams * layoutParams = 0 )
2020-02-29 20:51:14 +00:00
: Clickable ( layoutParams ) , text_ ( text ) , imageID_ ( ImageID : : invalid ( ) ) { }
2013-12-11 08:32:14 +00:00
Button ( const std : : string & text , ImageID imageID , LayoutParams * layoutParams = 0 )
: Clickable ( layoutParams ) , text_ ( text ) , imageID_ ( imageID ) { }
2013-08-27 17:43:40 +00:00
2020-08-03 09:58:55 +00:00
void Click ( ) override ;
2015-02-02 23:10:38 +00:00
void Draw ( UIContext & dc ) override ;
void GetContentDimensions ( const UIContext & dc , float & w , float & h ) const override ;
2013-06-27 14:20:18 +00:00
const std : : string & GetText ( ) const { return text_ ; }
2021-02-22 00:38:02 +00:00
std : : string DescribeText ( ) const override ;
2018-06-02 23:32:04 +00:00
void SetPadding ( int w , int h ) {
paddingW_ = w ;
paddingH_ = h ;
}
2021-01-08 19:05:43 +00:00
void SetImageID ( ImageID imageID ) {
imageID_ = imageID ;
}
2021-02-22 02:48:01 +00:00
void SetIgnoreText ( bool ignore ) {
ignoreText_ = ignore ;
}
2020-08-30 15:50:42 +00:00
// Needed an extra small button...
void SetScale ( float f ) {
scale_ = f ;
}
2013-05-02 22:21:39 +00:00
private :
Style style_ ;
std : : string text_ ;
2013-12-11 08:32:14 +00:00
ImageID imageID_ ;
2018-06-02 23:32:04 +00:00
int paddingW_ = 16 ;
int paddingH_ = 8 ;
2020-08-30 15:50:42 +00:00
float scale_ = 1.0f ;
2021-02-22 02:48:01 +00:00
bool ignoreText_ = false ;
2013-05-02 22:21:39 +00:00
} ;
2021-09-19 13:54:01 +00:00
class RadioButton : public Clickable {
public :
RadioButton ( int * value , int thisButtonValue , const std : : string & text , LayoutParams * layoutParams = 0 )
: Clickable ( layoutParams ) , value_ ( value ) , thisButtonValue_ ( thisButtonValue ) , text_ ( text ) { }
void Click ( ) override ;
void Draw ( UIContext & dc ) override ;
void GetContentDimensions ( const UIContext & dc , float & w , float & h ) const override ;
std : : string DescribeText ( ) const override ;
private :
int * value_ ;
int thisButtonValue_ ;
std : : string text_ ;
const float paddingW_ = 8 ;
const float paddingH_ = 4 ;
const float radioRadius_ = 16.0f ;
const float radioInnerRadius_ = 8.0f ;
} ;
2013-07-18 08:25:30 +00:00
class Slider : public Clickable {
public :
Slider ( int * value , int minValue , int maxValue , LayoutParams * layoutParams = 0 )
2016-09-05 23:14:01 +00:00
: Clickable ( layoutParams ) , value_ ( value ) , showPercent_ ( false ) , minValue_ ( minValue ) , maxValue_ ( maxValue ) , paddingLeft_ ( 5 ) , paddingRight_ ( 70 ) , step_ ( 1 ) , repeat_ ( - 1 ) { }
2014-05-06 03:52:10 +00:00
2014-05-06 03:39:57 +00:00
Slider ( int * value , int minValue , int maxValue , int step = 1 , LayoutParams * layoutParams = 0 )
2016-09-05 23:14:01 +00:00
: Clickable ( layoutParams ) , value_ ( value ) , showPercent_ ( false ) , minValue_ ( minValue ) , maxValue_ ( maxValue ) , paddingLeft_ ( 5 ) , paddingRight_ ( 70 ) , repeat_ ( - 1 ) {
2014-05-06 04:55:37 +00:00
step_ = step < = 0 ? 1 : step ;
2014-05-06 03:52:10 +00:00
}
2015-02-02 23:10:38 +00:00
void Draw ( UIContext & dc ) override ;
2021-02-22 00:38:02 +00:00
std : : string DescribeText ( ) const override ;
2015-02-02 23:10:38 +00:00
bool Key ( const KeyInput & input ) override ;
2022-11-27 15:15:16 +00:00
bool Touch ( const TouchInput & input ) override ;
2017-03-15 05:01:18 +00:00
void Update ( ) override ;
2015-02-02 23:10:38 +00:00
void GetContentDimensions ( const UIContext & dc , float & w , float & h ) const override ;
2013-08-20 10:48:48 +00:00
void SetShowPercent ( bool s ) { showPercent_ = s ; }
2013-12-06 14:01:34 +00:00
// OK to call this from the outside after having modified *value_
2013-07-18 08:25:30 +00:00
void Clamp ( ) ;
2015-02-02 23:10:38 +00:00
2015-11-12 18:25:11 +00:00
Event OnChange ;
2013-12-06 14:01:34 +00:00
private :
2023-05-26 16:40:13 +00:00
bool ApplyKey ( InputKeyCode keyCode ) ;
2016-09-05 23:14:01 +00:00
2013-07-18 08:25:30 +00:00
int * value_ ;
2013-08-20 10:48:48 +00:00
bool showPercent_ ;
2013-07-18 08:25:30 +00:00
int minValue_ ;
int maxValue_ ;
2013-08-20 10:48:48 +00:00
float paddingLeft_ ;
float paddingRight_ ;
2014-05-06 04:55:37 +00:00
int step_ ;
2019-06-17 22:18:40 +00:00
int repeat_ = 0 ;
2023-05-26 16:40:13 +00:00
InputKeyCode repeatCode_ = NKCODE_UNKNOWN ;
2013-07-18 08:25:30 +00:00
} ;
2013-07-20 11:54:09 +00:00
class SliderFloat : public Clickable {
public :
SliderFloat ( float * value , float minValue , float maxValue , LayoutParams * layoutParams = 0 )
2016-09-05 23:14:01 +00:00
: Clickable ( layoutParams ) , value_ ( value ) , minValue_ ( minValue ) , maxValue_ ( maxValue ) , paddingLeft_ ( 5 ) , paddingRight_ ( 70 ) , repeat_ ( - 1 ) { }
2015-02-02 23:10:38 +00:00
void Draw ( UIContext & dc ) override ;
2021-02-22 00:38:02 +00:00
std : : string DescribeText ( ) const override ;
2015-02-02 23:10:38 +00:00
bool Key ( const KeyInput & input ) override ;
2022-11-27 15:15:16 +00:00
bool Touch ( const TouchInput & input ) override ;
2017-03-15 05:01:18 +00:00
void Update ( ) override ;
2015-02-02 23:10:38 +00:00
void GetContentDimensions ( const UIContext & dc , float & w , float & h ) const override ;
2013-07-20 11:54:09 +00:00
2013-12-06 14:01:34 +00:00
// OK to call this from the outside after having modified *value_
2013-07-20 11:54:09 +00:00
void Clamp ( ) ;
2015-11-12 18:25:11 +00:00
Event OnChange ;
2013-12-06 14:01:34 +00:00
private :
2023-05-26 16:40:13 +00:00
bool ApplyKey ( InputKeyCode keyCode ) ;
2016-09-05 23:14:01 +00:00
2013-07-20 11:54:09 +00:00
float * value_ ;
float minValue_ ;
float maxValue_ ;
2013-08-20 10:48:48 +00:00
float paddingLeft_ ;
float paddingRight_ ;
2016-09-05 23:14:01 +00:00
int repeat_ ;
2023-05-26 16:40:13 +00:00
InputKeyCode repeatCode_ = NKCODE_UNKNOWN ;
2013-07-20 11:54:09 +00:00
} ;
2013-07-18 08:25:30 +00:00
2013-05-27 20:22:35 +00:00
// Basic button that modifies a bitfield based on the pressed status. Supports multitouch.
// Suitable for controller simulation (ABXY etc).
class TriggerButton : public View {
public :
2020-02-29 20:51:14 +00:00
TriggerButton ( uint32_t * bitField , uint32_t bit , ImageID imageBackground , ImageID imageForeground , LayoutParams * layoutParams )
2013-05-27 20:22:35 +00:00
: View ( layoutParams ) , down_ ( 0.0 ) , bitField_ ( bitField ) , bit_ ( bit ) , imageBackground_ ( imageBackground ) , imageForeground_ ( imageForeground ) { }
2022-11-27 15:15:16 +00:00
bool Touch ( const TouchInput & input ) override ;
2015-02-02 23:10:38 +00:00
void Draw ( UIContext & dc ) override ;
void GetContentDimensions ( const UIContext & dc , float & w , float & h ) const override ;
2013-05-27 20:22:35 +00:00
private :
int down_ ; // bitfield of pressed fingers, translates into bitField
uint32_t * bitField_ ;
uint32_t bit_ ;
2020-02-29 20:51:14 +00:00
ImageID imageBackground_ ;
ImageID imageForeground_ ;
2013-05-27 20:22:35 +00:00
} ;
// The following classes are mostly suitable as items in ListView which
// really is just a LinearLayout in a ScrollView, possibly with some special optimizations.
2013-05-25 10:40:57 +00:00
class Item : public InertView {
public :
2013-05-27 22:50:19 +00:00
Item ( LayoutParams * layoutParams ) ;
2015-02-02 23:10:38 +00:00
void GetContentDimensions ( const UIContext & dc , float & w , float & h ) const override ;
2013-05-25 10:40:57 +00:00
} ;
class ClickableItem : public Clickable {
public :
2013-05-27 22:50:19 +00:00
ClickableItem ( LayoutParams * layoutParams ) ;
2015-02-02 23:10:38 +00:00
void GetContentDimensions ( const UIContext & dc , float & w , float & h ) const override ;
2013-05-25 10:40:57 +00:00
2013-05-25 14:52:27 +00:00
// Draws the item background.
2015-02-02 23:10:38 +00:00
void Draw ( UIContext & dc ) override ;
2013-05-25 14:52:27 +00:00
} ;
2013-05-25 10:40:57 +00:00
2013-05-02 22:21:39 +00:00
// Use to trigger something or open a submenu screen.
2013-05-25 10:40:57 +00:00
class Choice : public ClickableItem {
2013-05-02 22:21:39 +00:00
public :
2017-12-10 08:17:35 +00:00
Choice ( const std : : string & text , LayoutParams * layoutParams = nullptr )
: Choice ( text , std : : string ( ) , false , layoutParams ) { }
2021-09-19 16:45:15 +00:00
Choice ( const std : : string & text , ImageID image , LayoutParams * layoutParams = nullptr )
: ClickableItem ( layoutParams ) , text_ ( text ) , image_ ( image ) { }
2017-12-10 08:17:35 +00:00
Choice ( const std : : string & text , const std : : string & smallText , bool selected = false , LayoutParams * layoutParams = nullptr )
2021-09-19 16:45:15 +00:00
: ClickableItem ( layoutParams ) , text_ ( text ) , smallText_ ( smallText ) , image_ ( ImageID : : invalid ( ) ) { }
2017-12-10 08:17:35 +00:00
Choice ( ImageID image , LayoutParams * layoutParams = nullptr )
2021-09-19 16:45:15 +00:00
: ClickableItem ( layoutParams ) , image_ ( image ) , rightIconImage_ ( ImageID : : invalid ( ) ) { }
2021-09-22 21:05:33 +00:00
Choice ( ImageID image , float imgScale , float imgRot , bool imgFlipH = false , LayoutParams * layoutParams = nullptr )
: ClickableItem ( layoutParams ) , image_ ( image ) , rightIconImage_ ( ImageID : : invalid ( ) ) , imgScale_ ( imgScale ) , imgRot_ ( imgRot ) , imgFlipH_ ( imgFlipH ) { }
2013-05-02 22:21:39 +00:00
2020-08-10 02:20:47 +00:00
void Click ( ) override ;
2016-08-08 00:35:41 +00:00
void GetContentDimensionsBySpec ( const UIContext & dc , MeasureSpec horiz , MeasureSpec vert , float & w , float & h ) const override ;
2015-02-02 23:10:38 +00:00
void Draw ( UIContext & dc ) override ;
2021-02-22 00:38:02 +00:00
std : : string DescribeText ( ) const override ;
2023-01-08 22:35:52 +00:00
void SetCentered ( bool c ) {
2013-08-30 20:42:02 +00:00
centered_ = c ;
}
2023-01-08 22:35:52 +00:00
void SetDrawTextFlags ( u32 flags ) {
drawTextFlags_ = flags ;
}
void SetIcon ( ImageID iconImage , float scale = 1.0f , float rot = 0.0f , bool flipH = false , bool keepColor = true ) {
2022-02-14 12:57:22 +00:00
rightIconKeepColor_ = keepColor ;
2021-09-22 21:05:33 +00:00
rightIconScale_ = scale ;
rightIconRot_ = rot ;
rightIconFlipH_ = flipH ;
2021-09-19 16:45:15 +00:00
rightIconImage_ = iconImage ;
2013-10-31 12:33:53 +00:00
}
2013-05-02 22:21:39 +00:00
2013-07-16 23:03:29 +00:00
protected :
2013-08-20 11:03:42 +00:00
// hackery
virtual bool IsSticky ( ) const { return false ; }
2013-05-02 22:21:39 +00:00
std : : string text_ ;
std : : string smallText_ ;
2021-09-19 16:45:15 +00:00
ImageID image_ ; // Centered if no text, on the left if text.
2021-09-22 21:05:33 +00:00
ImageID rightIconImage_ = ImageID : : invalid ( ) ; // Shows in the right.
2023-02-16 18:01:13 +00:00
float rightIconScale_ = 0.0f ;
float rightIconRot_ = 0.0f ;
bool rightIconFlipH_ = false ;
bool rightIconKeepColor_ = false ;
2016-08-07 18:39:15 +00:00
Padding textPadding_ ;
2021-09-19 16:45:15 +00:00
bool centered_ = false ;
2021-09-22 21:05:33 +00:00
float imgScale_ = 1.0f ;
float imgRot_ = 0.0f ;
bool imgFlipH_ = false ;
2023-01-08 22:35:52 +00:00
u32 drawTextFlags_ = 0 ;
2013-08-30 12:44:23 +00:00
2013-07-16 23:03:29 +00:00
private :
2021-09-19 16:45:15 +00:00
bool selected_ = false ;
2013-05-02 22:21:39 +00:00
} ;
2013-07-15 17:56:36 +00:00
// Different key handling.
class StickyChoice : public Choice {
public :
StickyChoice ( const std : : string & text , const std : : string & smallText = " " , LayoutParams * layoutParams = 0 )
2013-07-15 22:25:08 +00:00
: Choice ( text , smallText , false , layoutParams ) { }
2013-08-19 22:34:54 +00:00
StickyChoice ( ImageID buttonImage , LayoutParams * layoutParams = 0 )
: Choice ( buttonImage , layoutParams ) { }
2013-07-15 17:56:36 +00:00
2015-02-02 23:10:38 +00:00
bool Key ( const KeyInput & key ) override ;
2022-11-27 15:15:16 +00:00
bool Touch ( const TouchInput & touch ) override ;
2015-02-02 23:10:38 +00:00
void FocusChanged ( int focusFlags ) override ;
2013-12-06 15:44:39 +00:00
2013-08-17 10:06:08 +00:00
void Press ( ) { down_ = true ; dragging_ = false ; }
2013-07-15 17:56:36 +00:00
void Release ( ) { down_ = false ; dragging_ = false ; }
bool IsDown ( ) { return down_ ; }
2013-10-08 12:34:56 +00:00
2013-08-20 11:03:42 +00:00
protected :
// hackery
2015-09-17 18:29:37 +00:00
bool IsSticky ( ) const override { return true ; }
2013-07-15 17:56:36 +00:00
} ;
2013-05-25 10:40:57 +00:00
class InfoItem : public Item {
public :
2017-12-10 08:17:35 +00:00
InfoItem ( const std : : string & text , const std : : string & rightText , LayoutParams * layoutParams = nullptr ) ;
2013-05-25 10:40:57 +00:00
2015-02-02 23:10:38 +00:00
void Draw ( UIContext & dc ) override ;
2021-02-22 00:38:02 +00:00
std : : string DescribeText ( ) const override ;
2013-05-25 10:40:57 +00:00
2015-06-29 01:48:22 +00:00
// These are focusable so that long lists of them can be keyboard scrolled.
2015-04-03 09:14:21 +00:00
bool CanBeFocused ( ) const override { return true ; }
2015-07-05 16:45:23 +00:00
void SetText ( const std : : string & text ) {
text_ = text ;
}
2015-09-17 20:46:59 +00:00
const std : : string & GetText ( ) const {
return text_ ;
}
2015-07-05 16:45:23 +00:00
void SetRightText ( const std : : string & text ) {
rightText_ = text ;
}
2021-09-19 17:19:15 +00:00
void SetChoiceStyle ( bool choiceStyle ) {
choiceStyle_ = choiceStyle ;
}
2015-07-05 16:45:23 +00:00
2013-05-25 10:40:57 +00:00
private :
2017-12-10 08:17:35 +00:00
CallbackColorTween * bgColor_ = nullptr ;
CallbackColorTween * fgColor_ = nullptr ;
2013-05-25 10:40:57 +00:00
std : : string text_ ;
std : : string rightText_ ;
2021-09-19 17:19:15 +00:00
bool choiceStyle_ = false ;
2013-05-25 10:40:57 +00:00
} ;
2023-12-29 13:10:03 +00:00
class AbstractChoiceWithValueDisplay : public Choice {
public :
AbstractChoiceWithValueDisplay ( const std : : string & text , LayoutParams * layoutParams = nullptr )
: Choice ( text , layoutParams ) {
}
void Draw ( UIContext & dc ) override ;
void GetContentDimensionsBySpec ( const UIContext & dc , MeasureSpec horiz , MeasureSpec vert , float & w , float & h ) const override ;
void SetPasswordDisplay ( ) {
passwordDisplay_ = true ;
}
protected :
virtual std : : string ValueText ( ) const = 0 ;
float CalculateValueScale ( const UIContext & dc , const std : : string & valueText , float availWidth ) const ;
bool passwordDisplay_ = false ;
} ;
class ChoiceWithCallbackValueDisplay : public AbstractChoiceWithValueDisplay {
public :
ChoiceWithCallbackValueDisplay ( const std : : string & text , std : : function < std : : string ( ) > valueFunc , LayoutParams * layoutParams = nullptr )
: AbstractChoiceWithValueDisplay ( text , layoutParams ) , valueFunc_ ( valueFunc ) { }
protected :
std : : string ValueText ( ) const override {
return valueFunc_ ( ) ;
}
std : : function < std : : string ( ) > valueFunc_ ;
} ;
2013-05-25 14:52:27 +00:00
class ItemHeader : public Item {
public :
2013-08-19 22:34:54 +00:00
ItemHeader ( const std : : string & text , LayoutParams * layoutParams = 0 ) ;
2015-02-02 23:10:38 +00:00
void Draw ( UIContext & dc ) override ;
2021-02-22 00:38:02 +00:00
std : : string DescribeText ( ) const override ;
2017-12-12 08:16:05 +00:00
void GetContentDimensionsBySpec ( const UIContext & dc , MeasureSpec horiz , MeasureSpec vert , float & w , float & h ) const override ;
2015-02-02 23:10:38 +00:00
2013-05-25 14:52:27 +00:00
private :
std : : string text_ ;
} ;
2013-08-14 21:29:27 +00:00
class PopupHeader : public Item {
public :
PopupHeader ( const std : : string & text , LayoutParams * layoutParams = 0 )
: Item ( layoutParams ) , text_ ( text ) {
layoutParams_ - > width = FILL_PARENT ;
layoutParams_ - > height = 64 ;
}
2015-02-02 23:10:38 +00:00
void Draw ( UIContext & dc ) override ;
2021-02-22 00:38:02 +00:00
std : : string DescribeText ( ) const override ;
2013-08-14 21:29:27 +00:00
private :
std : : string text_ ;
} ;
2013-05-25 13:12:46 +00:00
class CheckBox : public ClickableItem {
2013-05-02 22:21:39 +00:00
public :
2022-12-07 10:12:10 +00:00
CheckBox ( bool * toggle , const std : : string & text , const std : : string & smallText = " " , LayoutParams * layoutParams = nullptr )
2013-06-08 20:41:17 +00:00
: ClickableItem ( layoutParams ) , toggle_ ( toggle ) , text_ ( text ) , smallText_ ( smallText ) {
2013-06-04 21:53:41 +00:00
OnClick . Handle ( this , & CheckBox : : OnClicked ) ;
2013-05-25 10:40:57 +00:00
}
2013-05-02 22:21:39 +00:00
2022-12-07 10:12:10 +00:00
// Image-only "checkbox", lights up instead of showing a checkmark.
CheckBox ( bool * toggle , ImageID imageID , LayoutParams * layoutParams = nullptr )
: ClickableItem ( layoutParams ) , toggle_ ( toggle ) , imageID_ ( imageID ) {
OnClick . Handle ( this , & CheckBox : : OnClicked ) ;
}
2015-02-02 23:10:38 +00:00
void Draw ( UIContext & dc ) override ;
2021-02-22 00:38:02 +00:00
std : : string DescribeText ( ) const override ;
2016-08-08 00:35:41 +00:00
void GetContentDimensions ( const UIContext & dc , float & w , float & h ) const override ;
2013-05-02 22:21:39 +00:00
2013-10-13 17:07:10 +00:00
EventReturn OnClicked ( EventParams & e ) ;
2013-10-27 05:28:16 +00:00
//allow external agents to toggle the checkbox
2019-02-03 22:02:47 +00:00
virtual void Toggle ( ) ;
virtual bool Toggled ( ) const ;
2023-07-16 15:34:56 +00:00
protected :
2013-05-25 10:40:57 +00:00
bool * toggle_ ;
2013-05-02 22:21:39 +00:00
std : : string text_ ;
std : : string smallText_ ;
2022-12-07 10:12:10 +00:00
ImageID imageID_ ;
2013-05-02 22:21:39 +00:00
} ;
2023-07-16 15:34:56 +00:00
class CollapsibleHeader : public CheckBox {
public :
CollapsibleHeader ( bool * toggle , const std : : string & text , LayoutParams * layoutParams = nullptr ) ;
void Draw ( UIContext & dc ) override ;
void GetContentDimensionsBySpec ( const UIContext & dc , MeasureSpec horiz , MeasureSpec vert , float & w , float & h ) const override ;
void GetContentDimensions ( const UIContext & dc , float & w , float & h ) const override ;
2023-07-23 09:04:42 +00:00
2023-12-20 15:20:26 +00:00
Point GetFocusPosition ( FocusDirection dir ) const override ;
2023-07-23 09:04:42 +00:00
void SetHasSubitems ( bool hasSubItems ) { hasSubItems_ = hasSubItems ; }
private :
bool hasSubItems_ = true ;
2023-07-16 15:34:56 +00:00
} ;
2019-02-03 22:02:47 +00:00
class BitCheckBox : public CheckBox {
public :
BitCheckBox ( uint32_t * bitfield , uint32_t bit , const std : : string & text , const std : : string & smallText = " " , LayoutParams * layoutParams = nullptr )
: CheckBox ( nullptr , text , smallText , layoutParams ) , bitfield_ ( bitfield ) , bit_ ( bit ) {
}
2023-01-27 08:19:29 +00:00
2023-01-28 23:25:00 +00:00
BitCheckBox ( int * bitfield , int bit , const std : : string & text , const std : : string & smallText = " " , LayoutParams * layoutParams = nullptr ) : BitCheckBox ( ( uint32_t * ) bitfield , ( uint32_t ) bit , text , smallText , layoutParams ) { }
2019-02-03 22:02:47 +00:00
void Toggle ( ) override ;
bool Toggled ( ) const override ;
private :
uint32_t * bitfield_ ;
uint32_t bit_ ;
} ;
2013-05-25 10:40:57 +00:00
// These are for generic use.
class Spacer : public InertView {
public :
Spacer ( LayoutParams * layoutParams = 0 )
2013-08-20 10:27:42 +00:00
: InertView ( layoutParams ) , size_ ( 0.0f ) { }
Spacer ( float size , LayoutParams * layoutParams = 0 )
: InertView ( layoutParams ) , size_ ( size ) { }
2015-09-17 18:29:37 +00:00
void GetContentDimensions ( const UIContext & dc , float & w , float & h ) const override {
2013-08-20 10:27:42 +00:00
w = size_ ; h = size_ ;
2013-05-25 10:40:57 +00:00
}
2023-12-11 12:56:16 +00:00
void GetContentDimensionsBySpec ( const UIContext & dc , MeasureSpec horiz , MeasureSpec vert , float & w , float & h ) const override {
if ( horiz . type = = AT_MOST | | horiz . type = = EXACTLY )
w = horiz . size ;
else
w = size_ ;
if ( vert . type = = AT_MOST | | vert . type = = EXACTLY )
h = vert . size ;
else
h = size_ ;
}
2015-02-02 23:10:38 +00:00
void Draw ( UIContext & dc ) override { }
2021-02-22 00:38:02 +00:00
std : : string DescribeText ( ) const override { return " " ; }
2013-08-20 10:27:42 +00:00
private :
2021-09-28 00:42:47 +00:00
float size_ = 0.0f ;
} ;
class BorderView : public InertView {
public :
BorderView ( Borders borderFlags , BorderStyle style , float size = 2.0f , LayoutParams * layoutParams = nullptr )
: InertView ( layoutParams ) , borderFlags_ ( borderFlags ) , style_ ( style ) , size_ ( size ) {
}
void GetContentDimensionsBySpec ( const UIContext & dc , MeasureSpec horiz , MeasureSpec vert , float & w , float & h ) const override ;
void Draw ( UIContext & dc ) override ;
std : : string DescribeText ( ) const override { return " " ; }
private :
Borders borderFlags_ ;
BorderStyle style_ ;
2013-08-20 10:27:42 +00:00
float size_ ;
2013-05-02 22:21:39 +00:00
} ;
class TextView : public InertView {
public :
2023-11-13 22:43:57 +00:00
TextView ( std : : string_view text , LayoutParams * layoutParams = 0 )
2015-09-23 15:34:16 +00:00
: InertView ( layoutParams ) , text_ ( text ) , textAlign_ ( 0 ) , textColor_ ( 0xFFFFFFFF ) , small_ ( false ) , shadow_ ( false ) , focusable_ ( false ) , clip_ ( true ) { }
2013-08-16 10:51:57 +00:00
2023-11-13 22:43:57 +00:00
TextView ( std : : string_view text , int textAlign , bool small , LayoutParams * layoutParams = 0 )
2015-09-23 15:39:52 +00:00
: InertView ( layoutParams ) , text_ ( text ) , textAlign_ ( textAlign ) , textColor_ ( 0xFFFFFFFF ) , small_ ( small ) , shadow_ ( false ) , focusable_ ( false ) , clip_ ( true ) { }
2013-05-02 22:21:39 +00:00
2016-08-07 20:34:47 +00:00
void GetContentDimensionsBySpec ( const UIContext & dc , MeasureSpec horiz , MeasureSpec vert , float & w , float & h ) const override ;
2015-02-02 23:10:38 +00:00
void Draw ( UIContext & dc ) override ;
2013-06-20 19:51:42 +00:00
void SetText ( const std : : string & text ) { text_ = text ; }
2015-09-17 20:46:59 +00:00
const std : : string & GetText ( ) const { return text_ ; }
2021-02-22 00:38:02 +00:00
std : : string DescribeText ( ) const override { return GetText ( ) ; }
2013-08-30 12:44:23 +00:00
void SetSmall ( bool small ) { small_ = small ; }
2017-03-26 15:57:04 +00:00
void SetTextColor ( uint32_t color ) { textColor_ = color ; hasTextColor_ = true ; }
2015-02-15 10:20:19 +00:00
void SetShadow ( bool shadow ) { shadow_ = shadow ; }
2015-04-03 09:14:21 +00:00
void SetFocusable ( bool focusable ) { focusable_ = focusable ; }
2015-09-23 15:34:16 +00:00
void SetClip ( bool clip ) { clip_ = clip ; }
2021-08-06 20:32:43 +00:00
void SetBullet ( bool bullet ) { bullet_ = bullet ; }
2023-01-31 20:26:12 +00:00
void SetPadding ( float pad ) { pad_ = pad ; }
2015-04-03 09:14:21 +00:00
bool CanBeFocused ( ) const override { return focusable_ ; }
2013-05-02 22:21:39 +00:00
private :
2013-06-01 16:59:03 +00:00
std : : string text_ ;
int textAlign_ ;
2015-01-05 00:19:49 +00:00
uint32_t textColor_ ;
2017-03-26 15:57:04 +00:00
bool hasTextColor_ = false ;
2013-08-30 18:18:16 +00:00
bool small_ ;
2015-02-15 10:20:19 +00:00
bool shadow_ ;
2015-04-03 09:14:21 +00:00
bool focusable_ ;
2015-09-23 15:34:16 +00:00
bool clip_ ;
2021-08-06 20:32:43 +00:00
bool bullet_ = false ;
2023-01-31 20:26:12 +00:00
float pad_ = 0.0f ;
2013-05-02 22:21:39 +00:00
} ;
2014-07-18 09:03:18 +00:00
class TextEdit : public View {
public :
2021-02-22 00:38:02 +00:00
TextEdit ( const std : : string & text , const std : : string & title , const std : : string & placeholderText , LayoutParams * layoutParams = nullptr ) ;
2017-10-24 21:05:21 +00:00
void SetText ( const std : : string & text ) { text_ = text ; scrollPos_ = 0 ; caret_ = ( int ) text_ . size ( ) ; }
2017-03-26 15:57:04 +00:00
void SetTextColor ( uint32_t color ) { textColor_ = color ; hasTextColor_ = true ; }
2014-07-18 09:03:18 +00:00
const std : : string & GetText ( ) const { return text_ ; }
2014-08-30 09:05:21 +00:00
void SetMaxLen ( size_t maxLen ) { maxLen_ = maxLen ; }
2017-11-22 21:14:06 +00:00
void SetTextAlign ( int align ) { align_ = align ; } // Only really useful for setting FLAG_DYNAMIC_ASCII
2014-07-18 09:03:18 +00:00
2023-08-23 17:01:00 +00:00
void FocusChanged ( int focusFlags ) override ;
2015-02-02 23:10:38 +00:00
void GetContentDimensions ( const UIContext & dc , float & w , float & h ) const override ;
void Draw ( UIContext & dc ) override ;
2021-02-22 00:38:02 +00:00
std : : string DescribeText ( ) const override ;
2015-02-02 23:10:38 +00:00
bool Key ( const KeyInput & key ) override ;
2022-11-27 15:15:16 +00:00
bool Touch ( const TouchInput & touch ) override ;
2014-07-18 09:03:18 +00:00
2014-11-16 15:44:07 +00:00
Event OnTextChange ;
2015-01-05 00:19:49 +00:00
Event OnEnter ;
2014-11-16 15:44:07 +00:00
2014-07-18 09:03:18 +00:00
private :
2014-07-21 09:59:05 +00:00
void InsertAtCaret ( const char * text ) ;
2014-07-18 09:03:18 +00:00
std : : string text_ ;
2021-02-22 00:38:02 +00:00
std : : string title_ ;
2014-07-22 20:16:09 +00:00
std : : string undo_ ;
2014-07-18 09:03:18 +00:00
std : : string placeholderText_ ;
2017-03-26 15:57:04 +00:00
uint32_t textColor_ ;
bool hasTextColor_ = false ;
2014-07-18 09:03:18 +00:00
int caret_ ;
2017-10-24 21:05:21 +00:00
int scrollPos_ = 0 ;
2014-08-30 09:05:21 +00:00
size_t maxLen_ ;
2017-03-26 15:57:04 +00:00
bool ctrlDown_ = false ; // TODO: Make some global mechanism for this.
2017-11-22 21:14:06 +00:00
int align_ = 0 ;
2014-07-18 09:03:18 +00:00
// TODO: Selections
} ;
2013-05-25 10:40:57 +00:00
enum ImageSizeMode {
IS_DEFAULT ,
2015-02-01 17:03:31 +00:00
IS_FIXED ,
2018-09-22 06:24:36 +00:00
IS_KEEP_ASPECT ,
2013-05-25 10:40:57 +00:00
} ;
2013-05-02 22:21:39 +00:00
class ImageView : public InertView {
public :
2021-02-22 00:38:02 +00:00
ImageView ( ImageID atlasImage , const std : : string & text , ImageSizeMode sizeMode , LayoutParams * layoutParams = 0 )
: InertView ( layoutParams ) , text_ ( text ) , atlasImage_ ( atlasImage ) , sizeMode_ ( sizeMode ) { }
2013-05-02 22:21:39 +00:00
2015-02-02 23:10:38 +00:00
void GetContentDimensions ( const UIContext & dc , float & w , float & h ) const override ;
void Draw ( UIContext & dc ) override ;
2021-02-22 00:38:02 +00:00
std : : string DescribeText ( ) const override { return text_ ; }
2013-05-02 22:21:39 +00:00
private :
2021-02-22 00:38:02 +00:00
std : : string text_ ;
2020-02-29 20:51:14 +00:00
ImageID atlasImage_ ;
2013-05-02 22:21:39 +00:00
ImageSizeMode sizeMode_ ;
} ;
2013-06-02 21:44:28 +00:00
class ProgressBar : public InertView {
public :
ProgressBar ( LayoutParams * layoutParams = 0 )
: InertView ( layoutParams ) , progress_ ( 0.0 ) { }
2015-02-02 23:10:38 +00:00
void GetContentDimensions ( const UIContext & dc , float & w , float & h ) const override ;
void Draw ( UIContext & dc ) override ;
2021-02-22 00:38:02 +00:00
std : : string DescribeText ( ) const override ;
2013-06-02 21:44:28 +00:00
2013-12-06 14:28:52 +00:00
void SetProgress ( float progress ) {
if ( progress > 1.0f ) {
progress_ = 1.0f ;
} else if ( progress < 0.0f ) {
progress_ = 0.0f ;
} else {
progress_ = progress ;
}
}
2013-06-02 21:44:28 +00:00
float GetProgress ( ) const { return progress_ ; }
private :
float progress_ ;
} ;
2018-02-08 11:02:44 +00:00
class Spinner : public InertView {
public :
2020-02-29 20:51:14 +00:00
Spinner ( const ImageID * images , int numImages , LayoutParams * layoutParams = 0 )
2018-02-08 11:02:44 +00:00
: InertView ( layoutParams ) , images_ ( images ) , numImages_ ( numImages ) {
}
void GetContentDimensions ( const UIContext & dc , float & w , float & h ) const override ;
void Draw ( UIContext & dc ) override ;
2021-02-22 00:38:02 +00:00
std : : string DescribeText ( ) const override { return " " ; }
2018-02-08 11:02:44 +00:00
void SetColor ( uint32_t color ) { color_ = color ; }
private :
2020-02-29 20:51:14 +00:00
const ImageID * images_ ;
2018-02-08 11:02:44 +00:00
int numImages_ ;
uint32_t color_ = 0xFFFFFFFF ;
} ;
2013-05-02 22:21:39 +00:00
void MeasureBySpec ( Size sz , float contentWidth , MeasureSpec spec , float * measured ) ;
2023-07-07 13:23:19 +00:00
void ApplyBoundsBySpec ( Bounds & bounds , MeasureSpec horiz , MeasureSpec vert ) ;
2013-05-02 22:21:39 +00:00
2015-08-28 18:51:33 +00:00
bool IsDPadKey ( const KeyInput & key ) ;
2015-08-28 15:05:11 +00:00
bool IsAcceptKey ( const KeyInput & key ) ;
bool IsEscapeKey ( const KeyInput & key ) ;
2023-11-13 11:32:31 +00:00
bool IsInfoKey ( const KeyInput & key ) ;
2015-08-28 15:05:11 +00:00
bool IsTabLeftKey ( const KeyInput & key ) ;
bool IsTabRightKey ( const KeyInput & key ) ;
2013-06-27 14:20:18 +00:00
2013-06-02 03:06:40 +00:00
} // namespace