From 8a0058b5b90bb7e9eacf1646142f4d73b426fd66 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Wed, 16 Sep 2009 19:16:18 +0000 Subject: [PATCH] Add Container class Derive all Widgets that contain other Widgets from Container Communicate various things to a Widget's parent with signals Make List::slider not a pointer --- source/container.cpp | 167 +++++++++++++++++++++++++++++++++ source/container.h | 57 ++++++++++++ source/dropdown.cpp | 63 ++++--------- source/dropdown.h | 8 +- source/list.cpp | 58 +++--------- source/list.h | 15 +-- source/panel.cpp | 217 ++++++++++++++++++------------------------- source/panel.h | 36 +++---- source/root.cpp | 3 +- source/widget.cpp | 13 ++- source/widget.h | 16 +++- 11 files changed, 390 insertions(+), 263 deletions(-) create mode 100644 source/container.cpp create mode 100644 source/container.h diff --git a/source/container.cpp b/source/container.cpp new file mode 100644 index 0000000..a755644 --- /dev/null +++ b/source/container.cpp @@ -0,0 +1,167 @@ +/* $Id$ + +This file is part of libmspgltk +Copyright © 2009 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ + +#include "container.h" + +using namespace std; + +namespace Msp { +namespace GLtk { + +Container::Container(const Resources &r): + Widget(r), + click_focus(0), + click_button(0) +{ } + +Container::~Container() +{ + while(!children.empty()) + delete children.front()->widget; +} + +void Container::add(Widget &wdg) +{ + set_parent(wdg, this); + children.push_back(create_child(&wdg)); +} + +void Container::remove(Widget &wdg) +{ + for(list::iterator i=children.begin(); i!=children.end(); ++i) + if((*i)->widget==&wdg) + { + set_parent(wdg, 0); + delete *i; + children.erase(i); + return; + } + + throw InvalidState("That Widget is not in this Container"); +} + +list Container::get_children() const +{ + list result; + for(list::const_iterator i=children.begin(); i!=children.end(); ++i) + result.push_back((*i)->widget); + return result; +} + +Widget *Container::get_child_at(int x, int y) +{ + for(list::iterator i=children.end(); i!=children.begin();) + if((*--i)->widget->is_visible() && (*i)->widget->get_geometry().is_inside(x, y)) + return (*i)->widget; + + return 0; +} + +Widget *Container::get_descendant_at(int x, int y) +{ + Widget *wdg=get_child_at(x, y); + if(Container *cont=dynamic_cast(wdg)) + { + const Geometry &cgeom=wdg->get_geometry(); + return cont->get_descendant_at(x-cgeom.x, y-cgeom.y); + } + return wdg; +} + +void Container::button_press(int x, int y, unsigned btn) +{ + if(click_focus) + { + const Geometry &cgeom=click_focus->get_geometry(); + click_focus->button_press(x-cgeom.x, y-cgeom.y, btn); + } + else + { + if(Widget *wdg=get_child_at(x, y)) + { + click_focus=wdg; + click_button=btn; + + const Geometry &cgeom=wdg->get_geometry(); + wdg->button_press(x-cgeom.x, y-cgeom.y, btn); + } + } +} + +void Container::button_release(int x, int y, unsigned btn) +{ + if(click_focus) + { + Widget *wdg=click_focus; + + if(btn==click_button) + click_focus=0; + + const Geometry &cgeom=wdg->get_geometry(); + wdg->button_release(x-cgeom.x, y-cgeom.y, btn); + } + else + { + if(Widget *wdg=get_child_at(x, y)) + { + const Geometry &cgeom=wdg->get_geometry(); + wdg->button_release(x-cgeom.x, y-cgeom.y, btn); + } + } +} + +void Container::pointer_motion(int x, int y) +{ + if(click_focus) + { + const Geometry &cgeom=click_focus->get_geometry(); + click_focus->pointer_motion(x-cgeom.x, y-cgeom.y); + } + else + { + Widget *wdg=get_child_at(x, y); + if(wdg) + { + const Geometry &cgeom=wdg->get_geometry(); + wdg->pointer_motion(x-cgeom.x, y-cgeom.y); + } + } +} + +void Container::pointer_leave() +{ + Widget::pointer_leave(); + click_focus=0; +} + +Container::Child *Container::create_child(Widget *wdg) +{ + return new Child(*this, wdg); +} + + +Container::Child::Child(Container &c, Widget *w): + container(c), + widget(w) +{ + widget->signal_visibility_changed.connect(sigc::mem_fun(this, &Child::visibility_changed)); +} + +Container::Child::~Child() +{ + if(widget==container.click_focus) + container.click_focus=0; +} + +void Container::Child::visibility_changed(bool v) +{ + if(!v && widget==container.click_focus) + container.click_focus=0; +} + +} // namespace GLtk +} // namespace Msp diff --git a/source/container.h b/source/container.h new file mode 100644 index 0000000..32e8157 --- /dev/null +++ b/source/container.h @@ -0,0 +1,57 @@ +/* $Id$ + +This file is part of libmspgltk +Copyright © 2009 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ + +#ifndef MSP_GLTK_CONTAINER_H_ +#define MSP_GLTK_CONTAINER_H_ + +#include +#include +#include "widget.h" + +namespace Msp { +namespace GLtk { + +class Container: virtual public Widget +{ +protected: + struct Child: public sigc::trackable + { + Container &container; + Widget *widget; + + Child(Container &, Widget *); + virtual ~Child(); + + void visibility_changed(bool); + }; + + std::list children; + Widget *click_focus; + unsigned click_button; + + Container(const Resources &); +public: + virtual ~Container(); + + void add(Widget &); + void remove(Widget &); + std::list get_children() const; + Widget *get_child_at(int, int); + Widget *get_descendant_at(int, int); + + virtual void button_press(int, int, unsigned); + virtual void button_release(int, int, unsigned); + virtual void pointer_motion(int, int); + virtual void pointer_leave(); +protected: + virtual Child *create_child(Widget *); +}; + +} // namespace GLtk +} // namespace Msp + +#endif diff --git a/source/dropdown.cpp b/source/dropdown.cpp index a4816d4..cbd7ee4 100644 --- a/source/dropdown.cpp +++ b/source/dropdown.cpp @@ -1,7 +1,7 @@ /* $Id$ This file is part of libmspgltk -Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Copyright © 2007-2009 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ @@ -19,19 +19,16 @@ namespace GLtk { Dropdown::Dropdown(const Resources &r): Widget(r), + Container(r), list(r), - dropped(false), - list_active(false) + dropped(false) { + add(list); list.signal_item_selected.connect(sigc::mem_fun(this, &Dropdown::list_item_selected)); update_style(); } -Dropdown::~Dropdown() -{ -} - void Dropdown::append(const string &item) { list.append(item); @@ -78,47 +75,21 @@ int Dropdown::get_selected_index() const 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(dropped) + if(dropped) { - dropped=false; - state&=~ACTIVE; - parent->ungrab_pointer(*this); + Container::button_press(x, y, btn); + if(!click_focus) + { + dropped=false; + state&=~ACTIVE; + signal_ungrab_pointer.emit(); + } } else if(btn==1) { dropped=true; 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); + signal_grab_pointer.emit(); } } @@ -144,7 +115,7 @@ void Dropdown::resize_list() unsigned n_items=list.get_n_items(); const Style &stl=list.get_style(); const GL::Font &font=*stl.get_font(); - unsigned h=min(max(n_items, 1U), 20U)*static_cast((font.get_ascent()-font.get_descent())*font.get_default_size()); + unsigned h=min(max(n_items, 1U), 10U)*static_cast((font.get_ascent()-font.get_descent())*font.get_default_size()); for(std::list::const_iterator i=stl.get_parts().begin(); i!=stl.get_parts().end(); ++i) if(i->get_name()=="items") { @@ -158,11 +129,9 @@ void Dropdown::list_item_selected(unsigned index, const std::string &item) { if(dropped) { - list_active=false; dropped=false; state&=~ACTIVE; - if(parent) - parent->ungrab_pointer(*this); + signal_ungrab_pointer.emit(); } signal_item_selected.emit(index, item); @@ -177,7 +146,7 @@ Dropdown::Loader::Loader(Dropdown &d): void Dropdown::Loader::item(const string &str) { - static_cast(wdg).append(str); + dynamic_cast(wdg).append(str); } } // namespace GLtk diff --git a/source/dropdown.h b/source/dropdown.h index ecba975..7428ebf 100644 --- a/source/dropdown.h +++ b/source/dropdown.h @@ -1,7 +1,7 @@ /* $Id$ This file is part of libmspgltk -Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Copyright © 2007-2009 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ @@ -17,7 +17,7 @@ namespace GLtk { class List; -class Dropdown: public Widget +class Dropdown: virtual public Widget, private Container { public: class Loader: public Widget::Loader @@ -31,13 +31,11 @@ public: private: List list; bool dropped; - bool list_active; public: sigc::signal signal_item_selected; Dropdown(const Resources &); - ~Dropdown(); void append(const std::string &); void insert(unsigned, const std::string &); @@ -50,8 +48,6 @@ public: int get_selected_index() const; virtual void button_press(int, int, unsigned); - virtual void button_release(int, int, unsigned); - virtual void pointer_motion(int, int); private: virtual const char *get_class() const { return "dropdown"; } diff --git a/source/list.cpp b/source/list.cpp index 5bef367..cc9f707 100644 --- a/source/list.cpp +++ b/source/list.cpp @@ -1,7 +1,7 @@ /* $Id$ This file is part of libmspgltk -Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Copyright © 2007-2009 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ @@ -21,25 +21,21 @@ namespace GLtk { List::List(const Resources &r): Widget(r), + Container(r), sel_index(-1), first(0), n_visible(1), row_height(1), items_part(0), - slider(new VSlider(res)), - slider_active(false) + slider(res) { - slider->set_step(1); - slider->signal_value_changed.connect(sigc::mem_fun(this, &List::slider_value_changed)); + add(slider); + slider.set_step(1); + slider.signal_value_changed.connect(sigc::mem_fun(this, &List::slider_value_changed)); update_style(); } -List::~List() -{ - delete slider; -} - void List::append(const string &v) { items.push_back(v); @@ -100,13 +96,8 @@ const string &List::get_selected() const void List::button_press(int x, int y, unsigned btn) { - if(slider->get_geometry().is_inside(x, y)) - { - const Geometry &sgeom=slider->get_geometry(); - slider->button_press(x-sgeom.x, y-sgeom.y, btn); - slider_active=true; - } - else if(btn==1) + Container::button_press(x, y, btn); + if(!click_focus && btn==1) { if(items_part) y+=items_part->get_margin().top; @@ -121,25 +112,6 @@ void List::button_press(int x, int y, unsigned btn) } } -void List::button_release(int x, int y, unsigned btn) -{ - if(slider_active) - { - const Geometry &sgeom=slider->get_geometry(); - slider->button_release(x-sgeom.x, y-sgeom.y, btn); - slider_active=false; - } -} - -void List::pointer_motion(int x, int y) -{ - if(slider_active) - { - const Geometry &sgeom=slider->get_geometry(); - slider->pointer_motion(x-sgeom.x, y-sgeom.y); - } -} - void List::render_special(const Part &part) const { if(part.get_name()=="items") @@ -193,7 +165,7 @@ void List::render_special(const Part &part) const } } else if(part.get_name()=="slider") - slider->render(); + slider.render(); } void List::on_geometry_change() @@ -225,7 +197,7 @@ void List::reposition_slider() { Geometry sgeom=i->get_geometry(); i->get_alignment().apply(sgeom, geom, i->get_margin()); - slider->set_geometry(sgeom); + slider.set_geometry(sgeom); } } @@ -250,13 +222,13 @@ void List::recalculate_parameters() if(items.size()>n_visible) { - slider->set_range(0, items.size()-n_visible); - slider->set_value(items.size()-n_visible-first); + slider.set_range(0, items.size()-n_visible); + slider.set_value(items.size()-n_visible-first); } else { - slider->set_range(0, 0); - slider->set_value(0); + slider.set_range(0, 0); + slider.set_value(0); } } @@ -275,7 +247,7 @@ List::Loader::Loader(List &l): void List::Loader::item(const string &v) { - static_cast(wdg).append(v); + dynamic_cast(wdg).append(v); } } // namespace GLtk diff --git a/source/list.h b/source/list.h index 770cc2f..dee57ed 100644 --- a/source/list.h +++ b/source/list.h @@ -1,7 +1,7 @@ /* $Id$ This file is part of libmspgltk -Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Copyright © 2007-2009 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ @@ -9,18 +9,17 @@ Distributed under the LGPL #define MSP_GLTK_LIST_H_ #include -#include "widget.h" +#include "container.h" +#include "vslider.h" namespace Msp { namespace GLtk { -class VSlider; - /** Shows a list of items, allowing the user to select one. A slider is included to allow scrolling through a long list. */ -class List: public Widget +class List: virtual public Widget, private Container { public: class Loader: public Widget::Loader @@ -40,14 +39,12 @@ private: const Part *items_part; - VSlider *slider; - bool slider_active; + VSlider slider; public: sigc::signal signal_item_selected; List(const Resources &); - ~List(); void append(const std::string &); void insert(unsigned, const std::string &); @@ -60,8 +57,6 @@ public: int get_selected_index() const { return sel_index; } virtual void button_press(int, int, unsigned); - virtual void button_release(int, int, unsigned); - virtual void pointer_motion(int, int); private: virtual const char *get_class() const { return "list"; } diff --git a/source/panel.cpp b/source/panel.cpp index aeca9e7..14e9b6e 100644 --- a/source/panel.cpp +++ b/source/panel.cpp @@ -1,7 +1,7 @@ /* $Id$ This file is part of libmspgltk -Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Copyright © 2007-2009 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ @@ -27,114 +27,73 @@ namespace GLtk { Panel::Panel(const Resources &r): Widget(r), + Container(r), pointer_focus(0), - pointer_grab(0), + pointer_grabbed(false), input_focus(0) { update_style(); } -Panel::~Panel() -{ - while(!children.empty()) - delete children.front(); -} - -void Panel::add(Widget &wdg) -{ - set_parent(wdg, this); - children.push_back(&wdg); -} - -void Panel::remove(Widget &wdg) -{ - list::iterator i=find(children.begin(), children.end(), &wdg); - if(i==children.end()) - throw InvalidState("That Widget is not in this Panel"); - - if(&wdg==pointer_focus) - set_pointer_focus(0, 0); - if(&wdg==input_focus) - set_input_focus(0); - - set_parent(wdg, 0); - children.erase(i); -} - void Panel::raise(Widget &wdg) { - list::iterator i=find(children.begin(), children.end(), &wdg); - if(i==children.end()) - throw InvalidState("That Widget is not in this Panel"); + for(list::iterator i=children.begin(); i!=children.end(); ++i) + if((*i)->widget==&wdg) + { + children.splice(children.end(), children, i); + return; + } - children.erase(i); - children.push_back(&wdg); + throw InvalidState("That Widget is not in this Panel"); } void Panel::button_press(int x, int y, unsigned btn) { - if(pointer_grab>0) + if(pointer_grabbed) { const Geometry &cgeom=pointer_focus->get_geometry(); pointer_focus->button_press(x-cgeom.x, y-cgeom.y, btn); } - else if(geom.is_inside_relative(x, y)) + else { if(Widget *wdg=get_child_at(x, y)) { - set_pointer_focus(wdg, btn); + set_pointer_focus(wdg); set_input_focus(wdg); - - const Geometry &cgeom=wdg->get_geometry(); - wdg->button_press(x-cgeom.x, y-cgeom.y, btn); } + Container::button_press(x, y, btn); } } void Panel::button_release(int x, int y, unsigned btn) { - if(pointer_grab>0) + if(pointer_grabbed) { - Widget *wdg=pointer_focus; - - if(btn==pointer_grab) - set_pointer_focus(get_child_at(x, y), 0); - - const Geometry &cgeom=wdg->get_geometry(); - wdg->button_release(x-cgeom.x, y-cgeom.y, btn); - } - else if(geom.is_inside_relative(x, y)) - { - if(Widget *wdg=get_child_at(x, y)) - { - const Geometry &cgeom=wdg->get_geometry(); - wdg->button_release(x-cgeom.x, y-cgeom.y, btn); - } + const Geometry &cgeom=pointer_focus->get_geometry(); + pointer_focus->button_release(x-cgeom.x, y-cgeom.y, btn); } + else + Container::button_release(x, y, btn); } void Panel::pointer_motion(int x, int y) { - if(pointer_grab>0) + if(pointer_grabbed) { const Geometry &cgeom=pointer_focus->get_geometry(); pointer_focus->pointer_motion(x-cgeom.x, y-cgeom.y); } - else if(geom.is_inside_relative(x, y)) + else { - Widget *wdg=get_child_at(x, y); - set_pointer_focus(wdg, 0); - if(wdg) - { - const Geometry &cgeom=wdg->get_geometry(); - wdg->pointer_motion(x-cgeom.x, y-cgeom.y); - } + set_pointer_focus(get_child_at(x, y)); + Container::pointer_motion(x, y); } } void Panel::pointer_leave() { - set_pointer_focus(0, 0); + Container::pointer_leave(); + set_pointer_focus(0); } void Panel::key_press(unsigned key, unsigned mod, wchar_t ch) @@ -154,64 +113,23 @@ void Panel::focus_out() set_input_focus(0); } -void Panel::child_hidden(Widget &wdg) -{ - if(&wdg==pointer_focus) - set_pointer_focus(0, 0); - if(&wdg==input_focus) - set_input_focus(0); -} - -void Panel::grab_pointer(Widget &wdg) -{ - if(pointer_grab==0 || pointer_focus==&wdg) - { - set_pointer_focus(&wdg, 255); - if(parent) - parent->grab_pointer(*this); - } - else - throw InvalidState("Pointer is already grabbed"); -} - -void Panel::ungrab_pointer(Widget &wdg) -{ - if(pointer_focus==&wdg) - { - set_pointer_focus(0, 0); - if(parent) - parent->ungrab_pointer(*this); - } - else if(pointer_grab>0) - throw Exception("Someone is trying to steal the pointer!"); -} - -void Panel::grab_focus(Widget &wdg) -{ - list::iterator i=find(children.begin(), children.end(), &wdg); - if(i==children.end()) - throw InvalidState("That Widget is not in this Panel"); - - set_input_focus(&wdg); - if(parent) - parent->grab_focus(*this); -} - void Panel::render_special(const Part &part) const { if(part.get_name()=="children") { - for(list::const_iterator i=children.begin(); i!=children.end(); ++i) - if((*i)->is_visible()) - (*i)->render(); + for(list::const_iterator i=children.begin(); i!=children.end(); ++i) + if((*i)->widget->is_visible()) + (*i)->widget->render(); } } -void Panel::set_pointer_focus(Widget *wdg, int grab) +Panel::Child *Panel::create_child(Widget *wdg) { - if(grab>0 && !wdg) - throw InvalidParameterValue("Can't grab on null widget"); + return new Child(*this, wdg); +} +void Panel::set_pointer_focus(Widget *wdg) +{ if(wdg!=pointer_focus) { if(pointer_focus) @@ -222,8 +140,6 @@ void Panel::set_pointer_focus(Widget *wdg, int grab) if(pointer_focus) pointer_focus->pointer_enter(); } - - pointer_grab=grab; } void Panel::set_input_focus(Widget *wdg) @@ -236,19 +152,13 @@ void Panel::set_input_focus(Widget *wdg) input_focus=wdg; if(input_focus) + { + raise(*wdg); input_focus->focus_in(); + } } } -Widget *Panel::get_child_at(int x, int y) -{ - for(list::reverse_iterator i=children.rbegin(); i!=children.rend(); ++i) - if((*i)->is_visible() && (*i)->get_geometry().is_inside(x, y)) - return *i; - - return 0; -} - Panel::Loader::Loader(Panel &p, map &m): Widget::Loader(p), @@ -285,5 +195,60 @@ void Panel::Loader::panel(const string &n) wdg_map[n]=p.release(); } + +Panel::Child::Child(Panel &p, Widget *w): + Container::Child(p, w) +{ + widget->signal_visibility_changed.connect(sigc::mem_fun(this, &Child::visibility_changed)); + widget->signal_request_focus.connect(sigc::mem_fun(this, &Child::request_focus)); + widget->signal_grab_pointer.connect(sigc::mem_fun(this, &Child::grab_pointer)); + widget->signal_ungrab_pointer.connect(sigc::mem_fun(this, &Child::ungrab_pointer)); +} + +Panel::Child::~Child() +{ + visibility_changed(false); +} + +void Panel::Child::visibility_changed(bool v) +{ + if(!v) + { + Panel &panel=static_cast(container); + if(widget==panel.pointer_focus) + panel.set_pointer_focus(0); + if(widget==panel.input_focus) + panel.set_input_focus(0); + } +} + +void Panel::Child::request_focus() +{ + static_cast(container).set_input_focus(widget); +} + +void Panel::Child::grab_pointer() +{ + Panel &panel=static_cast(container); + if(!panel.pointer_grabbed) + { + panel.set_pointer_focus(widget); + panel.pointer_grabbed=true; + panel.signal_grab_pointer.emit(); + } +} + +void Panel::Child::ungrab_pointer() +{ + Panel &panel=static_cast(container); + if(panel.pointer_grabbed && panel.pointer_focus==widget) + { + // XXX Should set to the widget under pointer + panel.set_pointer_focus(0); + panel.pointer_grabbed=false; + panel.signal_ungrab_pointer.emit(); + } +} + } // namespace GLtk } // namespace Msp diff --git a/source/panel.h b/source/panel.h index e269ca2..b431a85 100644 --- a/source/panel.h +++ b/source/panel.h @@ -1,14 +1,14 @@ /* $Id$ This file is part of libmspgltk -Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Copyright © 2007-2009 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ #ifndef MSP_GLTK_PANEL_H_ #define MSP_GLTK_PANEL_H_ -#include "widget.h" +#include "container.h" namespace Msp { namespace GLtk { @@ -18,7 +18,7 @@ Panels are containers for other widgets. Panel styles should have a special part "children" to render the child widgets. All properties of this part are ignored. */ -class Panel: public Widget +class Panel: public Container { public: class Loader: public Widget::Loader @@ -36,22 +36,28 @@ public: }; private: - std::list children; + struct Child: public Container::Child + { + Child(Panel &, Widget *); + virtual ~Child(); + + void visibility_changed(bool); + void request_focus(); + void grab_pointer(); + void ungrab_pointer(); + void raise(); + }; + Widget *pointer_focus; - unsigned pointer_grab; + bool pointer_grabbed; Widget *input_focus; Panel(const Panel &); Panel &operator=(const Panel &); public: Panel(const Resources &); - ~Panel(); - void add(Widget &); - void remove(Widget &); - const std::list &get_children() const { return children; } void raise(Widget &); - void set_focus(Widget &); virtual void button_press(int, int, unsigned); virtual void button_release(int, int, unsigned); @@ -60,19 +66,13 @@ public: virtual void key_press(unsigned, unsigned, wchar_t); virtual void key_release(unsigned, unsigned); virtual void focus_out(); - - // These functions are not intended to be called from outside GLtk - void child_hidden(Widget &); - void grab_pointer(Widget &); - void ungrab_pointer(Widget &); - void grab_focus(Widget &); private: virtual const char *get_class() const { return "panel"; } virtual void render_special(const Part &) const; + virtual Child *create_child(Widget *); - void set_pointer_focus(Widget *, int); + void set_pointer_focus(Widget *); void set_input_focus(Widget *); - Widget *get_child_at(int, int); }; } // namespace GLtk diff --git a/source/root.cpp b/source/root.cpp index 9d02c4a..6bc5793 100644 --- a/source/root.cpp +++ b/source/root.cpp @@ -1,7 +1,7 @@ /* $Id$ This file is part of libmspgltk -Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Copyright © 2007-2009 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ @@ -12,6 +12,7 @@ namespace Msp { namespace GLtk { Root::Root(const Resources &r, Graphics::Window &w): + Widget(r), Panel(r), window(w) { diff --git a/source/widget.cpp b/source/widget.cpp index 48b647b..84d0425 100644 --- a/source/widget.cpp +++ b/source/widget.cpp @@ -1,7 +1,7 @@ /* $Id$ This file is part of libmspgltk -Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Copyright © 2007-2009 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ @@ -65,8 +65,7 @@ void Widget::set_visible(bool v) visible=v; - if(!visible && parent) - parent->child_hidden(*this); + signal_visibility_changed.emit(visible); } void Widget::set_focus() @@ -76,7 +75,7 @@ void Widget::set_focus() if(!visible) throw InvalidState("Can't set focus on invisible widget"); - parent->grab_focus(*this); + signal_request_focus.emit(); } void Widget::render() const @@ -158,16 +157,16 @@ void Widget::update_style() on_style_change(); } -void Widget::set_parent(Panel *p) +void Widget::set_parent(Container *p) { if(parent && p) - throw InvalidState("Widget is already in a Panel"); + throw InvalidState("Widget is already in a Container"); parent=p; on_reparent(); } -void Widget::set_parent(Widget &w, Panel *p) +void Widget::set_parent(Widget &w, Container *p) { w.set_parent(p); } diff --git a/source/widget.h b/source/widget.h index 8cf67d4..6774cbe 100644 --- a/source/widget.h +++ b/source/widget.h @@ -1,7 +1,7 @@ /* $Id$ This file is part of libmspgltk -Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Copyright © 2007-2009 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ @@ -15,7 +15,7 @@ Distributed under the LGPL namespace Msp { namespace GLtk { -class Panel; +class Container; class Part; class Resources; class Style; @@ -41,6 +41,12 @@ public: void style(const std::string &); }; + sigc::signal signal_visibility_changed; + sigc::signal signal_request_focus; + sigc::signal signal_grab_pointer; + sigc::signal signal_ungrab_pointer; + sigc::signal signal_request_raise; + protected: const Resources &res; Geometry geom; @@ -48,7 +54,7 @@ protected: const Style *style; State state; bool visible; - Panel *parent; + Container *parent; Widget(const Resources &); public: @@ -104,12 +110,12 @@ protected: Sets the widget's parent Panel. The widget must be unparented when calling this function with a nonzero parameter. */ - void set_parent(Panel *); + void set_parent(Container *); /** A helper function to set the parent of another widget. */ - void set_parent(Widget &, Panel *); + void set_parent(Widget &, Container *); // More events virtual void on_geometry_change() { } -- 2.43.0