[gcalctool] Make MathDisplay a GtkWidget



commit f50d2e199b1088827b767e0fe217997bd647c995
Author: Robert Ancell <robert ancell gmail com>
Date:   Tue Apr 6 08:20:50 2010 +1000

    Make MathDisplay a GtkWidget

 data/gcalctool.ui |   70 -------------------
 src/ui-display.c  |  191 ++++++++++++++++++++++-------------------------------
 src/ui-display.h  |   18 +++---
 src/ui.c          |   38 ++++++++++-
 4 files changed, 123 insertions(+), 194 deletions(-)
---
diff --git a/data/gcalctool.ui b/data/gcalctool.ui
index 2390997..5d869bd 100644
--- a/data/gcalctool.ui
+++ b/data/gcalctool.ui
@@ -167,79 +167,9 @@
             <property name="position">0</property>
           </packing>
         </child>
-        <child>
-          <object class="GtkEventBox" id="display_eventbox">
-            <property name="visible">True</property>
-            <child>
-              <object class="GtkScrolledWindow" id="display_scroll">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="border_width">7</property>
-                <property name="hscrollbar_policy">automatic</property>
-                <property name="vscrollbar_policy">never</property>
-                <property name="shadow_type">in</property>
-                <child>
-                  <object class="GtkViewport" id="viewport1">
-                    <property name="visible">True</property>
-                    <property name="resize_mode">queue</property>
-                    <child>
-                      <object class="GtkVBox" id="vbox1">
-                        <property name="visible">True</property>
-                        <child>
-                          <object class="GtkTextView" id="displayitem">
-                            <property name="visible">True</property>
-                            <property name="can_focus">True</property>
-                            <property name="can_default">True</property>
-                            <property name="pixels_above_lines">8</property>
-                            <property name="pixels_below_lines">2</property>
-                            <property name="editable">False</property>
-                            <property name="wrap_mode">word</property>
-                            <property name="justification">right</property>
-                            <property name="right_margin">6</property>
-                            <property name="buffer">display_buffer</property>
-                            <child internal-child="accessible">
-                              <object class="AtkObject" id="displayitem-atkobject">
-                                <property name="AtkObject::accessible-description" translatable="yes" comments="Accessible description for the area in which results are displayed">Result Region</property>
-                              </object>
-                            </child>
-                            <signal name="populate_popup" handler="buffer_populate_popup_cb"/>
-                            <signal name="button_release_event" handler="middle_click_paste_cb"/>
-                            <signal name="paste_clipboard" handler="paste_cb"/>
-                          </object>
-                          <packing>
-                            <property name="position">0</property>
-                          </packing>
-                        </child>
-                        <child>
-                          <object class="GtkTextView" id="info_textview">
-                            <property name="visible">True</property>
-                            <property name="editable">False</property>
-                            <property name="wrap_mode">word</property>
-                            <property name="justification">right</property>
-                            <property name="right_margin">6</property>
-                            <property name="cursor_visible">False</property>
-                            <property name="buffer">info_buffer</property>
-                          </object>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="position">1</property>
-                          </packing>
-                        </child>
-                      </object>
-                    </child>
-                  </object>
-                </child>
-              </object>
-            </child>
-          </object>
-          <packing>
-            <property name="position">1</property>
-          </packing>
-        </child>
       </object>
     </child>
   </object>
-  <object class="GtkTextBuffer" id="display_buffer"/>
   <object class="GtkAccelGroup" id="accelgroup1"/>
   <object class="GtkImage" id="image1">
     <property name="visible">True</property>
diff --git a/src/ui-display.c b/src/ui-display.c
index e753eaa..ebfc72e 100644
--- a/src/ui-display.c
+++ b/src/ui-display.c
@@ -24,11 +24,6 @@
 #include "calctool.h"
 
 enum {
-    PROP_0,
-    PROP_UI
-};
-
-enum {
     NUMBER_MODE_CHANGED,
     LAST_SIGNAL
 };
