From aba0416fb73e17d068b30ff163c2fedcb0254da2 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 16 Aug 2008 12:35:31 +0000 Subject: [PATCH] Add Widget::set_focus Add Entry::signal_enter Make Panel throw on an attempt to handle a widget which is not in it --- source/entry.cpp | 2 ++ source/entry.h | 2 ++ source/panel.cpp | 47 +++++++++++++++++++++++++++++------------------ source/panel.h | 7 ++++--- source/widget.cpp | 10 ++++++++++ source/widget.h | 1 + 6 files changed, 48 insertions(+), 21 deletions(-) diff --git a/source/entry.cpp b/source/entry.cpp index 7f50ed0..523fea5 100644 --- a/source/entry.cpp +++ b/source/entry.cpp @@ -52,6 +52,8 @@ void Entry::key_press(unsigned key, unsigned, wchar_t ch) if(edit_pos>0) text.erase(--edit_pos, 1); } + else if(key==Input::KEY_ENTER) + signal_enter.emit(); else if(ch>=' ') { text.insert(edit_pos, Codecs::encode(Codecs::ustring(1, ch))); diff --git a/source/entry.h b/source/entry.h index e5f3fd8..29fec41 100644 --- a/source/entry.h +++ b/source/entry.h @@ -35,6 +35,8 @@ private: unsigned edit_pos; public: + sigc::signal signal_enter; + Entry(const Resources &, const std::string & =std::string()); void set_text(const std::string &); diff --git a/source/panel.cpp b/source/panel.cpp index ac277a9..3123db4 100644 --- a/source/panel.cpp +++ b/source/panel.cpp @@ -48,27 +48,27 @@ void Panel::add(Widget &wdg) void Panel::remove(Widget &wdg) { - ChildSeq::iterator i=find(children.begin(), children.end(), &wdg); - if(i!=children.end()) - { - if(&wdg==pointer_focus) - set_pointer_focus(0, 0); - if(&wdg==input_focus) - set_input_focus(0); + list::iterator i=find(children.begin(), children.end(), &wdg); + if(i==children.end()) + throw InvalidState("That Widget is not in this Panel"); - set_parent(wdg, 0); - children.erase(i); - } + 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) { - ChildSeq::iterator i=find(children.begin(), children.end(), &wdg); - if(i!=children.end()) - { - children.erase(i); - children.push_back(&wdg); - } + list::iterator i=find(children.begin(), children.end(), &wdg); + if(i==children.end()) + throw InvalidState("That Widget is not in this Panel"); + + children.erase(i); + children.push_back(&wdg); } void Panel::button_press(int x, int y, unsigned btn) @@ -174,11 +174,22 @@ void Panel::ungrab_pointer(Widget &wdg) 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(ChildSeq::const_iterator i=children.begin(); i!=children.end(); ++i) + for(list::const_iterator i=children.begin(); i!=children.end(); ++i) if((*i)->is_visible()) (*i)->render(); } @@ -219,7 +230,7 @@ void Panel::set_input_focus(Widget *wdg) Widget *Panel::get_child_at(int x, int y) { - for(ChildSeq::reverse_iterator i=children.rbegin(); i!=children.rend(); ++i) + for(list::reverse_iterator i=children.rbegin(); i!=children.rend(); ++i) if((*i)->is_visible() && (*i)->get_geometry().is_inside(x, y)) return *i; diff --git a/source/panel.h b/source/panel.h index 529354d..397d71f 100644 --- a/source/panel.h +++ b/source/panel.h @@ -36,9 +36,7 @@ public: }; private: - typedef std::list ChildSeq; - - ChildSeq children; + std::list children; Widget *pointer_focus; unsigned pointer_grab; Widget *input_focus; @@ -52,6 +50,7 @@ public: void add(Widget &); void remove(Widget &); void raise(Widget &); + void set_focus(Widget &); virtual void button_press(int, int, unsigned); virtual void button_release(int, int, unsigned); @@ -61,9 +60,11 @@ public: 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; diff --git a/source/widget.cpp b/source/widget.cpp index efb6155..48b647b 100644 --- a/source/widget.cpp +++ b/source/widget.cpp @@ -69,6 +69,16 @@ void Widget::set_visible(bool v) parent->child_hidden(*this); } +void Widget::set_focus() +{ + if(!parent) + throw InvalidState("No parent"); + if(!visible) + throw InvalidState("Can't set focus on invisible widget"); + + parent->grab_focus(*this); +} + void Widget::render() const { if(!style) diff --git a/source/widget.h b/source/widget.h index 7fdc906..8663814 100644 --- a/source/widget.h +++ b/source/widget.h @@ -64,6 +64,7 @@ public: void set_style(const std::string &); void set_visible(bool); + void set_focus(); const Geometry &get_geometry() const { return geom; } bool is_visible() const { return visible; } -- 2.45.2