[gtkmm] Gtk: Add PadActionEntry and PadController::set_action_entries()



commit b627802c9d2fe061e69786b51e6511ff9e28758e
Author: Kjell Ahlstedt <kjellahlstedt gmail com>
Date:   Tue Mar 5 09:58:20 2019 +0100

    Gtk: Add PadActionEntry and PadController::set_action_entries()

 .gitignore                     |   2 +
 gtk/src/filelist.am            |   1 +
 gtk/src/gtk_extra_objects.defs |   6 +++
 gtk/src/padactionentry.ccg     | 103 +++++++++++++++++++++++++++++++++++++++++
 gtk/src/padactionentry.hg      |  88 +++++++++++++++++++++++++++++++++++
 gtk/src/padcontroller.ccg      |  17 +++++++
 gtk/src/padcontroller.hg       |  31 +++++++++----
 7 files changed, 238 insertions(+), 10 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index 5f0b974a..211c6efb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -363,6 +363,8 @@ gtk/gtkmm/orientable.cc
 gtk/gtkmm/orientable.h
 gtk/gtkmm/overlay.cc
 gtk/gtkmm/overlay.h
+gtk/gtkmm/padactionentry.cc
+gtk/gtkmm/padactionentry.h
 gtk/gtkmm/padcontroller.cc
 gtk/gtkmm/padcontroller.h
 gtk/gtkmm/pagesetup.cc
diff --git a/gtk/src/filelist.am b/gtk/src/filelist.am
index 1fcd98d1..3a3b44c5 100644
--- a/gtk/src/filelist.am
+++ b/gtk/src/filelist.am
@@ -128,6 +128,7 @@ gtkmm_files_any_hg =                \
        notebookpage.hg \
        orientable.hg           \
        overlay.hg              \
+       padactionentry.hg \
        padcontroller.hg \
        pagesetup.hg            \
        paned.hg                \
diff --git a/gtk/src/gtk_extra_objects.defs b/gtk/src/gtk_extra_objects.defs
index 0aee951c..681fd53d 100644
--- a/gtk/src/gtk_extra_objects.defs
+++ b/gtk/src/gtk_extra_objects.defs
@@ -160,6 +160,12 @@
   (gtype-id "GTK_TYPE_NATIVE_DIALOG")
 )
 
