[pygtk] Wrap gtk.RcStyle attributes



commit ed89f5605c57e21e95cfc2fecfc6830947faf2de
Author: Paul Pogonyshev <pogonyshev gmx net>
Date:   Fri May 8 20:59:33 2009 +0300

    Wrap gtk.RcStyle attributes
    
    Closes bug #421196.
---
 docs/reference/pygtk-gtkrcstyle.xml |   92 +++++++++++++++++++++
 gtk/Makefile.am                     |    1 +
 gtk/gtk-base-types.defs             |   11 +++
 gtk/gtk-types.c                     |  154 ++++++++++++++++++++++++++++++++++-
 gtk/gtk.override                    |    1 +
 gtk/gtkrcstyle.override             |  150 ++++++++++++++++++++++++++++++++++
 gtk/pygtk-private.h                 |   11 +++
 7 files changed, 419 insertions(+), 1 deletions(-)

diff --git a/docs/reference/pygtk-gtkrcstyle.xml b/docs/reference/pygtk-gtkrcstyle.xml
index 2222f2d..54a13f0 100644
--- a/docs/reference/pygtk-gtkrcstyle.xml
+++ b/docs/reference/pygtk-gtkrcstyle.xml
@@ -82,6 +82,98 @@
 
   </refsect1>
 
+  <refsect1 id="attributes-gtkrcstyle">
+    <title>Attributes</title>
+
+    <note>
+      <para>Available in PyGTK 2.16 and above.</para>
+    </note>
+
+    <note>
+      <para>Some of the following attributes are arrays
+      of <link linkend="class-gdkcolor"><classname>gtk.gdk.Color</classname></link> or
+      strings.  Array objects themselves are read-only but individual elements are
+      read-write.</para>
+    </note>
+
+    <blockquote role="properties">
+      <informaltable pgwide="1" frame="none">
+	<tgroup cols="3">
+	<?dbhtml cellpadding="5"?>
+	  <colspec column="1" colwidth="1in"/>
+	  <colspec column="2" colwidth="1in"/>
+	  <colspec column="3" colwidth="4in"/>
+
+          <tbody>
+	    <row valign="top">
+	      <entry>"name"</entry>
+	      <entry>Read-Write</entry>
+	      <entry>Name of the style.</entry>
+	    </row>
+
+	    <row valign="top">
+	      <entry>"bg_pixmap_name"</entry>
+	      <entry>Read</entry>
+	      <entry>An array of names of pixmap files to be used as the background in
+	        each widget state.</entry>
+	    </row>
+
+	    <row valign="top">
+	      <entry>"font_desc"</entry>
+	      <entry>Read-Write</entry>
+	      <entry>A <classname>pango.FontDescription</classname> used as the default
+                text font.</entry>
+	    </row>
+
+	    <row valign="top">
+	      <entry>"fg"</entry>
+	      <entry>Read</entry>
+	      <entry>An array
+                of <link linkend="class-gdkcolor"><classname>gtk.gdk.Color</classname></link>s
+                to be used for the foreground colors in each widget state.</entry>
+	    </row>
+
+	    <row valign="top">
+	      <entry>"bg"</entry>
+	      <entry>Read</entry>
+	      <entry>An array
+                of <link linkend="class-gdkcolor"><classname>gtk.gdk.Color</classname></link>s
+                to be used for the background colors in each widget state.</entry>
+	    </row>
+
+	    <row valign="top">
+	      <entry>"text"</entry>
+	      <entry>Read</entry>
+	      <entry>An array
+                of <link linkend="class-gdkcolor"><classname>gtk.gdk.Color</classname></link>s
+                to be used for the text colors in each widget state.</entry>
+	    </row>
+
+	    <row valign="top">
+	      <entry>"base"</entry>
+	      <entry>Read</entry>
+	      <entry>An array
+                of <link linkend="class-gdkcolor"><classname>gtk.gdk.Color</classname></link>s
+                to be used for the base colors in each widget state.</entry>
+	    </row>
+
+	    <row valign="top">
+	      <entry>"xthickness"</entry>
+	      <entry>Read-Write</entry>
+	      <entry>The thickness of lines drawn vertically.</entry>
+	    </row>
+
+	    <row valign="top">
+	      <entry>"ythickness"</entry>
+	      <entry>Read-Write</entry>
+	      <entry>The thickness of lines drawn horizontally.</entry>
+	    </row>
+	</tbody>
+      </tgroup>
+      </informaltable>
+    </blockquote>
+  </refsect1>
+
   <refsect1 id="signal-prototypes-gtkrcstyle">
     <title>gtk.RcStyle Signal Prototypes</title>
 
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index b9ec8f3..0f92ae8 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -107,6 +107,7 @@ GTK_OVERRIDES = 		\
 	gtkcontainer.override 	\
 	gtkctree.override 	\
 	gtkiconview.override 	\
