From b3f54024225855f2d23a4b2e9086c33b9f778b99 Mon Sep 17 00:00:00 2001 From: paulc Date: Mon, 29 May 2006 13:58:09 +0000 Subject: [PATCH] Support for expandable panels. Better handling of keypad. git-svn-id: http://yate.null.ro/svn/yate/trunk@820 acf43c95-373e-0410-b603-e72c3f656dc1 --- contrib/gtk2/gtk2client.cpp | 16 ++++++++++++ contrib/gtk2/gtk2client.h | 1 + engine/Client.cpp | 49 ++++++++++++++++++++++++++++++++++--- yatecbase.h | 8 ++++++ 4 files changed, 70 insertions(+), 4 deletions(-) diff --git a/contrib/gtk2/gtk2client.cpp b/contrib/gtk2/gtk2client.cpp index 55fff924..633cf594 100644 --- a/contrib/gtk2/gtk2client.cpp +++ b/contrib/gtk2/gtk2client.cpp @@ -1314,6 +1314,22 @@ bool GTKWindow::setActive(const String& name, bool active) return true; } +bool GTKWindow::setFocus(const String& name, bool select) +{ + GtkWidget* wid = find(name); + if (!wid) + return false; + if (GTK_IS_COMBO(wid)) + wid = GTK_COMBO(wid)->entry; + gtk_widget_grab_focus(wid); + if (GTK_IS_EDITABLE(wid)) { + GtkEditable* edit = GTK_EDITABLE(wid); + gtk_editable_select_region(edit,0,select ? -1 : 0); + gtk_editable_set_position(edit,-1); + } + return true; +} + bool GTKWindow::setText(const String& name, const String& text) { GtkWidget* wid = find(name); diff --git a/contrib/gtk2/gtk2client.h b/contrib/gtk2/gtk2client.h index a23ec891..2e4a9930 100644 --- a/contrib/gtk2/gtk2client.h +++ b/contrib/gtk2/gtk2client.h @@ -128,6 +128,7 @@ public: virtual bool hasElement(const String& name); virtual void setOver(const Window* parent); virtual bool setActive(const String& name, bool active); + virtual bool setFocus(const String& name, bool select); virtual bool setShow(const String& name, bool visible); virtual bool setText(const String& name, const String& text); virtual bool setCheck(const String& name, bool checked); diff --git a/engine/Client.cpp b/engine/Client.cpp index 06ec62be..be18b49d 100644 --- a/engine/Client.cpp +++ b/engine/Client.cpp @@ -64,6 +64,7 @@ public: setShow, setText, setActive, + setFocus, setCheck, setSelect, setUrgent, @@ -168,6 +169,8 @@ bool Window::setParams(const NamedList& params) ok = setShow(n,s->toBoolean()) && ok; else if (n.startSkip("active:",false)) ok = setActive(n,s->toBoolean()) && ok; + else if (n.startSkip("focus:",false)) + ok = setFocus(n,s->toBoolean()) && ok; else if (n.startSkip("check:",false)) ok = setCheck(n,s->toBoolean()) && ok; else if (n.startSkip("select:",false)) @@ -306,6 +309,9 @@ void ClientThreadProxy::process() case setActive: m_rval = client->setActive(m_name,m_bool,m_wnd,m_skip); break; + case setFocus: + m_rval = client->setFocus(m_name,m_bool,m_wnd,m_skip); + break; case setCheck: m_rval = client->setCheck(m_name,m_bool,m_wnd,m_skip); break; @@ -654,6 +660,26 @@ bool Client::setActive(const String& name, bool active, Window* wnd, Window* ski return ok; } +bool Client::setFocus(const String& name, bool select, Window* wnd, Window* skip) +{ + if (needProxy()) { + ClientThreadProxy proxy(ClientThreadProxy::setFocus,name,select,wnd,skip); + return proxy.execute(); + } + if (wnd) + return wnd->setFocus(name,select); + ++s_changing; + bool ok = false; + ObjList* l = &m_windows; + for (; l; l = l->next()) { + wnd = static_cast(l->get()); + if (wnd && (wnd != skip)) + ok = wnd->setFocus(name,select) || ok; + } + --s_changing; + return ok; +} + bool Client::setText(const String& name, const String& text, Window* wnd, Window* skip) { if (needProxy()) { @@ -1015,10 +1041,13 @@ bool Client::action(Window* wnd, const String& name) return true; } String target; + Window* win = (wnd && hasElement("callto",wnd)) ? wnd : 0; if (getText("callto",target)) { target += name.at(6); - if (setText("callto",target)) + if (setText("callto",target,win)) { + setFocus("callto",false,win); return true; + } } } else if (name.startsWith("line:")) { @@ -1031,16 +1060,22 @@ bool Client::action(Window* wnd, const String& name) else if (name.startsWith("clear:")) { // clear a text field or table String wid = name.substr(6); - if (wid && (setText(wid,"") || clearTable(wid))) + Window* win = (wnd && hasElement(wid,wnd)) ? wnd : 0; + if (wid && (setText(wid,"",win) || clearTable(wid,win))) { + setFocus(wid,false,win); return true; + } } else if (name.startsWith("back:")) { // delete last character (backspace) String wid = name.substr(5); String str; - if (getText(wid,str,wnd)) { - if (str.null() || setText(wid,str.substr(0,str.length()-1),wnd)) + Window* win = (wnd && hasElement(wid,wnd)) ? wnd : 0; + if (getText(wid,str,win)) { + if (str.null() || setText(wid,str.substr(0,str.length()-1),win)) { + setFocus(wid,false,win); return true; + } } } // accounts window actions @@ -1379,6 +1414,10 @@ bool Client::toggle(Window* wnd, const String& name, bool active) // handle the window visibility buttons, these will sync toggles themselves if (setVisible(name,active)) return true; + else if (name.startsWith("display:")) { + if (setShow(name.substr(8),active,wnd)) + return true; + } // keep the toggle in sync in all windows setCheck(name,active,0,wnd); if (name == "autoanswer") { @@ -1827,6 +1866,8 @@ bool UIHandler::received(Message &msg) ok = Client::self()->setSelect(name,msg.getValue("item"),wnd); else if (action == "set_active") ok = Client::self()->setActive(name,msg.getBoolValue("active"),wnd); + else if (action == "set_focus") + ok = Client::self()->setFocus(name,msg.getBoolValue("select"),wnd); else if (action == "set_visible") ok = Client::self()->setShow(name,msg.getBoolValue("visible"),wnd); else if (action == "has_option") diff --git a/yatecbase.h b/yatecbase.h index 285f90db..5e03d906 100644 --- a/yatecbase.h +++ b/yatecbase.h @@ -106,6 +106,13 @@ public: */ virtual bool setActive(const String& name, bool active) = 0; + /** + * Set an element as receiving input in the window + * @param name Name of the element + * @return True if the operation was successfull + */ + virtual bool setFocus(const String& name, bool select = false) = 0; + /** * Set the visibility of an element in the window * @param name Name of the element @@ -303,6 +310,7 @@ public: void line(int newLine); bool hasElement(const String& name, Window* wnd = 0, Window* skip = 0); bool setActive(const String& name, bool active, Window* wnd = 0, Window* skip = 0); + bool setFocus(const String& name, bool select = false, Window* wnd = 0, Window* skip = 0); bool setShow(const String& name, bool visible, Window* wnd = 0, Window* skip = 0); bool setText(const String& name, const String& text, Window* wnd = 0, Window* skip = 0); bool setCheck(const String& name, bool checked, Window* wnd = 0, Window* skip = 0);