@@ -42,7 +37,6 @@ struct MathDisplayPrivate
     GtkWidget *display_item;           /* Calculator display. */
     GtkTextBuffer *display_buffer;     /* Buffer used in display */
     GtkTextBuffer *info_buffer;        /* Buffer used in info messages */
-    GtkWidget *scrolled_window;        /* Scrolled window for display_item. */
 
     GdkAtom clipboard_atom;
     GdkAtom primary_atom;
@@ -52,14 +46,14 @@ struct MathDisplayPrivate
     char *last_text;
 };
 
-G_DEFINE_TYPE (MathDisplay, ui_display, G_TYPE_OBJECT);
+G_DEFINE_TYPE (MathDisplay, ui_display, GTK_TYPE_VBOX);
 
 #define GET_WIDGET(ui, name)  GTK_WIDGET(gtk_builder_get_object(ui, name))
 
 MathDisplay *
-ui_display_new(GtkBuilder *ui)
+ui_display_new()
 {
-    return g_object_new (ui_display_get_type(), "ui", ui, NULL);
+    return g_object_new (ui_display_get_type(), NULL);
 }
 
 
@@ -256,29 +250,6 @@ ui_display_toggle_bit(MathDisplay *display, guint bit)
 }
 
 
-static gboolean
-redo_display(MathDisplay *display)
-{
-    gchar *text;
-    GtkTextIter start, end, cursor;
-    gint cursor_position;
-
-    gtk_text_buffer_get_start_iter(display->priv->display_buffer, &start);
-    gtk_text_buffer_get_end_iter(display->priv->display_buffer, &end);
-    text = gtk_text_buffer_get_text(display->priv->display_buffer, &start, &end, FALSE);
-
-    g_object_get(G_OBJECT(display->priv->display_buffer), "cursor-position", &cursor_position, NULL);
-
-    gtk_text_buffer_set_text(display->priv->display_buffer, text, -1);
-    gtk_text_buffer_get_iter_at_offset(display->priv->display_buffer, &cursor, cursor_position);
-    gtk_text_buffer_place_cursor(display->priv->display_buffer, &cursor);
-
-    g_free(text);
-
-    return FALSE;
-}
-
-
 void
 ui_display_set(MathDisplay *display, char *str, int cursor)
 {
@@ -294,19 +265,11 @@ ui_display_set(MathDisplay *display, char *str, int cursor)
     gtk_text_buffer_place_cursor(display->priv->display_buffer, &iter);
     gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(display->priv->display_item), &iter, 0.0, TRUE, 1.0, 0.0);
 
-    /* This is a workaround for bug #524602.
-     * Basically the above code can cause the display to disappear when going from
-     * a display that is wider than the widget to one that is thinner. The following
-     * causes the display to be set twice which seems to work the second time.
-     */
-    g_idle_add((GSourceFunc)redo_display, display);
-
     /* Align to the right */
-    if (cursor < 0) {
-        adj = gtk_scrolled_window_get_hadjustment(
-                 GTK_SCROLLED_WINDOW(display->priv->scrolled_window));
+    /*FIXME: if (cursor < 0) {
+        adj = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(display));
         gtk_adjustment_set_value(adj, gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj));
-    }
+    }*/
 }
 
 
@@ -601,8 +564,7 @@ for_each_menu(GtkWidget *widget, MathDisplay *display)
 
 
 // FIXME: Kill this
-G_MODULE_EXPORT
-void
+static void
 buffer_populate_popup_cb(GtkTextView *textview, GtkMenu *menu, MathDisplay *display)
 {
     gtk_container_foreach(GTK_CONTAINER(menu), (GtkCallback)for_each_menu, display);
@@ -625,8 +587,7 @@ ui_display_paste(MathDisplay *display)
 }
 
 
