123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401 |
- <?xml version="1.0" ?>
- <diagram name="Bouncing_Balls" author="Simon Van Mierlo+Joeri Exelmans+Raphael Mannadiar">
- <description>
- Tkinter frame with bouncing balls in it.
- </description>
- <inport name="field_ui"/>
- <inport name="ball_ui"/>
- <inport name="ui"/>
- <top>
- from python_runtime.libs.ui import *
- from python_runtime.libs.utils import *
- </top>
- <class name="Button">
- <relationships>
- <association name="parent" class="Field" min="1" max="1"/>
- </relationships>
- <method name="Button">
- <parameter name="parent" type="Field"/>
- <parameter name="event_name" type="str"/>
- <parameter name="button_text" type="str"/>
- <body>
- <![CDATA[
- self.event_name = event_name
- button = ui.append_button(parent.field_window, event_name)
- ui.bind_event(button.element, ui.EVENTS.MOUSE_CLICK, self.controller, 'mouse_click')
- ]]>
- </body>
- </method>
- <scxml initial="initializing">
- <state id="initializing">
- <transition target="../running">
- <raise event="button_created" scope="narrow" target="'parent'">
- </raise>
- </transition>
- </state>
- <state id="running">
- <transition port="ui" target="." event="mouse_click" cond="button == ui.MOUSE_BUTTONS.LEFT">
- <parameter name="x" type="int"/>
- <parameter name="y" type="int"/>
- <parameter name="button" type="Button"/>
- <raise event="button_pressed" scope="narrow" target="'parent'">
- <parameter expr="self.event_name"/>
- </raise>
- </transition>
- </state>
- </scxml>
- </class>
- <class name="Field">
- <inport name="field_ui"/>
- <relationships>
- <association name="parent" class="MainApp" min="1" max="1"/>
- <association name="buttons" class="Button"/>
- <association name="balls" class="Ball"/>
- </relationships>
- <attribute name="field_window"/>
- <attribute name="canvas"/>
- <method name="Field">
- <body>
- <![CDATA[
- self.field_window = ui.new_window(400, 450)
- self.canvas = ui.append_canvas(self.field_window, 400, 400, {'background':'#eee'})
- ui.bind_event(self.field_window, ui.EVENTS.WINDOW_CLOSE, self.controller, 'window_close')
- ui.bind_event(self.field_window, ui.EVENTS.KEY_PRESS, self.controller, 'key_press')
- ui.bind_event(self.canvas.element, ui.EVENTS.MOUSE_RIGHT_CLICK, self.controller, 'right_click', self.inports['field_ui'])
- ui.bind_event(self.canvas.element, ui.EVENTS.MOUSE_MOVE, self.controller, 'mouse_move')
- ui.bind_event(self.canvas.element, ui.EVENTS.MOUSE_RELEASE, self.controller, 'mouse_release')
- ]]>
- </body>
- </method>
- <method name="~Field">
- <body>
- <![CDATA[
- ui.close_window(self.field_window)
- ]]>
- </body>
- </method>
- <scxml initial="root">
- <state id="root" initial="waiting">
- <state id="waiting">
- <transition target="../initializing" event="set_association_name">
- <parameter name="association_name" type="str"/>
- <script>
- <![CDATA[
- self.association_name = association_name
- ]]>
- </script>
- </transition>
- </state>
- <state id="packing">
- <transition target="../running" event="button_created">
- </transition>
- </state>
- <state id="deleting">
- <transition after="0.05" target="../deleted">
- <raise event="delete_field" scope="narrow" target="'parent'">
- <parameter expr="self.association_name"/>
- </raise>
- </transition>
- </state>
- <state id="creating">
- <transition target="../packing" event="instance_created">
- <parameter name="association_name" type="string"/>
- <raise event="start_instance" scope="cd">
- <parameter expr="association_name"/>
- </raise>
- </transition>
- </state>
- <state id="initializing">
- <transition target="../creating">
- <raise event="create_instance" scope="cd">
- <parameter expr="'buttons'"/>
- <parameter expr="'Button'"/>
- <parameter expr="self"/>
- <parameter expr="'create_new_field'"/>
- <parameter expr="'Spawn New Window'"/>
- </raise>
- </transition>
- </state>
- <state id="deleted">
- </state>
- <parallel id="running">
- <transition port="ui" target="../deleting" event="window_close" cond="window == self.field_window or window == ui.window">
- <parameter name="window" type="Window"/>
- <raise event="delete_instance" scope="cd">
- <parameter expr="'buttons'"/>
- </raise>
- <raise event="delete_self" scope="narrow" target="'balls'">
- </raise>
- </transition>
- <state id="main_behaviour" initial="running">
- <state id="running">
- <transition port="field_ui" target="../creating" event="right_click">
- <parameter name="x" type="int"/>
- <parameter name="y" type="int"/>
- <parameter name="button" type="Button"/>
- <raise event="create_instance" scope="cd">
- <parameter expr="'balls'"/>
- <parameter expr="'Ball'"/>
- <parameter expr="self.canvas"/>
- <parameter expr="x"/>
- <parameter expr="y"/>
- <parameter expr="self.field_window"/>
- </raise>
- </transition>
- </state>
- <state id="creating">
- <transition target="../running" event="instance_created">
- <parameter name="association_name" type="string"/>
- <raise event="set_association_name" scope="narrow" target="association_name">
- <parameter expr="association_name"/>
- </raise>
- <raise event="start_instance" scope="cd">
- <parameter expr="association_name"/>
- </raise>
- </transition>
- </state>
- </state>
- <state id="deleting_behaviour" initial="running">
- <state id="running">
- <transition target="." event="delete_ball">
- <parameter name="association_name" type="str"/>
- <raise event="delete_instance" scope="cd">
- <parameter expr="association_name"/>
- </raise>
- </transition>
- </state>
- </state>
- <state id="child_behaviour" initial="listening">
- <state id="listening">
- <transition target="." event="button_pressed">
- <parameter name="event_name" type="str"/>
- <raise event="button_pressed" scope="narrow" target="'parent'">
- <parameter expr="event_name"/>
- </raise>
- </transition>
- </state>
- </state>
- </parallel>
- </state>
- </scxml>
- </class>
- <class name="MainApp" default="True">
- <relationships>
- <association name="fields" class="Field"/>
- </relationships>
- <method name="MainApp">
- <body>
- <![CDATA[
- self.nr_of_fields = 0
- ui.bind_event(ui.window, ui.EVENTS.WINDOW_CLOSE, self.controller, 'window_close')
- ]]>
- </body>
- </method>
- <scxml initial="running">
- <state id="running" initial="root">
- <state id="stopped">
- </state>
- <parallel id="root">
- <state id="main_behaviour" initial="initializing">
- <state id="initializing">
- <transition target="../running">
- <raise event="create_field">
- </raise>
- </transition>
- </state>
- <state id="running">
- <transition target="." event="button_pressed" cond="event_name == 'create_new_field'">
- <parameter name="event_name" type="str"/>
- <raise event="create_field">
- </raise>
- </transition>
- </state>
- </state>
- <state id="cd_behaviour" initial="waiting">
- <state id="creating">
- <transition target="../waiting" event="instance_created">
- <parameter name="association_name" type="string"/>
- <raise event="start_instance" scope="cd">
- <parameter expr="association_name"/>
- </raise>
- <raise event="set_association_name" scope="narrow" target="association_name">
- <parameter expr="association_name"/>
- </raise>
- <script>
- <![CDATA[
- self.nr_of_fields += 1
- ]]>
- </script>
- </transition>
- </state>
- <state id="waiting">
- <transition target="../creating" event="create_field">
- <raise event="create_instance" scope="cd">
- <parameter expr="'fields'"/>
- </raise>
- </transition>
- <transition target="../check_nr_of_fields" event="delete_field">
- <parameter name="association_name" type="str"/>
- <raise event="delete_instance" scope="cd">
- <parameter expr="association_name"/>
- </raise>
- <script>
- <![CDATA[
- self.nr_of_fields -= 1
- ]]>
- </script>
- </transition>
- </state>
- <state id="check_nr_of_fields">
- <transition target="../waiting" cond="self.nr_of_fields != 0">
- </transition>
- <transition target="../../../stopped" cond="self.nr_of_fields == 0">
- <script>
- <![CDATA[
- ui.close_window(ui.window)
- ]]>
- </script>
- </transition>
- </state>
- </state>
- </parallel>
- </state>
- </scxml>
- </class>
- <class name="Ball">
- <inport name="ball_ui"/>
- <relationships>
- <association name="parent" class="Field" min="1" max="1"/>
- </relationships>
- <attribute name="field_window"/>
- <attribute name="canvas"/>
- <attribute name="element"/>
- <method name="Ball">
- <parameter name="canvas"/>
- <parameter name="x"/>
- <parameter name="y"/>
- <parameter name="field_window"/>
- <body>
- <![CDATA[
- self.canvas = canvas
- self.field_window = field_window
- self.r = 20.0
- self.vel = {'x':utils.random() * 2.0 - 1.0, 'y':utils.random() * 2.0 - 1.0}
- self.mouse_pos = {'':''}
- self.smooth = 0.4
- circle = self.canvas.add_circle(x, y, self.r, {'fill':'#000'})
- ui.bind_event(circle, ui.EVENTS.MOUSE_PRESS, self.controller, 'mouse_press', self.inports['ball_ui'])
- ui.bind_event(circle, ui.EVENTS.MOUSE_RIGHT_CLICK, self.controller, 'right_click')
- self.element = circle
- ]]>
- </body>
- </method>
- <method name="~Ball">
- <body>
- <![CDATA[
- self.canvas.remove_element(self.element)
- ]]>
- </body>
- </method>
- <scxml initial="main_behaviour">
- <state id="main_behaviour" initial="initializing">
- <transition target="../deleted" event="delete_self">
- <raise event="delete_ball" scope="narrow" target="'parent'">
- <parameter expr="self.association_name"/>
- </raise>
- </transition>
- <state id="dragging">
- <transition port="ui" target="../bouncing" event="mouse_release">
- <parameter name="x" type="int"/>
- <parameter name="y" type="int"/>
- <script>
- <![CDATA[
- self.element.set_color('#f00')
- ]]>
- </script>
- </transition>
- <transition port="ui" target="." event="mouse_move">
- <parameter name="x" type="int"/>
- <parameter name="y" type="int"/>
- <parameter name="button" type="Button"/>
- <script>
- <![CDATA[
- dx = x - self.mouse_pos['x']
- dy = y - self.mouse_pos['y']
- self.element.move(dx, dy)
- pos = self.element.get_position()
- if pos.x - self.r <= 0:
- pos.x = self.r + 1
- else:
- if pos.x + self.r >= self.canvas.width:
- pos.x = self.canvas.width - self.r - 1
- if pos.y - self.r <= 0:
- pos.y = self.r + 1
- else:
- if pos.y + self.r >= self.canvas.height:
- pos.y = self.canvas.height - self.r - 1
- self.element.set_position(pos.x, pos.y)
- self.mouse_pos = {'x':x, 'y':y}
- self.vel = {'x':(1 - self.smooth) * dx + self.smooth * self.vel['x'], 'y':(1 - self.smooth) * dy + self.smooth * self.vel['y']}
- ]]>
- </script>
- </transition>
- </state>
- <state id="selected">
- <transition port="ball_ui" target="../dragging" event="mouse_press" cond="button == ui.MOUSE_BUTTONS.LEFT">
- <parameter name="x" type="int"/>
- <parameter name="y" type="int"/>
- <parameter name="button" type="Button"/>
- <script>
- <![CDATA[
- self.mouse_pos = {'x':x, 'y':y}
- ]]>
- </script>
- </transition>
- <transition port="ui" target="." event="key_press" cond="key == ui.KEYCODES.DELETE and active_window == self.field_window">
- <parameter name="key" type="Key"/>
- <parameter name="active_window" type="Window"/>
- <raise event="delete_self" scope="local">
- </raise>
- </transition>
- </state>
- <state id="initializing">
- <transition target="../bouncing" event="set_association_name">
- <parameter name="association_name" type="str"/>
- <script>
- <![CDATA[
- self.association_name = association_name
- ]]>
- </script>
- </transition>
- </state>
- <state id="bouncing">
- <transition after="0.01" target=".">
- <script>
- <![CDATA[
- pos = self.element.get_position()
- if pos.x - self.r <= 0 or pos.x + self.r >= self.canvas.width:
- self.vel['x'] = -self.vel['x']
- if pos.y - self.r <= 0 or pos.y + self.r >= self.canvas.height:
- self.vel['y'] = -self.vel['y']
- self.element.move(self.vel['x'], self.vel['y'])
- ]]>
- </script>
- </transition>
- <transition port="ball_ui" target="../selected" event="mouse_press" cond="button == ui.MOUSE_BUTTONS.LEFT">
- <parameter name="x" type="int"/>
- <parameter name="y" type="int"/>
- <parameter name="button" type="Button"/>
- <script>
- <![CDATA[
- self.element.set_color('#ff0')
- ]]>
- </script>
- </transition>
- </state>
- </state>
- <state id="deleted">
- </state>
- </scxml>
- </class>
- </diagram>
|