diff options
author | laurent-bernabe <laurent.bernabe@gmail.com> | 2012-11-09 11:15:42 (GMT) |
---|---|---|
committer | laurent-bernabe <laurent.bernabe@gmail.com> | 2012-11-09 11:15:42 (GMT) |
commit | 6c58ef0c803e311b492f202cbf49806fd381b4b8 (patch) | |
tree | c4c7abef85478ea45f4ccf04b348c7d2e6f5de69 /com/gmail/bernabe/laurent | |
parent | b1a3dc1326102543002c26c6ce65bbb255db62ad (diff) |
I've just reorganized the project : moved all core classes to an inner
package (kept at root : both launchers, and setup.py).
Diffstat (limited to 'com/gmail/bernabe/laurent')
14 files changed, 491 insertions, 0 deletions
diff --git a/com/gmail/bernabe/laurent/__init__.py b/com/gmail/bernabe/laurent/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/com/gmail/bernabe/laurent/__init__.py diff --git a/com/gmail/bernabe/laurent/__init__.pyc b/com/gmail/bernabe/laurent/__init__.pyc Binary files differnew file mode 100644 index 0000000..71eb9a5 --- /dev/null +++ b/com/gmail/bernabe/laurent/__init__.pyc diff --git a/com/gmail/bernabe/laurent/sugar_olpc/__init__.py b/com/gmail/bernabe/laurent/sugar_olpc/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/com/gmail/bernabe/laurent/sugar_olpc/__init__.py diff --git a/com/gmail/bernabe/laurent/sugar_olpc/__init__.pyc b/com/gmail/bernabe/laurent/sugar_olpc/__init__.pyc Binary files differnew file mode 100644 index 0000000..3c5e16e --- /dev/null +++ b/com/gmail/bernabe/laurent/sugar_olpc/__init__.pyc diff --git a/com/gmail/bernabe/laurent/sugar_olpc/learning_writing/InputDialog.py b/com/gmail/bernabe/laurent/sugar_olpc/learning_writing/InputDialog.py new file mode 100755 index 0000000..fc52d86 --- /dev/null +++ b/com/gmail/bernabe/laurent/sugar_olpc/learning_writing/InputDialog.py @@ -0,0 +1,66 @@ +# InputDialog.py Own implementation of InputDialog +# +#This file is part of LearningWriting. +# +#LearningWriting is free software: you can redistribute it and/or modify +#it under the terms of the GNU General Public License as published by +#the Free Software Foundation, either version 3 of the License, or +#(at your option) any later version. +# +#LearningWriting 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 General Public License for more details. +# +#You should have received a copy of the GNU General Public License +#along with LearningWriting. If not, see <http://www.gnu.org/licenses/>. + +import pygtk +pygtk.require('2.0') +import gtk + +class InputDialog(gtk.MessageDialog): + ''' + Creates an input dialog with + => a label (for the prompt) + => a text entry + => ok_button and cancel_button + ''' + + + def __init__(self, prompt, parent=None, text=""): + ''' + Constructor(prompt, parent=None) + prompt argument : the text of the dialog + parent : the parent control + text : the initial text in the TextEntry + ''' + gtk.MessageDialog.__init__(self, + parent, gtk.DIALOG_MODAL, gtk.MESSAGE_QUESTION, + gtk.BUTTONS_OK_CANCEL, prompt) + self.__entry = gtk.Entry() + self.__entry.set_text(text) + self.vbox.pack_start(self.__entry, True, True, 0) + self.connect("delete-event", lambda widget, event : self.__close() ) + + def run(self): + ''' + Run() + Runs the dialog + ''' + self.show_all() + response = super(InputDialog,self).run() + if response == gtk.RESPONSE_OK : + text = self.__entry.get_text() + else : + text = None + self.destroy() + return text + + def __close(self): + ''' + __close() + Closes the dialog and returns None + ''' + self.destroy() + return None
\ No newline at end of file diff --git a/com/gmail/bernabe/laurent/sugar_olpc/learning_writing/InputDialog.pyc b/com/gmail/bernabe/laurent/sugar_olpc/learning_writing/InputDialog.pyc Binary files differnew file mode 100644 index 0000000..fd4ee7c --- /dev/null +++ b/com/gmail/bernabe/laurent/sugar_olpc/learning_writing/InputDialog.pyc diff --git a/com/gmail/bernabe/laurent/sugar_olpc/learning_writing/MenuActions.py b/com/gmail/bernabe/laurent/sugar_olpc/learning_writing/MenuActions.py new file mode 100755 index 0000000..e2d6b44 --- /dev/null +++ b/com/gmail/bernabe/laurent/sugar_olpc/learning_writing/MenuActions.py @@ -0,0 +1,83 @@ +# MenuActions.py Stores the actions for the MenuItems +# +#This file is part of LearningWriting. +# +#LearningWriting is free software: you can redistribute it and/or modify +#it under the terms of the GNU General Public License as published by +#the Free Software Foundation, either version 3 of the License, or +#(at your option) any later version. +# +#LearningWriting 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 General Public License for more details. +# +#You should have received a copy of the GNU General Public License +#along with LearningWriting. If not, see <http://www.gnu.org/licenses/>. +from gettext import gettext as _ +from InputDialog import InputDialog + +import pygtk +pygtk.require('2.0') +import gtk + +class MenuActions(object): + ''' + Wraps codes for the menu actions in both + pure pygtk mode and in sugar mode + ''' + + def __init__(self, wrappedDrawingArea): + ''' + Constructor + => wrappedDrawingArea argument : the instance of + TheDrawingAreaEventBox to act upon + => MenuActions(wrappedDrawingArea) + ''' + self.__wrappedDrawingArea = wrappedDrawingArea + + def manageDrawingWrite(self): + ''' + manageDrawingWrite() + Wraps code for menu Drawing->Write + ''' + dialog = InputDialog(_("Line thickness value ?"),text="5") + user_value = dialog.run() + if user_value != None : + try: + line_thickness = int(user_value) + assert line_thickness > 0 + except (ValueError, AssertionError) : + message = _("As you did not give an correct integer value,\n5 will be taken") + message_dialog = gtk.MessageDialog(None, + gtk.DIALOG_MODAL, + gtk.MESSAGE_ERROR, + gtk.BUTTONS_OK, + message) + message_dialog.run() + message_dialog.destroy() + line_thickness = 5 + self.__wrappedDrawingArea.setRecordingMode(line_thickness) + + def manageDrawingRead(self): + ''' + manageDrawingRead() + Wraps code for menu Drawing->Read + ''' + dialog = InputDialog(_("Steps drawing delays (milliseconds) ?"),text="10") + user_value = dialog.run() + if user_value != None : + try: + delay_milliseconds = int(user_value) + assert delay_milliseconds > 0 + except (ValueError, AssertionError) : + message = _("As you did not give an correct integer value,\n10 will be taken") + message_dialog = gtk.MessageDialog(None, + gtk.DIALOG_MODAL, + gtk.MESSAGE_ERROR, + gtk.BUTTONS_OK, + message) + message_dialog.run() + message_dialog.destroy() + delay_milliseconds = 10 + self.__wrappedDrawingArea.setReadingMode(delay_milliseconds)
\ No newline at end of file diff --git a/com/gmail/bernabe/laurent/sugar_olpc/learning_writing/MenuActions.pyc b/com/gmail/bernabe/laurent/sugar_olpc/learning_writing/MenuActions.pyc Binary files differnew file mode 100644 index 0000000..f70f1e6 --- /dev/null +++ b/com/gmail/bernabe/laurent/sugar_olpc/learning_writing/MenuActions.pyc diff --git a/com/gmail/bernabe/laurent/sugar_olpc/learning_writing/TheDrawingAreaEventBox.py b/com/gmail/bernabe/laurent/sugar_olpc/learning_writing/TheDrawingAreaEventBox.py new file mode 100755 index 0000000..af42a74 --- /dev/null +++ b/com/gmail/bernabe/laurent/sugar_olpc/learning_writing/TheDrawingAreaEventBox.py @@ -0,0 +1,264 @@ +# TheDrawingAreaEventBox.py Manages the drawing component +# +#This file is part of LearningWriting. +# +#LearningWriting is free software: you can redistribute it and/or modify +#it under the terms of the GNU General Public License as published by +#the Free Software Foundation, either version 3 of the License, or +#(at your option) any later version. +# +#LearningWriting 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 General Public License for more details. +# +#You should have received a copy of the GNU General Public License +#along with LearningWriting. If not, see <http://www.gnu.org/licenses/>. + +import pygtk +pygtk.require('2.0') +import gtk +import cairo +import gobject + +class TheDrawingAreaEventBox(gtk.EventBox): + ''' + A gtk.EventBox wrapping the DrawingArea (or canvas) of the application + We use an EventBox in order to pass events to the contained DrawingArea + ''' + __DARK_GREEN = (27.0/255.0, 103.0/255.0,46.0/255.0) + __WHITE = (1.0, 1.0, 1.0) + + + def __init__(self): + ''' + Simple constructor without argument + ''' + gtk.EventBox.__init__(self) + self.__setFields() + self.__setConnections() + + def __setFields(self): + ''' + Gives values to fields + ''' + self.__drawingArea = gtk.DrawingArea() + self.add(self.__drawingArea) + self.__figures = [] + self.__lineThickness = 5 + # number of steps (for the figures overall) currently drawn + # only used in reading mode (which is the starting mode) + self.__drawn_steps = -1 + # __overall_maximum_steps stores the steps of all the figures + # only used in reading mode (which is the starting mode) + self.__overall_maximum_steps = -1 + # __current_maximum_steps stores the maximum steps the updater thread + # is allowing to draw. In each cycle of the updater thread, this value + # is incremented, giving this impression of a tape reading + # only used in reading mode (which is the starting mode) + self.__current_maximum_steps = -1 + # the updater delay in milliseconds + # => at which intervals, in reading mode, + # the redraws should be done + self.__updater_delay_milliseconds = -1 + self.__mousePressed = False + self.__readingMode = False + + def __setConnections(self): + ''' + Define the events connections + ''' + self.__drawingArea.connect("expose-event", self.__paintSurface) + self.connect("motion-notify-event", self.__manageMouseMovedEvent) + self.connect("button-press-event", self.__manageButtonPressedEvent) + self.connect("button-release-event", self.__manageButtonReleasedEvent) + + def setRecordingMode(self, line_thickness): + ''' + Switch drawing area management to recording mode + => setRecordingMode(line_thickness) + where line_thickness is an integer + ''' + self.__readingMode = False + self.__figures = [] + self.__drawingArea.queue_draw() + self.__startNewFigure() + self.__setLineThickness(line_thickness) + + def setReadingMode(self, intervals_between_steps_milliseconds): + ''' + Switch drawing area management to reading mode + => intervals_between_steps argument is an integer saying delays + in millisecond between steps + => setReadingMode(intervals_between_steps_milliseconds) + => intervals_between_steps_milliseconds : integer + ''' + self.__updater_delay_milliseconds = intervals_between_steps_milliseconds + self.__drawn_steps = 0 + self.__current_maximum_steps = 0 + self.__computeOverallMaximumSteps() + self.__drawingArea.queue_draw() + self.__readingMode = True + self.__regularlyUpdatePaintForReadingMode() + + + def __setLineThickness(self, line_thickness): + ''' + Sets lines thickness. Only integers greater than 0 will be taken + in consideration. + => __setLineThickness(line_thickness) + where line_thickness is an integer + ''' + if isinstance(line_thickness, int) and line_thickness > 0: + self.__lineThickness = line_thickness + + def __paintSurface(self, widget, event): + ''' + Paint the whole drawing area + => __paintSurface(widget, event) + ''' + cairoContext = self.__drawingArea.window.cairo_create() + self.__drawBackground(cairoContext) + self.__drawFigures(cairoContext) + return True + + def __drawBackground(self, cairoContext): + ''' + Paints the background + => __drawBackground(cairoContext) + where cairoContext is a cairo context of the DrawingArea + ''' + cairoContext.set_source_rgb(*TheDrawingAreaEventBox.__DARK_GREEN) + cairoContext.rectangle( 0,0, *(self.window.get_size()) ) + cairoContext.fill() + + def __drawFigures(self, cairoContext): + ''' + Draws the figures + => __drawFigures(cairoContext) + where cairoContext is a cairo context of the DrawingArea + ''' + cairoContext.set_source_rgb(*TheDrawingAreaEventBox.__WHITE) + cairoContext.set_line_width(self.__lineThickness) + cairoContext.set_line_join(cairo.LINE_JOIN_ROUND) + cairoContext.set_line_cap(cairo.LINE_CAP_ROUND) + if self.__readingMode: + self.__drawn_steps = 0 + for current_figure in self.__figures: + if len(current_figure) > 0 : + startPoint = current_figure[0] + cairoContext.move_to(*startPoint) + if self.__readingMode: + self.__drawn_steps += 1 + for pointIndex in range(1, len(current_figure)): + if self.__readingMode and self.__drawn_steps >= self.__current_maximum_steps : + cairoContext.stroke() + return + endPoint = current_figure[pointIndex] + cairoContext.line_to(*endPoint) + startPoint = endPoint + if self.__readingMode : + self.__drawn_steps += 1 + cairoContext.stroke() + + def __startNewFigure(self): + ''' + Starts a new figure + ''' + self.__figures += [[]] + + def __addPointToCurrentFigure(self, pointTuple): + ''' + Adds a point to the current figure + ==> __addPointToCurrentFigure(pointTuple) + where pointTuple is a tuple of the point coordinates + ''' + self.__figures[len(self.__figures)-1] += [pointTuple] + + def __computeOverallMaximumSteps(self): + ''' + Computes the number of steps of all the Figures to draw + ''' + self.__overall_maximum_steps = 0 + for current_figure in self.__figures : + self.__overall_maximum_steps += len(current_figure) + + def __manageMouseMovedEvent(self, widget, event): + ''' + Manage mouse move event + => __manageMouseMovedEvent(widget, event) + ''' + if self.__mousePressed: + self.__addPointToCurrentFigure((event.x, event.y)) + self.__drawingArea.queue_draw() # repaint the drawing area + return True # we don't need further handling for this event + + def __manageButtonPressedEvent(self, widget, event): + ''' + Manage button pressed event + => __manageButtonPressedEvent(widget, event) + ''' + self.__startNewFigure() + self.__mousePressed = True + return True # we don't need further handling for this event + + def __manageButtonReleasedEvent(self, widget, event): + ''' + Manage button released event + => __manageButtonReleasedEvent(widget, event) + ''' + self.__mousePressed = False + return True # we don't need further handling for this event + + def __regularlyUpdatePaintForReadingMode(self): + ''' + Increases the current maximum drawn steps and repaint all, at + regular delays. (For reading mode) + => __regularlyUpdatePaintForReadingMode(regular_delay_milliseconds) + regular_delay_milliseconds : integer + ''' + if self.__readingMode: + self.__current_maximum_steps += 1 + self.__drawingArea.queue_draw() + if self.__current_maximum_steps < self.__overall_maximum_steps : + gobject.timeout_add( + self.__updater_delay_milliseconds, + self.__regularlyUpdatePaintForReadingMode + ) + + def saveFiguresInTextFile(self, text_file): + ''' + Save the points in a file opened with function 'open' in write mode. + Be careful !!! Do not pass a file opened in binary mode !!! + And also, remember to close the file after this method call !!! + => saveFiguresInTextFile(text_file) + ''' + for current_figure in self.__figures : + if current_figure: + text_file.write("New\n") + for point_coordinates in current_figure: + if point_coordinates: + text_file.write("%d#%d " % point_coordinates) + text_file.write("\n") + + def readFiguresFromTextFile(self, text_file): + ''' + Read the points from a file opened with function 'open' in read mode. + Be careful !!! Do not pass a filed opened in a binary mode !!! + And also, remember to close the file after this method call !!! + => readFiguresFromTextFile(text_file) + ''' + new_figures_array = [] + for current_line in text_file.readlines(): + if current_line != "New\n" : + new_figure = [] + for current_point_string in current_line.split(' '): + if current_point_string: + current_point_string_parts = current_point_string.split('#') + new_figure.append((int(current_point_string_parts[0]), + int(current_point_string_parts[1]))) + if new_figure: + new_figures_array.append(new_figure) + self.__figures = new_figures_array + self.__drawingArea.queue_draw() +
\ No newline at end of file diff --git a/com/gmail/bernabe/laurent/sugar_olpc/learning_writing/TheDrawingAreaEventBox.pyc b/com/gmail/bernabe/laurent/sugar_olpc/learning_writing/TheDrawingAreaEventBox.pyc Binary files differnew file mode 100644 index 0000000..9893cf0 --- /dev/null +++ b/com/gmail/bernabe/laurent/sugar_olpc/learning_writing/TheDrawingAreaEventBox.pyc diff --git a/com/gmail/bernabe/laurent/sugar_olpc/learning_writing/TheWindow.py b/com/gmail/bernabe/laurent/sugar_olpc/learning_writing/TheWindow.py new file mode 100755 index 0000000..aea35e0 --- /dev/null +++ b/com/gmail/bernabe/laurent/sugar_olpc/learning_writing/TheWindow.py @@ -0,0 +1,78 @@ +# TheWindow.py Manages the window in non-Sugar environments +# +#This file is part of LearningWriting. +# +#LearningWriting is free software: you can redistribute it and/or modify +#it under the terms of the GNU General Public License as published by +#the Free Software Foundation, either version 3 of the License, or +#(at your option) any later version. +# +#LearningWriting 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 General Public License for more details. +# +#You should have received a copy of the GNU General Public License +#along with LearningWriting. If not, see <http://www.gnu.org/licenses/>. + +import pygtk + +from MenuActions import MenuActions + +pygtk.require('2.0') +import gtk + +from TheDrawingAreaEventBox import TheDrawingAreaEventBox + +class TheWindow(gtk.Window): + ''' + The Window of the application + ''' + + def __init__(self): + ''' + Simple constructor + ''' + gtk.Window.__init__(self) + self.__wrapped_drawing_area = TheDrawingAreaEventBox() + self.__menu_actions = MenuActions(self.__wrapped_drawing_area) + self.__vbox = gtk.VBox(False, 2) + self.add(self.__vbox) + self.__addMenuBar() + self.__vbox.pack_start(self.__wrapped_drawing_area) + self.set_size_request(300, 300) + self.connect("delete-event", lambda widget, event : gtk.main_quit()) + self.show_all() + + def __addMenuBar(self): + ''' + Adds a menu bar + ''' + menu_bar = gtk.MenuBar() + drawing_item = gtk.MenuItem("_Drawing") + menu_bar.append(drawing_item) + drawing_sub_menu = gtk.Menu() + drawing_write_item = gtk.RadioMenuItem(None, "_Write") + drawing_write_item.set_active(True) + drawing_write_item.connect("activate", self.__manageDrawingWrite) + drawing_read_item = gtk.RadioMenuItem(drawing_write_item, "_Read") + drawing_read_item.connect("activate", self.__manageDrawingRead) + drawing_sub_menu.append(drawing_write_item) + drawing_sub_menu.append(drawing_read_item) + drawing_item.set_submenu(drawing_sub_menu) + self.__vbox.pack_start(menu_bar, False, True) + menu_bar.show_all() + + def __manageDrawingWrite(self, menu_item): + ''' + Manages drawing->write menu + ''' + if menu_item.get_active() : + self.__menu_actions.manageDrawingWrite() + + def __manageDrawingRead(self, menu_item): + ''' + Manages drawing->read menu + ''' + if menu_item.get_active() : + self.__menu_actions.manageDrawingRead()
\ No newline at end of file diff --git a/com/gmail/bernabe/laurent/sugar_olpc/learning_writing/TheWindow.pyc b/com/gmail/bernabe/laurent/sugar_olpc/learning_writing/TheWindow.pyc Binary files differnew file mode 100644 index 0000000..61b0681 --- /dev/null +++ b/com/gmail/bernabe/laurent/sugar_olpc/learning_writing/TheWindow.pyc diff --git a/com/gmail/bernabe/laurent/sugar_olpc/learning_writing/__init__.py b/com/gmail/bernabe/laurent/sugar_olpc/learning_writing/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/com/gmail/bernabe/laurent/sugar_olpc/learning_writing/__init__.py diff --git a/com/gmail/bernabe/laurent/sugar_olpc/learning_writing/__init__.pyc b/com/gmail/bernabe/laurent/sugar_olpc/learning_writing/__init__.pyc Binary files differnew file mode 100644 index 0000000..7bcc804 --- /dev/null +++ b/com/gmail/bernabe/laurent/sugar_olpc/learning_writing/__init__.pyc |