| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138 |
- // ================================================================================
- // == 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: 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;
- };
- /** 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(); }
- /** 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
|