-G_MODULE_EXPORT
-gboolean
+static gboolean
 middle_click_paste_cb(GtkWidget *widget, GdkEventButton *event, MathDisplay *display)
 {
     if (event->button == 2)
@@ -636,6 +597,13 @@ middle_click_paste_cb(GtkWidget *widget, GdkEventButton *event, MathDisplay *dis
 }
 
 
+static void
+paste_cb(GtkWidget *widget, MathDisplay *display)
+{
+    ui_display_paste(display);
+}
+
+
 void
 ui_display_set_base(MathDisplay *display, gint base)
 {
@@ -665,78 +633,12 @@ ui_display_set_base(MathDisplay *display, gint base)
 
 
 static void
-ui_display_set_property (GObject      *object,
-                         guint         prop_id,
-                         const GValue *value,
-                         GParamSpec   *pspec)
-{
-    MathDisplay *self;
-    GtkBuilder *ui;
-    PangoFontDescription *font_desc;
-    GtkCellRenderer *renderer;
-
-    self = MATH_DISPLAY (object);
-
-    switch (prop_id) {
-    case PROP_UI:
-        ui = g_value_get_object (value);
-      
-        self->priv->scrolled_window = GET_WIDGET(ui, "display_scroll");
-        self->priv->info_buffer = GTK_TEXT_BUFFER(gtk_builder_get_object(ui, "info_buffer"));
-        self->priv->display_item = GET_WIDGET(ui, "displayitem");
-        self->priv->display_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(self->priv->display_item));
-
-        gtk_widget_ensure_style(self->priv->display_item);
-        font_desc = pango_font_description_copy(gtk_widget_get_style(self->priv->display_item)->font_desc);
-        pango_font_description_set_size(font_desc, 16 * PANGO_SCALE);
-        gtk_widget_modify_font(self->priv->display_item, font_desc);
-        pango_font_description_free(font_desc);
-        gtk_widget_set_name(self->priv->display_item, "displayitem");
-        atk_object_set_role(gtk_widget_get_accessible(self->priv->display_item), ATK_ROLE_EDITBAR);
-        break;
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-        break;
-    }
-}
-
-
-static void
-ui_display_get_property (GObject    *object,
-                         guint       prop_id,
-                         GValue     *value,
-                         GParamSpec *pspec)
-{
-    MathDisplay *self;
-
-    self = MATH_DISPLAY (object);
-
-    switch (prop_id) {
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-        break;
-    }
-}
-
-
-static void
 ui_display_class_init (MathDisplayClass *klass)
 {
     GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
-    object_class->get_property = ui_display_get_property;
-    object_class->set_property = ui_display_set_property;
-  
     g_type_class_add_private (klass, sizeof (MathDisplayPrivate));
 
-    g_object_class_install_property (object_class,
-                                     PROP_UI,
-                                     g_param_spec_object ("ui",
-                                                          "ui",
-                                                          "GtkBuilder to get widgets from (temp)",
-                                                          gtk_builder_get_type(),
-                                                          G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
-
     signals[NUMBER_MODE_CHANGED] =
         g_signal_new ("number-mode-changed",
                       G_TYPE_FROM_CLASS (klass),
@@ -748,10 +650,73 @@ ui_display_class_init (MathDisplayClass *klass)
 }
 
 
+/*
+        <child>
+          <object class="GtkEventBox" id="display_eventbox">
+            <property name="visible">True</property>
+            <child>
+              <object class="GtkScrolledWindow" id="display_scroll">
+                <property name="can_focus">True</property>
+                <child>
+                  <object class="GtkViewport" id="viewport1">
+                    <property name="resize_mode">queue</property>
+                    <child>
+                      <object class="GtkVBox" id="vbox1">
+                        <child>
+                          <object class="GtkTextView" id="displayitem">
+                            <property name="wrap_mode">word</property>
+                            <child internal-child="accessible">
+                              <object class="AtkObject" id="displayitem-atkobject">
+                                <property name="AtkObject::accessible-description" translatable="yes" comments="Accessible description for the area in which results are displayed">Result Region</property>
+                              </object>
+                            </child>
+                          </object>
+                        </child>
+                        <child>
+                          <object class="GtkTextView" id="info_textview">
+                            <property name="wrap_mode">word</property>
+                          </object>
+ */
 static void 
 ui_display_init(MathDisplay *display)
 {
+    GtkWidget *vbox, *info_view;
+    PangoFontDescription *font_desc;
+
     display->priv = G_TYPE_INSTANCE_GET_PRIVATE (display, ui_display_get_type(), MathDisplayPrivate);
     display->priv->primary_atom = gdk_atom_intern("PRIMARY", FALSE);
     display->priv->clipboard_atom = gdk_atom_intern("CLIPBOARD", FALSE);
+
+    display->priv->display_item = gtk_text_view_new();
+    gtk_text_view_set_editable(GTK_TEXT_VIEW(display->priv->display_item), FALSE);
+    gtk_text_view_set_pixels_above_lines(GTK_TEXT_VIEW(display->priv->display_item), 8);
+    gtk_text_view_set_pixels_below_lines(GTK_TEXT_VIEW(display->priv->display_item), 2);
+    gtk_text_view_set_right_margin(GTK_TEXT_VIEW(display->priv->display_item), 6);
+    gtk_text_view_set_justification(GTK_TEXT_VIEW(display->priv->display_item), GTK_JUSTIFY_RIGHT);
+    g_signal_connect(display->priv->display_item, "populate-popup", G_CALLBACK(buffer_populate_popup_cb), display); // FIXME
+    g_signal_connect(display->priv->display_item, "button-release-event", G_CALLBACK(middle_click_paste_cb), display);
+    g_signal_connect(display->priv->display_item, "paste-clipboard", G_CALLBACK(paste_cb), display);
+    gtk_box_pack_start(GTK_BOX(display), display->priv->display_item, TRUE, TRUE, 0);
+
+    display->priv->display_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(display->priv->display_item));
+
+    gtk_widget_ensure_style(display->priv->display_item);
+    font_desc = pango_font_description_copy(gtk_widget_get_style(display->priv->display_item)->font_desc);
+    pango_font_description_set_size(font_desc, 16 * PANGO_SCALE);
+    gtk_widget_modify_font(display->priv->display_item, font_desc);
+    pango_font_description_free(font_desc);
+    gtk_widget_set_name(display->priv->display_item, "displayitem");
+    atk_object_set_role(gtk_widget_get_accessible(display->priv->display_item), ATK_ROLE_EDITBAR);
+  
+    info_view = gtk_text_view_new();
+    gtk_widget_set_can_focus(info_view, TRUE); // FIXME: This should be FALSE but it locks the cursor inside the main view for some reason
+    gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(info_view), FALSE); // FIXME: Just here so when incorrectly gets focus doesn't look editable
+    gtk_text_view_set_editable(GTK_TEXT_VIEW(info_view), FALSE);
+    gtk_text_view_set_justification(GTK_TEXT_VIEW(info_view), GTK_JUSTIFY_RIGHT);
+    gtk_text_view_set_right_margin(GTK_TEXT_VIEW(info_view), 6);
+    gtk_box_pack_start(GTK_BOX(display), info_view, FALSE, TRUE, 0);
+    display->priv->info_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(info_view));
+
+    gtk_widget_show(info_view);
+    gtk_widget_show(display->priv->display_item);
 }
diff --git a/src/ui-display.h b/src/ui-display.h
index 47e890a..fe54c58 100644
--- a/src/ui-display.h
+++ b/src/ui-display.h
@@ -28,28 +28,28 @@ G_BEGIN_DECLS
 
 typedef struct MathDisplayPrivate MathDisplayPrivate;
 
-typedef enum {
-    NORMAL,
-    SUPERSCRIPT,
-    SUBSCRIPT
-} NumberMode;
-
 typedef struct
 {
-    GObject             parent_instance; // FIXME: Extend GtkVBox, remove widgets from gcalctool.ui
+    GtkVBox parent_instance;
     MathDisplayPrivate *priv;
 } MathDisplay;
 
 typedef struct
 {
-    GObjectClass parent_class;
+    GtkVBoxClass parent_class;
 
     void (*number_mode_changed)(MathDisplay *display);
 } MathDisplayClass;
 
-GType ui_display_get_type();
+typedef enum {
+    NORMAL,
+    SUPERSCRIPT,
+    SUBSCRIPT
+} NumberMode;
 
+GType ui_display_get_type();
 MathDisplay *ui_display_new();
+
 void ui_display_set_base(MathDisplay *display, gint base);
 void ui_display_set_number_mode(MathDisplay *display, NumberMode mode);
 void ui_display_set(MathDisplay *display, gchar *, gint); // FIXME: Make obsolete by Math model
diff --git a/src/ui.c b/src/ui.c
index 1da9010..5e18461 100644
--- a/src/ui.c
+++ b/src/ui.c
@@ -33,6 +33,7 @@ struct GCalctoolUIPrivate
     MathDisplay *display;
     MathButtons *buttons;
     PreferencesDialog *preferences_dialog;
+    gboolean right_aligned;
 };
 
 G_DEFINE_TYPE (GCalctoolUI, ui, G_TYPE_OBJECT);
