Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/plotter/view/puzzletree/__init__.py
blob: 093ef8dcdea32eac7d5928c7ce5fcd2f37b8cb85 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
"""Module for mouse function input."""

import gtk

from .display import PuzzleDisplay
from .palette import PuzzlePalette
from .nodes import Node

_FILE_VERSION = 1

class PuzzleInput(gtk.VBox):
    """PuzzleInput is a control that uses mouse input to create functions."""

    CLASS = "puzzle"

    def __init__(self, app, rootnode=None):
        """Creates input (and display) of tree.

        We'd like to support multiple trees for click-and-drag,
        but for now, just one tree is made at a time.
        """
        gtk.VBox.__init__(self)

        self.app = app

        # create box to hold display and undo button
        displaybox = gtk.HBox()
        self.pack_start(displaybox)

        # create display for drawing function tree
        displayscroll = gtk.ScrolledWindow()
        displayscroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_NEVER)
        displayview = gtk.Viewport()
        self._display = PuzzleDisplay(rootnode)
        displayview.add(self._display)
        displayscroll.add(displayview)
        displaybox.pack_start(displayscroll)

        # undo button (TODO: this isn't really undo)
        undoimage = gtk.Image()
        undoimage.set_from_stock(gtk.STOCK_UNDO, gtk.ICON_SIZE_BUTTON)
        undobutton = gtk.Button()
        undobutton.add(undoimage)
        undobutton.show_all()
        displaybox.pack_start(undobutton, expand=False)

        # connect undo event (should show palette and undo)
        undobutton.connect("clicked", self.on_undo)

        # create buttons for adding nodes
        palette = PuzzlePalette(app, self._display)
        self.pack_start(palette)
        self._palette = palette

        # hide palette if it cannot be used
        self.show_all()
        if (self._display.rootnode is not None and
            self._display.nextnode is None):
            palette.hide()


    @staticmethod
    def load(app, settings):
        """Create new input from dictionary state."""

        if settings["version"] > _FILE_VERSION:
            return PuzzleInput()
        return PuzzleInput(app, Node.load(settings["settings"]))


    def save(self):
        """Create a dictionary to save current state."""

        nodesettings = None
        if self._display.rootnode is not None:
            nodesettings = self._display.rootnode.save()

        settings = {
            "version": _FILE_VERSION,
            "settings": nodesettings
        }
        return settings


    def on_undo(self, widget, data=None):
        """Undoes the previous action (removes bottom-right node)."""

        removednode = self._display.undo()
        self._palette.show_all()

        # register action for undo/redo
        def action():
            self._display.undo()
            self._palette.show_all()
        def inverse():
            self._display.addnode(removednode)
            if self._display.nextnode is None:
                self._palette.hide()
        self.app.register_action(action, inverse)


    def get_model(self):
        """Returns callable model from the tree."""
        return self._display.get_model()


    def get_equation_string(self):
        """Returns a string representing the current equation."""
        return Node.get_equation_string(self._display.rootnode, "x")