diff --git a/.gitattributes b/.gitattributes index bdb0cabc..07e66bc7 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,6 +1,8 @@ # Auto detect text files and perform LF normalization * text=auto +*.sh -text + # Custom for Visual Studio *.cs diff=csharp diff --git a/src/Widget.cpp b/src/Widget.cpp index 50a1a957..10f2e987 100644 --- a/src/Widget.cpp +++ b/src/Widget.cpp @@ -127,6 +127,8 @@ Widget::Widget(int abn): BevelWidth(this), Size(this), Location(this), + ExtendedFlags(this), + WidgetFlags(this), //callbacks: Destroyed(this), Blocked(this), @@ -154,6 +156,8 @@ Widget::Widget(PtWidget_t* wdg): BevelWidth(this), Size(this), Location(this), + ExtendedFlags(this), + WidgetFlags(this), //callbacks: Destroyed(this), Blocked(this), @@ -218,6 +222,8 @@ Widget::Widget(const Widget &rhs): BevelWidth(this), Size(this), Location(this), + ExtendedFlags(this), + WidgetFlags(this), //callbacks: Destroyed(this), Blocked(this), @@ -304,12 +310,12 @@ Widget::operator PtWidget_t*() //for properties: void Widget::setEnabled(bool val) { - resource.argument[Arguments::flags].set(Pt_BLOCKED | Pt_GHOST, !val); + resource.argument[Arguments::flags].set(Flags::Blocked | Flags::Ghost, !val); } bool Widget::getEnabled() const { - return resource.argument[Arguments::flags].get(Pt_BLOCKED); + return resource.argument[Arguments::flags].get(Flags::Blocked); } void PhWidgets::Widget::setHelpTopic(std::string val) @@ -321,3 +327,39 @@ std::string PhWidgets::Widget::getHelpTopic() const { return resource.argument[Arguments::help_topic].get(); } + +cppbitmasks::bitmask operator|(const PhWidgets::Widget::Flags::Extended::eExFlags &flag1, const PhWidgets::Widget::Flags::Extended::eExFlags &flag2) +{ + cppbitmasks::bitmask bm(flag1); + return bm | flag2; +} + +cppbitmasks::bitmask operator&(const PhWidgets::Widget::Flags::Extended::eExFlags &flag1, const PhWidgets::Widget::Flags::Extended::eExFlags &flag2) +{ + cppbitmasks::bitmask bm(flag1); + return bm & flag2; +} + +cppbitmasks::bitmask operator^(const PhWidgets::Widget::Flags::Extended::eExFlags &flag1, const PhWidgets::Widget::Flags::Extended::eExFlags &flag2) +{ + cppbitmasks::bitmask bm(flag1); + return bm ^ flag2; +} + +cppbitmasks::bitmask operator|(const PhWidgets::Widget::Flags::eFlags &flag1, const PhWidgets::Widget::Flags::eFlags &flag2) +{ + cppbitmasks::bitmask bm(flag1); + return bm | flag2; +} + +cppbitmasks::bitmask operator&(const PhWidgets::Widget::Flags::eFlags &flag1, const PhWidgets::Widget::Flags::eFlags &flag2) +{ + cppbitmasks::bitmask bm(flag1); + return bm & flag2; +} + +cppbitmasks::bitmask operator^(const PhWidgets::Widget::Flags::eFlags &flag1, const PhWidgets::Widget::Flags::eFlags &flag2) +{ + cppbitmasks::bitmask bm(flag1); + return bm ^ flag2; +} diff --git a/src/Widget.h b/src/Widget.h index dba94519..aeeaf9e4 100644 --- a/src/Widget.h +++ b/src/Widget.h @@ -15,6 +15,7 @@ #include "./service/stdex/stdex.h" #include "./service/phproperty.hpp" #include "./service/phevent.hpp" +#include "./service/phbitmask.hpp" #include "./WidgetResource.hpp" @@ -28,6 +29,7 @@ namespace PhWidgets { using namespace cppproperties; using namespace phevents; + using namespace cppbitmasks; class Widget: protected detail::IPtWidget, @@ -174,8 +176,7 @@ namespace PhWidgets { enum eArgUnsignedLong { - eflags = Pt_ARG_EFLAGS //!< Extended flags inherited by all widgets: - //!< Documentation in progress... + eflags = Pt_ARG_EFLAGS //!< Extended \link Widget::ExtendedFlags flags\endlink inherited by all widgets. }; }; @@ -183,7 +184,7 @@ namespace PhWidgets { enum eArgLong { - flags = Pt_ARG_FLAGS, //!< Common flags used by all widgets. Except for those indicated as read-only, these flags are all read/write. + flags = Pt_ARG_FLAGS, //!< Common \link Widget::WidgetFlags flags\endlink used by all widgets. Except for those indicated as read-only, these flags are all read/write. resize_flags = Pt_ARG_RESIZE_FLAGS //!< Controls a widget's resize policy in both the x and y directions. //!< Documentation in progress... }; @@ -335,6 +336,69 @@ namespace PhWidgets }; }; + struct ThisFlags + { + struct Extended + { + //! Extended flags inherited by all widgets + enum eExFlags + { + //! Consume any event encountered, whether or not an action was performed as a result of that event. + //! (When a widget has processed an event and prevents another widget from interacting with the event, the first widget is said to have consumed the event.) + ConsumeEvents = Pt_CONSUME_EVENTS, + + InternalHelp = Pt_INTERNAL_HELP, //!< Display help information for the widget in a balloon, not in the Helpviewer. + //damage_parent = Pt_DAMAGE_PARENT, //!< If the widget is damaged for any reason, damage its parent instead (internal use only). + SkipLayout = Pt_SKIP_LAYOUT //!< Skip this widget when performing a layout. + }; + }; + + //! Common flags used by all widgets. Except for those indicated as read-only, these flags are all read/write. + enum eFlags + { + + AllButtons = Pt_ALL_BUTTONS, //!< Any pointer button can activate the widget. Default is the left button only. + Autohighlight = Pt_AUTOHIGHLIGHT, //!< Highlight and give focus to the widget when the cursor enters its extent, and unhighlight and remove focus when the cursor leaves. + Blocked = Pt_BLOCKED, //!< Prevent the widget and all its non-window-class children from interacting with Photon events. + + //! If certain widgets have this bit set, and your application sets their resources, the relevant callbacks are invoked. + //! Otherwise callbacks aren't invoked when your application sets resources. If a callback refers to this flag, its description says so explicitly. + //! For example, if this bit is set for a Divider and you use Divider::Undefined to change the size of one of its children, the Divider::DeviderDraged event is invoked. + CallbacksActive = Pt_CALLBACKS_ACTIVE, + + Clear = Pt_CLEAR, //!< (read-only) The widget's brothers-in-front don't intersect with its extent. + ClipHighlight = Pt_CLIP_HIGHLIGHT, //!< Clip the corners of the highlighting rectangle. + Damaged = Pt_DAMAGED, //!< (read-only) The Widget requires repair. + DamageFamily = Pt_DAMAGE_FAMILY, //!< (read-only) The widget and all its children need to be repaired. + DelayRealize = Pt_DELAY_REALIZE, //!< Prevent the widget from becoming realized unless it's explicitly realized with Widget::Realized event. + Destroyed = Pt_DESTROYED, //!< (read-only) The widget has been marked for destruction. + FocusRender = Pt_FOCUS_RENDER, //!< Render a focus indicator when the widget when it gets focus. + GetsFocus = Pt_GETS_FOCUS, //!< Allow the widget to be granted focus. The widget needs to have this bit set if it's to receive key events. + Ghost = Pt_GHOST, //!< Dim the widget. Setting this flag doesn't affect the widget's behavior, just its appearance. The simplest way to disable the widget is to set the Blocked flag in this resource. + Highlighted = Pt_HIGHLIGHTED, //!< Allow the widget to be highlighted as defined by the Widget::BevelWidth, and the Basic::BasicFlags. + InFlux = Pt_IN_FLUX, //!< (read-only) A call to PtContainerHold() has been made on the widget. + Menuable = Pt_MENUABLE, //!< Respond to clicks on the pointer's right button (i.e. enable the Basic::MenuActivate event). + MenuButton = Pt_MENU_BUTTON, //!< The widget is a menu item. + Obscured = Pt_OBSCURED, //!< (read-only) The widget is completely covered by one other widget, or it's completely outside its parent container's canvas. + Opaque = Pt_OPAQUE, //!< (read-only) This widget obscures everything directly behind it (i.e. it isn't transparent). + Procreated = Pt_PROCREATED, //!< (read-only) The widget was created by another widget (as opposed to an application), such as the List and Text created by a ComboBox. + Realized = Pt_REALIZED, //!< (read-only) The widget is realized. + Realizing = Pt_REALIZING, //!< (read-only) The widget is in the process of being realized. + Region = Pt_REGION, //!< Force the widget to have a region. + Selectable = Pt_SELECTABLE, //!< You can select (\link Basic::Repeat repeat \endlink, \link Basic::Arm arm \endlink, \link Basic::Disarm disarm \endlink and \link Basic::Activate activate \endlink) the widget. Widgets usually provide visual feedback when selected. + SelectNoredraw = Pt_SELECT_NOREDRAW, //!< The widget doesn't change its appearance when set or unset. This is meaningful only when the widget is Selectable. + Set = Pt_SET, //!< The widget is in a “set” state. Generally, this indicates that the widget has been selected. + + //! Pressing the pointer button on this widget causes it to toggle between being set and unset. + //! Normally, selectable widgets act as push buttons — they become set when you press the pointer button, and unset when you release the button. + Toggle = Pt_TOGGLE, + + WidgetRebuild = Pt_WIDGET_REBUILD, //!< (read-only) The widget will be rebuilt(rerealized) when the widget engine is finished applying resource changes. + WidgetResize = Pt_WIDGET_RESIZE, //!< (read-only) The widget will be resized when the widget engine is finished applying resource changes. + }; + + }; + struct ArgArea: public ThisArgs::ArgArea { @@ -445,7 +509,11 @@ namespace PhWidgets { }; - + struct Flags: + public ThisFlags + { + }; + private: @@ -547,6 +615,9 @@ namespace PhWidgets phproperty::bind Size; //!< Gets or sets the size of the widget. phproperty::bind Location; //!< Gets or sets the position of the widget. + phbitmask::bind ExtendedFlags; //!< Gets or sets extended flags inherited by all widgets. See Flags::Extended. + phbitmask::bind WidgetFlags; //!< Gets or sets flags inherited by all widgets. See Flags::eFlags. + phwidgets_event Destroyed; //!< Occurs when the widget is destroyed. phwidgets_event Blocked; //!< Occurs when the widget is blocked. phwidgets_event DragDrop; //!< Occurs when a drag-and-drop operation is completed. @@ -565,10 +636,20 @@ namespace PhWidgets }; - - }//namespace PhWidgets +cppbitmasks::bitmask operator|(const PhWidgets::Widget::Flags::Extended::eExFlags &flag1, const PhWidgets::Widget::Flags::Extended::eExFlags &flag2); + +cppbitmasks::bitmask operator&(const PhWidgets::Widget::Flags::Extended::eExFlags &flag1, const PhWidgets::Widget::Flags::Extended::eExFlags &flag2); + +cppbitmasks::bitmask operator^(const PhWidgets::Widget::Flags::Extended::eExFlags &flag1, const PhWidgets::Widget::Flags::Extended::eExFlags &flag2); + +cppbitmasks::bitmask operator|(const PhWidgets::Widget::Flags::eFlags &flag1, const PhWidgets::Widget::Flags::eFlags &flag2); + +cppbitmasks::bitmask operator&(const PhWidgets::Widget::Flags::eFlags &flag1, const PhWidgets::Widget::Flags::eFlags &flag2); + +cppbitmasks::bitmask operator^(const PhWidgets::Widget::Flags::eFlags &flag1, const PhWidgets::Widget::Flags::eFlags &flag2); + #endif diff --git a/src/WidgetResource.hpp b/src/WidgetResource.hpp index 6aecf72c..e82299d1 100644 --- a/src/WidgetResource.hpp +++ b/src/WidgetResource.hpp @@ -503,6 +503,15 @@ namespace PhWidgets { return this->setFlag(flag, static_cast::type>(mask)); } + + template + inline int set(A1 bitmask) + { + int err = this->setFlag(bitmask, true); + if(0 != err) + return err; + return this->setFlag(~bitmask, false); + } inline resource_type get() const { diff --git a/src/service/bitmask.hpp b/src/service/bitmask.hpp new file mode 100644 index 00000000..d4cc1a43 --- /dev/null +++ b/src/service/bitmask.hpp @@ -0,0 +1,229 @@ +#ifndef CPP_BITMASK_HPP +#define CPP_BITMASK_HPP + +namespace cppbitmasks +{ + template + class bitmask + { + bitmask(MaskT val) : + _val(val) + { + } + public: + bitmask() : + _val(MaskT()) + { + } + + bitmask(const FlagT &flag) : + _val(flag) + { + } + + bitmask(const bitmask &other) : + _val(other._val) + { + } + + inline bool test(const FlagT &flag) const + { + return 0 != (_val & flag); + } + + inline bool test(const bitmask &mask) const + { + return 0 != (_val & mask); + } + + inline bitmask& set(const FlagT &flag) + { + _val |= flag; + return *this; + } + + inline bitmask& set(const bitmask &mask) + { + _val |= mask._val; + return *this; + } + + inline bitmask& reset(const FlagT &flag) + { + _val &= ~flag; + return *this; + } + + inline bitmask& reset(const bitmask &mask) + { + _val &= ~mask._val; + return *this; + } + + inline bitmask& keep(const FlagT &flag) + { + _val &= flag; + return *this; + } + + inline bitmask& keep(const bitmask &mask) + { + _val &= mask._val; + return *this; + } + + inline bitmask& flip(const FlagT &flag) + { + _val ^= flag; + return *this; + } + + inline bitmask& flip(const bitmask &mask) + { + _val ^= mask._val; + return *this; + } + + inline bitmask operator|(const FlagT &flag) const + { + return *this | bitmask(flag); + } + + inline bitmask operator|(const bitmask &mask) const + { + return _val | mask._val; + } + + inline bitmask operator&(const FlagT &flag) const + { + return *this & bitmask(flag); + } + + inline bitmask operator&(const bitmask &mask) const + { + return _val & mask._val; + } + + inline bitmask operator^(const FlagT &flag) const + { + return *this ^ bitmask(flag); + } + + inline bitmask operator^(const bitmask &mask) const + { + return _val ^ mask._val; + } + + inline bitmask& operator=(const FlagT &flag) + { + *this = bitmask(flag); + return *this; + } + + inline bitmask& operator=(const bitmask &other) + { + _val = other._val; + return *this; + } + + inline bitmask& operator|=(const FlagT &flag) + { + return set(flag); + } + + inline bitmask& operator|=(const bitmask &other) + { + return set(other); + } + + inline bitmask& operator&=(const FlagT &flag) + { + return keep(flag); + } + + inline bitmask& operator&=(const bitmask &other) + { + return keep(other); + } + + inline bitmask& operator^=(const FlagT &flag) + { + return flip(flag); + } + + inline bitmask& operator^=(const bitmask &other) + { + return flip(other); + } + + inline bool operator==(const FlagT &flag) const + { + return test(flag); + } + + inline bool operator==(const bitmask &other) const + { + return test(other); + } + + inline bool operator!=(const FlagT &flag) const + { + return !test(flag); + } + + inline bool operator!=(const bitmask &other) const + { + return !test(other); + } + + inline bool operator<(const bitmask &other) const + { + return _val < other._val; + } + + inline bool operator>(const bitmask &other) const + { + return _val > other._val; + } + + inline operator const MaskT&() const + { + return _val; + } + + private: + MaskT _val; + }; +} + +template +inline cppbitmasks::bitmask operator|(const FlagT &flag, const cppbitmasks::bitmask &mask) +{ + return mask | flag; +} + +template +inline cppbitmasks::bitmask operator&(const FlagT &flag, const cppbitmasks::bitmask &mask) +{ + return mask & flag; +} + +template +inline cppbitmasks::bitmask operator^(const FlagT &flag, const cppbitmasks::bitmask &mask) +{ + return mask ^ flag; +} + +template +inline cppbitmasks::bitmask operator==(const FlagT &flag, const cppbitmasks::bitmask &mask) +{ + return mask == flag; +} + +template +inline cppbitmasks::bitmask operator!=(const FlagT &flag, const cppbitmasks::bitmask &mask) +{ + return mask != flag; +} + +#endif \ No newline at end of file diff --git a/src/service/phbitmask.hpp b/src/service/phbitmask.hpp new file mode 100644 index 00000000..eb902bf6 --- /dev/null +++ b/src/service/phbitmask.hpp @@ -0,0 +1,100 @@ +#ifndef PH_BITMASK_HPP +#define PH_BITMASK_HPP + +#include "phproperty.hpp" +#include "bitmask.hpp" + +#include + +namespace PhWidgets +{ + template + class phbitmask + { + template + class bind_internal : + private phproperty::template bind + { + typedef cppbitmasks::bitmask value_t; + typedef phproperty ph_property_t; + typedef typename ph_property_t::template bind ph_bind_t; + + public: + bind_internal(WidgetClassT *parent) : + ph_bind_t(parent) + {} + + inline void set(value_t value) + { + static_cast(this)->set(value); + } + + inline value_t get() const + { + value_t bm; + MaskT mask = static_cast(this)->get(); + std::memcpy(&bm, &mask, sizeof(MaskT)); + return bm; + } + + inline operator value_t() const { return get(); } + + inline bind_internal &operator=(value_t value) { set(value); return *this; } + + inline value_t operator()(void) const { return get(); } + + inline void operator()(value_t value) { set(value); return *this; } + }; + + public: + template + class bind : + public bind_internal + { + typedef bind_internal internal_bind_t; + + public: + bind(WidgetClassT *parent) : + internal_bind_t(parent) + {} + + using internal_bind_t::operator=; + }; + }; + + /*template + class phbitmask + { + public: + template + class bind : + private phproperty::template bind + { + typedef cppbitmasks::bitmask value_t; + typedef phproperty::template bind ph_bind_t; + + public: + bind(WidgetClassT *parent) : + ph_bind_t(parent) + {} + + inline value_t get() const + { + value_t bm; + MaskT mask = static_cast(this)->get(); + std::memcpy(&bm, &mask, sizeof(MaskT)); + return bm; + } + + inline operator value_t() const { return get(); } + + inline value_t operator()(void) const { return get(); } + + private: + inline bind &operator=(value_t const &); + inline bind &operator=(bind const &); + }; + };*/ +} + +#endif \ No newline at end of file diff --git a/src/service/phproperty.hpp b/src/service/phproperty.hpp index e9fcdd31..4496b0a6 100644 --- a/src/service/phproperty.hpp +++ b/src/service/phproperty.hpp @@ -90,6 +90,7 @@ namespace PhWidgets inline bind &operator=(ValueT const &); inline bind &operator=(bind const &); }; + }; diff --git a/src/service/property.hpp b/src/service/property.hpp index 2cc93962..baa04349 100644 --- a/src/service/property.hpp +++ b/src/service/property.hpp @@ -232,7 +232,6 @@ namespace cppproperties inline operator value_t() const { return get(); } - inline bind &operator=(bind const &) {return *this;} inline bind &operator=(value_t value) { set(value); return *this; } inline value_t operator()(void) const { return get(); } @@ -299,7 +298,6 @@ namespace cppproperties (_obj->*Setter)(value); } - inline bind &operator=(bind const &) {return *this;} inline bind &operator=(value_t value) { set(value); return *this; } inline void operator()(value_t value) { set(value); return *this; }