From 50bf1ef2e2c3c38de20f6996a6c5ed0066111177 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Mon, 3 Mar 2008 17:48:55 +0000 Subject: [PATCH] Change State into a bitmask to allow more fine-grained control of styles --- source/button.cpp | 16 ++++------------ source/button.h | 1 - source/dropdown.cpp | 26 +++++++++----------------- source/dropdown.h | 3 +-- source/entry.cpp | 12 ------------ source/entry.h | 2 -- source/hslider.cpp | 6 ------ source/indicator.cpp | 5 ++++- source/part.cpp | 9 ++++----- source/slider.cpp | 2 ++ source/state.cpp | 37 +++++++++++++++++++++++++++---------- source/state.h | 26 +++++++++++++++++++++----- source/toggle.cpp | 24 ++++++++---------------- source/toggle.h | 2 -- source/vslider.cpp | 6 ------ source/widget.cpp | 20 ++++++++++++++++++++ source/widget.h | 8 ++++---- 17 files changed, 104 insertions(+), 101 deletions(-) diff --git a/source/button.cpp b/source/button.cpp index 3661c01..20e0ed9 100644 --- a/source/button.cpp +++ b/source/button.cpp @@ -29,7 +29,7 @@ void Button::button_press(int, int, unsigned btn) if(btn==1) { pressed=true; - state=ACTIVE; + state|=ACTIVE; } } @@ -38,25 +38,17 @@ void Button::button_release(int x, int y, unsigned btn) if(pressed && btn==1) { if(geom.is_inside_relative(x, y)) - { - state=HOVER; signal_clicked.emit(); - } - else - state=NORMAL; + state&=~ACTIVE; pressed=false; } } -void Button::pointer_enter() -{ - state=HOVER; -} - void Button::pointer_leave() { - state=NORMAL; + Widget::pointer_leave(); + state&=~ACTIVE; } void Button::render_special(const Part &part) const diff --git a/source/button.h b/source/button.h index ea96a7d..63159ee 100644 --- a/source/button.h +++ b/source/button.h @@ -39,7 +39,6 @@ public: void set_text(const std::string &); virtual void button_press(int, int, unsigned); virtual void button_release(int, int, unsigned); - virtual void pointer_enter(); virtual void pointer_leave(); private: virtual const char *get_class() const { return "button"; } diff --git a/source/dropdown.cpp b/source/dropdown.cpp index 5f49b9e..4d18187 100644 --- a/source/dropdown.cpp +++ b/source/dropdown.cpp @@ -18,6 +18,7 @@ namespace GLtk { Dropdown::Dropdown(const Resources &r): Widget(r), list(new List(res)), + dropped(false), list_active(false) { list->signal_item_selected.connect(sigc::mem_fun(this, &Dropdown::list_item_selected)); @@ -43,14 +44,16 @@ void Dropdown::button_press(int x, int y, unsigned btn) list->button_press(x-lgeom.x, y-lgeom.y, btn); list_active=true; } - else if(state==ACTIVE) + else if(dropped) { - state=HOVER; + dropped=false; + state&=~ACTIVE; parent->ungrab_pointer(*this); } else if(btn==1) { - state=ACTIVE; + dropped=true; + state|=ACTIVE; if(parent) { @@ -79,23 +82,11 @@ void Dropdown::pointer_motion(int x, int y) } } -void Dropdown::pointer_enter() -{ - if(state==NORMAL) - state=HOVER; -} - -void Dropdown::pointer_leave() -{ - if(state==HOVER) - state=NORMAL; -} - void Dropdown::render_special(const Part &part) const { if(part.get_name()=="text") render_text(part, text); - else if(part.get_name()=="list" && state==ACTIVE) + else if(part.get_name()=="list" && dropped) list->render(); } @@ -109,7 +100,8 @@ void Dropdown::list_item_selected(unsigned index, const std::string &item) text=item; list_active=false; - state=NORMAL; + dropped=false; + state&=~ACTIVE; if(parent) parent->ungrab_pointer(*this); diff --git a/source/dropdown.h b/source/dropdown.h index d1a2609..49088e2 100644 --- a/source/dropdown.h +++ b/source/dropdown.h @@ -30,6 +30,7 @@ public: private: List *list; std::string text; + bool dropped; bool list_active; public: @@ -43,8 +44,6 @@ public: virtual void button_press(int, int, unsigned); virtual void button_release(int, int, unsigned); virtual void pointer_motion(int, int); - virtual void pointer_enter(); - virtual void pointer_leave(); private: virtual const char *get_class() const { return "dropdown"; } virtual void render_special(const Part &) const; diff --git a/source/entry.cpp b/source/entry.cpp index 7e503b3..9f7c761 100644 --- a/source/entry.cpp +++ b/source/entry.cpp @@ -57,18 +57,6 @@ void Entry::key_press(unsigned key, unsigned, wchar_t ch) } } -void Entry::focus_in() -{ - if(state!=DISABLED) - state=ACTIVE; -} - -void Entry::focus_out() -{ - if(state==ACTIVE) - state=NORMAL; -} - void Entry::render_special(const Part &part) const { if(part.get_name()=="text") diff --git a/source/entry.h b/source/entry.h index c880bb4..e5f3fd8 100644 --- a/source/entry.h +++ b/source/entry.h @@ -41,8 +41,6 @@ public: const std::string &get_text() const { return text; } virtual void key_press(unsigned, unsigned, wchar_t); - virtual void focus_in(); - virtual void focus_out(); private: virtual const char *get_class() const { return "entry"; } virtual void render_special(const Part &) const; diff --git a/source/hslider.cpp b/source/hslider.cpp index 32d0f65..a0caca5 100644 --- a/source/hslider.cpp +++ b/source/hslider.cpp @@ -27,20 +27,14 @@ void HSlider::button_press(int x, int y, unsigned btn) { int sx=geom.x+static_cast((geom.w-slider_size)*(value-min)/(max-min)); if(btn==1 && x>=sx && x(sx+slider_size)) - { - state=ACTIVE; start_drag(x); - } } } void HSlider::button_release(int, int, unsigned btn) { if(btn==1) - { end_drag(); - state=NORMAL; - } } void HSlider::pointer_motion(int x, int) diff --git a/source/indicator.cpp b/source/indicator.cpp index 86c2524..2debf35 100644 --- a/source/indicator.cpp +++ b/source/indicator.cpp @@ -18,7 +18,10 @@ Indicator::Indicator(const Resources &r): void Indicator::set_active(bool a) { - state=(a ? ACTIVE : NORMAL); + if(a) + state|=ACTIVE; + else + state&=~ACTIVE; } } // namespace GLtk diff --git a/source/part.cpp b/source/part.cpp index a74c911..1f58b61 100644 --- a/source/part.cpp +++ b/source/part.cpp @@ -56,21 +56,20 @@ Part::Loader::Loader(Part &p, Resources &r): Part::Loader::~Loader() { for(unsigned i=0; iget_shadow(); part.geom.w=max(part.geom.w, part.graphic[i]->get_width()-shadow.left-shadow.right); part.geom.h=max(part.geom.h, part.graphic[i]->get_height()-shadow.bottom-shadow.top); } - else - part.graphic[i]=part.graphic[NORMAL]; - } } void Part::Loader::graphic(State s, const string &n) { - part.graphic[s]=res.get(n); + Graphic *grph=res.get(n); + for(int i=0; i>(istream &is, State &state) { string str; is>>str; - if(str=="NORMAL") - state=NORMAL; - else if(str=="HOVER") - state=HOVER; - else if(str=="ACTIVE") - state=ACTIVE; - else if(str=="DISABLED") - state=DISABLED; - else - is.setstate(ios_base::failbit); + + unsigned start=0; + state=NORMAL; + + while(1) + { + unsigned underscore=str.find('_', start); + if(!str.compare(start, underscore-start, "NORMAL")) + state|=NORMAL; + else if(!str.compare(start, underscore-start, "HOVER")) + state|=HOVER; + else if(!str.compare(start, underscore-start, "ACTIVE")) + state|=ACTIVE; + else if(!str.compare(start, underscore-start, "FOCUS")) + state|=FOCUS; + else if(!str.compare(start, underscore-start, "DISABLED")) + state|=DISABLED; + else + { + is.setstate(ios_base::failbit); + break; + } + + if(underscore==std::string::npos) + break; + start=underscore+1; + } return is; } diff --git a/source/state.h b/source/state.h index 8e29ab0..688d8dc 100644 --- a/source/state.h +++ b/source/state.h @@ -16,13 +16,29 @@ namespace GLtk { enum State { - NORMAL, //< Default state - HOVER, //< Pointer over the widget - ACTIVE, //< Widget is active (e.g. pressed button) - DISABLED, //< Widget is unresponsive - N_STATES_ //< Sentry value + NORMAL=0, //< Default state + HOVER=1, //< Pointer over the widget + ACTIVE=2, //< Widget is active (e.g. pressed button) + FOCUS=4, //< Widget has input focus + DISABLED=8, //< Widget is unresponsive + N_STATES_=16 //< Sentry value }; +inline State operator|(State a, State b) +{ return static_cast(static_cast(a)|static_cast(b)); } + +inline State operator|=(State &a, State b) +{ a=a|b; return a; } + +inline State operator&(State a, State b) +{ return static_cast(static_cast(a)&static_cast(b)); } + +inline State operator&=(State &a, State b) +{ a=a&b; return a; } + +inline State operator~(State a) +{ return static_cast(~static_cast(a)); } + extern std::istream &operator>>(std::istream &, State &); } // namespace GLtk diff --git a/source/toggle.cpp b/source/toggle.cpp index 1495344..dd6ce35 100644 --- a/source/toggle.cpp +++ b/source/toggle.cpp @@ -22,7 +22,10 @@ Toggle::Toggle(const Resources &r): void Toggle::set_value(bool v) { value=v; - state=(value ? ACTIVE : HOVER); + if(value) + state|=ACTIVE; + else + state&=~ACTIVE; } void Toggle::button_press(int, int, unsigned btn) @@ -40,25 +43,11 @@ void Toggle::button_release(int x, int y, unsigned btn) set_value(!value); signal_toggled.emit(value); } - else - state=NORMAL; pressed=false; } } -void Toggle::pointer_enter() -{ - if(!value) - state=HOVER; -} - -void Toggle::pointer_leave() -{ - if(!value) - state=NORMAL; -} - void Toggle::render_special(const Part &part) const { if(part.get_name()=="text") @@ -81,7 +70,10 @@ Toggle &Toggle::Loader::get_object() const void Toggle::Loader::finish() { Toggle &tgl=static_cast(wdg); - tgl.state=(tgl.value ? ACTIVE : NORMAL); + if(tgl.value) + tgl.state|=ACTIVE; + else + tgl.state&=~ACTIVE; } } // namespace GLtk diff --git a/source/toggle.h b/source/toggle.h index 6e3d632..f01f84b 100644 --- a/source/toggle.h +++ b/source/toggle.h @@ -44,8 +44,6 @@ public: virtual void button_press(int, int, unsigned); virtual void button_release(int, int, unsigned); - virtual void pointer_enter(); - virtual void pointer_leave(); private: virtual const char *get_class() const { return "toggle"; } virtual void render_special(const Part &) const; diff --git a/source/vslider.cpp b/source/vslider.cpp index d9e9e4d..57f98d5 100644 --- a/source/vslider.cpp +++ b/source/vslider.cpp @@ -27,20 +27,14 @@ void VSlider::button_press(int x, int y, unsigned btn) { int sy=static_cast((geom.h-slider_size)*(value-min)/(max-min)); if(btn==1 && y>=sy && y(sy+slider_size)) - { - state=ACTIVE; start_drag(y); - } } } void VSlider::button_release(int, int, unsigned btn) { if(btn==1 && dragging) - { end_drag(); - state=NORMAL; - } } void VSlider::pointer_motion(int, int y) diff --git a/source/widget.cpp b/source/widget.cpp index 0128367..be1f0a0 100644 --- a/source/widget.cpp +++ b/source/widget.cpp @@ -115,6 +115,26 @@ void Widget::render_text(const Part &part, const string &text) const GL::pop_matrix(); } +void Widget::pointer_enter() +{ + state|=HOVER; +} + +void Widget::pointer_leave() +{ + state&=~HOVER; +} + +void Widget::focus_in() +{ + state|=FOCUS; +} + +void Widget::focus_out() +{ + state&=~FOCUS; +} + void Widget::update_style() { string sname=get_class(); diff --git a/source/widget.h b/source/widget.h index a83cecc..7fdc906 100644 --- a/source/widget.h +++ b/source/widget.h @@ -79,12 +79,12 @@ public: virtual void button_press(int, int, unsigned) { } virtual void button_release(int, int, unsigned) { } virtual void pointer_motion(int, int) { } - virtual void pointer_enter() { } - virtual void pointer_leave() { } + virtual void pointer_enter(); + virtual void pointer_leave(); virtual void key_press(unsigned, unsigned, wchar_t) { } virtual void key_release(unsigned, unsigned) { } - virtual void focus_in() { } - virtual void focus_out() { } + virtual void focus_in(); + virtual void focus_out(); protected: /** -- 2.45.2