namespace GLtk {
Button::Button(const Resources &r, const std::string &t):
- Widget(r)
+ Widget(r),
+ pressed(false)
{
set_text(t);
update_style();
void Button::button_press(int, int, unsigned btn)
{
if(btn==1)
+ {
+ pressed=true;
state=ACTIVE;
+ }
}
void Button::button_release(int x, int y, unsigned btn)
{
- if(btn==1)
+ if(pressed && btn==1)
{
if(geom.is_inside_relative(x, y))
{
}
else
state=NORMAL;
+
+ pressed=false;
}
}
--- /dev/null
+/* $Id$
+
+This file is part of libmspgltk
+Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#include "dropdown.h"
+#include "list.h"
+#include "panel.h"
+#include "part.h"
+
+using namespace std;
+
+namespace Msp {
+namespace GLtk {
+
+Dropdown::Dropdown(const Resources &r):
+ Widget(r),
+ list(new List(res)),
+ list_active(false)
+{
+ list->signal_item_selected.connect(sigc::mem_fun(this, &Dropdown::list_item_selected));
+
+ update_style();
+}
+
+Dropdown::~Dropdown()
+{
+ delete list;
+}
+
+void Dropdown::append(const string &item)
+{
+ list->append(item);
+}
+
+void Dropdown::button_press(int x, int y, unsigned btn)
+{
+ if(list->get_geometry().is_inside(x, y))
+ {
+ const Geometry &lgeom=list->get_geometry();
+ list->button_press(x-lgeom.x, y-lgeom.y, btn);
+ list_active=true;
+ }
+ else if(state==ACTIVE)
+ {
+ state=HOVER;
+ parent->ungrab_pointer(*this);
+ }
+ else if(btn==1)
+ {
+ state=ACTIVE;
+
+ if(parent)
+ {
+ parent->raise(*this);
+ parent->grab_pointer(*this);
+ }
+ }
+}
+
+void Dropdown::button_release(int x, int y, unsigned btn)
+{
+ if(list_active)
+ {
+ const Geometry &lgeom=list->get_geometry();
+ list->button_release(x-lgeom.x, y-lgeom.y, btn);
+ list_active=false;
+ }
+}
+
+void Dropdown::pointer_motion(int x, int y)
+{
+ if(list_active)
+ {
+ const Geometry &lgeom=list->get_geometry();
+ list->pointer_motion(x-lgeom.x, y-lgeom.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)
+ list->render();
+}
+
+void Dropdown::on_geometry_change()
+{
+ list->set_geometry(Geometry(0, -100, geom.w, 100));
+}
+
+void Dropdown::list_item_selected(unsigned index, const std::string &item)
+{
+ text=item;
+
+ list_active=false;
+ state=NORMAL;
+ if(parent)
+ parent->ungrab_pointer(*this);
+
+ signal_item_selected.emit(index, item);
+}
+
+} // namespace GLtk
+} // namespace Msp
--- /dev/null
+/* $Id$
+
+This file is part of libmspgltk
+Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#ifndef MSP_GLTK_DROPDOWN_H_
+#define MSP_GLTK_DROPDOWN_H_
+
+#include <sigc++/signal.h>
+#include "widget.h"
+
+namespace Msp {
+namespace GLtk {
+
+class List;
+
+class Dropdown: public Widget
+{
+private:
+ List *list;
+ std::string text;
+ bool list_active;
+
+public:
+ sigc::signal<void, int, const std::string &> signal_item_selected;
+
+ Dropdown(const Resources &);
+ ~Dropdown();
+
+ void append(const std::string &);
+
+ 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;
+
+ virtual void on_geometry_change();
+
+ void list_item_selected(unsigned, const std::string &);
+};
+
+} // namespace GLtk
+} // namespace Msp
+
+#endif
update_style();
}
+List::~List()
+{
+ delete slider;
+}
+
void List::append(const string &v)
{
items.push_back(v);
sigc::signal<void, unsigned, const std::string &> signal_item_selected;
List(const Resources &);
+ ~List();
+
void append(const std::string &);
void insert(unsigned, const std::string &);
void remove(unsigned);
#include <msp/core/refptr.h>
#include "button.h"
+#include "dropdown.h"
#include "entry.h"
#include "hslider.h"
#include "indicator.h"
}
}
+void Panel::raise(Widget &wdg)
+{
+ ChildSeq::iterator i=find(children.begin(), children.end(), &wdg);
+ if(i!=children.end())
+ {
+ children.erase(i);
+ children.push_back(&wdg);
+ }
+}
+
void Panel::button_press(int x, int y, unsigned btn)
{
if(pointer_grab>0)
set_pointer_focus(0, 0);
}
+void Panel::grab_pointer(Widget &wdg)
+{
+ if(pointer_grab==0 || pointer_focus==&wdg)
+ set_pointer_focus(&wdg, 255);
+ else
+ throw InvalidState("Pointer is already grabbed");
+}
+
+void Panel::ungrab_pointer(Widget &wdg)
+{
+ if(pointer_focus==&wdg)
+ set_pointer_focus(0, 0);
+ else if(pointer_grab>0)
+ throw Exception("Someone is trying to steal the pointer!");
+}
+
void Panel::render_special(const Part &part) const
{
if(part.get_name()=="children")
wdg_map(m)
{
add("button", &Loader::child<Button>);
+ add("dropdown", &Loader::child<Dropdown>);
add("entry", &Loader::child<Entry>);
add("hslider", &Loader::child<HSlider>);
add("indicator", &Loader::child<Indicator>);
void add(Widget &);
void remove(Widget &);
+ void raise(Widget &);
virtual void button_press(int, int, unsigned);
virtual void button_release(int, int, unsigned);
virtual void key_press(unsigned, unsigned, wchar_t);
virtual void key_release(unsigned, unsigned);
virtual void focus_out();
+
void child_hidden(Widget &);
+ void grab_pointer(Widget &);
+ void ungrab_pointer(Widget &);
private:
virtual const char *get_class() const { return "panel"; }
virtual void render_special(const Part &) const;
+
void set_pointer_focus(Widget *, int);
void set_input_focus(Widget *);
Widget *get_child_at(int, int);
Toggle::Toggle(const Resources &r):
Widget(r),
+ pressed(false),
value(false)
{
update_style();
}
-void Toggle::button_release(int x, int y, unsigned btn)
+void Toggle::set_value(bool v)
+{
+ value=v;
+ state=(value ? ACTIVE : HOVER);
+}
+
+void Toggle::button_press(int, int, unsigned btn)
{
if(btn==1)
+ pressed=true;
+}
+
+void Toggle::button_release(int x, int y, unsigned btn)
+{
+ if(pressed && btn==1)
{
if(geom.is_inside_relative(x, y))
{
- value=!value;
- state=(value ? ACTIVE : HOVER);
+ set_value(!value);
signal_toggled.emit(value);
}
else
state=NORMAL;
+
+ pressed=false;
}
}
return static_cast<Toggle &>(wdg);
}
+void Toggle::Loader::finish()
+{
+ Toggle &tgl=static_cast<Toggle &>(wdg);
+ tgl.state=(tgl.value ? ACTIVE : NORMAL);
+}
+
} // namespace GLtk
} // namespace Msp
public:
Loader(Toggle &);
Toggle &get_object() const;
+ private:
+ virtual void finish();
};
private:
std::string text;
+ bool pressed;
bool value;
public:
Toggle(const Resources &);
+ void set_value(bool);
bool get_value() const { return value; }
+ virtual void button_press(int, int, unsigned);
virtual void button_release(int, int, unsigned);
virtual void pointer_enter();
virtual void pointer_leave();