@@ -270,6 +271,24 @@ quit_cb(GtkWidget *widget, GCalctoolUI *ui)
 
 
 static void
+scroll_changed_cb(GtkAdjustment *adjustment, GCalctoolUI *ui)
+{
+    if (ui->priv->right_aligned)
+        gtk_adjustment_set_value(adjustment, gtk_adjustment_get_upper(adjustment) - gtk_adjustment_get_page_size(adjustment));
+}
+
+
+static void
+scroll_value_changed_cb(GtkAdjustment *adjustment, GCalctoolUI *ui)
+{
+    if (gtk_adjustment_get_value(adjustment) == gtk_adjustment_get_upper(adjustment) - gtk_adjustment_get_page_size(adjustment))
+        ui->priv->right_aligned = TRUE;
+    else
+        ui->priv->right_aligned = FALSE;
+}
+
+
+static void
 ui_class_init (GCalctoolUIClass *klass)
 {
     g_type_class_add_private (klass, sizeof (GCalctoolUIPrivate));
@@ -279,6 +298,7 @@ ui_class_init (GCalctoolUIClass *klass)
 static void 
 ui_init(GCalctoolUI *ui)
 {
+    GtkWidget *scrolled_window;
     GError *error = NULL;
     int i;
 
@@ -305,9 +325,23 @@ ui_init(GCalctoolUI *ui)
     g_object_set_data(gtk_builder_get_object(ui->priv->ui, "view_financial_menu"), "calcmode", GINT_TO_POINTER(FINANCIAL));
     g_object_set_data(gtk_builder_get_object(ui->priv->ui, "view_programming_menu"), "calcmode", GINT_TO_POINTER(PROGRAMMING));
 
-    ui->priv->display = ui_display_new(ui->priv->ui);
+    scrolled_window = gtk_scrolled_window_new(NULL, NULL);
+    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER);
+    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_window), GTK_SHADOW_IN);
+    gtk_container_set_border_width(GTK_CONTAINER(scrolled_window), 7);
+    gtk_box_pack_start(GTK_BOX(GET_WIDGET(ui->priv->ui, "window_vbox")), GTK_WIDGET(scrolled_window), TRUE, TRUE, 0);
+    g_signal_connect(gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(scrolled_window)), "changed", G_CALLBACK(scroll_changed_cb), ui);
+    g_signal_connect(gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(scrolled_window)), "value-changed", G_CALLBACK(scroll_value_changed_cb), ui);
+    ui->priv->right_aligned = TRUE;
+    gtk_widget_show(scrolled_window);
+
+    ui->priv->display = ui_display_new();
+    gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window), GTK_WIDGET(ui->priv->display));
+    gtk_widget_show(GTK_WIDGET(ui->priv->display));
+
     ui->priv->buttons = ui_buttons_new(ui->priv->display);
-    gtk_box_pack_end(GTK_BOX(GET_WIDGET(ui->priv->ui, "window_vbox")), GTK_WIDGET(ui->priv->buttons), TRUE, TRUE, 0);
+    gtk_box_pack_start(GTK_BOX(GET_WIDGET(ui->priv->ui, "window_vbox")), GTK_WIDGET(ui->priv->buttons), TRUE, TRUE, 0);
     gtk_widget_show(GTK_WIDGET(ui->priv->buttons));
+
     ui->priv->preferences_dialog = ui_preferences_dialog_new(ui);
 }



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