+	gtkrcstyle.override 	\
 	gtkstyle.override 	\
 	gtktextview.override 	\
 	gtktoolbar.override 	\
diff --git a/gtk/gtk-base-types.defs b/gtk/gtk-base-types.defs
index 5ced775..bfd23cb 100644
--- a/gtk/gtk-base-types.defs
+++ b/gtk/gtk-base-types.defs
@@ -2199,6 +2199,17 @@
   (in-module "Gtk")
   (parent "GObject")
   (c-name "GtkRcStyle")
+  (fields
+    '("gchar*" "name")
+    '("gchar**" "bg_pixmap_name")
+    '("PangoFontDescription*" "font_desc")
+    '("GdkColor*" "fg")
+    '("GdkColor*" "bg")
+    '("GdkColor*" "text")
+    '("GdkColor*" "base")
+    '("gint" "xthickness")
+    '("gint" "ythickness")
+  )
   (gtype-id "GTK_TYPE_RC_STYLE")
 )
 
diff --git a/gtk/gtk-types.c b/gtk/gtk-types.c
index d75b088..a7e078b 100644
--- a/gtk/gtk-types.c
+++ b/gtk/gtk-types.c
@@ -64,9 +64,10 @@ PyGdkAtom_New(GdkAtom atom)
 }
 
 
-/* style helper code */
+/* style & rc-style helper code */
 #define NUM_STATES 5
 staticforward PyTypeObject PyGtkStyleHelper_Type;
+staticforward PyTypeObject PyGtkRcStyleHelper_Type;
 
 PyObject *
 _pygtk_style_helper_new(GtkStyle *style, int type, gpointer array)
@@ -233,6 +234,155 @@ static PyTypeObject PyGtkStyleHelper_Type = {
     NULL
 };
 
