[gnome-games/sudoku-tube] Trying to separate out the user-input related code



commit 4fcaa62c6225c3b11c5337b2a0d43cbb72348d7e
Author: Zhang Sen <zh jesse gmail com>
Date:   Thu Jul 9 11:49:11 2009 +0800

    Trying to separate out the user-input related code
    
    * NumberSelector shouldn't keep data (View shouldn't know about data)
    * delete no-so-needed signal, thus **undo is broken**
    * rename signal
    * NumberBox shouldn't keep data neither, so i make all the signals have
       additional data. When the user makes change, simply emit a signal with the
       change.  Signal handler is free to update the View accordingly or not.
    * NumberBox only keeps self.value and self{top,bottom}_note_text.
    * only emit notes-changed signal when user presses Enter

 gnome-sudoku/src/lib/gsudoku.py    |   18 +++---
 gnome-sudoku/src/lib/main.py       |    2 +
 gnome-sudoku/src/lib/number_box.py |  127 +++++++++++++-----------------------
 3 files changed, 57 insertions(+), 90 deletions(-)
---
diff --git a/gnome-sudoku/src/lib/gsudoku.py b/gnome-sudoku/src/lib/gsudoku.py
index 0c33247..8a9419e 100644
--- a/gnome-sudoku/src/lib/gsudoku.py
+++ b/gnome-sudoku/src/lib/gsudoku.py
@@ -181,11 +181,14 @@ class SudokuGameDisplay (SudokuNumberGrid, gobject.GObject):
         self._setup_grid(grid, group_size)
         for e in self.__entries__.values():
             e.show()
-            e.connect('undo-change', self._entry_callback)
-            e.connect('changed', self._entry_callback)
+            e.connect('number-changed', self._number_changed_cb)
+            e.connect('notes-changed', self._notes_changed_cb)
             e.connect('focus-in-event', self._focus_callback)
             e.connect('key-press-event', self._key_press_cb)
 
+    def _notes_changed_cb(self, box, top_note, bottom_note):
+        box.set_notes((top_note, bottom_note))
+
     def _key_press_cb(self, widget, event):
         key = gtk.gdk.keyval_name(event.keyval)
         dest_x, dest_y = self._go_around(widget.x, widget.y, key)
@@ -386,13 +389,10 @@ class SudokuGameDisplay (SudokuNumberGrid, gobject.GObject):
                     self.add_value(x, y, val)
         self.doing_initial_setup = False
 
-    def _entry_callback(self, widget, *args):
-        if not widget.get_text():
-            if self.grid and self.grid._get_(widget.x, widget.y):
-                self.grid.remove(widget.x, widget.y)
-            self.remove(widget.x, widget.y)
-        else:
-            self._entry_validate(widget)
+    def _number_changed_cb(self, widget, new_value):
+        # TODO
+        widget.set_value(new_value)
+        self._entry_validate(widget)
         if self.show_impossible_implications:
             self._mark_impossible_implications(widget.x, widget.y)
         if self.always_show_hints:
diff --git a/gnome-sudoku/src/lib/main.py b/gnome-sudoku/src/lib/main.py
index 38e55a5..a27b6f7 100644
--- a/gnome-sudoku/src/lib/main.py
+++ b/gnome-sudoku/src/lib/main.py
@@ -242,6 +242,8 @@ class UI (gconf_wrapper.GConfWrapper):
             action.connect("activate", callback)
 
     def setup_undo (self):
+        # TODO
+        return
         self.cleared = [] # used for Undo memory
         self.cleared_notes = [] # used for Undo memory
         # Set up our UNDO stuff
diff --git a/gnome-sudoku/src/lib/number_box.py b/gnome-sudoku/src/lib/number_box.py
index b7e1c63..00c289c 100644
--- a/gnome-sudoku/src/lib/number_box.py
+++ b/gnome-sudoku/src/lib/number_box.py
@@ -23,11 +23,10 @@ NORMAL_LINE_WIDTH = 1 # The size of the line we draw around a box
 class _NumberSelector (gtk.EventBox):
 
     __gsignals__ = {
-        'number-selected': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
+        'number-selected': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (int,))
         }
 
-    def __init__ (self, default = None, upper = 9):
-        self.value = default
+    def __init__(self, initial_value=0, upper=9):
         gtk.EventBox.__init__(self)
         self.table = gtk.Table()
         self.add(self.table)
@@ -37,7 +36,7 @@ class _NumberSelector (gtk.EventBox):
             for x in range(side):
                 b = gtk.Button()
                 l = gtk.Label()
