[gtkmm-documentation] Add a Gtk::ListBox example



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]