Completion API and ComboBox API extension



Hey,

After a few good discussions with Owen, we came up with the following
ideas for the Completion API. I'll attach the headers and give some
explanation here. I've implemented all of it already and it works fine.


GtkCellLayout
-------------

GtkCellLayout is a new interface to be implemented by all objects which
want to provide a GtkTreeViewColumn-like API for packing cells, setting
attributes and data funcs. Objects in GTK+-2.4 which will implement this
interface are:
- GtkTreeViewColumn (I have a patch handy here)
- GtkEntryCompletion
- GtkComboBox

GtkComboBox just has functions for this right now, but I am
contemplating removing those (if this is not too confusing, I will write
docs for all my new code, so I guess it will be fine).

The only bit I don't really like is:
  /* keep in sync with GtkTreeCellDataFunc */

I am not sure how to get around that.



GtkEntryCompletion
------------------

GtkEntryCompletion is an auxiliary object to be used in conjunction with
GtkEntry to provide the completion functionality. It implements the
above described GtkCellLayout interface, to allow the user to add extra
cells to the TreeView with completion matches. I think the API in there
is pretty clear.

The API addition to GtkEntry remains small:

void gtk_entry_set_completion (GtkEntry           *entry,
                               GtkEntryCompletion *completion);
GtkEntryCompletion *gtk_entry_get_completion (GtkEntry *entry);
 
However, the patch to gtkentry.c is bigger, because a good chunk has to
be implemented in here.



Well, that's all. Comments/Suggestions/etc are welcome as always.



thanks,


	-Kris
/* gtkcelllayout.h
 * Copyright (C) 2003  Kristian Rietveld  <kris gtk org>
 *
 * <LGPL notice here>
 */

#ifndef __GTK_CELL_LAYOUT_H__
#define __GTK_CELL_LAYOUT_H__

#include <glib-object.h>

#include <gtk/gtkcellrenderer.h>
#include <gtk/gtktreeviewcolumn.h>

G_BEGIN_DECLS

#define GTK_TYPE_CELL_LAYOUT            (gtk_cell_layout_get_type ())
#define GTK_CELL_LAYOUT(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_CELL_LAYOUT, GtkCellLayout))
#define GTK_IS_CELL_LAYOUT(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_CELL_LAYOUT))
#define GTK_CELL_LAYOUT_GET_IFACE(obj)  (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GTK_TYPE_CELL_LAYOUT, GtkCellLayoutIface))

typedef struct _GtkCellLayout           GtkCellLayout; /* dummy typedef */
typedef struct _GtkCellLayoutIface      GtkCellLayoutIface;

/* keep in sync with GtkTreeCellDataFunc */
typedef void (* GtkCellLayoutDataFunc) (GtkCellLayout   *cell_layout,
                                        GtkCellRenderer *cell,
                                        GtkTreeModel    *tree_model,
                                        GtkTreeIter     *iter,
                                        gpointer         data);

struct _GtkCellLayoutIface
{
  GTypeInterface g_iface;

  /* Virtual Table */
  void (* pack_start)         (GtkCellLayout         *cell_layout,
                               GtkCellRenderer       *cell,
                               gboolean               expand);
  void (* pack_end)           (GtkCellLayout         *cell_layout,
                               GtkCellRenderer       *cell,
                               gboolean               expand);
  void (* clear)              (GtkCellLayout         *cell_layout);
  void (* add_attribute)      (GtkCellLayout         *cell_layout,
                               GtkCellRenderer       *cell,
                               const gchar           *attribute,
                               gint                   column);
  void (* set_cell_data_func) (GtkCellLayout         *cell_layout,
                               GtkCellRenderer       *cell,
                               GtkCellLayoutDataFunc  func,
                               gpointer               func_data,
                               GDestroyNotify         destroy);
  void (* clear_attributes)   (GtkCellLayout         *cell_layout,
                               GtkCellRenderer       *cell);
};

GType gtk_cell_layout_get_type           (void);
void  gtk_cell_layout_pack_start         (GtkCellLayout         *cell_layout,
                                          GtkCellRenderer       *cell,
                                          gboolean               expand);
void  gtk_cell_layout_pack_end           (GtkCellLayout         *cell_layout,
                                          GtkCellRenderer       *cell,
                                          gboolean               expand);
void  gtk_cell_layout_clear              (GtkCellLayout         *cell_layout);
void  gtk_cell_layout_set_attributes     (GtkCellLayout         *cell_layout,
                                          GtkCellRenderer       *cell,
                                          ...);
void  gtk_cell_layout_add_attribute      (GtkCellLayout         *cell_layout,
                                          GtkCellRenderer       *cell,
                                          const gchar           *attribute,
                                          gint                   column);
