| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158 |
- // ================================================================================
- // == This file is a part of Turbo Badger. (C) 2011-2014, Emil Segerås ==
- // == See tb_core.h for more information. ==
- // ================================================================================
- #ifndef TB_WIDGETS_H
- #define TB_WIDGETS_H
- #include "tb_core.h"
- #include "tb_geometry.h"
- #include "tb_skin.h"
- #include "tb_linklist.h"
- #include "tb_widget_value.h"
- #include "tb_object.h"
- #include "tb_font_desc.h"
- namespace tb {
- class TBWindow;
- class TBWidget;
- class TBFontFace;
- class TBScroller;
- class TBWidgetListener;
- class TBLongClickTimer;
- struct INFLATE_INFO;
- // == Generic widget stuff =================================================
- enum TB_ALIGN {
- TB_ALIGN_LEFT, ///< Align to the left side
- TB_ALIGN_TOP, ///< Align to the top (above)
- TB_ALIGN_RIGHT, ///< Align to the right side
- TB_ALIGN_BOTTOM ///< Align to the bottom (below)
- };
- enum EVENT_TYPE {
- /** Click event is what should be used to trig actions in almost all cases.
- It is invoked on a widget after POINTER_UP if the pointer is still inside
- its hit area. It can also be invoked by keyboard on some clickable widgets
- (see TBWidget::SetClickByKey).
- If panning of scrollable widgets start while the pointer is down, CLICK
- won't be invoked when releasing the pointer (since that should stop panning). */
- EVENT_TYPE_CLICK,
- /** Long click event is sent when the pointer has been down for some time
- without moving much.
- It is invoked on a widget that has enabled it (TBWidget::SetWantLongClick
- If this event isn't handled, the widget will invoke a CONTEXT_MENU event.
- If any of those are handled, the CLICK event that would normally be
- invoked after the pending POINTER_UP will be suppressed. */
- EVENT_TYPE_LONG_CLICK,
- EVENT_TYPE_POINTER_DOWN,
- EVENT_TYPE_POINTER_UP,
- EVENT_TYPE_POINTER_MOVE,
- EVENT_TYPE_RIGHT_POINTER_DOWN,
- EVENT_TYPE_RIGHT_POINTER_UP,
- EVENT_TYPE_WHEEL,
- /** Invoked after changing text in a TBTextField, changing selected item
- in a TBSelectList etc. Invoking this event trigs synchronization with
- connected TBWidgetValue and other widgets connected to it. */
- EVENT_TYPE_CHANGED,
- EVENT_TYPE_KEY_DOWN,
- EVENT_TYPE_KEY_UP,
- /** Invoked by the platform when a standard keyboard shortcut is pressed.
- It's called before InvokeKeyDown (EVENT_TYPE_KEY_DOWN) and if the event
- is handled (returns true), the KeyDown is canceled.
- The ref_id will be set to one of the following:
- "cut", "copy", "paste", "selectall", "undo", "redo", "new", "open", "save". */
- EVENT_TYPE_SHORTCUT,
- /** Invoked when a context menu should be opened at the event x and y coordinates.
- It may be invoked automatically for a widget on long click, if nothing handles
- the long click event. */
- EVENT_TYPE_CONTEXT_MENU,
- /** Invoked by the platform when one or multiple files has been dropped on
- the widget. The event is guaranteed to be a TBWidgetEventFileDrop. */
- EVENT_TYPE_FILE_DROP,
- /** Invoked by the platform when a tab container's tab changed */
- EVENT_TYPE_TAB_CHANGED,
- /** Custom event. Not used internally. ref_id may be used for additional type info. */
- EVENT_TYPE_CUSTOM,
-
- /** Turbobadger implementation for touch events */
- EVENT_TYPE_TOUCH_DOWN,
- EVENT_TYPE_TOUCH_UP,
- EVENT_TYPE_TOUCH_MOVE,
- EVENT_TYPE_TOUCH_CANCEL
- };
- enum MODIFIER_KEYS {
- TB_MODIFIER_NONE = 0,
- TB_CTRL = 1,
- TB_SHIFT = 2,
- TB_ALT = 4,
- TB_SUPER = 8
- };
- MAKE_ENUM_FLAG_COMBO(MODIFIER_KEYS);
- enum SPECIAL_KEY
- {
- TB_KEY_UNDEFINED = 0,
- TB_KEY_UP, TB_KEY_DOWN, TB_KEY_LEFT, TB_KEY_RIGHT,
- TB_KEY_PAGE_UP, TB_KEY_PAGE_DOWN, TB_KEY_HOME, TB_KEY_END,
- TB_KEY_TAB, TB_KEY_BACKSPACE, TB_KEY_INSERT, TB_KEY_DELETE,
- TB_KEY_ENTER, TB_KEY_ESC,
- TB_KEY_F1, TB_KEY_F2, TB_KEY_F3, TB_KEY_F4, TB_KEY_F5, TB_KEY_F6,
- TB_KEY_F7, TB_KEY_F8, TB_KEY_F9, TB_KEY_F10, TB_KEY_F11, TB_KEY_F12
- };
- class TBWidgetEvent : public TBTypedObject
- {
- public:
- TBWidget *target; ///< The widget that invoked the event
- EVENT_TYPE type; ///< Which type of event
- int target_x; ///< X position in target widget. Set for all pointer events, click and wheel.
- int target_y; ///< Y position in target widget. Set for all pointer events, click and wheel.
- int delta_x; ///< Set for EVENT_TYPE_WHEEL. Positive is a turn right.
- int delta_y; ///< Set for EVENT_TYPE_WHEEL. Positive is a turn against the user.
- int count; ///< 1 for all events, but increased for POINTER_DOWN event to 2 for doubleclick, 3 for tripleclick and so on.
- int key;
- SPECIAL_KEY special_key;
- MODIFIER_KEYS modifierkeys;
- TBID ref_id; ///< Sometimes (when documented) events have a ref_id (The id that caused this event)
- bool touch; ///< Set for pointer events. True if the event is a touch event (finger or pen on screen)
- ///< False if mouse or other cursor input.
- TBOBJECT_SUBCLASS(TBWidgetEvent, TBTypedObject);
- TBWidgetEvent(EVENT_TYPE type) : target(nullptr), type(type), target_x(0), target_y(0), delta_x(0), delta_y(0), count(1),
- key(0), special_key(TB_KEY_UNDEFINED), modifierkeys(TB_MODIFIER_NONE), touch(false) {}
- TBWidgetEvent(EVENT_TYPE type, int x, int y, bool touch, MODIFIER_KEYS modifierkeys = TB_MODIFIER_NONE) :
- target(nullptr), type(type), target_x(x), target_y(y), delta_x(0), delta_y(0),
- count(1), key(0), special_key(TB_KEY_UNDEFINED), modifierkeys(modifierkeys),
- touch(touch) {}
- /** The count value may be 1 to infinity. If you f.ex want to see which count it is for something
- handling click and double click, call GetCountCycle(2). If you also handle triple click, call
- GetCountCycle(3) and so on. That way you'll get a count that always cycle in the range you need. */
- int GetCountCycle(int max) { return ((count - 1) % max) + 1; }
- bool IsPointerEvent() const { return type == EVENT_TYPE_POINTER_DOWN ||
- type == EVENT_TYPE_POINTER_UP ||
- type == EVENT_TYPE_POINTER_MOVE; }
- bool IsTouchEvent() const { return type == EVENT_TYPE_TOUCH_DOWN ||
- type == EVENT_TYPE_TOUCH_UP ||
- type == EVENT_TYPE_TOUCH_MOVE ||
- type == EVENT_TYPE_TOUCH_CANCEL; }
- bool IsKeyEvent() const { return type == EVENT_TYPE_KEY_DOWN ||
- type == EVENT_TYPE_KEY_UP; }
- };
- /** TBWidgetEventFileDrop is a event of type EVENT_TYPE_FILE_DROP.
- It contains a list of filenames of the files that was dropped. */
- class TBWidgetEventFileDrop : public TBWidgetEvent
- {
- public:
- TBListAutoDeleteOf<TBStr> files;
- TBOBJECT_SUBCLASS(TBWidgetEventFileDrop, TBWidgetEvent);
- TBWidgetEventFileDrop() : TBWidgetEvent(EVENT_TYPE_FILE_DROP) {}
- };
- /** TBWidget state types (may be combined).
- NOTE: This should exactly match SKIN_STATE in tb_skin.h! */
- enum WIDGET_STATE {
- WIDGET_STATE_NONE = 0,
- WIDGET_STATE_DISABLED = 1,
- WIDGET_STATE_FOCUSED = 2,
- WIDGET_STATE_PRESSED = 4,
- WIDGET_STATE_SELECTED = 8,
- WIDGET_STATE_HOVERED = 16,
- WIDGET_STATE_ALL = WIDGET_STATE_DISABLED |
- WIDGET_STATE_FOCUSED |
- WIDGET_STATE_PRESSED |
- WIDGET_STATE_SELECTED |
- WIDGET_STATE_HOVERED
- };
- MAKE_ENUM_FLAG_COMBO(WIDGET_STATE);
- /** TBWidget gravity (may be combined).
- Gravity gives hints about positioning and sizing preferences. */
- enum WIDGET_GRAVITY {
- WIDGET_GRAVITY_NONE = 0,
- WIDGET_GRAVITY_LEFT = 1,
- WIDGET_GRAVITY_RIGHT = 2,
- WIDGET_GRAVITY_TOP = 4,
- WIDGET_GRAVITY_BOTTOM = 8,
- WIDGET_GRAVITY_LEFT_RIGHT = WIDGET_GRAVITY_LEFT | WIDGET_GRAVITY_RIGHT,
- WIDGET_GRAVITY_TOP_BOTTOM = WIDGET_GRAVITY_TOP | WIDGET_GRAVITY_BOTTOM,
- WIDGET_GRAVITY_ALL = WIDGET_GRAVITY_LEFT_RIGHT | WIDGET_GRAVITY_TOP_BOTTOM,
- WIDGET_GRAVITY_DEFAULT = WIDGET_GRAVITY_LEFT | WIDGET_GRAVITY_TOP
- };
- MAKE_ENUM_FLAG_COMBO(WIDGET_GRAVITY);
- enum AXIS {
- AXIS_X, ///< Horizontal layout
- AXIS_Y, ///< Vertical layout
- };
- /** Defines how the size in one axis depend on the other axis when a widgets size is
- affected by constraints. */
- enum SIZE_DEP {
- /** No dependency (Faster layout). */
- SIZE_DEP_NONE = 0,
- /** The width is dependant on the height. Additional layout pass may be required. */
- SIZE_DEP_WIDTH_DEPEND_ON_HEIGHT = 1,
- /** The height is dependant on the width. Additional layout pass may be required. */
- SIZE_DEP_HEIGHT_DEPEND_ON_WIDTH = 2,
- /** Both width and height are dependant on each other. Additional layout pass may
- be required. */
- SIZE_DEP_BOTH = SIZE_DEP_WIDTH_DEPEND_ON_HEIGHT |
- SIZE_DEP_HEIGHT_DEPEND_ON_WIDTH
- };
- MAKE_ENUM_FLAG_COMBO(SIZE_DEP);
- /** PreferredSize contains size preferences for a TBWidget.
- This is calculated during layout for each widget from
- the current skin, widget preferences and LayoutParams. */
- class PreferredSize
- {
- public:
- PreferredSize() : min_w(0), min_h(0)
- , max_w(10000), max_h(10000)
- , pref_w(0), pref_h(0)
- , size_dependency(SIZE_DEP_NONE) {}
- PreferredSize(int w, int h) : min_w(w), min_h(h)
- , max_w(w), max_h(h)
- , pref_w(w), pref_h(h)
- , size_dependency(SIZE_DEP_NONE) {}
- int min_w, min_h; ///< The minimal preferred width and height.
- int max_w, max_h; ///< The maximum preferred width and height.
- int pref_w, pref_h; ///< The preferred width and height.
- SIZE_DEP size_dependency; ///< The size dependency when size is affected by constraints.
- };
- /** LayoutParams defines size preferences for a TBWidget that
- are set on the widget to override size preferences from
- skin and widget. */
- class LayoutParams
- {
- public:
- static const int UNSPECIFIED = TB_INVALID_DIMENSION;
- LayoutParams() : min_w(UNSPECIFIED), min_h(UNSPECIFIED)
- , max_w(UNSPECIFIED), max_h(UNSPECIFIED)
- , pref_w(UNSPECIFIED), pref_h(UNSPECIFIED) {}
- /** Set both min max and preferred width to the given width. */
- void SetWidth(int width) { min_w = max_w = pref_w = width; }
- /** Set both min max and preferred height to the given height. */
- void SetHeight(int height) { min_h = max_h = pref_h = height; }
- int min_w, min_h; ///< The minimal preferred width and height.
- int max_w, max_h; ///< The maximum preferred width and height.
- int pref_w, pref_h; ///< The preferred width and height.
- };
- /** Specifies size constraints used during size calculations. */
- class SizeConstraints
- {
- public:
- static const int NO_RESTRICTION = 10000;
- /** The available width and height. May be NO_RESTRICTION which is a large value. */
- int available_w, available_h;
- /** Constrain to the given width and height. */
- SizeConstraints(int w, int h) : available_w(w), available_h(h) {}
- /** No constraints. */
- SizeConstraints() : available_w(NO_RESTRICTION), available_h(NO_RESTRICTION) {}
- /** Return new constraints reduced by the given padding. */
- SizeConstraints ConstrainByPadding(int horizontal_padding, int vertical_padding) const
- {
- return SizeConstraints(available_w == NO_RESTRICTION ? NO_RESTRICTION : available_w - horizontal_padding,
- available_h == NO_RESTRICTION ? NO_RESTRICTION : available_h - vertical_padding);
- }
- /** Return new constraints that are constrained by LayoutParams. */
- SizeConstraints ConstrainByLayoutParams(const LayoutParams &lp) const
- {
- return SizeConstraints(ConstrainByLPMax(available_w, lp.min_w, lp.max_w),
- ConstrainByLPMax(available_h, lp.min_h, lp.max_h));
- }
- bool operator == (const SizeConstraints &sc) const { return available_w == sc.available_w &&
- available_h == sc.available_h; }
- private:
- int ConstrainByLPMax(int constraint, int lp_min, int lp_max) const
- {
- if (constraint == NO_RESTRICTION)
- return lp_max != LayoutParams::UNSPECIFIED ? lp_max : NO_RESTRICTION;
- int ret = constraint;
- if (lp_min != LayoutParams::UNSPECIFIED)
- ret = MAX(ret, lp_min);
- if (lp_max != LayoutParams::UNSPECIFIED)
- ret = MIN(ret, lp_max);
- return ret;
- }
- };
- /** Defines widget z level, used with TBWidget::SetZ, TBWidget::AddChild. */
- enum WIDGET_Z {
- WIDGET_Z_TOP, ///< The toplevel (Visually drawn on top of everything else).
- WIDGET_Z_BOTTOM ///< The bottomlevel (Visually drawn behind everything else).
- };
- /** Defines widget z level relative to another widget, used with TBWidget::AddChildRelative. */
- enum WIDGET_Z_REL {
- WIDGET_Z_REL_BEFORE, ///< Before the reference widget (visually behind reference).
- WIDGET_Z_REL_AFTER ///< After the reference widget (visually above reference).
- };
- /** Defines widget visibility, used with TBWidget::SetVisibility. */
- enum WIDGET_VISIBILITY {
- WIDGET_VISIBILITY_VISIBLE, ///< Visible (default)
- WIDGET_VISIBILITY_INVISIBLE, ///< Invisible, but layouted. Interaction disabled.
- WIDGET_VISIBILITY_GONE ///< Invisible and no layout. Interaction disabled.
- };
- enum WIDGET_INVOKE_INFO {
- WIDGET_INVOKE_INFO_NORMAL,
- WIDGET_INVOKE_INFO_NO_CALLBACKS
- };
- enum WIDGET_FOCUS_REASON {
- WIDGET_FOCUS_REASON_NAVIGATION, ///< Set focus by navigation (i.e. keyboard tab). This will
- ///< scroll to the widget if needed.
- WIDGET_FOCUS_REASON_POINTER, ///< Set focus by pointer (i.e. clicking)
- WIDGET_FOCUS_REASON_UNKNOWN ///< Set focus by anything else.
- };
- /** Hit status return value for TBWidget::GetHitStatus */
- enum WIDGET_HIT_STATUS {
- WIDGET_HIT_STATUS_NO_HIT = 0, ///< The widget was not hit
- WIDGET_HIT_STATUS_HIT, ///< The widget was hit, any child may be hit too.
- WIDGET_HIT_STATUS_HIT_NO_CHILDREN ///< The widget was hit, no children should be hit.
- };
- // ATOMIC BEGIN: this must only be used by UIWidget, as we are casting to it
- class TBWidgetDelegate
- {
- public:
- virtual bool OnEvent(const TBWidgetEvent &ev) = 0;
- virtual void OnFocusChanged(bool focused) = 0;
- virtual void OnDelete() = 0;
- virtual void OnResized(int old_w, int old_h) = 0;
- };
- // ATOMIC END
- /** The base TBWidget class.
- Make a subclass to implement UI controls.
- Each widget has a background skin (no skin specified by default) which will be used to
- calculate the default size preferences and padding around the preferred content size.
- Note: When you subclass a widget, use the TBOBJECT_SUBCLASS macro to define the type
- casting functions instead of implementing those manually. */
- class TBWidget : public TBTypedObject, public TBLinkOf<TBWidget>
- {
- public:
- // For safe typecasting
- TBOBJECT_SUBCLASS(TBWidget, TBTypedObject);
- TBWidget();
- virtual ~TBWidget();
- /** Set the rect for this widget in its parent. The rect is relative to the parent widget.
- The skin may expand outside this rect to draw f.ex shadows. */
- void SetRect(const TBRect &rect);
- inline TBRect GetRect() const { return m_rect; }
- /** Set position of this widget in its parent. The position is relative to the parent widget. */
- void SetPosition(const TBPoint &pos) { SetRect(TBRect(pos.x, pos.y, m_rect.w, m_rect.h)); }
- /** Set size of this widget. */
- void SetSize(int width, int height) { SetRect(TBRect(m_rect.x, m_rect.y, width, height)); }
- /** Invalidate should be called if the widget need to be repainted,
- to make sure the renderer repaints it and its children next frame. */
- void Invalidate();
- /** Call if something changes that might need other widgets to update their state.
- F.ex if a action availability changes, some widget might have to become enabled/disabled.
- Calling this will result in a later call to OnProcessStates().
- This is done automatically for all invoked events of type:
- EVENT_TYPE_CLICK, EVENT_TYPE_LONG_CLICK, EVENT_TYPE_CHANGED, EVENT_TYPE_KEYDOWN,
- EVENT_TYPE_KEYUP. */
- void InvalidateStates();
- /** Call if something changes that might cause any skin to change due to different state
- or conditions. This is called automatically from InvalidateStates(), when event
- EVENT_TYPE_CHANGED is invoked, and in various other situations. */
- void InvalidateSkinStates();
- /** Delete the widget with the possibility for some extended life during animations.
- If any widget listener responds true to OnWidgetDying it will be kept as a child and live
- until the animations are done, but the widgets and all its children are marked as dying.
- Dying widgets get no input or focus.
- If no widget listener responded, it will be deleted immediately. */
- void Die();
- /** Return true if this widget or any of its parents is dying. */
- bool GetIsDying() const { return m_packed.is_dying || (m_parent && m_parent->GetIsDying()); }
- /** Set the id reference for this widgets. This id is 0 by default.
- You can use this id to receive the widget from GetWidgetByID (or
- preferable TBSafeGetByID to avoid dangerous casts). */
- void SetID(const TBID &id);
- TBID &GetID() { return m_id; }
- /** Set the group id reference for this widgets. This id is 0 by default.
- All widgets with the same group id under the same group root will
- be automatically changed when one change its value. */
- void SetGroupID(const TBID &id) { m_group_id = id; }
- TBID &GetGroupID() { return m_group_id; }
- /** Get this widget or any child widget with a matching id, or nullptr if none is found. */
- TBWidget *GetWidgetByID(const TBID &id) { return GetWidgetByIDInternal(id); }
- /** Get this widget or any child widget with a matching id and type, or nullptr if none is found. */
- template<class T> T *GetWidgetByIDAndType(const TBID &id)
- { return (T*) GetWidgetByIDInternal(id, GetTypeId<T>()); }
- /** Enable or disable the given state(s). The state affects which skin state is used when drawing.
- Some states are set automatically on interaction. See GetAutoState(). */
- void SetState(WIDGET_STATE state, bool on);
- /** Get status of the given state(s). Returns true if the given state combination is set. */
- bool GetState(WIDGET_STATE state) const { return (m_state & state) ? true : false; }
- /** Set the widget state. Like SetState but setting the entire state as given, instead
- of toggling individual states. See SetState for more info on states. */
- void SetStateRaw(WIDGET_STATE state);
- /** Get the widget state. */
- WIDGET_STATE GetStateRaw() const { return m_state; }
- /** Return the current combined state for this widget. It will also add some
- automatic states, such as hovered (if the widget is currently hovered), or pressed etc.
- Automatic states: WIDGET_STATE_PRESSED, WIDGET_STATE_HOVERED, WIDGET_STATE_FOCUSED.
- Remarks for WIDGET_STATE_FOCUSED: May also be controlled by calling SetAutoFocusState and
- the define TB_ALWAYS_SHOW_EDIT_FOCUS. */
- WIDGET_STATE GetAutoState() const;
- /** Set if the state WIDGET_STATE_FOCUSED should be set automatically for the focused widget.
- This value is set to true when moving focus by keyboard, and set to off when clicking
- with the pointer. */
- static void SetAutoFocusState(bool on);
- /** Set opacity for this widget and its children from 0.0 - 1.0.
- If opacity is 0 (invisible), the widget won't receive any input. */
- void SetOpacity(float opacity);
- float GetOpacity() const { return m_opacity; }
- /** Set opacity for this widget and its children from 0.0 - 1.0 when in WIDGET_STATE_DISABLED.
- If disabled opacity is < 0, default skin opacity will be used.
- If opacity is 0 (invisible), the widget won't receive any input. */
- void SetDisabledOpacity(float opacity);
- float GetDisabledOpacity() const { return m_disabledOpacity; }
- /** Set visibility for this widget and its children.
- If visibility is not WIDGET_VISIBILITY_VISIBLE, the widget won't receive any input. */
- void SetVisibilility(WIDGET_VISIBILITY vis);
- WIDGET_VISIBILITY GetVisibility() const;
- /** Return true if this widget and all its ancestors are visible
- (has a opacity > 0 and visibility WIDGET_VISIBILITY_VISIBLE) */
- bool GetVisibilityCombined() const;
- /** Return true if this widget or any of its parents are disabled (has state WIDGET_STATE_DISABLED). */
- bool GetDisabled() const;
- /** Add the child to this widget. The child widget will automatically be deleted when
- this widget is deleted. (If the child isn't removed again with RemoveChild.) */
- void AddChild(TBWidget *child, WIDGET_Z z = WIDGET_Z_TOP, WIDGET_INVOKE_INFO info = WIDGET_INVOKE_INFO_NORMAL);
- /** Add the child to this widget. See AddChild for adding a child to the top or bottom.
- This takes a relative Z and insert the child before or after the given reference widget.*/
- void AddChildRelative(TBWidget *child, WIDGET_Z_REL z, TBWidget *reference, WIDGET_INVOKE_INFO info = WIDGET_INVOKE_INFO_NORMAL);
- /** Remove child from this widget without deleting it. */
- void RemoveChild(TBWidget *child, WIDGET_INVOKE_INFO info = WIDGET_INVOKE_INFO_NORMAL);
- /** Remove and delete all children in this widget.
- Note: This won't invoke Die so there's no chance for widgets to survive or
- animate. They will be instantly removed and deleted. */
- void DeleteAllChildren();
- /** Sets the z-order of this widget related to its siblings. When a widget is added with AddChild, it will be
- placed at the top in the parent (Above previously added widget). SetZ can be used to change the order. */
- void SetZ(WIDGET_Z z);
- /** Set the z order in which children are added during resource loading. */
- void SetZInflate(WIDGET_Z z) { m_packed.inflate_child_z = z; }
- WIDGET_Z GetZInflate() const { return (WIDGET_Z) m_packed.inflate_child_z; }
- /** Set the widget gravity (any combination of WIDGET_GRAVITY).
- For child widgets in a layout, the gravity affects how the layout is done depending on the layout settings.
- For child widgets in a non layout widget, it will do some basic resizing/moving:
- -left && right: Widget resize horizontally when parent resize.
- -!left && right: Widget follows the right edge when parent resize.
- -top && bottom: Widget resize vertically when parent resize.
- -!top && bottom: Widget follows the bottom edge when parent resize. */
- void SetGravity(WIDGET_GRAVITY g);
- WIDGET_GRAVITY GetGravity() const { return m_gravity; }
- /** Set the skin background for this widget and call OnSkinChanged if it changed.
- The skin background is used for calculating padding, preferred size
- etc. if the widget doesn't have any preferences itself.
- The skin will be painted according to the current widget state (WIDGET_STATE).
- If there is no special skin state for WIDGET_STATE_FOCUSED, it will paint the skin
- element called "generic_focus" (if it exist) after painting all widget children.
- It's possible to omit the OnSkinChanged callback using WIDGET_INVOKE_INFO_NO_CALLBACKS. */
- void SetSkinBg(const TBID &skin_bg, WIDGET_INVOKE_INFO info = WIDGET_INVOKE_INFO_NORMAL);
- /** Return the current skin background, as set by SetSkinBg. */
- TBID GetSkinBg() const { return m_skin_bg; }
- /** Return the skin background element, or nullptr. */
- TBSkinElement *GetSkinBgElement();
- /** Set if this widget is a group root. Grouped widgets (such as TBRadioButton) will toggle all other
- widgets with the same group_id under the nearest parent group root. TBWindow is a group root by default. */
- void SetIsGroupRoot(bool group_root) { m_packed.is_group_root = group_root; }
- bool GetIsGroupRoot() const { return m_packed.is_group_root; }
- /** Set if this widget should be able to receive focus or not. */
- void SetIsFocusable(bool focusable) { m_packed.is_focusable = focusable; }
- bool GetIsFocusable() const { return m_packed.is_focusable; }
- /** Set if this widget should emulate a click when it's focused and pressing enter or space. */
- void SetClickByKey(bool click_by_key) { m_packed.click_by_key = click_by_key; }
- bool GetClickByKey() const { return m_packed.click_by_key; }
- /** Set if this widget should generate long-click event (or context menu event if nothing
- handles the long click event). The default is false. */
- void SetWantLongClick(bool want_long_click) { m_packed.want_long_click = want_long_click; }
- bool GetWantLongClick() const { return m_packed.want_long_click; }
- /** Set if this widget should ignore input, as if it didn't exist. */
- void SetIgnoreInput(bool ignore_input) { m_packed.ignore_input = ignore_input; }
- bool GetIgnoreInput() const { return m_packed.ignore_input; }
- /** Get if this widget wants interaction depending on various states.
- Cares about zero opacity, visibility, flag set by SetIgnoreInput, disabled state,
- and if the widget is currently dying. */
- bool GetIsInteractable() const;
- /** Set this widget to be the focused widget. It will be the one receiving keyboard input.
- Widgets can be focused only after enabling it (See SetIsFocusable(true)).
- Invisible or disabled widgets can not be focused.
- If SetFocus is called on a widget in a inactive window, it will succeed (return true),
- but it won't actually become focused until that window is activated (See TBWindow::SetLastFocus).
- Returns true if successfully focused, or if set as last focus in its window. */
- bool SetFocus(WIDGET_FOCUS_REASON reason, WIDGET_INVOKE_INFO info = WIDGET_INVOKE_INFO_NORMAL);
- bool GetIsFocused() const { return focused_widget == this; }
- /** Call SetFocus on all children and their children, until a widget is found that accepts it.
- Returns true if some child was successfully focused. */
- bool SetFocusRecursive(WIDGET_FOCUS_REASON reason);
- /** Move focus from the currently focused widget to another focusable widget. It will search
- for a focusable widget in the same TBWindow (or top root if there is no window) forward or
- backwards in the widget order. */
- bool MoveFocus(bool forward);
- /** Returns the child widget that contains the coordinate or nullptr if no one does. If include_children
- is true, the search will recurse into the childrens children. */
- TBWidget *GetWidgetAt(int x, int y, bool include_children) const;
- /** Get the child at the given index, or nullptr if there was no child at that index.
- Note: Avoid calling this in loops since it does iteration. Consider iterating
- the widgets directly instead! */
- TBWidget *GetChildFromIndex(int index) const;
- /** Get the child index of the given widget (that must be a child of this widget).
- Note: Avoid calling this in loops since it does iteration. Consider iterating
- the widgets directly instead! */
- int GetIndexFromChild(TBWidget *child) const;
- /** Get the text of a child widget with the given id, or an empty string if there was
- no widget with that id. */
- TBStr GetTextByID(const TBID &id);
- /** Get the value of a child widget with the given id, or 0 if there was no widget
- with that id. */
- int GetValueByID(const TBID &id);
- TBWidget *GetNextDeep(const TBWidget *bounding_ancestor = nullptr) const;
- TBWidget *GetPrevDeep() const;
- TBWidget *GetLastLeaf() const;
- inline TBWidget *GetFirstChild() const { return m_children.GetFirst(); }
- inline TBWidget *GetLastChild() const { return m_children.GetLast(); }
- TBLinkListOf<TBWidget>::Iterator GetIteratorForward() { return m_children.IterateForward(); }
- TBLinkListOf<TBWidget>::Iterator GetIteratorBackward() { return m_children.IterateBackward(); }
- // ATOMIC BEGIN
- /** Returns the number of children this widget contains. */
- int numChildren();
- /// searches for specified widget ID from the top of the widget tree, returns the 1st one found.
- TBWidget *FindWidget ( TBID searchid );
- /// print out the widget tree to stdout
- void PrintPretty( TBStr indent, bool last);
- /// return all of the widgets of the specified classname
- void SearchWidgetClass ( TBStr className, TBValue &results );
- /// return all of the widgets of the specified id
- void SearchWidgetId ( TBID searchid, TBValue &results );
- /// return all of the widgets with the specified text
- void SearchWidgetText ( TBStr searchText, TBValue &results );
- // ATOMIC END
- /** Return true if this widget is the same or a ancestor of other_widget. */
- bool IsAncestorOf(TBWidget *other_widget) const;
- /** Return true if this widget is the same as other_widget or if other_widget
- events are going through this widget (See GetEventDestination()) */
- bool IsEventDestinationFor(TBWidget *other_widget) const;
- TBWidgetDelegate* GetDelegate() {return m_delegate; }
- void SetDelegate(TBWidgetDelegate* delegate) { m_delegate = delegate; }
- // == Callbacks ==============================================
- /** Add a listener to this widget. It should be removed again with
- RemoveListener before the widget is deleted. */
- void AddListener(TBWidgetListener *listener);
- void RemoveListener(TBWidgetListener *listener);
- bool HasListener(TBWidgetListener *listener) const;
- /** Callback for handling events.
- Return true if the event is handled and should not
- continue to be handled by any parent widgets. */
- virtual bool OnEvent(const TBWidgetEvent &ev) { if (m_delegate) return m_delegate->OnEvent(ev); return false; }
- /** Callback for doing anything that might be needed before paint.
- F.ex Updating invalid layout, formatting text etc. */
- virtual void OnProcess() {}
- /** Callback for doing anything that might be needed before paint.
- This is called after OnProcess has been called on this widgets children. */
- virtual void OnProcessAfterChildren() {}
- /** Callback for doing state updates that depend on your application state.
- F.ex setting the disabled state on a widget which action is currently not
- available. This callback is called for all widgets before OnProcess if
- something has called InvalidateStates().*/
- virtual void OnProcessStates() {}
- /** PaintProps contains properties needed for painting a widget.
- Properties may be inherited from the parent widget if not specified
- in the skin. */
- class PaintProps
- {
- public:
- PaintProps();
- /** Text color as specified in the skin element, or inherited from parent. */
- TBColor text_color;
- };
- /** Callback for painting this widget.
- The skin is already painted and the opacity set to reflect this widgets.
- This is only called for widgets with a opacity > 0 */
- virtual void OnPaint(const PaintProps &paint_props) {}
- /** Callback for painting child widgets.
- The default implementation is painting all children. */
- virtual void OnPaintChildren(const PaintProps &paint_props);
- /** Callback for when this widget or any of its children have
- called Invalidate() */
- virtual void OnInvalid() {}
- /** Called when the background skin changes by calling SetSkinBg(), or when the skin
- has changed indirectly after a skin condition changes in a way that may affect layout.
- For indirect skin changes, OnSkinChanged is called before validation of layouts is about
- to happen in InvokeProcess().
- */
- virtual void OnSkinChanged() {}
- /** Called when the font has changed. */
- virtual void OnFontChanged() {}
- /** Called when the focus has changed. */
- virtual void OnFocusChanged(bool focused) { if (m_delegate) return m_delegate->OnFocusChanged(focused); }
- /** Called when the visibility has changed.
- Note: This is not called when combined visibility change, so it may change visibility
- because of ancestors without this being called. */
- virtual void OnVisibilityChanged() {}
- /** Called when the capture has changed. */
- virtual void OnCaptureChanged(bool captured) { SetCaptured(captured); }
- /** Called when a child widget has been added to this widget (before calling OnAdded on child). */
- virtual void OnChildAdded(TBWidget *child) {}
- /** Called when a child widget is about to be removed from this widget (before calling OnRemove on child). */
- virtual void OnChildRemove(TBWidget *child) {}
- /** Called when this widget has been added to a parent (after calling OnChildAdded on parent). */
- virtual void OnAdded() {}
- /** Called when a this widget has been removed from its parent (after calling OnChildRemove on parent). */
- virtual void OnRemove() {}
- /** Called when Die() is called on this widget. Note: Not called for children to the widget Die() was
- invoked on even though they are also dying. */
- virtual void OnDie() {}
- /** Called when this widget has been resized.
- The default implementation move and resize all children according to their gravity. */
- virtual void OnResized(int old_w, int old_h);
- /** Called when this widget has been scrolled. */
- virtual void OnScroll(int scroll_x, int scroll_y) {}
- /** Called just after a child has been inflated into this widget.
- The default implementation will resize the child to it's preferred size
- and position it according to the gravity. If you implement a layouting
- widget, you should override this to prevent doing unnecessary measuring. */
- virtual void OnInflateChild(TBWidget *child);
- /** Called when this widget is inflated from resources, before any children
- has been inflated. This will read generic widget properties and add the
- widget to the hierarchy if it's not already added. If overridden, you
- must call the super implementation. */
- virtual void OnInflate(const INFLATE_INFO &info);
- /** Get hit status tests if this widget should be hit at the given coordinate.
- The default implementation checks the visibility, ignored input flag, rectangle,
- and disabled status. */
- virtual WIDGET_HIT_STATUS GetHitStatus(int x, int y);
- /** Get if skin condition applies to this widget. This is called when a skin condition has the property
- PROPERTY_CUSTOM (not a generic one known by skin and the default widget condition context).
- This can be used to extend the skin conditions support with properties specific to different widgets. */
- virtual bool GetCustomSkinCondition(const TBSkinCondition::CONDITION_INFO &info) { return false; }
- /** Get this widget or a child widget that should be root for other children. This is useful
- for widgets having multiple children by default, to specify which one that should get the children. */
- virtual TBWidget *GetContentRoot() { return this; }
- /** Get this widget or a parent widget that is the absolute root parent
- if view_root is true, will return the widget for the UIView attached to root widget */
- TBWidget *GetParentRoot(bool view_root = true);
- /** Get the closest parent widget that is a TBWindow or nullptr if there is none.
- If this widget is a window itself, this will be returned. */
- TBWindow *GetParentWindow();
- /** Get the parent widget, or nullptr if this widget is not added. */
- inline TBWidget *GetParent() const { return m_parent; }
- /** Get the widget that should receive the events this widget invoke. By default the parent. */
- virtual TBWidget *GetEventDestination() { return m_parent; }
- /** Return translation the children should have. Any scrolling of child widgets
- should be done with this method, by returning the wanted translation.
- When implementing this, you must also implement ScrollTo and GetScrollInfo
- so focus-scroll and panning will work automatically when dragging this or
- any child widget. Note: You can apply the translation on one widget and
- implement those methods on a parent, by returning this widget from the
- parents GetScrollRoot(). */
- virtual void GetChildTranslation(int &x, int &y) const { x = y = 0; }
- /** If this is a widget that scroll children (see GetChildTranslation), it should
- scroll to the coordinates x, y.
- This must result in calling OnScroll if scrolling occured. */
- virtual void ScrollTo(int x, int y) {}
- /** Start the TBScroller for this widget and scroll it to the given position.
- Will cancel any on going smooth scroll operation. */
- void ScrollToSmooth(int x, int y);
- /** If this is a widget that scroll children (see GetChildTranslation), it will
- scroll by delta dx, dy relative to its current position. */
- void ScrollBy(int dx, int dy);
- /** Start the TBScroller for this widget and scroll it by the given delta.
- Consecutive calls will accumulate the scroll speed. */
- void ScrollBySmooth(int dx, int dy);
- /** Information about scrolling for a widget at the time of calling GetScrollInfo. */
- class ScrollInfo
- {
- public:
- ScrollInfo() : min_x(0), min_y(0), max_x(0), max_y(0), x(0), y(0) {}
- bool CanScrollX() const { return max_x > min_x; }
- bool CanScrollY() const { return max_y > min_y; }
- bool CanScrollLeft() const { return x > min_x; }
- bool CanScrollRight() const { return x < max_x; }
- bool CanScrollUp() const { return y > min_y; }
- bool CanScrollDown() const { return y < max_y; }
- bool CanScroll() const { return CanScrollX() || CanScrollY(); }
- int min_x, min_y; ///< Minimum x and y scroll position.
- int max_x, max_y; ///< Maximum x and y scroll position.
- int x, y; ///< Current x and y scroll position.
- };
- /** If this is a widget that scroll children (see GetChildTranslation),
- it should return the current scroll information. */
- virtual ScrollInfo GetScrollInfo() { return ScrollInfo(); }
- /** If this widget is implementing ScrollTo and GetScrollInfo but
- the corresponding GetChildTranslation is implemented on a child,
- you should return that child from this method. */
- virtual TBWidget *GetScrollRoot() { return this; }
- /** Scroll this widget and/or any parent widgets by the given delta.
- dx and dy will be reduced by the amount that was successfully
- scrolled. */
- void ScrollByRecursive(int &dx, int &dy);
- /** Make this widget visible by calling ScrollIntoView on all parent widgets */
- void ScrollIntoViewRecursive();
- /** If this is a widget that scroll children (see GetChildTranslation), it will
- scroll so that rect is visible. Rect is relative to this widget. */
- void ScrollIntoView(const TBRect &rect);
- /** Return the TBScroller set up for this widget, or nullptr if creation failed. */
- TBScroller *GetScroller();
- // == Setter shared for many types of widgets ============
- /** Set along which axis the content should be layouted. */
- virtual void SetAxis(AXIS axis) {}
- virtual AXIS GetAxis() const { return AXIS_X; }
- /** Set the value of this widget. Implemented by most widgets (that has a value).
- Note: Some widgets also provide special setters with other types (such as double). */
- virtual void SetValue(int value) {}
- virtual int GetValue() { return 0; }
- /** Set the value in double precision. It only makes sense to use this instead
- of SetValue() on widgets that store the value as double. F.ex TBScrollBar, TBSlider. */
- virtual void SetValueDouble(double value) { SetValue((int) value); }
- /** Return the value in double precision. It only makes sense to use this instead
- of GetValue() on widgets that store the value as double. F.ex TBScrollBar, TBSlider. */
- virtual double GetValueDouble() { return (double) GetValue(); }
- /** Set the text of this widget. Implemented by most widgets (that has text). */
- virtual bool SetText(const char *text) { return true; }
- /** Get the text of this widget. Implemented by most widgets (that has text).
- returns false if it failed. */
- virtual bool GetText(TBStr &text) { text.Clear(); return true; }
- /** Get the text of this widget. Implemented by most widgets (that has text). */
- TBStr GetText() { TBStr str; GetText(str); return str; }
- /** Connect this widget to a widget value.
- When this widget invoke EVENT_TYPE_CHANGED, it will automatically update the
- connected widget value, and any other widgets that may be connected to it.
- On connection, the value of this widget will be updated to the value of the
- given TBWidgetValue. */
- void Connect(TBWidgetValue *value) { m_connection.Connect(value, this); }
- /** Unconnect, if this widget is connected to a TBWidgetValue. */
- void Unconnect() { m_connection.Unconnect(); }
- /** Get the rectangle inside any padding, relative to this widget. This is the
- rectangle in which the content should be rendered.
- This may be overridden to f.ex deduct space allocated by visible scrollbars
- managed by this widget. Anything that removes space from the content area. */
- virtual TBRect GetPaddingRect();
- /** Calculate the preferred content size for this widget. This is the size of the actual
- content. Don't care about padding or other decoration. */
- virtual PreferredSize OnCalculatePreferredContentSize(const SizeConstraints &constraints);
- /** Calculate the preferred size for this widget. This is the full size of the widget,
- content + padding + eventual other decoration (but not skin expansion).
- This is the size that should be used for layouting a widget.
- The returned PreferredSize also contains minimal size and maximum size. */
- virtual PreferredSize OnCalculatePreferredSize(const SizeConstraints &constraints);
- /** Get the PreferredSize for this widget.
- This returns cached data if valid, or calls OnCalculatePreferredSize if needed. */
- PreferredSize GetPreferredSize(const SizeConstraints &constraints);
- PreferredSize GetPreferredSize() { return GetPreferredSize(SizeConstraints()); }
- /** Type used for InvalidateLayout */
- enum INVALIDATE_LAYOUT {
- INVALIDATE_LAYOUT_TARGET_ONLY, ///< InvalidateLayout should not be recursively called on parents.
- INVALIDATE_LAYOUT_RECURSIVE ///< InvalidateLayout should recursively be called on parents too.
- };
- /** Invalidate layout for this widget so it will be scheduled for relayout.
- Any change to the size preferences for a widget should call this to let parent layout adjust to the change.
- Remarks for layout widgets:
- - When a layout widget get this, it should mark its layout as invalid and do the layout later
- (in GetPreferredContentSize/GetPreferredSize are called). If a layout knows that no parents will
- be affected, it may stop recursion to parents to avoid unnecessary relayout.
- - When setting the size of a layout widget (typically from another layout widget or from a OnResize),
- it should be called with INVALIDATE_LAYOUT_TARGET_ONLY to avoid recursing back up to parents when
- already recursing down, to avoid unnecessary computation.
- */
- virtual void InvalidateLayout(INVALIDATE_LAYOUT il);
- /** Set layout params. Calls InvalidateLayout. */
- void SetLayoutParams(const LayoutParams &lp);
- /** Get layout params, or nullptr if not specified.
- Note: The layout params has already been applied to the PreferredSize returned
- from GetPreferredSize so you normally don't need to check these params. */
- const LayoutParams *GetLayoutParams() const { return m_layout_params; }
- // == Misc methods for invoking events. Should normally be called only on the root widget ===============
- /** Invoke OnProcess and OnProcessAfterChildren on this widget and its children. */
- void InvokeProcess();
- /** Invoke OnProcessStates on all child widgets, if state processing
- is needed (InvalidateStates() has been called) */
- void InvokeProcessStates(bool force_update = false);
- /** Invoke paint on this widget and all its children */
- void InvokePaint(const PaintProps &parent_paint_props);
- /** Invoke OnFontChanged on this widget and recursively on any children that inherit the font. */
- void InvokeFontChanged();
- /** Invoke a event on this widget.
- This will first check with all registered TBWidgetListener if the event should be dispatched.
- If the widgets OnEvent returns false (event not handled), it will continue traversing to
- GetEventDestination (by default the parent) until a widget handles the event.
- Note: When invoking event EVENT_TYPE_CHANGED, this will update the value of other widgets connected
- to the same group.
- Note: Some event types will automatically invalidate states (See InvalidateStates(), InvalidateSkinStates())
- Note: Remember that this widgets may be deleted after this call! So if you really must do something after
- this call and are not sure what the event will cause, use TBWidgetSafePointer to detect self deletion. */
- bool InvokeEvent(TBWidgetEvent &ev);
- bool InvokePointerDown(int x, int y, int click_count, MODIFIER_KEYS modifierkeys, bool touch, int touchId = 0);
- bool InvokePointerUp(int x, int y, MODIFIER_KEYS modifierkeys, bool touch, int touchId = 0);
- void InvokePointerMove(int x, int y, MODIFIER_KEYS modifierkeys, bool touch, int touchId = 0);
- void InvokePointerCancel();
- /** Invoke touch events with ref_id set as the given id.
- Note: For id 0, it will invoke EVENT_TYPE_POINTER_DOWN (with touch flag set to true), and EVENT_TYPE_TOUCH_DOWN
- for other id > 0. This results in normal interaction for first finger, and optional handling of other
- simultaneous interaction. GetTouchInfo(id) can be used to get additional interaction info. */
- bool InvokeTouchDown(int x, int y, uint32 id, int click_count, MODIFIER_KEYS modifierkeys);
- bool InvokeTouchUp(int x, int y, uint32 id, MODIFIER_KEYS modifierkeys);
- void InvokeTouchMove(int x, int y, uint32 id, MODIFIER_KEYS modifierkeys);
- void InvokeTouchCancel(uint32 id);
- void InvokeWheel(int x, int y, int delta_x, int delta_y, MODIFIER_KEYS modifierkeys);
- void InvokeRightPointerDown(int x, int y, int click_count, MODIFIER_KEYS modifierkeys);
- void InvokeRightPointerUp(int x, int y, MODIFIER_KEYS modifierkeys);
- /** Invoke the EVENT_TYPE_KEY_DOWN and EVENT_TYPE_KEY_UP events on the currently focused widget.
- This will also do some generic key handling, such as cycling focus on tab etc. */
- bool InvokeKey(int key, SPECIAL_KEY special_key, MODIFIER_KEYS modifierkeys, bool down);
- /** A widget that receive a EVENT_TYPE_POINTER_DOWN event, will stay "captured" until EVENT_TYPE_POINTER_UP
- is received. While captured, all EVENT_TYPE_POINTER_MOVE are sent to it. This method can force release the capture,
- which may happen f.ex if the TBWidget is removed while captured. */
- void ReleaseCapture();
- /** Make x and y (relative to this widget) relative to the upper left corner of the root widget. */
- void ConvertToRoot(int &x, int &y) const;
- /** Make x and y (relative to the upper left corner of the root widget) relative to this widget. */
- void ConvertFromRoot(int &x, int &y) const;
- /** Set the font description for this widget and any children that inherit the font.
- Setting a unspecified TBFontDescription (no changes made since construction) means
- it will be inherited from parent (the default).
- Returns true and invokes OnFontChanged on all affected widgets, if the
- font was successfully set.
- Returns false and keep the font onchanged if it no matching font exists or fails creation. */
- bool SetFontDescription(const TBFontDescription &font_desc);
- /** Get the font description as set with SetFontDescription. Use GetCalculatedFontDescription()
- to get the calculated font description (Inherit from parent widget etc.) */
- TBFontDescription GetFontDescription() const { return m_font_desc; }
- /** Calculate the font description for this widget. If this widget have unspecified font
- description, it will be inheritted from parent. If no parent specify any font,
- the default font description will be returned. */
- TBFontDescription GetCalculatedFontDescription() const;
- /** Get the TBFontFace for this widget from the current font description (calculated
- by GetCalculatedFontDescription) */
- TBFontFace *GetFont() const;
- void SetCapturing(bool needCapturing) { needCapturing_ = needCapturing; }
- bool GetCapturing() { return needCapturing_; }
- void SetCaptured(bool captured) { captured_ = captured; }
- bool IsCaptured() { return captured_; }
- void SetTouchId(unsigned touchId) { touchId_ = touchId; }
- unsigned GetTouchId() { return touchId_; }
- TBWidget *GetWidgetByTouchId(unsigned touchId);
- bool GetShortened() { return shortened_; }
- void SetShortened(bool shortened) { shortened_ = shortened; }
- TBStr GetTooltip() { return tooltip_; }
- bool SetTooltip(const char *tooltip) { return tooltip_.Set(tooltip); }
- private:
- friend class TBWidgetListener; ///< It does iteration of m_listeners for us.
- TBWidget *m_parent; ///< The parent of this widget
- TBRect m_rect; ///< The rectangle of this widget, relative to the parent. See SetRect.
- TBID m_id; ///< ID for GetWidgetByID and others.
- TBID m_group_id; ///< ID for button groups (such as TBRadioButton)
- TBID m_skin_bg; ///< ID for the background skin (0 for no skin).
- TBID m_skin_bg_expected; ///< ID for the background skin after strong override,
- ///< used to indirect skin changes because of condition changes.
- TBLinkListOf<TBWidget> m_children;///< List of child widgets
- TBWidgetValueConnection m_connection; ///< TBWidget value connection
- TBLinkListOf<TBWidgetListener> m_listeners; ///< List of listeners
- float m_opacity; ///< Opacity 0-1. See SetOpacity.
- float m_disabledOpacity; ///< Opacity 0-1. See SetDisabledOpacity.
- WIDGET_STATE m_state; ///< The widget state (excluding any auto states)
- WIDGET_GRAVITY m_gravity; ///< The layout gravity setting.
- TBFontDescription m_font_desc; ///< The font description.
- PreferredSize m_cached_ps; ///< Cached preferred size.
- SizeConstraints m_cached_sc; ///< Cached size constraints.
- LayoutParams *m_layout_params; ///< Layout params, or nullptr.
- TBScroller *m_scroller;
- TBLongClickTimer *m_long_click_timer;
- TBWidgetDelegate* m_delegate;
- bool needCapturing_; //if ours widget need capturing
- bool captured_; //if ours widget is currently captured
- unsigned touchId_;
- bool shortened_;
- TBStr tooltip_;
- union {
- struct {
- uint16 is_group_root : 1;
- uint16 is_focusable : 1;
- uint16 click_by_key : 1;
- uint16 has_key_pressed_state : 1;
- uint16 ignore_input : 1;
- uint16 is_dying : 1;
- uint16 is_cached_ps_valid : 1;
- uint16 no_automatic_hover_state : 1;
- uint16 is_panning : 1;
- uint16 want_long_click : 1;
- uint16 visibility : 2;
- uint16 inflate_child_z : 1; // Should have enough bits to hold WIDGET_Z values.
- } m_packed;
- uint16 m_packed_init;
- };
- public:
- /** This value is free to use for anything. It's not used by TBWidget itself. Initially TYPE_NULL. */
- TBValue data;
- // Debugging
- #ifdef TB_RUNTIME_DEBUG_INFO
- double last_measure_time;
- double last_layout_time;
- #endif // TB_RUNTIME_DEBUG_INFO
- // TBWidget related globals
- static TBWidget *hovered_widget; ///< The currently hovered widget, or nullptr.
- static TBWidget *captured_widget; ///< The currently captured widget, or nullptr.
- static TBWidget *focused_widget; ///< The currently focused widget, or nullptr.
- static int pointer_down_widget_x; ///< Pointer x position on down event, relative to the captured widget.
- static int pointer_down_widget_y; ///< Pointer y position on down event, relative to the captured widget.
- static int pointer_move_widget_x; ///< Pointer x position on last pointer event, relative to the captured widget (if any) or hovered widget.
- static int pointer_move_widget_y; ///< Pointer y position on last pointer event, relative to the captured widget (if any) or hovered widget.
- static bool cancel_click; ///< true if the pointer up event should not generate a click event.
- static bool update_widget_states; ///< true if something has called InvalidateStates() and it still hasn't been updated.
- static bool update_skin_states; ///< true if something has called InvalidateStates() and skin still hasn't been updated.
- static bool show_focus_state; ///< true if the focused state should be painted automatically.
- struct TOUCH_INFO {
- TBWidget *hovered_widget; ///< The currently hovered widget, or nullptr.
- TBWidget *captured_widget; ///< The currently captured widget, or nullptr.
- int down_widget_x; ///< Touch x position on down event, relative to the captured widget.
- int down_widget_y; ///< Touch y position on down event, relative to the captured widget.
- int move_widget_x; ///< Touch x position on last touch event, relative to the captured widget.
- int move_widget_y; ///< Touch y position on last touch event, relative to the captured widget.
- };
- /** Return TOUCH_INFO for the given id, or nullptr if no touch is active for that id. */
- static TOUCH_INFO *GetTouchInfo(uint32 id);
- private:
- /** Return this widget or the nearest parent that is scrollable
- in the given axis, or nullptr if there is none. */
- TBWidget *FindScrollableWidget(bool scroll_x, bool scroll_y);
- TBScroller *FindStartedScroller();
- TBScroller *GetReadyScroller(bool scroll_x, bool scroll_y);
- TBWidget *GetWidgetByIDInternal(const TBID &id, const TB_TYPE_ID type_id = nullptr);
- void InvokeSkinUpdatesInternal(bool force_update);
- void InvokeProcessInternal();
- static void SetHoveredWidget(TBWidget *widget, bool touch);
- static void SetCapturedWidget(TBWidget *widget);
- void HandlePanningOnMove(int x, int y);
- void StartLongClickTimer(bool touch);
- void StopLongClickTimer();
- friend class TBLongClickTimer;
- void MaybeInvokeLongClickOrContextMenu(bool touch);
- /** Returns the opacity for this widget multiplied with its skin opacity and state opacity. */
- float CalculateOpacityInternal(WIDGET_STATE state, TBSkinElement *skin_element) const;
- };
- }; // namespace tb
- #endif // TB_WIDGETS_H
|