[gtkmm-documentation] Add a Gtk::ListBox example
- From: Kjell Ahlstedt <kjellahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtkmm-documentation] Add a Gtk::ListBox example
- Date: Tue, 1 Oct 2013 13:24:42 +0000 (UTC)
commit e70f3053e2b03382f0b3d9b3a24398365084f501
Author: Kjell Ahlstedt <kjell ahlstedt bredband net>
Date: Tue Oct 1 15:21:56 2013 +0200
Add a Gtk::ListBox example
* examples/Makefile.am: Add book/listbox/example.
* examples/book/listbox/examplewindow.[h|cc]:
* examples/book/listbox/examplerow.[h|cc]:
* examples/book/listbox/main.cc: New files.
This example is a translation (with very small changes) to C++ of
gtk+/tests/testlist.c. Bug #708115.
examples/Makefile.am | 8 +
examples/book/listbox/examplerow.cc | 27 +++
examples/book/listbox/examplerow.h | 37 ++++
examples/book/listbox/examplewindow.cc | 314 ++++++++++++++++++++++++++++++++
examples/book/listbox/examplewindow.h | 76 ++++++++
examples/book/listbox/main.cc | 27 +++
6 files changed, 489 insertions(+), 0 deletions(-)
---
diff --git a/examples/Makefile.am b/examples/Makefile.am
index 26bf4b8..35717ec 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -72,6 +72,7 @@ check_PROGRAMS = \
book/keyboard_events/simple/example \
book/keyboard_events/propagation/example \
book/label/example \
+ book/listbox/example \
book/menus/main_menu/main_menu \
book/menus/popup/popup \
book/menus_and_toolbars/example \
@@ -469,6 +470,13 @@ book_label_example_SOURCES = \
book/label/examplewindow.h \
book/label/main.cc
+book_listbox_example_SOURCES = \
+ book/listbox/examplewindow.cc \
+ book/listbox/examplewindow.h \
+ book/listbox/examplerow.cc \
+ book/listbox/examplerow.h \
+ book/listbox/main.cc
+
book_menus_main_menu_main_menu_SOURCES = \
book/menus/main_menu/examplewindow.cc \
book/menus/main_menu/examplewindow.h \
diff --git a/examples/book/listbox/examplerow.cc b/examples/book/listbox/examplerow.cc
new file mode 100644
index 0000000..5ae5433
--- /dev/null
+++ b/examples/book/listbox/examplerow.cc
@@ -0,0 +1,27 @@
+/* gtkmm example Copyright (C) 2013 gtkmm development team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "examplerow.h"
+
+ExampleRow::ExampleRow(const Glib::ustring& text, int sort_id)
+: m_label(text),
+ m_sort_id(sort_id)
+{
+ if (!text.empty())
+ {
+ add(m_label);
+ m_label.show();
+ }
+}
diff --git a/examples/book/listbox/examplerow.h b/examples/book/listbox/examplerow.h
new file mode 100644
index 0000000..694afc4
--- /dev/null
+++ b/examples/book/listbox/examplerow.h
@@ -0,0 +1,37 @@
+/* gtkmm example Copyright (C) 2013 gtkmm development team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GTKMM_EXAMPLEROW_H
+#define GTKMM_EXAMPLEROW_H
+
+#include <gtkmm.h>
+
+class ExampleRow : public Gtk::ListBoxRow
+{
+public:
+ ExampleRow(const Glib::ustring& text, int sort_id);
+
+ Glib::ustring get_text() const { return m_label.get_text(); }
+ void set_text(const Glib::ustring & text) { m_label.set_text(text); }
+
+ int get_sort_id() const { return m_sort_id; }
+ void set_sort_id(int sort_id) { m_sort_id = sort_id; }
+
+private:
+ Gtk::Label m_label;
+ int m_sort_id;
+};
+
+#endif // GTKMM_EXAMPLEROW_H
diff --git a/examples/book/listbox/examplewindow.cc b/examples/book/listbox/examplewindow.cc
new file mode 100644
index 0000000..ff24931
--- /dev/null
+++ b/examples/book/listbox/examplewindow.cc
@@ -0,0 +1,314 @@
+/* gtkmm example Copyright (C) 2013 gtkmm development team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "examplewindow.h"
+#include <iostream>
+
+namespace
+{
+const char css[] =
+ "GtkListBoxRow {"
+ " border-width: 1px;"
+ " border-style: solid;"
+ " border-color: blue;"
+ "}"
+ "GtkListBoxRow:prelight {"
+ "background-color: green;"
+ "}"
+ "GtkListBoxRow:selected {"
+ "background-color: yellow;"
+ "}"
+ "GtkListBoxRow:active {"
+ "background-color: red;"
+ "}";
+
+struct SelectionModeStruct
+{
+ Gtk::SelectionMode mode;
+ Glib::ustring text;
+};
+
+const SelectionModeStruct selectionModes[] =
+{
+ { Gtk::SELECTION_NONE, "SELECTION_NONE" },
+ { Gtk::SELECTION_SINGLE, "SELECTION_SINGLE" },
+ { Gtk::SELECTION_BROWSE, "SELECTION_BROWSE" }
+};
+
+} // anonymous namespace
+
+ExampleWindow::ExampleWindow() :
+ m_HBox(Gtk::ORIENTATION_HORIZONTAL, 0),
+ m_VBox1(Gtk::ORIENTATION_VERTICAL, 0),
+ m_VBox2(Gtk::ORIENTATION_VERTICAL, 0),
+ m_ListBox(),
+ m_ComboBox(/* has_entry= */ false),
+ m_CheckButton_SingleClick("single click mode", /* mnemonic= */ false),
+ m_ScrolledWindow(),
+ m_Row3("blah3", 3),
+ m_VBox_Row(Gtk::ORIENTATION_VERTICAL, 0),
+ m_HBox_Row(Gtk::ORIENTATION_HORIZONTAL, 0),
+ m_Label_Row("a check box"),
+ m_CheckButton_Row1(),
+ m_CheckButton_Row2(),
+ m_Button_Row1("hi!"),
+ m_Button_Row2("focusable row"),
+ m_Button_Sort("sort"),
+ m_Button_ReverseSort("reverse sort"),
+ m_Button_Change("change"),
+ m_Button_Filter("filter"),
+ m_Button_Unfilter("unfilter"),
+ m_Button_Add("add"),
+ m_Button_Separate("separate"),
+ m_Button_Unseparate("unseparate"),
+ m_Button_Visibility("visibility")
+{
+ set_title("ListBox example");
+ set_border_width(5);
+ set_default_size(300, 300);
+
+ // Add a style sheet for GtkListBoxRow.
+ // (2013-10-01: If this is not done, ListBoxRows look dull, and selection
+ // is not marked in any way. I suppose this is necessary only temporarily.
+ // It ought to be part of gtk+.)
+ m_refCssProvider = Gtk::CssProvider::create();
+ Gtk::StyleContext::add_provider_for_screen(get_screen(), m_refCssProvider,
+ GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+ try
+ {
+ m_refCssProvider->load_from_data(css);
+ }
+ catch (const Glib::Error& ex)
+ {
+ std::cerr << "Gtk::CssProvider::load_from_data() failed: " << ex.what() << std::endl;
+ }
+
+ add(m_HBox);
+ m_HBox.pack_start(m_VBox1, Gtk::PACK_SHRINK);
+
+ // ComboBox for selection mode.
+ for (std::size_t i = 0; i < G_N_ELEMENTS(selectionModes); ++i)
+ m_ComboBox.append(selectionModes[i].text);
+
+ m_ComboBox.signal_changed().connect(sigc::mem_fun(*this, &ExampleWindow::on_selection_mode_changed));
+ m_VBox1.pack_start(m_ComboBox, Gtk::PACK_SHRINK);
+
+ const Gtk::SelectionMode mode = m_ListBox.get_selection_mode();
+ int index = 0;
+ for (std::size_t i = 0; i < G_N_ELEMENTS(selectionModes); ++i)
+ {
+ if (selectionModes[i].mode == mode)
+ {
+ index = i;
+ break;
+ }
+ }
+ m_ComboBox.set_active(index);
+
+ // Check button for single click.
+ m_CheckButton_SingleClick.set_active(m_ListBox.get_activate_on_single_click());
+ m_CheckButton_SingleClick.signal_toggled().connect(sigc::mem_fun(*this,
&ExampleWindow::on_single_click_toggled));
+ m_VBox1.pack_start(m_CheckButton_SingleClick, Gtk::PACK_SHRINK);
+
+ // Put the ListBox in a ScrolledWindow.
+ m_ScrolledWindow.set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
+ m_ScrolledWindow.add(m_ListBox);
+ m_HBox.pack_start(m_ScrolledWindow, Gtk::PACK_SHRINK);
+
+ m_ListBox.signal_row_selected().connect(sigc::mem_fun(*this, &ExampleWindow::on_row_selected));
+ m_ListBox.signal_row_activated().connect(sigc::mem_fun(*this, &ExampleWindow::on_row_activated));
+
+ // Add some rows to the ListBox.
+ ExampleRow* row = Gtk::manage(new ExampleRow("blah4", 4));
+ m_ListBox.append(*row);
+ m_ListBox.append(m_Row3); // blah3
+ row = Gtk::manage(new ExampleRow("blah1", 1));
+ m_ListBox.append(*row);
+ row = Gtk::manage(new ExampleRow("blah2", 2));
+ m_ListBox.append(*row);
+
+ row = Gtk::manage(new ExampleRow("", 0));
+ m_HBox_Row.pack_start(m_Label_Row, Gtk::PACK_SHRINK);
+ m_HBox_Row.pack_start(m_CheckButton_Row1, Gtk::PACK_SHRINK);
+ m_HBox_Row.pack_start(m_Button_Row1, Gtk::PACK_SHRINK);
+ m_VBox_Row.pack_start(m_HBox_Row, Gtk::PACK_SHRINK);
+ m_VBox_Row.pack_start(m_CheckButton_Row2, Gtk::PACK_SHRINK);
+ row->add(m_VBox_Row);
+ m_ListBox.append(*row);
+
+ row = Gtk::manage(new ExampleRow("", 0));
+ m_Button_Row2.set_hexpand(false);
+ m_Button_Row2.set_halign(Gtk::ALIGN_START);
+ row->add(m_Button_Row2);
+ m_ListBox.append(*row);
+
+ // Put buttons in a vertical box, and connect signal handlers.
+ m_HBox.pack_start(m_VBox2, Gtk::PACK_SHRINK);
+ m_VBox2.pack_start(m_Button_Sort, Gtk::PACK_SHRINK);
+ m_Button_Sort.signal_clicked().connect(sigc::mem_fun(*this, &ExampleWindow::on_sort_clicked));
+ m_VBox2.pack_start(m_Button_ReverseSort, Gtk::PACK_SHRINK);
+ m_Button_ReverseSort.signal_clicked().connect(sigc::mem_fun(*this,
&ExampleWindow::on_reverse_sort_clicked));
+ m_VBox2.pack_start(m_Button_Change, Gtk::PACK_SHRINK);
+ m_Button_Change.signal_clicked().connect(sigc::mem_fun(*this, &ExampleWindow::on_change_clicked));
+ m_VBox2.pack_start(m_Button_Filter, Gtk::PACK_SHRINK);
+ m_Button_Filter.signal_clicked().connect(sigc::mem_fun(*this, &ExampleWindow::on_filter_clicked));
+ m_VBox2.pack_start(m_Button_Unfilter, Gtk::PACK_SHRINK);
+ m_Button_Unfilter.signal_clicked().connect(sigc::mem_fun(*this, &ExampleWindow::on_unfilter_clicked));
+ m_VBox2.pack_start(m_Button_Add, Gtk::PACK_SHRINK);
+ m_Button_Add.signal_clicked().connect(sigc::mem_fun(*this, &ExampleWindow::on_add_clicked));
+ m_VBox2.pack_start(m_Button_Separate, Gtk::PACK_SHRINK);
+ m_Button_Separate.signal_clicked().connect(sigc::mem_fun(*this, &ExampleWindow::on_separate_clicked));
+ m_VBox2.pack_start(m_Button_Unseparate, Gtk::PACK_SHRINK);
+ m_Button_Unseparate.signal_clicked().connect(sigc::mem_fun(*this, &ExampleWindow::on_unseparate_clicked));
+ m_VBox2.pack_start(m_Button_Visibility, Gtk::PACK_SHRINK);
+ m_Button_Visibility.signal_clicked().connect(sigc::mem_fun(*this, &ExampleWindow::on_visibility_clicked));
+
+ show_all_children();
+}
+
+void ExampleWindow::on_selection_mode_changed()
+{
+ int index = m_ComboBox.get_active_row_number();
+ if (index < 0 || static_cast<std::size_t>(index) >= G_N_ELEMENTS(selectionModes))
+ index = 0;
+ m_ListBox.set_selection_mode(selectionModes[index].mode);
+}
+
+void ExampleWindow::on_single_click_toggled()
+{
+ std::cout << "single: " << m_CheckButton_SingleClick.get_active() << std::endl;
+ m_ListBox.set_activate_on_single_click(m_CheckButton_SingleClick.get_active());
+}
+
+void ExampleWindow::on_row_selected(Gtk::ListBoxRow* row)
+{
+ std::cout << "selected row: " << row << std::endl;
+}
+
+void ExampleWindow::on_row_activated(Gtk::ListBoxRow* row)
+{
+ std::cout << "activated row: " << row << std::endl;
+}
+
+void ExampleWindow::on_sort_clicked()
+{
+ m_ListBox.set_sort_func(sigc::ptr_fun(&ExampleWindow::sort_func));
+}
+
+void ExampleWindow::on_reverse_sort_clicked()
+{
+ m_ListBox.set_sort_func(sigc::ptr_fun(&ExampleWindow::reverse_sort_func));
+}
+
+int ExampleWindow::sort_func(Gtk::ListBoxRow* row1, Gtk::ListBoxRow* row2)
+{
+ ExampleRow* xrow1 = dynamic_cast<ExampleRow*>(row1);
+ ExampleRow* xrow2 = dynamic_cast<ExampleRow*>(row2);
+ if (xrow1 && xrow2)
+ return xrow1->get_sort_id() - xrow2->get_sort_id();
+ return 0;
+}
+
+int ExampleWindow::reverse_sort_func(Gtk::ListBoxRow* row1, Gtk::ListBoxRow* row2)
+{
+ return sort_func(row2, row1);
+}
+
+void ExampleWindow::on_change_clicked()
+{
+ if (m_Row3.get_text() == "blah3")
+ {
+ m_Row3.set_text("blah5");
+ m_Row3.set_sort_id(5);
+ }
+ else
+ {
+ m_Row3.set_text("blah3");
+ m_Row3.set_sort_id(3);
+ }
+}
+
+void ExampleWindow::on_filter_clicked()
+{
+ m_ListBox.set_filter_func(sigc::ptr_fun(&ExampleWindow::filter_func));
+}
+
+void ExampleWindow::on_unfilter_clicked()
+{
+ m_ListBox.unset_filter_func();
+}
+
+bool ExampleWindow::filter_func(Gtk::ListBoxRow* row)
+{
+ ExampleRow* xrow = dynamic_cast<ExampleRow*>(row);
+ return xrow && xrow->get_text() != "blah3";
+}
+
+void ExampleWindow::on_add_clicked()
+{
+ static int new_button_nr = 1;
+ const Glib::ustring text = "blah2 new " + Glib::ustring::format(new_button_nr);
+ ExampleRow* new_row = Gtk::manage(new ExampleRow(text, new_button_nr));
+ new_row->show_all();
+ m_ListBox.append(*new_row);
+ ++new_button_nr;
+}
+
+void ExampleWindow::on_separate_clicked()
+{
+ m_ListBox.set_header_func(sigc::ptr_fun(&ExampleWindow::update_header_func));
+}
+
+void ExampleWindow::on_unseparate_clicked()
+{
+ m_ListBox.unset_header_func();
+}
+
+void ExampleWindow::update_header_func(Gtk::ListBoxRow* row, Gtk::ListBoxRow* before)
+{
+ ExampleRow* xrow = dynamic_cast<ExampleRow*>(row);
+ if (!before || (xrow && xrow->get_text() == "blah3"))
+ {
+ // Create header if needed.
+ if (!row->get_header())
+ {
+ Gtk::Box* hbox = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL, 0));
+ Gtk::Label* label = Gtk::manage(new Gtk::Label("Header"));
+ hbox->pack_start(*label, Gtk::PACK_SHRINK);
+ Gtk::Button* button = Gtk::manage(new Gtk::Button("button"));
+ hbox->pack_start(*button, Gtk::PACK_SHRINK);
+ hbox->show_all();
+ row->set_header(*hbox);
+ }
+ Gtk::Container* header = dynamic_cast<Gtk::Container*>(row->get_header());
+ if (header)
+ {
+ std::vector<Gtk::Widget*> children = header->get_children();
+ if (children.size() > 0)
+ {
+ Gtk::Label* label = dynamic_cast<Gtk::Label*>(children[0]);
+ if (label && xrow)
+ label->set_text("Header " + Glib::ustring::format(xrow->get_sort_id()));
+ }
+ }
+ }
+ else
+ row->unset_header();
+}
+
+void ExampleWindow::on_visibility_clicked()
+{
+ m_Row3.set_visible(!m_Row3.get_visible());
+}
diff --git a/examples/book/listbox/examplewindow.h b/examples/book/listbox/examplewindow.h
new file mode 100644
index 0000000..3fb3f48
--- /dev/null
+++ b/examples/book/listbox/examplewindow.h
@@ -0,0 +1,76 @@
+/* gtkmm example Copyright (C) 2013 gtkmm development team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GTKMM_EXAMPLEWINDOW_H
+#define GTKMM_EXAMPLEWINDOW_H
+
+#include <gtkmm.h>
+#include "examplerow.h"
+
+class ExampleWindow : public Gtk::Window
+{
+public:
+ ExampleWindow();
+
+private:
+ // Signal handlers.
+ void on_selection_mode_changed();
+ void on_single_click_toggled();
+ void on_row_selected(Gtk::ListBoxRow* row);
+ void on_row_activated(Gtk::ListBoxRow* row);
+ void on_sort_clicked();
+ void on_reverse_sort_clicked();
+ void on_change_clicked();
+ void on_filter_clicked();
+ void on_unfilter_clicked();
+ void on_add_clicked();
+ void on_separate_clicked();
+ void on_unseparate_clicked();
+ void on_visibility_clicked();
+
+ static int sort_func(Gtk::ListBoxRow* row1, Gtk::ListBoxRow* row2);
+ static int reverse_sort_func(Gtk::ListBoxRow* row1, Gtk::ListBoxRow* row2);
+ static bool filter_func(Gtk::ListBoxRow* row);
+ static void update_header_func(Gtk::ListBoxRow* row, Gtk::ListBoxRow* before);
+
+ // Member data.
+ Glib::RefPtr<Gtk::CssProvider> m_refCssProvider;
+ Gtk::Box m_HBox;
+ Gtk::Box m_VBox1;
+ Gtk::Box m_VBox2;
+ Gtk::ListBox m_ListBox;
+ Gtk::ComboBoxText m_ComboBox;
+ Gtk::CheckButton m_CheckButton_SingleClick;
+ Gtk::ScrolledWindow m_ScrolledWindow;
+ ExampleRow m_Row3;
+ Gtk::Box m_VBox_Row;
+ Gtk::Box m_HBox_Row;
+ Gtk::Label m_Label_Row;
+ Gtk::CheckButton m_CheckButton_Row1;
+ Gtk::CheckButton m_CheckButton_Row2;
+ Gtk::Button m_Button_Row1;
+ Gtk::Button m_Button_Row2;
+ Gtk::Button m_Button_Sort;
+ Gtk::Button m_Button_ReverseSort;
+ Gtk::Button m_Button_Change;
+ Gtk::Button m_Button_Filter;
+ Gtk::Button m_Button_Unfilter;
+ Gtk::Button m_Button_Add;
+ Gtk::Button m_Button_Separate;
+ Gtk::Button m_Button_Unseparate;
+ Gtk::Button m_Button_Visibility;
+};
+
+#endif // GTKMM_EXAMPLEWINDOW_H
diff --git a/examples/book/listbox/main.cc b/examples/book/listbox/main.cc
new file mode 100644
index 0000000..3d7a9e6
--- /dev/null
+++ b/examples/book/listbox/main.cc
@@ -0,0 +1,27 @@
+/* gtkmm example Copyright (C) 2013 gtkmm development team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "examplewindow.h"
+#include <gtkmm/application.h>
+
+int main (int argc, char* argv[])
+{
+ Glib::RefPtr<Gtk::Application> app = Gtk::Application::create(argc, argv, "org.gtkmm.example");
+
+ ExampleWindow window;
+
+ //Shows the window and returns when it is closed.
+ return app->run(window);
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]