+(define-object PadController
+  (in-module "Gtk")
+  (c-name "GtkPadController")
+  (gtype-id "GTK_TYPE_PAD_CONTROLLER")
+)
+
 (define-object PageSetup
   (in-module "Gtk")
   (c-name "GtkPageSetup")
diff --git a/gtk/src/padactionentry.ccg b/gtk/src/padactionentry.ccg
new file mode 100644
index 00000000..022cc267
--- /dev/null
+++ b/gtk/src/padactionentry.ccg
@@ -0,0 +1,103 @@
+/* Copyright (C) 2019 The gtkmm Development Team
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <gtk/gtk.h>
+
+namespace Gtk
+{
+
+PadActionEntry::PadActionEntry()
+ : gobject_(g_new0(GtkPadActionEntry, 1))
+{
+}
+
+PadActionEntry::PadActionEntry(PadActionType type, int index, int mode,
+  const Glib::ustring& label, const Glib::ustring& action_name)
+ : gobject_(g_new(GtkPadActionEntry, 1))
+{
+  gobject_->type = static_cast<GtkPadActionType>(type);
+  gobject_->index = index;
+  gobject_->mode = mode;
+  gobject_->label = g_strdup(label.c_str());
+  gobject_->action_name = g_strdup(action_name.c_str());
+}
+
+PadActionEntry::~PadActionEntry()
+{
+  release_gobject();
+}
+
+void PadActionEntry::release_gobject() noexcept
+{
+  if (!gobject_)
+    return;
+
+  g_free(gobject_->label);
+  g_free(gobject_->action_name);
+  g_free(gobject_);
+  gobject_ = nullptr;
+}
+
+PadActionEntry::PadActionEntry(const PadActionEntry& src)
+ : gobject_(nullptr)
+{
+  operator=(src);
+}
+
+PadActionEntry& PadActionEntry::operator=(const PadActionEntry& src)
+{
+  if (this == &src)
+    return *this;
+
+  if (!src.gobject_)
+  {
+    release_gobject();
+    return *this;
+  }
+
+  if (!gobject_)
+    gobject_ = g_new(GtkPadActionEntry, 1);
+  else
+  {
+    g_free(gobject_->label);
+    g_free(gobject_->action_name);
+  }
+  
+  *gobject_ = *src.gobject_;
+
+  gobject_->label = g_strdup(src.gobject_->label);
+  gobject_->action_name = g_strdup(src.gobject_->action_name);
+
+  return *this;
+}
+
+PadActionEntry::PadActionEntry(PadActionEntry&& other) noexcept
+ : gobject_(std::move(other.gobject_))
+{
+  other.gobject_ = nullptr;
+}
+
+PadActionEntry& PadActionEntry::operator=(PadActionEntry&& other) noexcept
+{
+  release_gobject();
+
+  gobject_ = std::move(other.gobject_);
+  other.gobject_ = nullptr;
+
+  return *this;
+}
+
+} // namespace Gtk
diff --git a/gtk/src/padactionentry.hg b/gtk/src/padactionentry.hg
new file mode 100644
index 00000000..edf657b5
--- /dev/null
+++ b/gtk/src/padactionentry.hg
@@ -0,0 +1,88 @@
+/* Copyright (C) 2019 The gtkmm Development Team
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glibmm/ustring.h>
+
+_DEFS(gtkmm,gtk)
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+extern "C" { typedef struct _GtkPadActionEntry GtkPadActionEntry; }
+#endif
+
+namespace Gtk
+{
+_WRAP_ENUM(PadActionType, GtkPadActionType)
+
+/** Class defining a pad action entry.
+ *
+ * @see Gtk::PadController
+ * @newin{3,96}
+ */
+class PadActionEntry
+{
+  _CLASS_GENERIC(PadActionEntry, GtkPadActionEntry)
+public:
+
+  PadActionEntry();
+
+  /** Construct a new %PadActionEntry.
+   *
+   * @param type The type of pad feature that will trigger this action.
+   * @param index The 0-indexed button/ring/strip number that will trigger this action.
+   * @param mode The mode that will trigger this action, or -1 for all modes.
+   * @param label Human readable description of this action, this string should
+   * be deemed user-visible.
+   * @param action_name Action name that will be activated in the Gio::ActionGroup.
+   */
+  PadActionEntry(PadActionType type, int index, int mode,
+    const Glib::ustring& label, const Glib::ustring& action_name);
+
+  PadActionEntry(const PadActionEntry& src);
+  PadActionEntry& operator=(const PadActionEntry& src);
+
+  PadActionEntry(PadActionEntry&& other) noexcept;
+  PadActionEntry& operator=(PadActionEntry&& other) noexcept;
+
+  virtual ~PadActionEntry();
+
+  _MEMBER_GET(type, type, PadActionType, GtkPadActionType)
+  _MEMBER_SET(type, type, PadActionType, GtkPadActionType)
+
+  _MEMBER_GET(index, index, int, gint)
+  _MEMBER_SET(index, index, int, gint)
+
+  _MEMBER_GET(mode, mode, int, gint)
+  _MEMBER_SET(mode, mode, int, gint)
+
+#m4 _CONVERSION(`gchar*',`Glib::ustring',`Glib::convert_const_gchar_ptr_to_ustring($3)')
+#m4 _CONVERSION(`Glib::ustring',`gchar*',`($3).c_str()')
+  _MEMBER_GET(label, label, Glib::ustring, gchar*)
+  _MEMBER_SET_STR(label, label, Glib::ustring, gchar*)
+
+  _MEMBER_GET(action_name, action_name, Glib::ustring, gchar*)
+  _MEMBER_SET_STR(action_name, action_name, Glib::ustring, gchar*)
+
+  GtkPadActionEntry*       gobj()       { return gobject_; }
+  const GtkPadActionEntry* gobj() const { return gobject_; }
+
+protected:
+  GtkPadActionEntry* gobject_;
+
+private:
+  void release_gobject() noexcept;
+};
+
+} // namespace Gtk
diff --git a/gtk/src/padcontroller.ccg b/gtk/src/padcontroller.ccg
index ced9fd5e..468debb4 100644
--- a/gtk/src/padcontroller.ccg
+++ b/gtk/src/padcontroller.ccg
@@ -15,6 +15,7 @@
  */
 
 #include <gtk/gtk.h>
