diff options
author | Walter Bender <walter@walter-laptop.(none)> | 2009-11-05 20:50:10 (GMT) |
---|---|---|
committer | Walter Bender <walter@walter-laptop.(none)> | 2009-11-05 20:50:10 (GMT) |
commit | a42a2a732c0f0b183259689d3e87dff06a8ca42f (patch) | |
tree | 5fde7aeff708c9ae2b9dcbccdd3a42e79593ec30 |
new project
-rw-r--r-- | COPYING | 20 | ||||
-rw-r--r-- | VisualMatchActivity.py | 211 | ||||
-rw-r--r-- | activity/activity-visualmatch.svg | 62 | ||||
-rw-r--r-- | activity/activity-visualmatch.svg~ | 83 | ||||
-rw-r--r-- | activity/activity.info | 8 | ||||
-rw-r--r-- | card.py | 49 | ||||
-rw-r--r-- | grid.py | 63 | ||||
-rw-r--r-- | icons/button1off.svg | 22 | ||||
-rw-r--r-- | icons/button1off.svg~ | 30 | ||||
-rw-r--r-- | icons/button1on.svg | 20 | ||||
-rw-r--r-- | icons/button1on.svg~ | 77 | ||||
-rw-r--r-- | icons/button2off.svg | 22 | ||||
-rw-r--r-- | icons/button2off.svg~ | 22 | ||||
-rw-r--r-- | icons/button2on.svg | 20 | ||||
-rw-r--r-- | icons/button2on.svg~ | 20 | ||||
-rw-r--r-- | images/card.svg | 16 | ||||
-rwxr-xr-x | setup.py | 5 | ||||
-rw-r--r-- | sprites.py | 161 | ||||
-rw-r--r-- | window.py | 141 |
19 files changed, 1052 insertions, 0 deletions
@@ -0,0 +1,20 @@ +Copyright (c) 2007-9, Playful Invention Company, Sugar Labs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/VisualMatchActivity.py b/VisualMatchActivity.py new file mode 100644 index 0000000..51f7824 --- /dev/null +++ b/VisualMatchActivity.py @@ -0,0 +1,211 @@ +#Copyright (c) 2009, Walter Bender + +#Permission is hereby granted, free of charge, to any person obtaining a copy +#of this software and associated documentation files (the "Software"), to deal +#in the Software without restriction, including without limitation the rights +#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +#copies of the Software, and to permit persons to whom the Software is +#furnished to do so, subject to the following conditions: + +#The above copyright notice and this permission notice shall be included in +#all copies or substantial portions of the Software. + +#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +#THE SOFTWARE. + +import pygtk +pygtk.require('2.0') +import gtk +import gobject + +import sugar +from sugar.activity import activity +try: # 0.86+ toolbar widgets + from sugar.bundle.activitybundle import ActivityBundle + from sugar.activity.widgets import ActivityToolbarButton + from sugar.activity.widgets import StopButton + from sugar.graphics.toolbarbox import ToolbarBox + from sugar.graphics.toolbarbox import ToolbarButton +except ImportError: + pass +from sugar.graphics.toolbutton import ToolButton +from sugar.graphics.menuitem import MenuItem +from sugar.graphics.icon import Icon +from sugar.datastore import datastore + +from gettext import gettext as _ +import locale +import os.path + +from sprites import * +import window + +SERVICE = 'org.sugarlabs.VisualMatchActivity' +IFACE = SERVICE +PATH = '/org/augarlabs/VisualMatchActivity' + +# +# Sugar activity +# +class VisualMatchActivity(activity.Activity): + + def __init__(self, handle): + super(VisualMatchActivity,self).__init__(handle) + + try: + # Use 0.86 toolbar design + toolbar_box = ToolbarBox() + + # Buttons added to the Activity toolbar + activity_button = ActivityToolbarButton(self) + toolbar_box.toolbar.insert(activity_button, 0) + activity_button.show() + + # Button 1 + self.button1 = ToolButton( "button1off" ) + self.button1.set_tooltip(_('Button 1')) + self.button1.props.sensitive = True + self.button1.connect('clicked', self._button1_cb) + toolbar_box.toolbar.insert(self.button1, -1) + self.button1.show() + + # 3x3 Button + self.button2 = ToolButton( "button2on" ) + self.button2.set_tooltip(_('Button 2')) + self.button2.props.sensitive = True + self.button2.connect('clicked', self._button2_cb) + toolbar_box.toolbar.insert(self.button2, -1) + self.button2.show() + + separator = gtk.SeparatorToolItem() + separator.show() + toolbar_box.toolbar.insert(separator, -1) + + # Label for showing status + self.results_label = gtk.Label(_("say something here")) + self.results_label.show() + results_toolitem = gtk.ToolItem() + results_toolitem.add(self.results_label) + toolbar_box.toolbar.insert(results_toolitem,-1) + + separator = gtk.SeparatorToolItem() + separator.props.draw = False + separator.set_expand(True) + separator.show() + toolbar_box.toolbar.insert(separator, -1) + + # The ever-present Stop Button + stop_button = StopButton(self) + stop_button.props.accelerator = '<Ctrl>Q' + toolbar_box.toolbar.insert(stop_button, -1) + stop_button.show() + + self.set_toolbar_box(toolbar_box) + toolbar_box.show() + + except NameError: + # Use pre-0.86 toolbar design + self.toolbox = activity.ActivityToolbox(self) + self.set_toolbox(self.toolbox) + + self.projectToolbar = ProjectToolbar(self) + self.toolbox.add_toolbar( _('Project'), self.projectToolbar ) + + self.toolbox.show() + + # Create a canvas + canvas = gtk.DrawingArea() + canvas.set_size_request(gtk.gdk.screen_width(), \ + gtk.gdk.screen_height()) + self.set_canvas(canvas) + canvas.show() + self.show_all() + + # Initialize the canvas + self.tw = window.new_window(canvas, \ + os.path.join(activity.get_bundle_path(), \ + 'images/card'), \ + self) + + # Read the mode from the Journal + try: + if self.metadata['status'] == 'one': + self.show_button1() + elif self.metadata['status'] == 'two': + self.show_button2() + except: + self.metadata['status'] = "two" + + + # + # Button callbacks + # + def _button1_cb(self, button): + self.show_button1() + return True + + def show_button1(self): + self.button1.set_icon("button1on") + self.button2.set_icon("button2off") + self.metadata['status'] = "one" + # do something here + + def _button2_cb(self, button): + self.show_button2() + return True + + def show_button2(self): + self.button1.set_icon("button1off") + self.button2.set_icon("button2on") + self.metadata['status'] = "two" + # do something here + + """ + Write the additional status to the Journal + """ + def write_file(self, file_path): + pass + +# +# Project toolbar for pre-0.86 toolbars +# +class ProjectToolbar(gtk.Toolbar): + + def __init__(self, pc): + gtk.Toolbar.__init__(self) + self.activity = pc + + # Button 1 + self.activity.button1 = ToolButton( "button1off" ) + self.activity.button1.set_tooltip(_('Button 1')) + self.activity.button1.props.sensitive = True + self.activity.button1.connect('clicked', self.activity._button1_cb) + self.insert(self.activity.button1, -1) + self.activity.button1.show() + + # Button 2 + self.activity.button2 = ToolButton( "button2on" ) + self.activity.button2.set_tooltip(_('Button 2')) + self.activity.button2.props.sensitive = True + self.activity.button2.connect('clicked', self.activity._button2_cb) + self.insert(self.activity.button2, -1) + self.activity.button2.show() + + separator = gtk.SeparatorToolItem() + separator.set_draw(True) + self.insert(separator, -1) + separator.show() + + # Label for showing status + self.activity.results_label = gtk.Label(\ + _("say something here")) + self.activity.results_label.show() + self.activity.results_toolitem = gtk.ToolItem() + self.activity.results_toolitem.add(self.activity.results_label) + self.insert(self.activity.results_toolitem, -1) + self.activity.results_toolitem.show() diff --git a/activity/activity-visualmatch.svg b/activity/activity-visualmatch.svg new file mode 100644 index 0000000..a4128bc --- /dev/null +++ b/activity/activity-visualmatch.svg @@ -0,0 +1,62 @@ +<?xml version="1.0" ?> +<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd' [ + <!ENTITY stroke_color "#000"> + <!ENTITY fill_color "#eee"> +]> +<svg height="55px" viewBox="0 0 55 55" width="55px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" stroke-linecap="round" stroke-linejoin="round" stroke-width="3.5" stroke="&stroke_color;" fill="&fill_color;"> + <path + d="M 1,54 L 1,1 L 54,1 L 54,54 L 1,54 z" + stroke="&stroke_color;" + style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <g + transform="translate(0,-0.4)"> + <rect + ry="8.9" + rx="11.0" + y="21.1" + x="18.2" + height="13.6" + width="18.6" + style="fill:&fill_color;;fill-opacity:1;stroke:&stroke_color;;stroke-width:1.4;stroke-linecap:square;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + <rect + ry="8.9" + rx="11.0" + y="4.9" + x="18.2" + height="13.6" + width="18.6" + style="fill:none;stroke:&stroke_color;;stroke-width:1.4;stroke-linecap:square;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + <g + transform="translate(65.8,18.5)"> + <rect + style="fill:&fill_color;;fill-opacity:1;fill-rule:evenodd;stroke:&stroke_color;;stroke-width:1.4;stroke-linecap:square;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" + width="18.6" + height="13.6" + x="-47.6" + y="18.9" + rx="11.0" + ry="8.9" /> + <path + style="fill:none;stroke:&stroke_color;;stroke-width:1.2px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m -44.976185,30.770204 c 4.589517,-11.530164 4.616819,-11.635243 4.616819,-11.635243" /> + <path + style="fill:none;stroke:&stroke_color;;stroke-width:1.2px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m -43.127191,31.961097 c 4.904753,-12.826136 5.177239,-12.826136 5.177239,-12.826136 l 0,0" /> + <path + style="fill:none;stroke:&stroke_color;;stroke-width:1.2px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m -40.717775,31.961097 c 4.904752,-12.826136 5.177239,-12.826136 5.177239,-12.826136 l 0,0" /> + <path + style="fill:none;stroke:&stroke_color;;stroke-width:1.2px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m -38.308364,31.961097 c 4.904753,-12.826136 4.862003,-12.230689 4.862003,-12.230689" /> + <path + style="fill:none;stroke:&stroke_color;;stroke-width:1.2px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m -35.898948,31.961097 c 4.414384,-11.109849 4.301582,-10.759586 4.301582,-10.759586" /> + <path + style="fill:none;stroke:&stroke_color;;stroke-width:1.2px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m -33.384459,31.575808 c 3.538728,-9.008273 3.460952,-8.973246 3.460952,-8.973246" /> + <path + style="fill:none;stroke:&stroke_color;;stroke-width:1.2px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m -46.650044,29.264074 c 3.853964,-9.848903 3.811214,-9.813877 3.811214,-9.813877" /> + </g> + </g> +</svg> diff --git a/activity/activity-visualmatch.svg~ b/activity/activity-visualmatch.svg~ new file mode 100644 index 0000000..df68bf3 --- /dev/null +++ b/activity/activity-visualmatch.svg~ @@ -0,0 +1,83 @@ +<?xml version="1.0" ?> +<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd' [ + <!ENTITY stroke_color "#000"> + <!ENTITY fill_color "#eee"> +]> +<svg height="55px" viewBox="0 0 55 55" width="55px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" stroke-linecap="round" stroke-linejoin="round" stroke-width="3.5" stroke="&stroke_color;" fill="&fill_color;"> + <path + d="M 1,54 L 1,1 L 54,1 L 54,54 L 1,54 z" + id="path2395" + stroke="&stroke_color;" + style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <g + id="g5200" + transform="translate(0,-0.40254307)"> + <rect + ry="8.8859863" + rx="11.00049" + y="21.123711" + x="18.221169" + height="13.557661" + width="18.557661" + id="rect2827" + style="fill:&fill_color;;fill-opacity:1;stroke:#000000;stroke-width:1.4423393;stroke-linecap:square;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + <rect + ry="8.8859863" + rx="11.00049" + y="4.8906612" + x="18.221169" + height="13.557661" + width="18.557661" + id="rect2827-4" + style="fill:none;stroke:&stroke_color;;stroke-width:1.4423393;stroke-linecap:square;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + <g + transform="translate(65.786775,18.5)" + id="g5190"> + <rect + style="fill:&fill_color;;fill-opacity:1;fill-rule:evenodd;stroke:&stroke_color;;stroke-width:1.4423393;stroke-linecap:square;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" + id="rect2827-6" + width="18.557661" + height="13.557661" + x="-47.565605" + y="18.856764" + rx="11.00049" + ry="8.8859863" /> + <path + style="fill:none;stroke:&stroke_color;;stroke-width:1.23778403px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m -44.976185,30.770204 c 4.589517,-11.530164 4.616819,-11.635243 4.616819,-11.635243" + id="path5074" + sodipodi:nodetypes="cc" /> + <path + style="fill:none;stroke:&stroke_color;;stroke-width:1.23778403px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m -43.127191,31.961097 c 4.904753,-12.826136 5.177239,-12.826136 5.177239,-12.826136 l 0,0" + id="path5074-6" + sodipodi:nodetypes="ccc" /> + <path + style="fill:none;stroke:&stroke_color;;stroke-width:1.23778403px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m -40.717775,31.961097 c 4.904752,-12.826136 5.177239,-12.826136 5.177239,-12.826136 l 0,0" + id="path5074-3" + sodipodi:nodetypes="ccc" /> + <path + style="fill:none;stroke:&stroke_color;;stroke-width:1.23778403px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m -38.308364,31.961097 c 4.904753,-12.826136 4.862003,-12.230689 4.862003,-12.230689" + id="path5074-4" + sodipodi:nodetypes="cc" + inkscape:transform-center-x="2.206655" /> + <path + style="fill:none;stroke:&stroke_color;;stroke-width:1.23778403px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m -35.898948,31.961097 c 4.414384,-11.109849 4.301582,-10.759586 4.301582,-10.759586" + id="path5074-2" + sodipodi:nodetypes="cc" /> + <path + style="fill:none;stroke:&stroke_color;;stroke-width:1.23778403px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m -33.384459,31.575808 c 3.538728,-9.008273 3.460952,-8.973246 3.460952,-8.973246" + id="path5074-7" + sodipodi:nodetypes="cc" /> + <path + style="fill:none;stroke:&stroke_color;;stroke-width:1.23778403px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m -46.650044,29.264074 c 3.853964,-9.848903 3.811214,-9.813877 3.811214,-9.813877" + id="path5074-78" + sodipodi:nodetypes="cc" /> + </g> + </g> +</svg> diff --git a/activity/activity.info b/activity/activity.info new file mode 100644 index 0000000..7298b29 --- /dev/null +++ b/activity/activity.info @@ -0,0 +1,8 @@ +[Activity] +name = Visual Match +activity_version = 4 +license = GPLv3 +bundle_id = org.sugarlabs.VisualMatchActivity +exec = sugar-activity VisualMatchActivity.VisualMatchActivity +icon = activity-visualmatch +show_launcher = yes @@ -0,0 +1,49 @@ +#Copyright (c) 2009, Walter Bender + +#Permission is hereby granted, free of charge, to any person obtaining a copy +#of this software and associated documentation files (the "Software"), to deal +#in the Software without restriction, including without limitation the rights +#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +#copies of the Software, and to permit persons to whom the Software is +#furnished to do so, subject to the following conditions: + +#The above copyright notice and this permission notice shall be included in +#all copies or substantial portions of the Software. + +#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +#THE SOFTWARE. + +import pygtk +pygtk.require('2.0') +import gtk +import gobject +import os.path + +from sprites import * + +# +# class for defining individual cards +# +class Card: + def __init__(self,tw,pattern): + # what do we need to know about each card? + # self.??? = ??? + # create sprite from svg file + self.spr = sprNew(tw, 0, 0,\ + self.load_image(tw.path,tw.card_dim*tw.scale)) + self.spr.label = "" + + def draw_card(self): + setlayer(self.spr,2000) + draw(self.spr) + + def load_image(self, file, wh): + return gtk.gdk.pixbuf_new_from_file_at_size(os.path.join(file + \ + '.svg'), \ + int(wh), int(wh)) + @@ -0,0 +1,63 @@ +#Copyright (c) 2009, Walter Bender + +#Permission is hereby granted, free of charge, to any person obtaining a copy +#of this software and associated documentation files (the "Software"), to deal +#in the Software without restriction, including without limitation the rights +#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +#copies of the Software, and to permit persons to whom the Software is +#furnished to do so, subject to the following conditions: + +#The above copyright notice and this permission notice shall be included in +#all copies or substantial portions of the Software. + +#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +#THE SOFTWARE. + +import pygtk +pygtk.require('2.0') +import gtk +import gobject + +from sprites import * +from card import * + +# +# class for defining 4x3 matrix of cards +# +class Grid: + def __init__(self, tw): + # the playing surface is a 3x4 grid + self.grid = [] + # create the deck of cards + self.deck = {} + # stuff to keep around for the graphics + self.w = tw.width + self.h = tw.height + self.d = tw.card_dim + self.s = tw.scale + # Initialize the deck of cards + # some loop through all the patterns + # self.deck[i] = Card(tw,pattern) + + # shuffle the deck + def shuffle(self,tw): + return + + # initial layout of 12 cards on the table + def start(self, tw): + return + + # draw a card from the deck + def draw_a_card(self, tw): + return + + # find a set + def find_a_set(self, tw): + return + + diff --git a/icons/button1off.svg b/icons/button1off.svg new file mode 100644 index 0000000..bbc5058 --- /dev/null +++ b/icons/button1off.svg @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + version="1.0" + width="55" + height="55"> + <rect + style="fill:#808080;fill-opacity:1;stroke:#808080;stroke-width:4;stroke-miterlimit:4;stroke-opacity:1;" + width="51" + height="51" + x="2" + y="2" + ry="7.0" + rx="8.1" /> + <text + x="13.5" + y="42.0" + style="font-size:40px;font-style:normal;font-weight:normal;fill:#ffffff;fill-opacity:1;font-family:Bitstream Vera Sans"><tspan + x="13.5" + y="42.0">1</tspan></text> +</svg> diff --git a/icons/button1off.svg~ b/icons/button1off.svg~ new file mode 100644 index 0000000..b3e9844 --- /dev/null +++ b/icons/button1off.svg~ @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> +<svg + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + version="1.0" + width="55" + height="55" + id="svg2"> + <defs + id="defs4" /> + <rect + style="fill:#808080;fill-opacity:1;stroke:#808080;stroke-width:4.05900620999999973;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" + id="rect2817" + width="50.94099" + height="50.940994" + x="2.0295048" + y="2.0295029" + ry="7.0263433" + rx="8.1506357" /> + <text + x="13.496094" + y="42.060547" + id="text2394" + xml:space="preserve" + style="font-size:40px;font-style:normal;font-weight:normal;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"><tspan + x="13.496094" + y="42.060547" + id="tspan2396">1</tspan></text> +</svg> diff --git a/icons/button1on.svg b/icons/button1on.svg new file mode 100644 index 0000000..ebe7c37 --- /dev/null +++ b/icons/button1on.svg @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns="http://www.w3.org/2000/svg" + version="1.0" + width="55" + height="55"> + <rect + style="fill:#000000;fill-opacity:1;stroke:#808080;stroke-width:4;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" + width="51" + height="51" + x="2" + y="2" + ry="7.0" + rx="8.1" /> + <text + style="font-size:40px;font-style:normal;font-weight:normal;fill:#ffffff;fill-opacity:1;font-family:Bitstream Vera Sans"><tspan + x="13.5" + y="42.0" + id="tspan2396">1</tspan></text> +</svg> diff --git a/icons/button1on.svg~ b/icons/button1on.svg~ new file mode 100644 index 0000000..a434afb --- /dev/null +++ b/icons/button1on.svg~ @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.0" + width="55" + height="55" + id="svg2" + inkscape:version="0.47pre4 r22446" + sodipodi:docname="Aon.svg"> + <metadata + id="metadata9"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1680" + inkscape:window-height="972" + id="namedview7" + showgrid="false" + inkscape:zoom="13.181818" + inkscape:cx="14.110345" + inkscape:cy="27.5" + inkscape:window-x="0" + inkscape:window-y="27" + inkscape:window-maximized="1" + inkscape:current-layer="svg2" /> + <defs + id="defs4"> + <inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="0 : 27.5 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="55 : 27.5 : 1" + inkscape:persp3d-origin="27.5 : 18.333333 : 1" + id="perspective11" /> + </defs> + <rect + style="fill:#000000;fill-opacity:1;stroke:#808080;stroke-width:4.05900620999999973;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" + id="rect2817" + width="50.94099" + height="50.940994" + x="2.0295048" + y="2.0295029" + ry="7.0263433" + rx="8.1506357" /> + <text + x="13.496094" + y="42.060547" + id="text2394" + xml:space="preserve" + style="font-size:40px;font-style:normal;font-weight:normal;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"><tspan + x="13.496094" + y="42.060547" + id="tspan2396">A</tspan></text> +</svg> diff --git a/icons/button2off.svg b/icons/button2off.svg new file mode 100644 index 0000000..d184b94 --- /dev/null +++ b/icons/button2off.svg @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + version="1.0" + width="55" + height="55"> + <rect + style="fill:#808080;fill-opacity:1;stroke:#808080;stroke-width:4;stroke-miterlimit:4;stroke-opacity:1;" + width="51" + height="51" + x="2" + y="2" + ry="7.0" + rx="8.1" /> + <text + x="13.5" + y="42.0" + style="font-size:40px;font-style:normal;font-weight:normal;fill:#ffffff;fill-opacity:1;font-family:Bitstream Vera Sans"><tspan + x="13.5" + y="42.0">2</tspan></text> +</svg> diff --git a/icons/button2off.svg~ b/icons/button2off.svg~ new file mode 100644 index 0000000..bbc5058 --- /dev/null +++ b/icons/button2off.svg~ @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + version="1.0" + width="55" + height="55"> + <rect + style="fill:#808080;fill-opacity:1;stroke:#808080;stroke-width:4;stroke-miterlimit:4;stroke-opacity:1;" + width="51" + height="51" + x="2" + y="2" + ry="7.0" + rx="8.1" /> + <text + x="13.5" + y="42.0" + style="font-size:40px;font-style:normal;font-weight:normal;fill:#ffffff;fill-opacity:1;font-family:Bitstream Vera Sans"><tspan + x="13.5" + y="42.0">1</tspan></text> +</svg> diff --git a/icons/button2on.svg b/icons/button2on.svg new file mode 100644 index 0000000..39a0f80 --- /dev/null +++ b/icons/button2on.svg @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns="http://www.w3.org/2000/svg" + version="1.0" + width="55" + height="55"> + <rect + style="fill:#000000;fill-opacity:1;stroke:#808080;stroke-width:4;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" + width="51" + height="51" + x="2" + y="2" + ry="7.0" + rx="8.1" /> + <text + style="font-size:40px;font-style:normal;font-weight:normal;fill:#ffffff;fill-opacity:1;font-family:Bitstream Vera Sans"><tspan + x="13.5" + y="42.0" + id="tspan2396">2</tspan></text> +</svg> diff --git a/icons/button2on.svg~ b/icons/button2on.svg~ new file mode 100644 index 0000000..ebe7c37 --- /dev/null +++ b/icons/button2on.svg~ @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns="http://www.w3.org/2000/svg" + version="1.0" + width="55" + height="55"> + <rect + style="fill:#000000;fill-opacity:1;stroke:#808080;stroke-width:4;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" + width="51" + height="51" + x="2" + y="2" + ry="7.0" + rx="8.1" /> + <text + style="font-size:40px;font-style:normal;font-weight:normal;fill:#ffffff;fill-opacity:1;font-family:Bitstream Vera Sans"><tspan + x="13.5" + y="42.0" + id="tspan2396">1</tspan></text> +</svg> diff --git a/images/card.svg b/images/card.svg new file mode 100644 index 0000000..e9ad27d --- /dev/null +++ b/images/card.svg @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> +<svg + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + version="1.0" + width="135" + height="135.00002" + id="svg3193"> + <defs + id="defs3195" /> + <path + d="M 1.1368684e-13,135 L 1.1368684e-13,-2.8421709e-14 L 135,-2.8421709e-14 L 135,135 L 1.1368684e-13,135 z" + id="path2395" + style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.34653473px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> +</svg> diff --git a/setup.py b/setup.py new file mode 100755 index 0000000..bd1e319 --- /dev/null +++ b/setup.py @@ -0,0 +1,5 @@ +#!/usr/bin/env python +from sugar.activity import bundlebuilder +if __name__ == "__main__": + bundlebuilder.start() + diff --git a/sprites.py b/sprites.py new file mode 100644 index 0000000..e1b037e --- /dev/null +++ b/sprites.py @@ -0,0 +1,161 @@ +# -*- coding: utf-8 -*- + +#Copyright (c) 2007-8, Playful Invention Company. +#Copyright (c) 2008-9, Walter Bender + +#Permission is hereby granted, free of charge, to any person obtaining a copy +#of this software and associated documentation files (the "Software"), to deal +#in the Software without restriction, including without limitation the rights +#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +#copies of the Software, and to permit persons to whom the Software is +#furnished to do so, subject to the following conditions: + +#The above copyright notice and this permission notice shall be included in +#all copies or substantial portions of the Software. + +#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +#THE SOFTWARE. + +import pygtk +pygtk.require('2.0') +import gtk +import gobject +import pango +class taSprite: pass + +def findsprite(tw,pos): + list = tw.sprites[:] + list.reverse() + for s in list: + if hit(s,pos): return s + return None + +def redrawsprites(tw): + for s in tw.sprites: draw(s) + +def sprNew(tw,x,y,image,altlabel=False): + spr = taSprite() + spr.tw, spr.x, spr.y = tw,x,y + setimage(spr,image) + spr.label = None + spr.ds_id = None + if altlabel: + spr.draw_label = draw_label2 + else: spr.draw_label = draw_label1 + return spr + +def setimage(spr,image): + spr.image = image + if isinstance(image,gtk.gdk.Pixbuf): + spr.width = image.get_width() + spr.height = image.get_height() + else: spr.width,spr.height=image.get_size() + +def move(spr,pos): + inval(spr) + spr.x,spr.y = pos + inval(spr) + +def setshape(spr,image): + inval(spr) + setimage(spr,image) + inval(spr) + +def setshapex(spr): + inval(spr) + +def setlayer(spr, layer): + sprites = spr.tw.sprites + if spr in sprites: sprites.remove(spr) + spr.layer = layer + for i in range(len(sprites)): + if layer < sprites[i].layer: + sprites.insert(i, spr) + inval(spr) + return + sprites.append(spr) + inval(spr) + +def hide(spr): + if spr not in spr.tw.sprites: return + inval(spr) + spr.tw.sprites.remove(spr) + +def setlabel(spr,label): + spr.label = label + inval(spr) + +def inval(spr): + spr.tw.area.invalidate_rect(gtk.gdk.Rectangle(spr.x,spr.y,spr.width, \ + spr.height), False) + +def draw(spr): + if isinstance(spr.image,gtk.gdk.Pixbuf): + spr.tw.area.draw_pixbuf(spr.tw.gc, spr.image, 0, 0, spr.x, spr.y) + else: + spr.tw.area.draw_drawable(spr.tw.gc,spr.image,0,0,spr.x,spr.y,-1,-1) + if spr.label!=None: + if hasattr(spr, 'proto') and hasattr(spr.proto, 'name'): + name = spr.proto.name + else: + name = "" + spr.draw_label(spr,str(spr.label)) + +def hit(spr,pos): + x,y = pos + if x<spr.x: return False + if x>spr.x+spr.width: return False + if y<spr.y: return False + if y>spr.y+spr.height: return False + if isinstance(spr.image,gtk.gdk.Pixmap): return True + if hasattr(spr, 'proto') and hasattr(spr.proto, 'name') and \ + spr.proto.name == 'journal': + return True + dx,dy = x-spr.x, y-spr.y + try: + return ord(spr.image.get_pixels()[(dy*spr.width+dx)*4+3]) == 255 + except IndexError: + if hasattr(spr, 'proto') and hasattr(spr.proto, 'name'): + print spr.proto.name + print "IndexError: string index out of range" + str(dx) + " " \ + + str(dy) + " " + str(spr.width) + " " + str(spr.height) + return True + +def draw_label(spr, label, myscale, center_flag, truncate_flag): + fd = pango.FontDescription('Sans') + fd.set_size(int(myscale*spr.tw.scale*pango.SCALE)) + if type(label) == str or type(label) == unicode: + mylabel = label.replace("\0"," ") + l = len(mylabel) + if truncate_flag and l > 8: + pl = spr.tw.canvas.create_pango_layout("..."+mylabel[l-8:]) + else: + pl = spr.tw.canvas.create_pango_layout(mylabel) + pl.set_font_description(fd) + if center_flag: + swidth = pl.get_size()[0]/pango.SCALE + centerx = spr.x+spr.width/2 + x = int(centerx-swidth/2) + else: + x = spr.x+70 + sheight = pl.get_size()[1]/pango.SCALE + centery = spr.y+spr.height/2 + y = int(centery-sheight/2) + spr.tw.gc.set_foreground(spr.tw.msgcolor) + spr.tw.area.draw_layout(spr.tw.gc, x, y, pl) + else: + print type(label) + +# used for most things +def draw_label1(spr, label): + draw_label(spr, label, 12, True, True) + +# used for status blocks +def draw_label2(spr, label): + draw_label(spr, str(label), 14, False, False) + diff --git a/window.py b/window.py new file mode 100644 index 0000000..8ee6559 --- /dev/null +++ b/window.py @@ -0,0 +1,141 @@ +#Copyright (c) 2009, Walter Bender + +#Permission is hereby granted, free of charge, to any person obtaining a copy +#of this software and associated documentation files (the "Software"), to deal +#in the Software without restriction, including without limitation the rights +#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +#copies of the Software, and to permit persons to whom the Software is +#furnished to do so, subject to the following conditions: + +#The above copyright notice and this permission notice shall be included in +#all copies or substantial portions of the Software. + +#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +#THE SOFTWARE. + +import pygtk +pygtk.require('2.0') +import gtk +from gettext import gettext as _ + +try: + from sugar.graphics import style + GRID_CELL_SIZE = style.GRID_CELL_SIZE +except: + GRID_CELL_SIZE = 0 + +from grid import * +from card import * + +from math import sqrt + +CARD_DIM = 135 + +class taWindow: pass + +# +# handle launch from both within and without of Sugar environment +# +def new_window(canvas, path, parent=None): + tw = taWindow() + tw.path = path + tw.activity = parent + + # starting from command line + # we have to do all the work that was done in CardSortActivity.py + if parent is None: + tw.sugar = False + tw.canvas = canvas + + # starting from Sugar + else: + tw.sugar = True + tw.canvas = canvas + parent.show_all() + + tw.canvas.set_flags(gtk.CAN_FOCUS) + tw.canvas.add_events(gtk.gdk.BUTTON_PRESS_MASK) + tw.canvas.add_events(gtk.gdk.BUTTON_RELEASE_MASK) + tw.canvas.connect("expose-event", _expose_cb, tw) + tw.canvas.connect("button-press-event", _button_press_cb, tw) + tw.canvas.connect("button-release-event", _button_release_cb, tw) + tw.canvas.connect("key_press_event", _keypress_cb, tw) + tw.width = gtk.gdk.screen_width() + tw.height = gtk.gdk.screen_height()-GRID_CELL_SIZE + tw.card_dim = CARD_DIM + tw.scale = 0.8 * tw.height/(tw.card_dim*3) + tw.area = tw.canvas.window + tw.gc = tw.area.new_gc() + tw.cm = tw.gc.get_colormap() + tw.msgcolor = tw.cm.alloc_color('black') + tw.sprites = [] + + # make the cards, the deck and start playing... + tw.deck = Grid(tw) + tw.deck.shuffle(tw) + tw.deck.start(tw) + + # Start doing something + tw.keypress = "" + tw.press = -1 + tw.release = -1 + tw.start_drag = [0,0] + + return tw + +# +# Button press +# +def _button_press_cb(win, event, tw): + win.grab_focus() + x, y = map(int, event.get_coords()) + tw.start_drag = [x,y] + spr = findsprite(tw,(x,y)) + if spr is None: + tw.press = None + tw.release = None + return True + # take note of card under button press + tw.press = spr + return True + +# +# Button release +# +def _button_release_cb(win, event, tw): + win.grab_focus() + x, y = map(int, event.get_coords()) + spr = findsprite(tw,(x,y)) + if spr is None: + tw.press = None + tw.release = None + return True + # take note of card under button release + tw.release = spr + return True + +# +# Keypress +# +def _keypress_cb(area, event, tw): + tw.keypress = gtk.gdk.keyval_name(event.keyval) + return True + +# +# Repaint +# +def _expose_cb(win, event, tw): + redrawsprites(tw) + return True + +# +# callbacks +# +def _destroy_cb(win, event, tw): + gtk.main_quit() + |