/* * moogpp/gobjtypes-gtk.h * * Copyright (C) 2004-2016 by Yevgen Muntyan * * This file is part of medit. medit 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. * * You should have received a copy of the GNU Lesser General Public * License along with medit. If not, see . */ #pragma once #ifndef __cplusplus #error "This is a C++ header" #endif #include #include "moogpp/gobjtypes-glib.h" #include "moogpp/strutils.h" #include #include #define MOO_DEFINE_GTK_TYPE(Object, Parent, obj_g_type) \ MOO_DEFINE_SIMPLE_GOBJ_CLASS(Object, Parent, Gtk##Object, obj_g_type) \ #define MOO_DEFINE_GTK_IFACE(Iface, iface_g_type) \ MOO_DEFINE_GIFACE_TYPE(Gtk##Iface, iface_g_type) \ namespace moo { \ namespace gtk { \ MOO_GIFACE_TYPEDEFS(Iface, Gtk##Iface) \ } \ } namespace gtk { using gstr = g::gstr; using gerrp = g::gerrp; MOO_DECLARE_GOBJ_CLASS(Object); MOO_DECLARE_GOBJ_CLASS(Widget); MOO_DECLARE_GOBJ_CLASS(TextView); MOO_DECLARE_GOBJ_CLASS(TreeModel); MOO_DECLARE_GOBJ_CLASS(TreeStore); MOO_DECLARE_GOBJ_CLASS(ListStore); MOO_DECLARE_GOBJ_CLASS(TreeView); MOO_DECLARE_GOBJ_CLASS(TreeViewColumn); MOO_DECLARE_GOBJ_CLASS(CellRenderer); MOO_DECLARE_GOBJ_CLASS(CellRendererText); MOO_DECLARE_GOBJ_CLASS(CellRendererToggle); MOO_DECLARE_GOBJ_CLASS(CellRendererPixbuf); MOO_DEFINE_GTK_TYPE(Object, g::Object, GTK_TYPE_OBJECT); MOO_DEFINE_GTK_TYPE(Widget, gtk::Object, GTK_TYPE_WIDGET); MOO_DEFINE_GTK_TYPE(Entry, gtk::Widget, GTK_TYPE_ENTRY); MOO_DEFINE_GTK_TYPE(Action, g::Object, GTK_TYPE_ACTION); MOO_DEFINE_GTK_TYPE(TextBuffer, g::Object, GTK_TYPE_TEXT_BUFFER); MOO_DEFINE_GTK_TYPE(TextMark, g::Object, GTK_TYPE_TEXT_MARK); MOO_DEFINE_GTK_TYPE(MenuShell, gtk::Widget, GTK_TYPE_MENU_SHELL); MOO_DEFINE_GTK_TYPE(Menu, gtk::MenuShell, GTK_TYPE_MENU); class TextView : public Widget { MOO_GOBJ_CLASS_DECL(TextView, Widget, GtkTextView, GTK_TYPE_TEXT_VIEW) public: gtk::TextBuffer get_buffer (); }; class TreeModel : public g::Iface { MOO_GOBJ_IFACE_DECL(TreeModel, GtkTreeModel, GTK_TYPE_TREE_MODEL) public: GtkTreeModelFlags get_flags (); int get_n_columns (); GType get_column_type (int index_); bool get_iter (GtkTreeIter& iter, const GtkTreePath& path); bool get_iter_from_string (GtkTreeIter& iter, const char* path_string); gstr get_string_from_iter (const GtkTreeIter& iter); bool get_iter_first (GtkTreeIter& iter); GtkTreePath* get_path (const GtkTreeIter& iter); void get_value (const GtkTreeIter& iter, int column, GValue* value); bool iter_next (GtkTreeIter& iter); bool iter_children (GtkTreeIter& iter, const GtkTreeIter& parent); bool iter_has_child (const GtkTreeIter& iter); int iter_n_children (const GtkTreeIter& iter); bool iter_nth_child (GtkTreeIter& iter, const GtkTreeIter& parent, int n); bool iter_parent (GtkTreeIter& iter, const GtkTreeIter& child); void get (const GtkTreeIter& iter, int column, bool& dest) { gboolean val; gtk_tree_model_get (gobj (), const_cast(&iter), column, &val, -1); dest = val; } template void get (const GtkTreeIter& iter, int column, T&& dest) { gtk_tree_model_get (gobj (), const_cast(&iter), column, cpp_vararg_dest_fixer::apply (std::forward (dest)), -1); } template void get (const GtkTreeIter& iter, int column, T&& dest, Args&&... args) { get (iter, column, std::forward (dest)); get (iter, std::forward (args)...); } // bool TFunc (const GtkTreePath&, const GtkTreeIter&) template void foreach (const TFunc& func) { const void* p = &func; gtk_tree_model_foreach (gobj (), foreach_func, const_cast(p)); } private: template static gboolean foreach_func (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) { const TFunc& func = *reinterpret_cast(data); return func (const_cast(*path), const_cast(*iter)); } }; class ListStore : public g::Object, public TreeModel { MOO_GOBJ_CLASS_DECL(ListStore, g::Object, GtkListStore, GTK_TYPE_LIST_STORE) public: static gtk::ListStorePtr create (std::initializer_list types) { return create (types.size (), types.begin ()); } static gtk::ListStorePtr create (size_t n_columns, std::initializer_list types) { g_return_val_if_fail (n_columns == types.size (), nullptr); return create (n_columns, types.begin ()); } static gtk::ListStorePtr create (size_t n_columns, const GType* types); template void set (const GtkTreeIter& iter, int column, T&& value) { gtk_list_store_set (gobj (), const_cast(&iter), column, cpp_vararg_value_fixer::apply (std::forward (value)), -1); } template void set (const GtkTreeIter& iter, int column, T&& value, Args&&... args) { set (iter, column, std::forward (value)); set (iter, std::forward (args)...); } void set_value (const GtkTreeIter& iter, int column, GValue* value); void set_valuesv (const GtkTreeIter& iter, int* columns, GValue* values, int n_values); bool remove (GtkTreeIter& iter); void insert (GtkTreeIter& iter, int position); void insert_before (GtkTreeIter& iter, GtkTreeIter& sibling); void insert_after (GtkTreeIter& iter, GtkTreeIter& sibling); //void insert_with_values (GtkTreeIter* iter, // int position, // ...); //void insert_with_values (GtkTreeIter* iter, // int position, // int* columns, // GValue* values, // int n_values); void prepend (GtkTreeIter& iter); void append (GtkTreeIter& iter); void clear (); bool iter_is_valid (const GtkTreeIter& iter); void reorder (int* new_order); void swap (GtkTreeIter& a, GtkTreeIter& b); void move_after (GtkTreeIter& iter, GtkTreeIter& position); void move_before (GtkTreeIter& iter, GtkTreeIter& position); }; class TreeStore : public g::Object, public TreeModel { MOO_GOBJ_CLASS_DECL(TreeStore, g::Object, GtkTreeStore, GTK_TYPE_TREE_STORE) }; MOO_DEFINE_GTK_TYPE(Container, Widget, GTK_TYPE_CONTAINER); MOO_DEFINE_GTK_TYPE(TreeView, Container, GTK_TYPE_TREE_VIEW); MOO_DEFINE_GTK_TYPE(TreeViewColumn, Object, GTK_TYPE_TREE_VIEW_COLUMN); MOO_DEFINE_GTK_TYPE(CellRenderer, Object, GTK_TYPE_CELL_RENDERER); MOO_DEFINE_GTK_TYPE(CellRendererText, CellRenderer, GTK_TYPE_CELL_RENDERER_TEXT); MOO_DEFINE_GTK_TYPE(CellRendererPixbuf, CellRenderer, GTK_TYPE_CELL_RENDERER_PIXBUF); MOO_DEFINE_GTK_TYPE(CellRendererToggle, CellRenderer, GTK_TYPE_CELL_RENDERER_TOGGLE); #if 0 template class TreeCellDataFunc { public: TreeCellDataFunc (TFunc func) : m_func (std::move (func)) {} ~TreeCellDataFunc () {} MOO_DISABLE_COPY_OPS (TreeCellDataFunc); static void destroy (gpointer d) { delete reinterpret_cast(d); } static void cell_data_func (GtkTreeViewColumn *tree_column, GtkCellRenderer *cell, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer p); private: TFunc m_func; }; template<> class moo::gobj_ref : public virtual moo::gobj_ref_parent { public: MOO_DEFINE_GOBJREF_METHODS (GtkTreeView); static gtk::TreeViewPtr create (gtk::TreeModelPtr model); gtk::TreeModelPtr get_model (); void set_model (gtk::TreeModelPtr model); GtkTreeSelection* get_selection (); GtkAdjustment* get_hadjustment (); void set_hadjustment (GtkAdjustment* adjustment); GtkAdjustment* get_vadjustment (); void set_vadjustment (GtkAdjustment* adjustment); bool get_headers_visible (); void set_headers_visible (bool headers_visible); void columns_autosize (); bool get_headers_clickable (); void set_headers_clickable (bool setting); void set_rules_hint (bool setting); bool get_rules_hint (); /* Column funtions */ int append_column (gtk::TreeViewColumn& column); int remove_column (gtk::TreeViewColumn& column); int insert_column (gtk::TreeViewColumn& column, int position); int insert_column_with_attributes (int position, const char* title, gtk::CellRenderer& cell, ...) G_GNUC_NULL_TERMINATED; template int insert_column_with_data_func (int position, const char* title, gtk::CellRenderer& cell, TFunc func); gtk::TreeViewColumnPtr get_column (int n); std::vector get_columns (); void move_column_after (gtk::TreeViewColumn& column, gtk::TreeViewColumn& base_column); void set_expander_column (gtk::TreeViewColumn& column); gtk::TreeViewColumnPtr get_expander_column (); void set_column_drag_function (GtkTreeViewColumnDropFunc func, gpointer user_data, GDestroyNotify destroy); /* Actions */ void scroll_to_point (int tree_x, int tree_y); void scroll_to_cell (GtkTreePath* path, gtk::TreeViewColumn& column, bool use_align, float row_align, float col_align); void row_activated (GtkTreePath* path, gtk::TreeViewColumn& column); void expand_all (); void collapse_all (); void expand_to_path (GtkTreePath* path); bool expand_row (GtkTreePath* path, bool open_all); bool collapse_row (GtkTreePath* path); void map_expanded_rows (GtkTreeViewMappingFunc func, gpointer data); bool row_expanded (GtkTreePath* path); void set_reorderable (bool reorderable); bool get_reorderable (); void set_cursor (GtkTreePath* path, gtk::TreeViewColumn& focus_column, bool start_editing); void set_cursor_on_cell (GtkTreePath* path, gtk::TreeViewColumn& focus_column, gtk::CellRenderer& focus_cell, bool start_editing); void get_cursor (GtkTreePath** path, gtk::TreeViewColumnPtr& focus_column); /* Layout information */ GdkWindow* get_bin_window (); bool get_path_at_pos (int x, int y, GtkTreePath** path, gtk::TreeViewColumnPtr& column, int* cell_x, int* cell_y); void get_cell_area (GtkTreePath* path, gtk::TreeViewColumn& column, GdkRectangle& rect); void get_background_area (GtkTreePath* path, gtk::TreeViewColumn& column, GdkRectangle& rect); void get_visible_rect (GdkRectangle& visible_rect); bool get_visible_range (GtkTreePath** start_path, GtkTreePath** end_path); /* Drag-and-Drop support */ void enable_model_drag_source (GdkModifierType start_button_mask, const GtkTargetEntry* targets, int n_targets, GdkDragAction actions); void enable_model_drag_dest (const GtkTargetEntry* targets, int n_targets, GdkDragAction actions); void unset_rows_drag_source (); void unset_rows_drag_dest (); /* These are useful to implement your own custom stuff. */ void set_drag_dest_row (GtkTreePath* path, GtkTreeViewDropPosition pos); void get_drag_dest_row (GtkTreePath** path, GtkTreeViewDropPosition* pos); bool get_dest_row_at_pos (int drag_x, int drag_y, GtkTreePath** path, GtkTreeViewDropPosition* pos); GdkPixmap* create_row_drag_icon (GtkTreePath* path); /* Interactive search */ void set_enable_search (bool enable_search); bool get_enable_search (); int get_search_column (); void set_search_column (int column); GtkTreeViewSearchEqualFunc get_search_equal_func (); void set_search_equal_func (GtkTreeViewSearchEqualFunc search_equal_func, gpointer search_user_data, GDestroyNotify search_destroy); GtkEntry* get_search_entry (); void set_search_entry (GtkEntry* entry); GtkTreeViewSearchPositionFunc get_search_position_func (); void set_search_position_func (GtkTreeViewSearchPositionFunc func, gpointer data, GDestroyNotify destroy); /* Convert between the different coordinate systems */ void convert_widget_to_tree_coords (int wx, int wy, int* tx, int* ty); void convert_tree_to_widget_coords (int tx, int ty, int* wx, int* wy); void convert_widget_to_bin_window_coords (int wx, int wy, int* bx, int* by); void convert_bin_window_to_widget_coords (int bx, int by, int* wx, int* wy); void convert_tree_to_bin_window_coords (int tx, int ty, int* bx, int* by); void convert_bin_window_to_tree_coords (int bx, int by, int* tx, int* ty); void set_fixed_height_mode (bool enable); bool get_fixed_height_mode (); void set_hover_selection (bool hover); bool get_hover_selection (); void set_hover_expand (bool expand); bool get_hover_expand (); void set_rubber_banding (bool enable); bool get_rubber_banding (); bool is_rubber_banding_active (); GtkTreeViewRowSeparatorFunc get_row_separator_func (); void set_row_separator_func (GtkTreeViewRowSeparatorFunc func, gpointer data, GDestroyNotify destroy); GtkTreeViewGridLines get_grid_lines (); void set_grid_lines (GtkTreeViewGridLines grid_lines); bool get_enable_tree_lines (); void set_enable_tree_lines (bool enabled); void set_show_expanders (bool enabled); bool get_show_expanders (); void set_level_indentation (int indentation); int get_level_indentation (); /* Convenience functions for setting tooltips */ void set_tooltip_row (GtkTooltip* tooltip, GtkTreePath* path); void set_tooltip_cell (GtkTooltip* tooltip, GtkTreePath* path, gtk::TreeViewColumn& column, gtk::CellRenderer& cell); bool get_tooltip_context (int* x, int* y, bool keyboard_tip, GtkTreeModel** model, GtkTreePath** path, GtkTreeIter* iter); void set_tooltip_column (int column); int get_tooltip_column (); }; template<> class moo::gobj_ref : public virtual moo::gobj_ref_parent { public: MOO_DEFINE_GOBJREF_METHODS (GtkTreeViewColumn); static gtk::TreeViewColumnPtr create (); static gtk::TreeViewColumnPtr create (const char* title, gtk::CellRendererPtr cell, ...) G_GNUC_NULL_TERMINATED; void pack_start (gtk::CellRenderer& cell, bool expand); void pack_end (gtk::CellRenderer& cell, bool expand); void clear (); std::vector get_cell_renderers (); void add_attribute (gtk::CellRenderer& cell, const char* attribute, int column); void set_attributes (gtk::CellRenderer& cell_renderer, const char* prop, int column); template void set_attributes (gtk::CellRenderer& cell_renderer, const char* prop, int column, Args&&... args) { set_attributes (cell_renderer, prop, column); set_attributes (cell_renderer, std::forward (args)...); } // void TFunc(gtk::TreeViewColumn, gtk::CellRenderer, gtk::TreeModel, const GtkTreeIter&) template inline void set_cell_data_func (gtk::CellRenderer& cell_renderer, TFunc func); void clear_attributes (gtk::CellRenderer& cell_renderer); void set_spacing (int spacing); int get_spacing (); void set_visible (bool visible); bool get_visible (); void set_resizable (bool resizable); bool get_resizable (); void set_sizing (GtkTreeViewColumnSizing type); GtkTreeViewColumnSizing get_sizing (); int get_width (); int get_fixed_width (); void set_fixed_width (int fixed_width); void set_min_width (int min_width); int get_min_width (); void set_max_width (int max_width); int get_max_width (); void clicked (); /* Options for manipulating the column headers */ void set_title (const char* title); gstr get_title (); void set_expand (bool expand); bool get_expand (); void set_clickable (bool clickable); bool get_clickable (); void set_widget (gtk::WidgetPtr widget); gtk::WidgetPtr get_widget (); void set_alignment (float xalign); float get_alignment (); void set_reorderable (bool reorderable); bool get_reorderable (); /* You probably only want to use gtk_tree_view_column_set_sort_column_id. The * other sorting functions exist primarily to let others do their own custom sorting. */ void set_sort_column_id (int sort_column_id); int get_sort_column_id (); void set_sort_indicator (bool setting); bool get_sort_indicator (); void set_sort_order (GtkSortType order); GtkSortType get_sort_order (); gtk::TreeViewPtr get_tree_view (); }; template<> class moo::gobj_ref : public virtual moo::gobj_ref_parent { public: MOO_DEFINE_GOBJREF_METHODS (GtkCellRenderer); }; template<> class moo::gobj_ref : public virtual moo::gobj_ref_parent { public: MOO_DEFINE_GOBJREF_METHODS (GtkCellRendererText); static gtk::CellRendererTextPtr create (); void set_fixed_height_from_font (int number_of_rows); }; template<> class moo::gobj_ref : public virtual moo::gobj_ref_parent { public: MOO_DEFINE_GOBJREF_METHODS (GtkCellRendererToggle); static gtk::CellRendererTogglePtr create (); bool get_radio (); void set_radio (bool radio); bool get_active (); void set_active (bool active); }; template<> class moo::gobj_ref : public virtual moo::gobj_ref_parent { public: MOO_DEFINE_GOBJREF_METHODS (GtkCellRendererPixbuf); static gtk::CellRendererPixbufPtr create (); }; template inline void TreeCellDataFunc::cell_data_func (GtkTreeViewColumn *tree_column, GtkCellRenderer *cell, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer p) { g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column)); g_return_if_fail (GTK_IS_CELL_RENDERER (cell)); g_return_if_fail (GTK_IS_TREE_MODEL (tree_model)); g_return_if_fail (iter != nullptr); g_return_if_fail (p != nullptr); TreeCellDataFunc& data = *reinterpret_cast(p); data.m_func (moo::wrap (*tree_column), moo::wrap (*cell), moo::wrap (*tree_model), const_cast(*iter)); } template inline int moo::gobj_ref::insert_column_with_data_func (int position, const char* title, gtk::CellRenderer& cell, TFunc func) { TreeCellDataFunc *data = new TreeCellDataFunc{ std::move (func) }; return gtk_tree_view_insert_column_with_data_func (gobj (), position, title, cell.gobj (), TreeCellDataFunc::cell_data_func, data, TreeCellDataFunc::destroy); } // void TFunc(gtk::TreeViewColumn, gtk::CellRenderer, gtk::TreeModel, const GtkTreeIter&) template inline void moo::gobj_ref::set_cell_data_func (gtk::CellRenderer& cell_renderer, TFunc func) { TreeCellDataFunc *data = new TreeCellDataFunc{ std::move (func) }; gtk_tree_view_column_set_cell_data_func (gobj (), cell_renderer.gobj (), TreeCellDataFunc::cell_data_func, data, TreeCellDataFunc::destroy); } MOO_DEFINE_FLAGS(GdkEventMask); MOO_DEFINE_FLAGS(GdkModifierType); MOO_DEFINE_FLAGS(GtkCellRendererState); MOO_DEFINE_FLAGS(GtkAttachOptions); MOO_DEFINE_FLAGS(GdkDragAction); #endif // 0 } // namespace gtk