+#include <memory>
 
 namespace Gtk
 {
@@ -27,4 +28,20 @@ PadController::PadController(const Glib::RefPtr<Gio::ActionGroup>& action_group,
 {
 }
 
+void PadController::set_action_entries(const std::vector<PadActionEntry>& entries)
+{
+  if (entries.empty())
+    return;
+
+  auto c_entries = std::make_unique<GtkPadActionEntry[]>(entries.size());
+
+  // Copy the GtkPadActionEntry instances to an array without duplicating the
+  // strings. Those strings are owned by entries. They are not deleted
+  // when the array in c_entries is deleted.
+  for (std::size_t i = 0; i < entries.size(); ++i)
+    c_entries[i] = *entries[i].gobj();
+
+  gtk_pad_controller_set_action_entries(gobj(), c_entries.get(), entries.size());
+}
+
 } // namespace Gtk
diff --git a/gtk/src/padcontroller.hg b/gtk/src/padcontroller.hg
index 9e24fc95..6daf094f 100644
--- a/gtk/src/padcontroller.hg
+++ b/gtk/src/padcontroller.hg
@@ -17,14 +17,13 @@
 #include <giomm/actiongroup.h>
 #include <gdkmm/device.h>
 #include <gtkmm/eventcontroller.h>
+#include <gtkmm/padactionentry.h>
 
 _DEFS(gtkmm,gtk)
 _PINCLUDE(gtkmm/private/eventcontroller_p.h)
 
 namespace Gtk
 {
-_WRAP_ENUM(PadActionType, GtkPadActionType)
-
 /** Event controller for drawing tablet pads.
  *
  * %Gtk::PadController is an event controller for the pads found in drawing
@@ -45,20 +44,25 @@ _WRAP_ENUM(PadActionType, GtkPadActionType)
  * Gdk::DevicePad::get_group_n_modes().
  *
  * Each of the actions that a given button/strip/ring performs for a given
- * mode is defined by a GtkPadActionEntry. It contains an action name that
+ * mode is defined by a Gtk::PadActionEntry. It contains an action name that
  * will be looked up in the given Gio::ActionGroup and activated whenever the
  * specified input element and mode are triggered.
  *
  * A simple example of %Gtk::PadController usage, assigning button 1 in all
- * modes and pad devices to an "invert-selection" action:
+ * modes and pad devices to a "black" action and button 2 to a "pink" action:
  *
  * @code
  * auto action_group = Gio::SimpleActionGroup::create();
- * auto action = action_group->add_action("pad-actions.invert-selection",
- *   sigc::ptr_fun(on_invert_selection_activated));
  * auto pad_controller = Gtk::PadController::create(action_group);
- * pad_controller->set_action(Gtk::PadActionType::BUTTON, 1, -1,
- *   "Invert selection", "pad-actions.invert-selection");
+ * std::vector<Gtk::PadActionEntry> entries = {
+ *   { Gtk::PadActionType::BUTTON, 1, -1, "Black", "pad.black" },
+ *   { Gtk::PadActionType::BUTTON, 2, -1, "Pink", "pad.pink" },
+ * };
+ * for (const auto& entry : entries)
+ *   action_group->add_action(entry.get_action_name(), sigc::mem_fun(*this, &MyWindow::on_pad_activated));
+ * pad_controller->set_action_entries(entries);
+ * // Assuming the code is in the MyWindow constructor.
+ * add_controller(pad_controller);
  * @endcode
  *
  * The actions belonging to rings/strips will be activated with a parameter
@@ -100,8 +104,15 @@ public:
   _WRAP_CREATE(const Glib::RefPtr<Gio::ActionGroup>& action_group,
     const Glib::RefPtr<Gdk::Device>& pad = {})
 
-//TODO: Wrap GtkPadActionEntry. Glib::OptionEntry may give some hints.
-//  _WRAP_METHOD(void set_action_entries(const std::vector<const PadActionEntry>& entries), 
gtk_pad_controller_set_action_entries)
+  /** This is a convenience function to add a group of action entries on the pad controller.
+   *
+   * See Gtk::PadActionEntry and set_action().
+   *
+   * @param entries The action entries to set on the controller.
+   */
+  void set_action_entries(const std::vector<PadActionEntry>& entries);
+  _IGNORE(gtk_pad_controller_set_action_entries)
+
   _WRAP_METHOD(void set_action(PadActionType type, int index, int mode,
     const Glib::ustring& label, const Glib::ustring& action_name), gtk_pad_controller_set_action)
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]