+PyObject *
+_pygtk_rc_style_helper_new(GtkRcStyle *rc_style, int type, gpointer array, GtkRcFlags is_set_flag)
+{
+    PyGtkRcStyleHelper_Object *self;
+
+    self = (PyGtkRcStyleHelper_Object *)PyObject_NEW(PyGtkRcStyleHelper_Object,
+                                                     &PyGtkRcStyleHelper_Type);
+    if (self == NULL)
+	return NULL;
+
+    self->rc_style = g_object_ref(rc_style);
+    self->type = type;
+    self->array = array;
+    self->is_set_flag = is_set_flag;
+    return (PyObject *)self;
+}
+
+static void
+pygtk_rc_style_helper_dealloc(PyGtkRcStyleHelper_Object *self)
+{
+    g_object_unref(self->rc_style);
+    PyObject_DEL(self);
+}
+
+static Py_ssize_t
+pygtk_rc_style_helper_length(PyGtkRcStyleHelper_Object *self)
+{
+    return NUM_STATES;
+}
+
+static PyObject *
+pygtk_rc_style_helper_getitem(PyGtkRcStyleHelper_Object *self, Py_ssize_t pos)
+{
+    if (pos < 0) pos += NUM_STATES;
+    if (pos < 0 || pos >= NUM_STATES) {
+	PyErr_SetString(PyExc_IndexError, "index out of range");
+	return NULL;
+    }
+    switch (self->type) {
+    case RC_STYLE_STRING_ARRAY:
+	{
+	    gchar **array = (gchar **)self->array;
+	    if (array[pos])
+		return PyString_FromString(array[pos]);
+	    else {
+		Py_INCREF(Py_None);
+		return Py_None;
+	    }
+	}
+    case RC_STYLE_COLOUR_ARRAY:
+        if (self->rc_style->color_flags[pos] & self->is_set_flag) {
+            GdkColor *array = (GdkColor *)self->array;
+            return pyg_boxed_new(GDK_TYPE_COLOR, &array[pos], TRUE, TRUE);
+        }
+        else {
+            Py_INCREF(Py_None);
+            return Py_None;
+        }
+    }
+    g_assert_not_reached();
+    return NULL;
+}
+
+static int
+pygtk_rc_style_helper_setitem(PyGtkRcStyleHelper_Object *self, Py_ssize_t pos,
+                              PyObject *value)
+{
+    extern PyTypeObject PyGdkGC_Type;
+    extern PyTypeObject PyGdkPixmap_Type;
+
+    if (pos < 0) pos += NUM_STATES;
+    if (pos < 0 || pos >= NUM_STATES) {
+	PyErr_SetString(PyExc_IndexError, "index out of range");
+	return -1;
+    }
+    switch (self->type) {
+    case RC_STYLE_STRING_ARRAY:
+	{
+            gchar **array = (gchar **)self->array;
+            gchar *string;
+	    PyObject *as_string;
+
+	    if (value == Py_None)
+                string = NULL;
+	    else if ((as_string = PyObject_Str(value)) != NULL) {
+		string = g_strdup(PyString_AsString(as_string));
+		Py_DECREF(as_string);
+	    }
+            else
+                return -1;
+
+            g_free(array[pos]);
+            array[pos] = string;
+	    return 0;
+	}
+    case RC_STYLE_COLOUR_ARRAY:
+        if (value == Py_None) {
+            self->rc_style->color_flags[pos] &= ~self->is_set_flag;
+            return 0;
+        }
+        if (pyg_boxed_check(value, GDK_TYPE_COLOR)) {
+	    GdkColor *array = (GdkColor *)self->array;
+	    array[pos] = *pyg_boxed_get(value, GdkColor);
+            self->rc_style->color_flags[pos] |= self->is_set_flag;
+	    return 0;
+        }
+        else {
+            PyErr_SetString(PyExc_TypeError, "can only assign a gtk.gdk.Color or None");
+            return -1;
+	}
+    }
+    g_assert_not_reached();
+    return -1;
+}
+
+static PySequenceMethods pygtk_rc_style_helper_seqmethods = {
+    (lenfunc)pygtk_rc_style_helper_length,
+    0,
+    0,
+    (ssizeargfunc)pygtk_rc_style_helper_getitem,
+    0,
+    (ssizeobjargproc)pygtk_rc_style_helper_setitem,
+    0,
+};
+static PyTypeObject PyGtkRcStyleHelper_Type = {
+    PyObject_HEAD_INIT(NULL)
+    0,
+    "gtk.GtkRcStyleHelper",
+    sizeof(PyGtkRcStyleHelper_Object),
+    0,
+    (destructor)pygtk_rc_style_helper_dealloc,
+    (printfunc)0,
+    (getattrfunc)0,
+    (setattrfunc)0,
+    (cmpfunc)0,
+    (reprfunc)0,
+    0,
+    &pygtk_rc_style_helper_seqmethods,
+    0,
+    (hashfunc)0,
+    (ternaryfunc)0,
+    (reprfunc)0,
+    (getattrofunc)0,
+    (setattrofunc)0,
+    0,
+    Py_TPFLAGS_DEFAULT,
+    NULL
+};
+
 #if 0
 static void
 PyGdkWindow_Dealloc(PyGdkWindow_Object *self)