-                if n == self.value:
+                if n == initial_value:
                     l.set_markup('<b><span size="x-small">%s</span></b>'%n)
                 else:
                     l.set_markup('<span size="x-small">%s</span>'%n)
@@ -50,7 +49,7 @@ class _NumberSelector (gtk.EventBox):
                 b.connect('clicked', self._number_clicked, n)
                 self.table.attach(b, x, x+1, y, y+1)
                 n += 1
-        if self.value:
+        if initial_value:
             clear_button = gtk.Button()
             label = gtk.Label()
             label.set_markup_with_mnemonic('<span size="x-small">'+_('_Clear')+'</span>')
@@ -61,16 +60,12 @@ class _NumberSelector (gtk.EventBox):
         self.show_all()
 
     def _number_clicked (self, button, n):
-        self.value = n
-        self.emit('number-selected')
-
-    def get_value (self):
-        return self.value
+        self.emit('number-selected', n)
 
 
 class _NumberBox (gtk.Widget):
 
-    text = ''
+    value = ''
     top_note_text = ''
     bottom_note_text = ''
     read_only = False
@@ -82,20 +77,15 @@ class _NumberBox (gtk.Widget):
     custom_background_color = None
 
     __gsignals__ = {
-        'value-about-to-change':(gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
-        'changed':(gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
-        # undo-change - A hacky way to handle the fact that we want to
-        # respond to undo's changes but we don't want undo to respond
-        # to itself...
-        'undo-change':(gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
-        'notes-changed':(gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
+        'number-changed':(gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (int,)),
+        'notes-changed':(gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (str, str))
         }
 
     base_state = gtk.STATE_NORMAL
     npicker = None
     draw_boxes = False
 
-    def __init__ (self, upper = 9, text = ''):
+    def __init__(self, upper=9, value=''):
         gtk.Widget.__init__(self)
         self.upper = upper
         self.font = self.style.font_desc
@@ -111,7 +101,7 @@ class _NumberBox (gtk.Widget):
         self.connect('focus-in-event', self.focus_in_cb)
         self.connect('focus-out-event', self.focus_out_cb)
         self.connect('motion-notify-event', self.motion_notify_cb)
-        self.set_text(text)
+        self.set_value(value)
 
     def pointer_enter_cb (self, *args):
         if not self.is_focus():
@@ -185,32 +175,23 @@ class _NumberBox (gtk.Widget):
             # Make sure we don't trigger on unplugging the A/C charger etc
             return
         txt = txt.replace('KP_', '')
-        if self.get_text() == txt:
-            # If there's no change, do nothing
-            return
         if txt in ['0', 'Delete', 'BackSpace']:
-            self.set_text_interactive('')
+            self._emit_number_changed_signal(0)
         elif txt in ['n', 'N']:
             self.show_note_editor(top = True)
         elif txt in ['m', 'M']:
             self.show_note_editor(top = False)
-        # And then add the new value if need be
         elif txt in [str(n) for n in range(1, self.upper+1)]:
-            # First do a removal event -- this is something of a
-            # kludge, but it works nicely with old code that was based
-            # on entries, which also behave this way (they generate 2
-            # events for replacing a number with a new number - a
-            # removal event and an addition event)
-            if self.get_text():
-                self.set_text_interactive('')
-            # Then add
-            self.set_text_interactive(txt)
-
-    def note_changed_cb (self, w, top = False):
+            self._emit_number_changed_signal(int(txt))
+
+    def note_changed_cb(self, entry, top, window):
+        new_text = entry.get_text()
+        window.destroy()
         if top:
-            self.set_note_text_interactive(top_text = w.get_text())
+            self.top_note_text = new_text
         else:
-            self.set_note_text_interactive(bottom_text = w.get_text())
+            self.bottom_note_text = new_text
+        self._emit_note_changed_signal(self.top_note_text, self.bottom_note_text)
 
     def show_note_editor (self, top = True):
         alloc = self.get_allocation()
@@ -228,9 +209,8 @@ class _NumberBox (gtk.Widget):
         else:
             e.set_text(self.bottom_note_text)
         w.add(f)
-        e.connect('changed', self.note_changed_cb, top)
         e.connect('focus-out-event', lambda e, ev, w: w.destroy(), w)
-        e.connect('activate', lambda e, w: w.destroy(), w)
+        e.connect('activate', self.note_changed_cb, top, w)
         x, y = self.window.get_origin()
         if top:
             w.move(x, y)
@@ -239,17 +219,14 @@ class _NumberBox (gtk.Widget):
         w.show_all()
         e.grab_focus()
 
-    def number_changed_cb (self, num_selector):
+    def _number_changed_cb(self, num_selector, new_number):
         self.destroy_npicker()
-        self.set_text_interactive('')
-        newval = num_selector.get_value()
-        if newval:
-            self.set_text_interactive(str(newval))
+        self._emit_number_changed_signal(new_number)
 
     def show_number_picker (self):
         w = gtk.Window(type = gtk.WINDOW_POPUP)
-        ns = _NumberSelector(upper = self.upper, default = self.get_value())
-        ns.connect('number-selected', self.number_changed_cb)
+        ns = _NumberSelector(upper=self.upper, initial_value=self.get_value())
+        ns.connect('number-selected', self._number_changed_cb)
         w.grab_focus()
         w.add(ns)
         r = w.get_allocation()
@@ -262,18 +239,12 @@ class _NumberBox (gtk.Widget):
         w.show()
         self.npicker = w
 
-    def set_text_interactive (self, text):
-        self.emit('value-about-to-change')
-        self.set_text(text)
-        self.queue_draw()
-        self.emit('changed')
-
     def set_font (self, font):
         if type(font) == str:
             font = pango.FontDescription(font)
         self.font = font
-        if self.text:
-            self.set_text(self.text)
+        if self.value:
+            self.set_text(str(self.value))
         self.queue_draw()
 
     def set_note_font (self, font):
@@ -286,7 +257,6 @@ class _NumberBox (gtk.Widget):
         self.queue_draw()
 
     def set_text (self, text):
-        self.text = text
         self._layout = self.create_pango_layout(text)
         self._layout.set_font_description(self.font)
 
@@ -310,10 +280,11 @@ class _NumberBox (gtk.Widget):
             self._bottom_note_layout.set_font_description(self.note_font)
         self.queue_draw()
 
-    def set_note_text_interactive (self, *args, **kwargs):
-        self.emit('value-about-to-change')
-        self.set_note_text(*args, **kwargs)
-        self.emit('notes-changed')
+    def _emit_number_changed_signal(self, new_number):
+        self.emit('number-changed', new_number)
+
+    def _emit_note_changed_signal(self, top_note, bottom_note):
+        self.emit('notes-changed', top_note, bottom_note)
 
     def do_realize (self):
         # The do_realize method is responsible for creating GDK (windowing system)
@@ -399,7 +370,6 @@ class _NumberBox (gtk.Widget):
         if self.draw_boxes and self.is_focus():
             self.draw_note_area_highlight_box(cr)
 
-
     def draw_background_color (self, cr):
         if self.read_only:
             if self.custom_background_color:
@@ -533,17 +503,8 @@ class _NumberBox (gtk.Widget):
         self.custom_background_color = color
         self.queue_draw()
 
-    def hide_notes (self):
-        pass
-
-    def show_notes (self):
-        pass
-
-    def set_value_from_undo (self, v):
-        self.set_value(v)
-        self.emit('undo_change')
-
     def set_value (self, v):
+        self.value = v
         if 0 < v <= self.upper:
             self.set_text(str(v))
         else:
@@ -551,13 +512,7 @@ class _NumberBox (gtk.Widget):
         self.queue_draw()
 
     def get_value (self):
-        try:
-            return int(self.text)
-        except:
-            return None
-
-    def get_text (self):
-        return self.text
+        return self.value
 
     def get_note_text (self):
         return self.top_note_text, self.bottom_note_text
@@ -603,15 +558,25 @@ if __name__ == '__main__':
     window.connect('delete-event', gtk.main_quit)
 
     def test_number_selector ():
-        nselector = _NumberSelector(default = 3)
-        def tell_me (b):
-            print 'value->', b.get_value()
+        def tell_me (widget, new_value):
+            print 'value selected', new_value
+
+        nselector = _NumberSelector(initial_value=3)
         nselector.connect('number-selected', tell_me)
         window.add(nselector)
 
     def test_number_box ():
+        def number_changed_cb(widget, new_value):
+            print 'new-value:', new_value
+            widget.set_value(new_value)
+        def notes_changed_cb(widget, top_note, bottom_note):
+            print 'new-notes:', (top_note, bottom_note)
+            widget.set_notes((top_note, bottom_note))
+
         window.set_size_request(100, 100)
         nbox = _NumberBox()
+        nbox.connect('number-changed', number_changed_cb)
+        nbox.connect('notes-changed', notes_changed_cb)
         window.add(nbox)
 
 #    test_number_selector()



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