From aaaa676f2e4f047a2107157fcb8a4552a791a163 Mon Sep 17 00:00:00 2001 From: VKamyshniy Date: Thu, 22 Jan 2015 14:32:24 +0200 Subject: [PATCH] [Summary] Extending UI capabilities: Gtk::TreeView, ediatble WavesDropdown, frame-less entry, XML-ed attributes per MenuItem in WavesDropdown. --- gtk2_ardour/waves_button.cc | 43 ++++++++++--- gtk2_ardour/waves_button.h | 1 + gtk2_ardour/waves_dropdown.cc | 21 ++++--- gtk2_ardour/waves_dropdown.h | 6 +- gtk2_ardour/waves_ui.cc | 114 ++++++++++++++++++++++++++++++---- gtk2_ardour/waves_ui.h | 3 + 6 files changed, 155 insertions(+), 33 deletions(-) diff --git a/gtk2_ardour/waves_button.cc b/gtk2_ardour/waves_button.cc index d1e2111700..cd444c0f0f 100644 --- a/gtk2_ardour/waves_button.cc +++ b/gtk2_ardour/waves_button.cc @@ -98,9 +98,14 @@ void WavesButton::set_text (const std::string& str) { _text = str; - Gtk::Label* child = _find_label (this); - if (child) { - child->set_text (str); + Gtk::Label* label = _find_label (this); + if (label) { + label->set_text (str); + } else { + Gtk::Entry* entry = _find_entry (this); + if (entry) { + entry->set_text (str); + } } _layout->set_text (str); queue_resize (); @@ -172,7 +177,7 @@ WavesButton::render_text (cairo_t* cr) { // text, if any - if ((!_find_label (this)) && + if ((!_find_label (this)) && (!_find_entry (this)) && (!_text.empty ())) { Glib::RefPtr style = get_style(); @@ -488,9 +493,14 @@ void WavesButton::on_realize () { Gtk::EventBox::on_realize (); - Gtk::Label* child = _find_label (this); - if (child) { - child->set_text (get_text()); + Gtk::Label* label = _find_label (this); + if (label) { + label->set_text (get_text()); + } else { + Gtk::Entry* entry = _find_entry (this); + if (entry) { + entry->set_text (get_text()); + } } } @@ -555,3 +565,22 @@ WavesButton::_find_label (Gtk::Container *container) } return label; } + +Gtk::Entry* +WavesButton::_find_entry (Gtk::Container *container) +{ + Gtk::Entry* entry = NULL; + if (container) { + std::list children = container->get_children (); + for (std::list::iterator i = children.begin(); i != children.end(); ++i) { + entry = dynamic_cast(*i); + if (!entry) { + entry = _find_entry (dynamic_cast(*i)); + } + if (entry) { + break; + } + } + } + return entry; +} diff --git a/gtk2_ardour/waves_button.h b/gtk2_ardour/waves_button.h index 22645cb431..368b30c28d 100644 --- a/gtk2_ardour/waves_button.h +++ b/gtk2_ardour/waves_button.h @@ -117,6 +117,7 @@ private: static void __prop_style_watcher(WavesButton *); void _prop_style_watcher(); Gtk::Label* _find_label (Gtk::Container *child); + Gtk::Entry* _find_entry (Gtk::Container *child); BindingProxy binding_proxy; diff --git a/gtk2_ardour/waves_dropdown.cc b/gtk2_ardour/waves_dropdown.cc index 808cd29647..29583f7340 100644 --- a/gtk2_ardour/waves_dropdown.cc +++ b/gtk2_ardour/waves_dropdown.cc @@ -121,19 +121,20 @@ WavesDropdown::set_current_item (int current_item_number) } Gtk::MenuItem& -WavesDropdown::add_menu_item (const std::string& item, void* cookie, DestroyNotify cookie_cleaner) +WavesDropdown::add_menu_item (const std::string& item, void* cookie, DestroyNotify cookie_cleaner, bool provide_style) { Gtk::Menu_Helpers::MenuList& items = _menu.items (); items.push_back (Gtk::Menu_Helpers::MenuElem (item, sigc::bind (sigc::mem_fun(*this, &WavesDropdown::_on_menu_item), items.size (), cookie))); Gtk::MenuItem& menuitem = _menu.items ().back (); - ensure_style(); - Widget* child = menuitem.get_child (); + + Widget* child = (provide_style ? menuitem.get_child () : 0); if (child) { + ensure_style(); child->set_style (get_style()); } - + if (cookie_cleaner) { menuitem.set_data (menu_item_data_key, cookie, cookie_cleaner); } else { @@ -144,7 +145,7 @@ WavesDropdown::add_menu_item (const std::string& item, void* cookie, DestroyNoti } Gtk::RadioMenuItem& -WavesDropdown::add_radio_menu_item (const std::string& item, void* cookie, DestroyNotify cookie_cleaner) +WavesDropdown::add_radio_menu_item (const std::string& item, void* cookie, DestroyNotify cookie_cleaner, bool provide_style) { Gtk::Menu_Helpers::MenuList& items = _menu.items (); @@ -158,9 +159,9 @@ WavesDropdown::add_radio_menu_item (const std::string& item, void* cookie, Destr } Gtk::RadioMenuItem& menuitem = *dynamic_cast (&_menu.items ().back ()); - ensure_style(); - Widget* child = menuitem.get_child (); + Widget* child = (provide_style ? menuitem.get_child () : 0); if (child) { + ensure_style(); child->set_style (get_style()); } @@ -174,16 +175,16 @@ WavesDropdown::add_radio_menu_item (const std::string& item, void* cookie, Destr } Gtk::CheckMenuItem& -WavesDropdown::add_check_menu_item (const std::string& item, void* cookie, DestroyNotify cookie_cleaner) +WavesDropdown::add_check_menu_item (const std::string& item, void* cookie, DestroyNotify cookie_cleaner, bool provide_style) { Gtk::Menu_Helpers::MenuList& items = _menu.items (); items.push_back (Gtk::Menu_Helpers::CheckMenuElem (item, sigc::bind (sigc::mem_fun(*this, &WavesDropdown::_on_menu_item), items.size (), cookie))); Gtk::CheckMenuItem& menuitem = *dynamic_cast (&_menu.items ().back ()); - ensure_style(); - Widget* child = menuitem.get_child (); + Widget* child = (provide_style ? menuitem.get_child () : 0); if (child) { + ensure_style(); child->set_style (get_style()); } diff --git a/gtk2_ardour/waves_dropdown.h b/gtk2_ardour/waves_dropdown.h index 9ee656bce3..a482a3b81f 100644 --- a/gtk2_ardour/waves_dropdown.h +++ b/gtk2_ardour/waves_dropdown.h @@ -40,9 +40,9 @@ class WavesDropdown : public WavesIconButton Gtk::MenuItem* get_item (int); Gtk::MenuItem* get_item (const std::string&); - Gtk::MenuItem& add_menu_item (const std::string& item, void* cookie = 0, DestroyNotify cookie_cleaner = 0); - Gtk::RadioMenuItem& add_radio_menu_item (const std::string& item, void* cookie = 0, DestroyNotify cookie_cleaner = 0); - Gtk::CheckMenuItem& add_check_menu_item (const std::string& item, void* cookie = 0, DestroyNotify cookie_cleaner = 0); + Gtk::MenuItem& add_menu_item (const std::string& item, void* cookie = 0, DestroyNotify cookie_cleaner = 0, bool provide_style = true); + Gtk::RadioMenuItem& add_radio_menu_item (const std::string& item, void* cookie = 0, DestroyNotify cookie_cleaner = 0, bool provide_style = true); + Gtk::CheckMenuItem& add_check_menu_item (const std::string& item, void* cookie = 0, DestroyNotify cookie_cleaner = 0, bool provide_style = true); void set_maxmenuheight (int maxmenuheight) { _maxmenuheight = ((maxmenuheight < 0) ? -1 : maxmenuheight); } int get_maxmenuheight () const { return _maxmenuheight; } diff --git a/gtk2_ardour/waves_ui.cc b/gtk2_ardour/waves_ui.cc index 9a8d09a63f..b91e7fab64 100644 --- a/gtk2_ardour/waves_ui.cc +++ b/gtk2_ardour/waves_ui.cc @@ -270,6 +270,8 @@ WavesUI::create_widget (const XMLNode& definition, const XMLNodeMap& styles) step, page_increment, page_size)); + } else if (widget_type == "TREEVIEW") { + child = manage (new Gtk::TreeView ()); } else if (widget_type != "STYLE") { dbg_msg (std::string("Illegal object type (" + definition.name() + @@ -523,25 +525,25 @@ WavesUI::add_dropdown_items (WavesDropdown &dropdown, const XMLNodeList& definit std::transform (node_name.begin (), node_name.end (), node_name.begin (), ::toupper); if (node_name == "DROPDOWNITEM") { - Gtk::MenuItem& menuitem = dropdown.add_menu_item (title, (void*)itemdata); - if (menuitem.get_child ()) { - set_attributes (*menuitem.get_child (), **ii, styles); + Gtk::MenuItem& menuitem = dropdown.add_menu_item (title, (void*)itemdata, 0, 0); + if (Gtk::Widget* child = menuitem.get_child ()) { + set_attributes (*child, **ii, styles); } if (!widget_id.empty ()) { (*this)[widget_id] = &menuitem; } } else if (node_name == "DROPDOWNCHECKITEM") { - Gtk::CheckMenuItem& menuitem = dropdown.add_check_menu_item (title, (void*)itemdata); - if (menuitem.get_child ()) { - set_attributes (*menuitem.get_child (), **ii, styles); + Gtk::CheckMenuItem& menuitem = dropdown.add_check_menu_item (title, (void*)itemdata, 0, 0); + if (Gtk::Widget* child = menuitem.get_child ()) { + set_attributes (*child, **ii, styles); } if (!widget_id.empty ()) { (*this)[widget_id] = &menuitem; } } else if (node_name == "DROPDOWNRADIOITEM") { - Gtk::RadioMenuItem& menuitem = dropdown.add_radio_menu_item (title, (void*)itemdata); - if (menuitem.get_child ()) { - set_attributes (*menuitem.get_child (), **ii, styles); + Gtk::RadioMenuItem& menuitem = dropdown.add_radio_menu_item (title, (void*)itemdata, 0, 0); + if (Gtk::Widget* child = menuitem.get_child ()) { + set_attributes (*child, **ii, styles); } if (!widget_id.empty ()) { (*this)[widget_id] = &menuitem; @@ -621,6 +623,7 @@ WavesUI::set_attributes (Gtk::Widget& widget, const XMLNode& definition, const X if (((width != -1) || (height != -1)) && (dynamic_cast (&widget) == 0)) { widget.set_size_request (width, height); } + property = xml_property (definition, "textcolornormal", styles, ""); if (!property.empty ()) { widget.unset_text(Gtk::STATE_NORMAL); @@ -687,6 +690,36 @@ WavesUI::set_attributes (Gtk::Widget& widget, const XMLNode& definition, const X widget.modify_bg(Gtk::STATE_PRELIGHT, Gdk::Color(property)); } + property = xml_property (definition, "basenormal", styles, ""); + if (!property.empty ()) { + widget.unset_base(Gtk::STATE_NORMAL); + widget.modify_base(Gtk::STATE_NORMAL, Gdk::Color(property)); + } + + property = xml_property (definition, "basedisabled", styles, property); + if (!property.empty ()) { + widget.unset_base(Gtk::STATE_INSENSITIVE); + widget.modify_base(Gtk::STATE_INSENSITIVE, Gdk::Color(property)); + } + + property = xml_property (definition, "baseactive", styles, ""); + if (!property.empty ()) { + widget.unset_base(Gtk::STATE_ACTIVE); + widget.modify_base(Gtk::STATE_ACTIVE, Gdk::Color(property)); + } + + property = xml_property (definition, "baseselected", styles, ""); + if (!property.empty ()) { + widget.unset_base(Gtk::STATE_SELECTED); + widget.modify_base(Gtk::STATE_SELECTED, Gdk::Color(property)); + } + + property = xml_property (definition, "basehover", styles, ""); + if (!property.empty ()) { + widget.unset_base(Gtk::STATE_PRELIGHT); + widget.modify_base(Gtk::STATE_PRELIGHT, Gdk::Color(property)); + } + property = xml_property (definition, "fgnormal", styles, ""); if (!property.empty ()) { widget.modify_fg(Gtk::STATE_NORMAL, Gdk::Color(property)); @@ -719,10 +752,14 @@ WavesUI::set_attributes (Gtk::Widget& widget, const XMLNode& definition, const X } else if (property == "impliciactive") { state = Gtkmm2ext::ImplicitActive; } else { - dbg_msg ("Invalid state for CairoWidget !"); + cairo_widget = 0; } - cairo_widget->set_active_state (state); - } else { + if (cairo_widget) { + cairo_widget->set_active_state (state); + } + } + + if (!cairo_widget) { Gtk::StateType state = Gtk::STATE_NORMAL; if (property == "normal") { state = Gtk::STATE_NORMAL; @@ -798,6 +835,10 @@ WavesUI::set_attributes (Gtk::Widget& widget, const XMLNode& definition, const X dbg_msg ("Invalid horizontal alignment for Gtk::Entry !"); } entry->set_alignment (xalign); + + if (!xml_property (definition, "hasframe", styles, true)) { + entry->set_has_frame (false); + } } Gtk::Label* label = dynamic_cast (&widget); @@ -860,6 +901,10 @@ WavesUI::set_attributes (Gtk::Widget& widget, const XMLNode& definition, const X dbg_msg ("Invalid ellipsize mode for Gtk::Label !"); } label->set_ellipsize (ellipsize_mode); + + if (xml_property (definition, "usemarkup", styles, false)) { + label->set_use_markup (true); + } } Gtk::SpinButton* spin_button = dynamic_cast (&widget); @@ -945,6 +990,13 @@ WavesUI::set_attributes (Gtk::Widget& widget, const XMLNode& definition, const X } scrolled_window->set_policy(hscrollbar_policy, vscrollbar_policy); } + + Gtk::TreeView* tree_view = dynamic_cast (&widget); + if (tree_view) { + if (xml_property (definition, "hscroll", styles, false)) { + tree_view->set_headers_visible (true); + } + } } Gtk::Object* @@ -952,12 +1004,24 @@ WavesUI::get_object(const char *id) { Gtk::Object* object = NULL; WavesUI::iterator it = find(id); - if(it != end()) + if(it != end()) { object = it->second; + } return object; } +Gtk::Widget& +WavesUI::get_widget (const char* id) +{ + Gtk::Widget* child = dynamic_cast (get_object(id)); + if (child == NULL ) { + dbg_msg (std::string("Widget ") + id + " not found in " + _script_file_name + "!"); + abort (); + } + return *child; +} + Gtk::Adjustment& WavesUI::get_adjustment(const char* id) { @@ -1294,3 +1358,27 @@ WavesUI::get_progressbar (const char* id) } return *child; } + +Gtk::ScrolledWindow& +WavesUI::get_scrolled_window (const char* id) +{ + Gtk::ScrolledWindow* child = dynamic_cast (get_object(id)); + if (child == NULL ) { + dbg_msg (std::string("Gtk::ScrolledWindow ") + id + " not found in " + _script_file_name + "!"); + abort (); + } + return *child; +} + +Gtk::TreeView& +WavesUI::get_tree_view (const char* id) +{ + Gtk::TreeView* child = dynamic_cast (get_object(id)); + if (child == NULL ) { + dbg_msg (std::string("Gtk::TreeView ") + id + " not found in " + _script_file_name + "!"); + abort (); + } + return *child; +} + + diff --git a/gtk2_ardour/waves_ui.h b/gtk2_ardour/waves_ui.h index 83f67e2042..ce84714bd3 100644 --- a/gtk2_ardour/waves_ui.h +++ b/gtk2_ardour/waves_ui.h @@ -47,6 +47,7 @@ class WavesUI : public std::map { WavesUI (const std::string& layout_script_file, Gtk::Container& root); virtual ~WavesUI (); + Gtk::Widget& get_widget (const char* id); Gtk::Adjustment& get_adjustment (const char* id); Gtk::Container& get_container (const char* id); Gtk::EventBox& get_event_box (const char* id); @@ -79,6 +80,8 @@ class WavesUI : public std::map { const XMLTree* xml_tree () { return _xml_tree; } Gtk::Container& root () { return _root_container; } Gtk::ProgressBar& get_progressbar (const char* id); + Gtk::TreeView& get_tree_view (const char* id); + Gtk::ScrolledWindow& get_scrolled_window (const char* id); protected: void set_attributes (Gtk::Widget& widget, const XMLNode& definition, const XMLNodeMap& styles);