@@ -1352,11 +1502,13 @@ void
 _pygtk_register_boxed_types(PyObject *moddict)
 {
     PyGtkStyleHelper_Type.ob_type = &PyType_Type;
+    PyGtkRcStyleHelper_Type.ob_type = &PyType_Type;
     PyGdkAtom_Type.ob_type = &PyType_Type;
     PyGtkTreeModelRow_Type.ob_type = &PyType_Type;
     PyGtkTreeModelRowIter_Type.ob_type = &PyType_Type;
 
     PyType_Ready(&PyGtkStyleHelper_Type);
+    PyType_Ready(&PyGtkRcStyleHelper_Type);
     PyType_Ready(&PyGdkAtom_Type);
     PyType_Ready(&PyGtkTreeModelRow_Type);
     PyType_Ready(&PyGtkTreeModelRowIter_Type);
diff --git a/gtk/gtk.override b/gtk/gtk.override
index b2e86f5..a3a9b74 100644
--- a/gtk/gtk.override
+++ b/gtk/gtk.override
@@ -135,6 +135,7 @@ include
   gtkcontainer.override
   gtkctree.override
   gtkiconview.override
+  gtkrcstyle.override
   gtkstyle.override
   gtktextview.override
   gtktoolbar.override
diff --git a/gtk/gtkrcstyle.override b/gtk/gtkrcstyle.override
new file mode 100644
index 0000000..1d77af8
--- /dev/null
+++ b/gtk/gtkrcstyle.override
@@ -0,0 +1,150 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * pygtk- Python bindings for the GTK toolkit.
+ * Copyright (C) 2007  Paul Pogonyshev
+ *
+ *   gtkrcstyle.override: overrides for the gtk.RcStyle object.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+%%
+override-attr GtkRcStyle.name
+static int
+_wrap_gtk_rc_style__set_name(PyGObject *self, PyObject *value, void *closure)
+{
+    GtkRcStyle *rc_style = GTK_RC_STYLE(self->obj);
+    gchar *name;
+    PyObject *as_string;
+
+    if (value == Py_None)
+        name = NULL;
+    else if ((as_string = PyObject_Str(value)) != NULL) {
+        name = g_strdup(PyString_AsString(as_string));
+        Py_DECREF(as_string);
+    }
+    else
+        return -1;
+
+    g_free(rc_style->name);
+    rc_style->name = name;
+    return 0;
+}
+
+%%
+override-attr GtkRcStyle.bg_pixmap_name
+static PyObject *
+_wrap_gtk_rc_style__get_bg_pixmap_name(PyGObject *self, void *closure)
+{
+    GtkRcStyle *rc_style = GTK_RC_STYLE(self->obj);
+
+    return _pygtk_rc_style_helper_new(rc_style, RC_STYLE_STRING_ARRAY, rc_style->bg_pixmap_name, 0);
+}
+
+%%
+override-attr GtkRcStyle.font_desc
+static int
+_wrap_gtk_rc_style__set_font_desc(PyGObject *self, PyObject *value, void *closure)
+{
+    GtkRcStyle *rc_style = GTK_RC_STYLE(self->obj);
+    PangoFontDescription *font_desc;
+
+    if (value == Py_None)
+        font_desc = NULL;
+    else if (pyg_boxed_check(value, PANGO_TYPE_FONT_DESCRIPTION))
+        font_desc = pango_font_description_copy(pyg_boxed_get(value, PangoFontDescription));
+    else {
+        PyErr_SetString(PyExc_TypeError, "can only assign a pango.FontDescription or None");
+        return -1;
+    }
+
+    pango_font_description_free(rc_style->font_desc);
+    rc_style->font_desc = font_desc;
+    return 0;
+}
+
+%%
+override-attr GtkRcStyle.fg
+static PyObject *
+_wrap_gtk_rc_style__get_fg(PyGObject *self, void *closure)
+{
+    GtkRcStyle *rc_style = GTK_RC_STYLE(self->obj);
+
+    return _pygtk_rc_style_helper_new(rc_style, RC_STYLE_COLOUR_ARRAY, rc_style->fg, GTK_RC_FG);
+}
+
+%%
+override-attr GtkRcStyle.bg
+static PyObject *
+_wrap_gtk_rc_style__get_bg(PyGObject *self, void *closure)
+{
+    GtkRcStyle *rc_style = GTK_RC_STYLE(self->obj);
+
+    return _pygtk_rc_style_helper_new(rc_style, RC_STYLE_COLOUR_ARRAY, rc_style->bg, GTK_RC_BG);
+}
+
+%%
+override-attr GtkRcStyle.text
+static PyObject *
+_wrap_gtk_rc_style__get_text(PyGObject *self, void *closure)
+{
+    GtkRcStyle *rc_style = GTK_RC_STYLE(self->obj);
+
+    return _pygtk_rc_style_helper_new(rc_style, RC_STYLE_COLOUR_ARRAY, rc_style->text, GTK_RC_TEXT);
+}
+
+%%
+override-attr GtkRcStyle.base
+static PyObject *
+_wrap_gtk_rc_style__get_base(PyGObject *self, void *closure)
+{
+    GtkRcStyle *rc_style = GTK_RC_STYLE(self->obj);
+
+    return _pygtk_rc_style_helper_new(rc_style, RC_STYLE_COLOUR_ARRAY, rc_style->base, GTK_RC_BASE);
+}
+
+%%
+override-attr GtkRcStyle.xthickness
+static int
+_wrap_gtk_rc_style__set_xthickness(PyGObject *self, PyObject *value, void *closure)
+{
+    GtkRcStyle *rc_style = GTK_RC_STYLE(self->obj);
+
+    if (PyInt_Check(value)) {
+        rc_style->xthickness = PyInt_AsLong(value);
+        return 0;
+    }
+    else {
+        PyErr_SetString(PyExc_TypeError, "can only assign an int");
+        return -1;
+    }
+}
+
+%%
+override-attr GtkRcStyle.ythickness
+static int
+_wrap_gtk_rc_style__set_ythickness(PyGObject *self, PyObject *value, void *closure)
+{
+    GtkRcStyle *rc_style = GTK_RC_STYLE(self->obj);
+
+    if (PyInt_Check(value)) {
+        rc_style->ythickness = PyInt_AsLong(value);
+        return 0;
+    }
+    else {
+        PyErr_SetString(PyExc_TypeError, "can only assign an int");
+        return -1;
+    }
+}
diff --git a/gtk/pygtk-private.h b/gtk/pygtk-private.h
index aab41e1..7830487 100644
--- a/gtk/pygtk-private.h
+++ b/gtk/pygtk-private.h
@@ -52,7 +52,18 @@ typedef struct {
     gpointer array;
 } PyGtkStyleHelper_Object;
 
+/* helper object for the rc-style helper */
+typedef struct {
+    PyObject_HEAD
+    GtkRcStyle *rc_style; /* parent style */
+    enum {RC_STYLE_COLOUR_ARRAY, RC_STYLE_STRING_ARRAY} type;
+    gpointer array;
+    GtkRcFlags is_set_flag; /* ignored for RC_STYLE_STRING_ARRAY */
+} PyGtkRcStyleHelper_Object;
+
 PyObject *_pygtk_style_helper_new(GtkStyle *style, int type, gpointer array);
+PyObject *_pygtk_rc_style_helper_new(GtkRcStyle *rc_style, int type, gpointer array,
+                                     GtkRcFlags is_set_flag);
 
 PyObject *_pygtk_tree_model_row_new(GtkTreeModel *model, GtkTreeIter *iter);
 PyObject *_pygtk_tree_model_row_iter_new(GtkTreeModel *model,



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