if(btn==1)
{
pressed=true;
- state=ACTIVE;
+ state|=ACTIVE;
}
}
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
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"; }
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));
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)
{
}
}
-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();
}
text=item;
list_active=false;
- state=NORMAL;
+ dropped=false;
+ state&=~ACTIVE;
if(parent)
parent->ungrab_pointer(*this);
private:
List *list;
std::string text;
+ bool dropped;
bool list_active;
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;
}
}
-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")
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;
{
int sx=geom.x+static_cast<int>((geom.w-slider_size)*(value-min)/(max-min));
if(btn==1 && x>=sx && x<static_cast<int>(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)
void Indicator::set_active(bool a)
{
- state=(a ? ACTIVE : NORMAL);
+ if(a)
+ state|=ACTIVE;
+ else
+ state&=~ACTIVE;
}
} // namespace GLtk
Part::Loader::~Loader()
{
for(unsigned i=0; i<N_STATES_; ++i)
- {
if(part.graphic[i])
{
const Sides &shadow=part.graphic[i]->get_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<Graphic>(n);
+ Graphic *grph=res.get<Graphic>(n);
+ for(int i=0; i<N_STATES_; ++i)
+ if((i&s)==s)
+ part.graphic[i]=grph;
}
void Part::Loader::align(float x, float y)
dragging=true;
drag_start_pos=p;
drag_start_value=value;
+ state|=ACTIVE;
}
void Slider::drag(int p)
void Slider::end_drag()
{
dragging=false;
+ state&=~ACTIVE;
}
{
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;
}
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<State>(static_cast<int>(a)|static_cast<int>(b)); }
+
+inline State operator|=(State &a, State b)
+{ a=a|b; return a; }
+
+inline State operator&(State a, State b)
+{ return static_cast<State>(static_cast<int>(a)&static_cast<int>(b)); }
+
+inline State operator&=(State &a, State b)
+{ a=a&b; return a; }
+
+inline State operator~(State a)
+{ return static_cast<State>(~static_cast<int>(a)); }
+
extern std::istream &operator>>(std::istream &, State &);
} // namespace GLtk
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)
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")
void Toggle::Loader::finish()
{
Toggle &tgl=static_cast<Toggle &>(wdg);
- tgl.state=(tgl.value ? ACTIVE : NORMAL);
+ if(tgl.value)
+ tgl.state|=ACTIVE;
+ else
+ tgl.state&=~ACTIVE;
}
} // namespace GLtk
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;
{
int sy=static_cast<int>((geom.h-slider_size)*(value-min)/(max-min));
if(btn==1 && y>=sy && y<static_cast<int>(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)
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();
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:
/**