void  gtk_cell_layout_set_cell_data_func (GtkCellLayout         *cell_layout,
                                          GtkCellRenderer       *cell,
                                          GtkCellLayoutDataFunc  func,
                                          gpointer               func_data,
                                          GDestroyNotify         destroy);
void  gtk_cell_layout_clear_attributes   (GtkCellLayout         *cell_layout,
                                          GtkCellRenderer       *cell);


G_END_DECLS

#endif /* __GTK_CELL_LAYOUT_H__ */
/* gtkentrycompletion.h
 * Copyright (C) 2003  Kristian Rietveld  <kris gtk org>
 *
 * <LGPL notice here>
 */

#ifndef __GTK_ENTRY_COMPLETION_H__
#define __GTK_ENTRY_COMPLETION_H__

#include <glib-object.h>

#include <gtk/gtktreemodel.h>
#include <gtk/gtkliststore.h>
#include <gtk/gtktreeviewcolumn.h>
#include <gtk/gtktreemodelfilter.h>

G_BEGIN_DECLS

#define GTK_TYPE_ENTRY_COMPLETION            (gtk_entry_completion_get_type ())
#define GTK_ENTRY_COMPLETION(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_ENTRY_COMPLETION, GtkEntryCompletion))
#define GTK_ENTRY_COMPLETION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_ENTRY_COMPLETION, GtkEntryCompletionClass))
#define GTK_IS_ENTRY_COMPLETION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_ENTRY_COMPLETION))
#define GTK_IS_ENTRY_COMPLETION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_ENTRY_COMPLETION))
#define GTK_ENTRY_COMPLETION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_ENTRY_COMPLETION, GtkEntryCompletionClass))

typedef struct _GtkEntryCompletion            GtkEntryCompletion;
typedef struct _GtkEntryCompletionClass       GtkEntryCompletionClass;

typedef gboolean (* GtkEntryCompletionMatchFunc) (GtkEntryCompletion *completion,
                                                  const gchar        *key,
                                                  GtkTreeIter        *iter,
                                                  gpointer            user_data);


struct _GtkEntryCompletion
{
  GObject parent_instance;

  /*< private >*/
  GtkWidget *entry;

  GtkWidget *tree_view;
  GtkTreeViewColumn *column;
  GtkTreeModelFilter *filter_model;
  GtkListStore *actions;

  GtkEntryCompletionMatchFunc match_func;
  gpointer match_data;
  GDestroyNotify match_notify;

  gint minimum_key_length;
  gint text_column;
  gint current_match;

  gchar *case_normalized_key;

  /* only used by GtkEntry when attached: */
  GtkWidget *popup_window;
  GtkWidget *vbox;
  GtkWidget *scrolled_window;
  GtkWidget *action_view;

  gulong completion_timeout;
  gulong changed_id;
  gulong key_press_id;
  gulong action_changed_id;
};

struct _GtkEntryCompletionClass
{
  GObjectClass parent_class;

  gboolean (* match_selected)   (GtkEntryCompletion *completion,
                                 GtkTreeModel       *model,
                                 GtkTreeIter        *iter);
  void     (* action_activated) (GtkEntryCompletion *completion,
                                 gint                index);
};

/* core */
GType               gtk_entry_completion_get_type               (void);
GtkEntryCompletion *gtk_entry_completion_new                    (void);

void                gtk_entry_completion_set_model              (GtkEntryCompletion          *completion,
                                                                 GtkTreeModel                *model);
GtkTreeModel       *gtk_entry_completion_get_model              (GtkEntryCompletion          *completion);
void                gtk_entry_completion_set_match_func         (GtkEntryCompletion          *completion,
                                                                 GtkEntryCompletionMatchFunc  func,
                                                                 gpointer                     func_data,
                                                                 GDestroyNotify               func_notify);
void                gtk_entry_completion_set_minimum_key_length (GtkEntryCompletion          *completion,
                                                                 gint                         length);
gint                gtk_entry_completion_get_minimum_key_length (GtkEntryCompletion          *completion);
void                gtk_entry_completion_complete               (GtkEntryCompletion          *completion);

void                gtk_entry_completion_insert_action_text     (GtkEntryCompletion          *completion,
                                                                 gint                         index,
                                                                 gchar                       *text);
void                gtk_entry_completion_insert_action_markup   (GtkEntryCompletion          *completion,
                                                                 gint                         index,
                                                                 gchar                       *markup);
void                gtk_entry_completion_delete_action          (GtkEntryCompletion          *completion,
                                                                 gint                         index);

/* convenience */
void                gtk_entry_completion_set_text_column        (GtkEntryCompletion          *completion,
                                                                 gint                         column);


G_END_DECLS

#endif /* __GTK_ENTRY_COMPLETION_H__ */


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