Пример #1
0
class Snake(Widget):
    body = props.ListProperty()
    size = props.ListProperty([SIZE, SIZE])

    def __init__(self, canvas):
        super().__init__()
        self.canvas = canvas
        for _ in range(4):
            self._grow([300, 300])

    @property
    def head_position(self):
        return self.body[0].pos

    def _grow(self, pos):
        with self.canvas:
            Color(0, 0, 1)
            head = Ellipse(pos=pos, size=self.size)
            self.body.append(head)

    def check_self_collision(self, next_head_pos):
        """ Проверка на столкновение головы змеи с телом """
        for body_segment in self.body[1:]:
            if list(body_segment.pos) == next_head_pos:
                return True
        return False

    def move_to(self, next_pos, grow=False):
        for i, segment in enumerate(self.body):
            self.body[i].pos, next_pos = next_pos, segment.pos
        if grow:
            self._grow(next_pos)
Пример #2
0
class InfoDayConfig(Screen):
    colorHora = Properties.ListProperty([1, 1, 1, 1])
    formatoHora = Properties.ListProperty(["24h", False])

    colorFecha = Properties.ListProperty([1, 1, 1, 1])
    formatoFecha = Properties.StringProperty("dd/mm")

    colorTemp = Properties.ListProperty([1, 1, 1, 1])
    formatoTemp = Properties.StringProperty("metric")

    formatoClima = Properties.NumericProperty(2)

    c_id = Properties.StringProperty('6361046')
    activeInter = Properties.BooleanProperty(True)

    colorInter = Properties.ListProperty([1, 1, 1, 1])

    def __init__(self, **kwargs):
        super(InfoDayConfig, self).__init__(**kwargs)
        self.pos_hint = {'center_y': 0.5, 'center_x': 0.5}
        self.getAllInter()

    def saveConfig(self):
        #guardar las configs
        if self.ids.textinput.text == "":
            self.c_id = self.ids.textinput.hint_text
        else:
            self.c_id = self.ids.textinput.text
        dbWrapper.saveHora("hora", self.formatoHora, self.colorHora)
        dbWrapper.saveFecha("fecha", self.formatoFecha, self.colorFecha)
        dbWrapper.saveTemp("temp", self.formatoTemp, self.colorTemp, self.c_id)
        dbWrapper.saveClima("weather", self.formatoClima, self.c_id)
        dbWrapper.saveInfoState(self.activeInter)
        dbWrapper.saveInternationalConfig("inter", self.colorInter)

    def getAllInter(self):
        datos = dbWrapper.getAllInterByMonth(str(strftime('%m')))

        for j in datos:
            layout = BoxLayout(orientation='horizontal',
                               size_hint_y=None,
                               height=20,
                               padding=[-40, 0, 0, 0])
            layout.add_widget(Texto(text=str(j.dia)))
            layout.add_widget(
                Texto(text=str(j.info if len(j.info) < 25 else '...' +
                               j.info[10:35] + '...')))
            self.ids.todos.add_widget(layout)

    def pressedBack(self, widget):
        anim = Animation(pos_hint={"center_x": .5, "y": -.03}, duration=.1)
        anim += Animation(pos_hint={"center_x": .5, "y": 0}, duration=.1)
        anim.bind(on_complete=partial(self.goToMenuScreen))
        anim.start(widget)

    def goToMenuScreen(self, widget, selected):
        self.saveConfig()
        App.get_running_app().root.transition = FadeTransition(duration=.3)
        App.get_running_app().root.current = "menu"
Пример #3
0
class Keybind(Button):
    """
    Stores keybindings and manages actually sending them out of
    TabletKeyApp and to the next window.
    """
    bound_keys = kp.ListProperty([])
    tab_back = kp.BooleanProperty(False)
    position = kp.ListProperty([0, 0])

    def output(self) -> dict:
        """

        :return: A dictionary containing the vital binding properties
            of the Keybind so that they can be saved.
        """
        return dict(
            position=self.pos,
            binding='+'.join(self.bound_keys),
            tab_back=self.tab_back
        )

    def setup(self, name: str, binding: str, position: (list, tuple) = None,
              tab_back: bool = False) -> None:
        """
        Sets a Keybind button up, or overwrites the existing properties
        if used on an existing Keybind object.

        :param name: A string, the user-supplied name of the keybinding
            to display on the button.
        :param binding: A string with each keyboard key separated by a
            plus (+) sign.
        :param position: A list or tuple, currently mostly a
            placeholder for when user-specified Keybind button
            placement is implemented.
        :param tab_back: A boolean, indicates whether, when this
            Keybind is pressed, the user wants to immediately tab back
            to the TabletKeyApp window.
        :return: None
        """
        self.bound_keys = binding.split('+')
        self.tab_back = tab_back
        self.position = position if position is not None else [0, 0]
        self.text = name

    def send(self) -> None:
        """
        Uses pyautogui to send the contents of the Keybind to the next
        window.

        :return: None
        """
        pg.hotkey('alt', 'tab')
        # A slight delay is necessary to successfully input the
        # keystroke into the other window.
        time.sleep(0.1)
        pg.hotkey(*self.bound_keys)
        if self.tab_back:
            time.sleep(0.1)
            pg.hotkey('alt', 'tab')
Пример #4
0
class Apple(Widget):
    coord = props.ListProperty([250, 300])
    body = props.ObjectProperty(None)

    def __init__(self, canvas):
        super().__init__()
        self.canvas = canvas
        with self.canvas:
            Color(1, 0, 0)
            self.body = Ellipse(pos=self.coord, size=(SIZE, SIZE))

    def check_collision(self, coord):
        print(self.coord, coord)
        if coord[0] <= self.coord[0] + SIZE/2 <= coord[0] + SIZE \
            and coord[1] <= self.coord[1] + SIZE/2 <= coord[1] + SIZE:
            print("check_collision")
            return True
        return False

    def new_position(self, snake):
        print("new_position")
        while True:
            apple_x = random.randint(SIZE, Window.size[0] - SIZE)
            apple_y = random.randint(SIZE, Window.size[1] - SIZE)

            apple_x -= apple_x % SIZE
            apple_y -= apple_y % SIZE

            for segment in snake.body:
                if [apple_x, apple_y] == segment.pos:
                    continue

            self.coord = [apple_x, apple_y]
            self.body.pos = [apple_x, apple_y]
            return
Пример #5
0
class TempWidget(Image, EventDispatcher):
    text = Properties.StringProperty('')
    unit = Properties.StringProperty()
    c_id = Properties.StringProperty()
    chosenColor = Properties.ListProperty()

    def on_text(self, *_):
        # Just get large texture:
        l = Label(text=self.text)
        l.font_size = '1000dp'  # something that'll give texture bigger than phone's screen size
        l.color = self.color
        l.texture_update()
        # Set it to image, it'll be scaled to image size automatically:
        self.texture = l.texture

    def __init__(self, **kwargs):
        super(TempWidget, self).__init__(**kwargs)

        currentTemp = getTemp()
        self.chosenColor = currentTemp.color
        self.unit = currentTemp.formato
        self.c_id = currentTemp.c_id
        self.color = self.chosenColor
        self.bind(chosenColor=self.update_temp)
        #Temperature
        self.text = str(
            int(getWeatherReducedByCityId(self.c_id, self.unit)['temp'])) + "º"
        Clock.schedule_interval(self.update_temp, 200)

    def update_temp(self, *args):
        self.text = str(
            int(getWeatherReducedByCityId(self.c_id, self.unit)['temp'])) + "º"
        self.color = self.chosenColor
Пример #6
0
class TwitterConfig(Screen):

    colorInter = Properties.ListProperty([1, 1, 1, 1])
    activeInter = Properties.BooleanProperty(False)
    halign = Properties.StringProperty('left')

    def __init__(self, **kwargs):
        super(TwitterConfig, self).__init__(**kwargs)
        self.pos_hint = {'center_y': 0.5, 'center_x': 0.5}

    def changeHalign(self, halign):
        self.halign = halign

    def saveConfig(self):
        #guardar las configs
        print(self.activeInter)
        dbWrapper.saveTwitter(self.activeInter, self.colorInter, self.halign)

    def pressedBack(self, widget):
        anim = Animation(pos_hint={"center_x": .5, "y": -.03}, duration=.1)
        anim += Animation(pos_hint={"center_x": .5, "y": 0}, duration=.1)
        anim.bind(on_complete=partial(self.goToMenuScreen))
        anim.start(widget)

    def goToMenuScreen(self, widget, selected):
        self.saveConfig()
        App.get_running_app().root.transition = FadeTransition(duration=.3)
        App.get_running_app().root.current = "menu"
Пример #7
0
class ScatterColoredLabel(Scatter):
    background_color = Properties.ListProperty((0, 0, 0, 1))
    visible = Properties.BooleanProperty()
    saveOnDBEvent = Properties.ObjectProperty()
    noteId = Properties.NumericProperty()
    text = Properties.StringProperty()

    def on_pos(self, instance, value):
        try:
            self.saveOnDBEvent.cancel()
        except:
            logging.info('Notes: No previous event')
        self.saveOnDBEvent = Clock.schedule_once(self.saveOnDB, 5)

    def saveOnDB(self, dt):
        noteToSave = Notes(
            _id=self.noteId,
            pinned=self.visible,
            text=self.text,
            posX=self.pos[0],
            posY=self.pos[1],
            scale=self.scale,
            rotation=self.rotation,
            rgb=[
                self.background_color[0]*255,
                self.background_color[1]*255,
                self.background_color[2]*255,
                self.background_color[3],
            ],

        )
        noteToSave.save()

        logging.info('DB: Updated note with id: ' + str(self.noteId))
Пример #8
0
class AppMenuTextItem(ToggleButton, AbstractMenuItem):
    label = kp.ObjectProperty(None)
    text = kp.StringProperty('')
    font_size = kp.NumericProperty(14)
    color = kp.ListProperty([1, 1, 1, 1])

    def on_release(self):
        submenu = self.get_submenu()

        if self.state == 'down':
            root = self._root_parent
            submenu.bounding_box_widget = root.bounding_box if root.bounding_box else root.parent

            submenu.bind(visible=self.on_visible)
            submenu.show(self.x, self.y - 1)

            for sibling in self.siblings:
                if sibling.get_submenu() is not None:
                    sibling.state = 'normal'
                    sibling.get_submenu().hide()

            self.parent._setup_hover_timer()
        else:
            self.parent._cancel_hover_timer()
            submenu.hide()

    def on_visible(self, *args):
        submenu = self.get_submenu()
        if self.width > submenu.get_max_width():
            submenu.width = self.width

    def _check_submenu(self):
        super(AppMenuTextItem, self)._check_submenu()
        self.disabled = (self.get_submenu() is None)
Пример #9
0
class Hex(Label):
    tile_color = properties.ListProperty([0, 1, 0, 0.5])

    def __init__(self, **kwargs):
        super(Hex, self).__init__(**kwargs)
        for hue in range(0, 3):
            self.tile_color[hue] = random.random()
Пример #10
0
class Application(App):
    '''A form manager demonstrating the power of RecycleView's key_viewclass
    property.
    '''
    data = P.ListProperty()

    def build(self):
        root = Builder.load_string(KV)
        rv = root.ids.rv
        self.data = [
            self.create_random_input(rv, index) for index in range(20)
        ]

        return root

    def handle_update(self, value, index):
        if None not in (index, value):
            self.data[index]['value'] = value

    def create_random_input(self, rv, index):
        return choice((self.create_textinput, self.create_checkbox,
                       self.create_spinner))(rv, index)

    def create_spinner(self, rv, index):
        """
        create a dict of data for a spinner
        """
        return {
            'index': index,
            'widget': 'RVSpinner',
            'value': '',
            'values': [letter * 5 for letter in ascii_lowercase[:5]],
            'ready': True,
        }

    def create_checkbox(self, rv, index):
        """
        create a dict of data for a checkbox
        """
        return {
            'index': index,
            'widget': 'RVCheckBox',
            'value': choice((True, False)),
            'title': ''.join(choices(ascii_lowercase, k=10)),
            'ready': True,
        }

    def create_textinput(self, rv, index):
        """
        create a dict of data for a textinput
        """
        return {
            'index': index,
            'widget': 'RVTextInput',
            'value': ''.join(choices(ascii_lowercase, k=10)),
            'title': ''.join(choices(ascii_lowercase, k=10)),
            'ready': True,
        }
Пример #11
0
class GameApp(App):
    table_size = kp.ListProperty(calc_table_size(*Window.size))

    def build(self):
        self.width = Window.width
        self.height = Window.height
        self.game = Game()
        Clock.schedule_interval(self.game.update, 1.0 / FPS)
        return self.game
Пример #12
0
class CommandTerminal(KivyCmd):

    text = prop.StringProperty()
    ''' property where the logs are stored '''

    top_pannel_items = prop.ListProperty()

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        clearbtn = Factory.TopPanelButton(icon='fa-trash-o')
        self.top_pannel_items.append(clearbtn)
Пример #13
0
class UnorderedDeskWidget(GridLayout):

    cards = prop.ListProperty()

    def __init__(self, **kwargs):
        pass

    def on_place_on(self, *cards, **kwargs):
        pass

    def on_take_off(self, *cards, **kwargs):
        pass
Пример #14
0
class MenuBar(box.BoxLayout):

    '''Background color, in the format (r, g, b, a).'''
    background_color = prop.ListProperty([0.2, 0.2, 0.2, 1])
    separator_color = prop.ListProperty([0.8, 0.8, 0.8, 1])
    selected = prop.BooleanProperty(False)

    def __init__(self, **kwargs):
        self.itemsList = []
        super(MenuBar, self).__init__(**kwargs)

    def add_widget(self, item, index=0):
        if not isinstance(item, MenuItem):
            raise TypeError("MenuBar accepts only MenuItem widgets")
        super(MenuBar, self).add_widget(item, index)
        if index == 0:
            index = len(self.itemsList)
        self.itemsList.insert(index, item)

    def on_touch_down(self, touch):
        if self.collide_point(*touch.pos) == False:
            self.selected = False
        else:
            self.selected = True
        super(MenuBar, self).on_touch_down(touch)

    def on_selected(self, instance, value):
        for w in self.children:
            if isinstance(w, MenuSubmenu):
                if value:
                    w.activate_hover()
                else:
                    w.deactivate_hover()

    def close_all_menus(self):
        for ch in self.children:
            if isinstance(ch, MenuSubmenu):
                ch.close()
Пример #15
0
class Tile(Widget):
    tile = kp.ListProperty([0, 0])
    mapx = kp.NumericProperty()
    mapy = kp.NumericProperty()
    def __init__(self, **kwargs):
        super().__init__()
        # print("\nTile", kwargs, type(self))
        # tilex=col, tiley=row
        self.tile = [kwargs.get("tilex", 0), kwargs.get("tiley", 0)]

    def on_tile(self, *args):
        # print("on_tile", args, self.tile)
        self.mapx = self.tile[0] * GAME.get("tilesize")
        self.mapy = self.tile[1] * GAME.get("tilesize")
Пример #16
0
class ContextMenuText(ContextMenuItem):
    label = kp.ObjectProperty(None)
    submenu_postfix = kp.StringProperty(' ...')
    text = kp.StringProperty('')
    font_size = kp.NumericProperty(14)
    color = kp.ListProperty([1, 1, 1, 1])

    def __init__(self, *args, **kwargs):
        super(ContextMenuText, self).__init__(*args, **kwargs)

    @property
    def content_width(self):
        # keep little space for eventual arrow for submenus
        return self.label.texture_size[0] + 10
Пример #17
0
class MenuItem(widget.Widget):
    '''Background color, in the format (r, g, b, a).'''
    background_color_normal = prop.ListProperty([0.2, 0.2, 0.2, 1])
    background_color_down = prop.ListProperty([0.3, 0.3, 0.3, 1])
    background_color = prop.ListProperty([])
    separator_color = prop.ListProperty([0.8, 0.8, 0.8, 1])
    text_color_hovered = prop.ListProperty([1, 1, 1, 1])
    text_color_unhovered = prop.ListProperty([.7, .7, .7, 1])
    inside_group = prop.BooleanProperty(False)
    pass
Пример #18
0
class Chart(BoxLayout):
	data= kp.ListProperty([])
	def __init__(self,**kwargs):
		super().__init__(**kwargs)
		self.fig, self.ax1 = plt.subplots()
		self.ax1.plot([],[],'bo')
		self.mpl_canvas = self.fig.canvas
		self.add_widget(self.mpl_canvas)
		Clock.schedule_interval(self.update,1)
	def on_data(self,*args):
		self.ax1.clear()
		y = [i**2 for i in self.data]
		self.ax1.plot(self.data,y,'bo-',linewidth=5.0)
		self.mpl_canvas.draw_idle()
	def update(self,*args):
		self.data = random.sample(range(-10,10),5)
Пример #19
0
class DraggableColoredLabel(DragBehavior, Label):
    background_color = Properties.ListProperty((0, 0, 0, 1))
    visible = Properties.BooleanProperty()
    saveOnDBEvent = Properties.ObjectProperty()
    noteId = Properties.NumericProperty()

    def on_pos(self, instance, value):
        try:
            self.bringToFront()
            self.saveOnDBEvent.cancel()
        except:
            logging.info('Notes: No previous event')

        self.saveOnDBEvent = Clock.schedule_once(self.saveOnDB, 5)

    def bringToFront(self):
        parent = self.parent
        children = parent.children
        childOnTop = children[0]

        if (self != childOnTop):
            parent.remove_widget(self)
            parent.add_widget(self)

    def saveOnDB(self, dt):
        noteToSave = Notes(
            _id=self.noteId,
            pinned=self.visible,
            text=self.text,
            posX=self.pos[0],
            posY=self.pos[1],
            sizeX=self.size_hint[0],
            sizeY=self.size_hint[1],
            rgb=[
                self.background_color[0]*255,
                self.background_color[1]*255,
                self.background_color[2]*255,
                self.background_color[3],
            ],

        )
        noteToSave.save()

        logging.info('DB: Updated note with id: ' + str(self.noteId))
Пример #20
0
class InternationalConfig(Screen):
    colorInter = Properties.ListProperty([1, 1, 1, 1])
    activeInter = Properties.BooleanProperty(True)

    def __init__(self, **kwargs):
        super(InternationalConfig, self).__init__(**kwargs)
        self.pos_hint = {'center_y': 0.5, 'center_x': 0.5}
        self.getAllInter()

    def printt(self, switch):
        print(switch.active)

    def saveConfig(self):
        # guardar las configs
        dbWrapper.saveInternationalConfig(
            "inter",
            self.colorInter if self.activeInter == False else [1, 1, 1, 0])

    def getAllInter(self):
        datos = dbWrapper.getAllInterByMonth(str(strftime('%m')))

        for j in datos:
            layout = BoxLayout(orientation='horizontal',
                               size_hint_y=None,
                               height=20,
                               padding=[-40, 0, 0, 0])
            layout.add_widget(Texto(text=str(j.dia)))
            layout.add_widget(
                Texto(text=str(j.info if len(j.info) < 25 else '...' +
                               j.info[10:35] + '...')))
            self.ids.todos.add_widget(layout)

    def pressedBack(self, widget):
        anim = Animation(pos_hint={"center_x": .5, "y": -.03}, duration=.1)
        anim += Animation(pos_hint={"center_x": .5, "y": 0}, duration=.1)
        anim.bind(on_complete=partial(self.goToMenuScreen))
        anim.start(widget)

    def goToMenuScreen(self, widget, selected):
        self.saveConfig()
        App.get_running_app().root.transition = FadeTransition(duration=.3)
        App.get_running_app().root.current = "menu"
Пример #21
0
class CanvasWidget(Widget):
    colorLinea = Properties.ListProperty((1, 0, 0))
    grosorLinea = Properties.NumericProperty(10)

    def __init__(self, **kwargs):
        super(CanvasWidget, self).__init__(**kwargs)

    def on_touch_down(self, touch):
        if not self.disabled:
            with self.canvas:
                Color(*self.colorLinea, mode='rgb')
                d = self.grosorLinea
                w = self.grosorLinea*0.5
                Ellipse(pos=(touch.x - d / 2, touch.y - d / 2), size=(d, d))
                touch.ud['line'] = Line(
                    points=(touch.x, touch.y), size=(d, d), width=w)

    def on_touch_move(self, touch):
        if not self.disabled:
            touch.ud['line'].points += [touch.x, touch.y]
Пример #22
0
class ClockWidget(Image):
    text = Properties.StringProperty('')
    chosenColor = Properties.ListProperty()
    segundos = Properties.BooleanProperty()
    horas = Properties.StringProperty()

    def on_text(self, *_):
        # Just get large texture:z
        l = Label(text=self.text)
        l.font_size = '1000dp'  # something that'll give texture bigger than phone's screen size
        l.color = self.color
        l.texture_update()
        # Set it to image, it'll be scaled to image size automatically:
        self.texture = l.texture

    def __init__(self, **kwargs):
        super(ClockWidget, self).__init__(**kwargs)
        currentHora = getHora()
        self.chosenColor = currentHora.color
        self.segundos = currentHora.formato[1]
        self.horas = currentHora.formato[0]
        self.color = self.chosenColor
        self.text = datetime.now().strftime(
            self.update_secondsAndFormat(self.segundos, self.horas))
        Clock.schedule_interval(self.update_time, 1)

    def update_time(self, *args):
        self.text = datetime.now().strftime(
            self.update_secondsAndFormat(self.segundos, self.horas))
        self.color = self.chosenColor

    def update_secondsAndFormat(self, seconds, formato):
        if (seconds == True and formato == "24h"):
            return '%H:%M:%S'
        elif (seconds == True and formato == "12h"):
            return '%I:%M:%S %p'
        elif (seconds == False and formato == "24h"):
            return '%H:%M'
        else:
            return '%I:%M %p'
Пример #23
0
class ErrorLogger(BoxLayout):

    text = prop.StringProperty()
    ''' property where the logs are stored '''

    top_pannel_items = prop.ListProperty()

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        clearbtn = Factory.TopPanelButton(icon='fa-trash-o')
        clearbtn.bind(on_release=self.clear_logs)
        self.top_pannel_items.append(clearbtn)

    def log(self, msg):
        lines = self.text.splitlines()
        if len(lines) > MAX_LOG_LINES:  # clean previous logs
            self.text = '\n'.join(lines[int(MAX_LOG_LINES / 2):])
        self.text += msg + '\n'
        self.ids.scroll.scroll_y = 0

    def clear_logs(self, *args):
        self.text = ''
Пример #24
0
class ColoredLabelConfig(GridLayout):
    editing = Properties.BooleanProperty(False)
    noteid = Properties.NumericProperty()
    pinned = Properties.BooleanProperty()
    bcolor = Properties.ListProperty((0, 0, 0, 1))
    texto = Properties.StringProperty()

    def pinNote(self, noteId, pinned):
        ColoredLabel.visible = pinned != True
        self.pinned = pinned != True
        note = dbWrapper.findNoteById(noteId)
        note.pinned = pinned != True
        note.save()

    def on_editing(self, instance, value):
        if (value == False):
            nuevoTexto = self.ids.textValue.text
            noteToUpdate = Notes(_id=self.noteid, pinned=self.pinned, rgb=[
                                 self.bcolor[0]*255, self.bcolor[1]*255, self.bcolor[2]*255, 1], text=nuevoTexto)
            noteToUpdate.save()

    def deleteNote(self):
        dbWrapper.deleteNoteById(self.noteid)
Пример #25
0
class DateWidget(Image):
    text = Properties.StringProperty('')
    chosenColor = Properties.ListProperty()
    formato = Properties.StringProperty()

    def on_text(self, *_):
        # Just get large texture:
        l = Label(text=self.text)
        l.font_size = '1000dp'  # something that'll give texture bigger than phone's screen size
        l.color = self.color
        l.texture_update()
        # Set it to image, it'll be scaled to image size automatically:
        self.texture = l.texture

    def __init__(self, **kwargs):
        super(DateWidget, self).__init__(**kwargs)
        currentFecha = getFecha()
        self.chosenColor = currentFecha.color
        self.formato = currentFecha.formato
        self.color = self.chosenColor
        self.text = datetime.now().strftime(self.update_Format())
        Clock.schedule_interval(self.update_time, 60)

    def update_time(self, *args):
        self.text = datetime.now().strftime(self.update_Format())
        self.color = self.chosenColor

    def update_Format(self):
        if (self.formato == "dd/mm"):
            return '%d/%m'
        elif (self.formato == "dd/mm/yyyy"):
            return '%d/%m/%y'
        elif (self.formato == "mm/dd"):
            return '%m/%d'
        else:
            return '%m/%d/%y'
Пример #26
0
class ShadowBehavior(object):
    shadow_texture1 = props.ObjectProperty(None)
    shadow_pos1 = props.ListProperty([0, 0])
    shadow_size1 = props.ListProperty([0, 0])

    shadow_texture2 = props.ObjectProperty(None)
    shadow_pos2 = props.ListProperty([0, 0])
    shadow_size2 = props.ListProperty([0, 0])

    elevation = props.NumericProperty(1)

    _shadows = {
        1: (1, 3, 0.12, 1, 2, 0.24),
        2: (3, 6, 0.16, 3, 6, 0.23),
        3: (10, 20, 0.19, 6, 6, 0.23),
        4: (14, 28, 0.25, 10, 10, 0.22),
        5: (19, 38, 0.30, 15, 12, 0.22)
    }

    # Shadows for each elevation.
    # Each tuple is: (offset_y1, blur_radius1, color_alpha1, offset_y2, blur_radius2, color_alpha2)
    # The values are extracted from the css (box-shadow rule).

    def __init__(self, *args, **kwargs):
        super(ShadowBehavior, self).__init__(*args, **kwargs)
        self._update_shadow = _us = Clock.create_trigger(self._create_shadow)
        self.bind(size=_us, pos=_us, elevation=_us)

    def _create_shadow(self, *args):
        # print "update shadow"
        ow, oh = self.size[0], self.size[1]

        offset_x = 0

        # Shadow 1
        shadow_data = self._shadows[self.elevation]
        offset_y = shadow_data[0]
        radius = shadow_data[1]
        w, h = ow + radius * 6.0, oh + radius * 6.0
        t1 = self._create_boxshadow(ow, oh, radius, shadow_data[2])
        self.shadow_texture1 = t1
        self.shadow_size1 = w, h
        self.shadow_pos1 = self.x - \
            (w - ow) / 2. + offset_x, self.y - (h - oh) / 2. - offset_y

        # Shadow 2
        shadow_data = self._shadows[self.elevation]
        offset_y = shadow_data[3]
        radius = shadow_data[4]
        w, h = ow + radius * 6.0, oh + radius * 6.0
        t2 = self._create_boxshadow(ow, oh, radius, shadow_data[5])
        self.shadow_texture2 = t2
        self.shadow_size2 = w, h
        self.shadow_pos2 = self.x - \
            (w - ow) / 2. + offset_x, self.y - (h - oh) / 2. - offset_y

    def _create_boxshadow(self, ow, oh, radius, alpha):
        # We need a bigger texture to correctly blur the edges
        w = ow + radius * 6.0
        h = oh + radius * 6.0
        w = int(w)
        h = int(h)
        texture = Texture.create(size=(w, h), colorfmt='rgba')
        im = Image.new('RGBA', (w, h), color=(1, 1, 1, 0))

        draw = ImageDraw.Draw(im)
        # the rectangle to be rendered needs to be centered on the texture
        x0, y0 = (w - ow) / 2., (h - oh) / 2.
        x1, y1 = x0 + ow - 1, y0 + oh - 1
        draw.rectangle((x0, y0, x1, y1), fill=(0, 0, 0, int(255 * alpha)))
        im = im.filter(ImageFilter.GaussianBlur(radius * RAD_MULT))
        texture.blit_buffer(im.tobytes(), colorfmt='rgba', bufferfmt='ubyte')
        return texture
Пример #27
0
class MapWidget(Widget):
    draw_color = properties.ListProperty([0, 0, 0])
    background = properties.ListProperty([1, 1, 1])
    point_color = properties.ListProperty([0, 0, 0])
    point_size = properties.ListProperty([10, 10])
    draw_from_text_file = properties.BooleanProperty(False)
    dragging_map = properties.BooleanProperty(False)
    translation = properties.ListProperty([0, 0])
    translation_last_point = properties.ListProperty([0, 0])

    # data_file_path = properties.StringProperty()

    def __init__(self, **kwargs):
        working_dir = Path.cwd()
        self.data_file_path = str(Path(str(working_dir) + "/" + DATA_FILE))
        self.objects = []  # Contains all objects that is drawn on the screen
        # Create empty file
        if not Path.exists(Path(self.data_file_path)):
            open(self.data_file_path, "w")
        super(MapWidget, self).__init__(**kwargs)
        self.bind(pos=self.resize, size=self.resize)

    def resize(self, *args):
        self.pos = self.pos
        self.size = self.size
        self.clear_canvas()

        if self.draw_from_text_file:
            self.draw_from_data_file()

    def on_touch_down(self, touch):
        if self.inside_widget(touch, "touch") and self.draw_from_text_file:
            self.dragging_map = True
            self.translation_last_point = [touch.x, touch.y]

    def on_touch_move(self, touch):
        # print("Touch: %f, %f" % (touch.x - self.center_x, touch.y - self.center_y))
        if self.dragging_map:
            self.translation[0] += -(self.translation_last_point[0] - touch.x
                                     )  # - self.center_x
            self.translation[1] += -(self.translation_last_point[1] - touch.y
                                     )  #- self.center_y
            self.translation_last_point = [touch.x, touch.y]
            self.clear_canvas()
            if self.draw_from_text_file:
                self.draw_from_data_file()

    def on_touch_up(self, touch):
        if self.inside_widget(touch, "touch"):
            if self.dragging_map:
                self.dragging_map = False
                self.translation[0] += -(self.translation_last_point[0] -
                                         touch.x)
                self.translation[1] += -(self.translation_last_point[1] -
                                         touch.y)

    def clear_canvas(self):
        for obj in self.objects:
            self.canvas.remove(obj)

        self.objects.clear()
        if not self.dragging_map:
            self.draw_from_text_file = False

    def inside_widget(self, touch, type):
        bottom_left_x = self.center_x - self.width / 2
        bottom_left_y = self.center_y - self.height / 2
        top_right_x = self.center_x + self.width / 2
        top_right_y = self.center_y + self.height / 2
        if type == "touch":
            x = touch.pos[0]
            y = touch.pos[1]
            return x >= bottom_left_x and x <= top_right_x and y >= bottom_left_y and y <= top_right_y
        elif type == "pos":
            x = touch[0]
            y = touch[1]
            return x >= bottom_left_x and x <= top_right_x and y >= bottom_left_y and y <= top_right_y

    def draw_from_data_file(self):
        if not self.draw_from_text_file:
            self.draw_from_text_file = True

        with open(self.data_file_path, "r") as input_file:
            for line in input_file:
                line = line.rstrip()
                line = line.split(",")
                position = [
                    self.center_x + int(line[0]) + self.translation[0],
                    self.center_y + int(line[1]) + self.translation[1]
                ]

                if self.inside_widget(position, "pos"):
                    self.obj = InstructionGroup()
                    self.obj.add(Color(*self.point_color))
                    self.obj.add(Ellipse(pos=position, size=self.point_size))
                    self.objects.append(self.obj)
                    self.canvas.add(self.obj)
Пример #28
0
class Snake(App):
    sprite_size = kp.NumericProperty(SPRITE_SIZE)

    head = kp.ListProperty([0, 0])
    snake = kp.ListProperty()
    length = kp.NumericProperty(LENGTH)

    fruit = kp.ListProperty([0, 0])
    fruit_sprite = kp.ObjectProperty(Fruit)

    direction = kp.StringProperty(RIGHT, options=(LEFT, UP, RIGHT, DOWN))
    buffer_direction = kp.StringProperty(RIGHT, options=(LEFT, UP, RIGHT, DOWN, ''))
    block_input = kp.BooleanProperty(False)

    alpha = kp.NumericProperty(0)

    def on_start(self):
        self.fruit_sprite = Fruit()
        self.fruit = self.new_fruit_location
        self.head = self.new_head_location
        Clock.schedule_interval(self.move, MOVESPEED)
        Window.bind(on_keyboard=self.key_handler)

    def on_fruit(self, *args):
        self.fruit_sprite.coord = self.fruit
        if not self.fruit_sprite.parent:
            self.root.add_widget(self.fruit_sprite)

    def key_handler(self, _, __, key, *____):
        try:
            self.try_change_direction(direction_keys[key])
        except KeyError:
            pass

    def try_change_direction(self, new_direction):
        if direction_group[new_direction] != direction_group[self.direction]:
            if self.block_input:
                self.buffer_direction = new_direction
            else:
                self.direction = new_direction
                self.block_input = True

    def on_head(self, *args):
        self.snake = self.snake[-self.length:]+[self.head]

    def on_snake(self, *args):
        for index, coord in enumerate(self.snake):
            sprite = SPRITES[index]
            sprite.coord = coord
            if not sprite.parent:
                self.root.add_widget(sprite)

    @property
    def new_head_location(self):
        return [randint(2, dim - 2)for dim in[COLS, ROWS]]

    @property
    def new_fruit_location(self):
        while True:
            fruit = [randint(2, dim)for dim in[COLS, ROWS]]
            if fruit not in self.snake and fruit != self.fruit:
                return fruit

    def move(self, *args):
        self.block_input = False
        new_head = [sum(x) for x in zip(self.head, direction_values[self.direction])]
        if not self.check_in_bounds(new_head) or new_head in self.snake:
            return self.die()
        if new_head == self.fruit:
            self.length += 1
            self.fruit = self.new_fruit_location
        if self.buffer_direction:
            self.try_change_direction(self.buffer_direction)
            self.buffer_direction = ''
        self.head = new_head

    def check_in_bounds(self, pos):
        return all(0 <= pos[x] < dim for x, dim in enumerate([COLS, ROWS]))

    def die(self):
        self.root.clear_widgets()
        self.alpha = ALPHA
        Animation(alpha=0, duration=MOVESPEED).start(self)

        self.snake.clear()
        self.length = LENGTH
        self.fruit = self.new_fruit_location
        self.head = self.new_head_location
Пример #29
0
class Sprite(Widget):
    coord = kp.ListProperty([0, 0])
    bgcolor = kp.ListProperty([0, 0, 0, 0])
Пример #30
0
class GlobalContainer(box.BoxLayout):

    graph_list = prop.ListProperty([])
    active_graph = prop.ObjectProperty(None)
    name_manager = NameManager.Instance()
    show_sidepanel = prop.BooleanProperty(True)
    modestr = prop.StringProperty('insert')
    itemstr = prop.StringProperty('atom')

    modes = {'insert': asp.Mode.INSERT, 'select': asp.Mode.SELECT}
    items = {
        'atom': asp.Item.ATOM,
        'ellipse': asp.Item.ELLIPSE,
        'rectangle': asp.Item.SQUARE
    }

    def __init__(self, **kwargs):
        super(GlobalContainer, self).__init__(**kwargs)
        self._keyboard = None
        self.request_keyboard()
        self.working_dir = './'
        self.tutorial = None
        self.popup_stack = []
        window.Window.bind(on_resize=self.on_resize)

        if DEBUG:
            self.tracker = ClassTracker()
            self.tracker.track_object(MenuButton)
            self.all_objects = muppy.get_objects()

    def request_keyboard(self):
        self._keyboard = window.Window.request_keyboard(
            self._keyboard_release, self)
        self._keyboard.bind(on_key_down=self._on_keyboard_down)

    def _keyboard_catch(self):
        self._keyboard.bind(on_key_down=self._on_keyboard_down)

    def _keyboard_release(self):
        self._keyboard.unbind(on_key_down=self._on_keyboard_down)
        #self._keyboard = None

    def _on_keyboard_down(self, keyboard, keycode, text, modifiers):
        if keycode[1] == 'escape':
            base.stopTouchApp()
        elif keycode[1] == 'd':
            self.set_mode('insert')
        elif keycode[1] == 's':
            self.set_mode('select')
        elif keycode[1] == 'w':
            self.set_item('atom')
        elif keycode[1] == 'e':
            self.set_item('ellipse')
        elif keycode[1] == 'r':
            self.set_item('rectangle')
        elif keycode[1] == 'p':
            self.active_graph.show_tree(0)
        elif keycode[1] == 'o':
            self.view_symbolic_formula()
        elif keycode[1] == 'n':
            self.show_gringo_query()
        elif keycode[1] == 'g':
            self.show_save()
        elif keycode[1] == 'l':
            self.show_load()
        elif keycode[1] == 'y':
            print self.name_manager.get_all()
            print asp.Line.get_all_lines()
        elif keycode[1] == 't':
            self.toggle_sidepanel()
        elif keycode[1] == 'tab':
            if not self.show_sidepanel:
                self.toggle_sidepanel()
            self.ids.atom_input.focus = True
        elif keycode[1] == '.':
            if DEBUG:
                rb = refbrowser.InteractiveBrowser(self)
                rb.main()

                # self.all_objects = muppy.get_objects()
                # sum1 = summary.summarize(self.all_objects)
                # summary.print_(sum1)

                # self.tracker.create_snapshot()
                # self.tracker.stats.print_summary()
        return True

    def _focus_name_list(self, value):
        if value and (asp.AtomWidget.active_atom is not None):
            previous_name = asp.AtomWidget.active_atom.name
            for button in self.ids.name_list.children:
                if (button.text == previous_name) and (button.state != 'down'):
                    button.trigger_action()
        elif value:
            if self.ids.name_list.children:
                self.ids.name_list.children[-1].trigger_action()
        else:
            for button in self.ids.name_list.children:
                if button.state == 'down':
                    button.trigger_action()

    def on_resize(self, window, width, height):
        if self.show_sidepanel:
            self.ids.sidepanel.width = self.width * .15
        self.active_graph.size = self.ids.stencilview.size

    def toggle_sidepanel(self):
        self.show_sidepanel = not self.show_sidepanel
        if self.show_sidepanel:
            width = self.width * .15
        else:
            width = 0
        anim.Animation(width=width, d=.15,
                       t='out_quart').start(self.ids.sidepanel)
        if not self.show_sidepanel:
            self.ids.sidepanel.focus = False
            # Also release keyboard
        #self.update_sourcecode()

    def update_atom_editor(self, name):
        editor = self.ids.atom_editor
        if name == '':
            editor.disabled = True
        else:
            if editor.disabled:
                editor.disabled = False
            atom = self.name_manager.get(name)
            editor.update(atom)

    def update_atom(self,
                    name,
                    new_name='',
                    new_hook_points=[],
                    is_constant=False):
        atom = self.name_manager.get(name)
        if new_name <> '':
            atom.name = new_name
        if len(new_hook_points) == 4:
            atom.hook_points = new_hook_points
            # print id(atom.hook_points)
        atom.is_constant = is_constant

    def register_atom(self,
                      name,
                      hooks=[False, False, False, False],
                      is_constant=False):
        if name == '':
            return
        children = self.ids.name_list.children
        new_button = None
        name_to_insert = name
        i = len(children) - 1

        # If the name doesn't exist, register atom
        if self.name_manager.get(name) is None:
            self.name_manager.register(name, asp.Atom(name, hooks,
                                                      is_constant))
            # print id(self.name_manager.get(name).hook_points)

        # Insert in name_list sorted by name
        while i >= 0:
            if children[i].text < name_to_insert:
                #print children[i].text, '<',  name_to_insert
                pass
            elif children[i].text == name_to_insert:
                # Already exists
                if children[i].state != 'down':
                    children[i].trigger_action()
                return
            elif children[i].text > name_to_insert:
                #print children[i].text, '>',  name_to_insert
                temp = children[i].text
                children[i].text = name_to_insert
                name_to_insert = temp
                if new_button == None:
                    new_button = children[i]
            i -= 1

        self.ids.name_list.add_widget(AtomSelectionButton(text=name_to_insert))
        if new_button == None:
            new_button = children[0]
        if new_button.state == 'down':
            asp.AtomWidget.active_atom = self.name_manager.get(name)
            self.update_atom_editor(name)
            self.set_item('atom')
        else:
            new_button.trigger_action()

    def rename_atom(self, new_name):
        old_name = ''
        for button in self.ids.name_list.children:
            if button.state == 'down':
                old_name = button.text
                selected_button = button
        if (old_name != '') and (new_name != ''):
            try:
                atom = self.name_manager.get(old_name)
                exists = self.name_manager.get(new_name)
                assert atom is not None
                assert exists is None
            except AssertionError:
                #self.show_error('Name already exists.')
                print 'Name already exists.'
                return
            selected_button.text = new_name
            atom.name = new_name
            self.name_manager.unregister(old_name)
            self.name_manager.register(new_name, atom)
            self.update_atom_editor(new_name)

    def delete_atom(self):
        for button in self.ids.name_list.children:
            if button.state == 'down':
                self.name_manager.unregister(button.text)
                self.active_graph.delete_atom(button.text)
                asp.AtomWidget.active_atom = None
                self.ids.name_list.remove_widget(button)
                self.update_atom_editor('')

    def clear_atoms(self):
        self.ids.name_list.clear_widgets()
        self.name_manager.clear()
        self.update_atom_editor('')
        asp.AtomWidget.active_atom = None

    def new_graph(self):
        # TODO: Migrate to tab system
        asp.Line.clear_lines()
        self.clear_atoms()
        if self.active_graph is None:
            g = asp.RootWidget()
            self.graph_list.append(g)
            self.active_graph = g
            self.ids.stencilview.add_widget(g)
        else:
            self.active_graph.delete_tree()

    def close_graph(self):
        if self.active_graph is not None:
            asp.Line.clear_lines()
            self.active_graph.delete_tree()
            self.active_graph.delete_root()
            self.clear_atoms()
            self.graph_list.pop()
            self.active_graph = None

    def set_mode(self, mode):
        try:
            prev_mode = self.active_graph.mode
            new_mode = self.modes[mode]
            if new_mode == asp.Mode.INSERT:
                self.active_graph.show_hooks()
            else:
                if prev_mode == asp.Mode.INSERT:
                    self.active_graph.hide_hooks()
            self.active_graph.mode = new_mode
            self.modestr = mode
        except KeyError as err:
            print 'ERROR: Invalid mode {0} requested.'.format(str(err))

    def set_item(self, item):
        try:
            self.active_graph.item = self.items[item]
            self.itemstr = item
        except KeyError as err:
            print 'ERROR: Invalid item {0} requested.'.format(str(err))
        except AttributeError:
            pass
        if item == 'atom':
            self._focus_name_list(True)
        else:
            self._focus_name_list(False)

    def push_popup(self, popup):
        self.popup_stack.append(popup)
        popup.open()

    def dismiss_popup(self):
        popup = self.popup_stack.pop()
        popup.dismiss()

    def show_rename_atom(self):
        content = TextInputDialog(caption="Enter new name",
                                  validate_callback=self.rename_atom,
                                  cancel=self.dismiss_popup)
        p = CustomPopup(self,
                        title="Rename atom",
                        content=content,
                        size_hint=(0.4, 0.25))
        self.push_popup(p)

    def show_load(self):
        content = LoadDialog(load=self.load, cancel=self.dismiss_popup)
        content.ids.filechooser.path = self.working_dir
        p = CustomPopup(self,
                        title="Load file",
                        content=content,
                        size_hint=(0.9, 0.9))
        self.push_popup(p)

    def show_save(self):
        content = SaveDialog(save=self.save, cancel=self.dismiss_popup)
        content.ids.filechooser.path = self.working_dir
        p = CustomPopup(self,
                        title="Save file",
                        content=content,
                        size_hint=(0.9, 0.9))
        self.push_popup(p)

    def show_export(self):
        content = ExportDialog(export=self.export, cancel=self.dismiss_popup)
        content.ids.filechooser.path = self.working_dir
        p = CustomPopup(self,
                        title="Export file",
                        content=content,
                        size_hint=(0.9, 0.9))
        self.push_popup(p)

    def show_gringo_query(self):
        caption = "Enter desired predicates separated by commas"
        content = TextInputDialog(caption=caption,
                                  validate_callback=self.gringo_query,
                                  dismiss_on_validate=False,
                                  focus=False,
                                  cancel=self.dismiss_popup)
        p = CustomPopup(self,
                        title="Output predicates",
                        content=content,
                        size_hint=(0.4, 0.25))
        self.push_popup(p)

    def show_stable_models(self, solver):
        models = solver.get_models()
        content = None
        if len(models) == 0:
            content = ErrorDialog('Unsatisfiable', cancel=self.dismiss_popup)
        else:
            solver.generate_graph(models[0])
            content = StableModelDialog(solver, cancel=self.dismiss_popup)
            content.ids.img.reload()
        p = CustomPopup(self,
                        catch_keyboard=False,
                        title="Stable Models",
                        content=content,
                        size_hint=(0.9, 0.9))
        self.push_popup(p)

    def show_error(self, err_str):
        content = ErrorDialog(err_str, cancel=self.dismiss_popup)
        p = CustomPopup(self,
                        catch_keyboard=False,
                        title="Error",
                        content=content,
                        size_hint=(0.4, 0.3))
        self.push_popup(p)

    def show_about(self):
        content = AboutDialog(cancel=self.dismiss_popup)
        p = CustomPopup(self,
                        catch_keyboard=False,
                        title="About " + __title__,
                        content=content,
                        size_hint=(0.5, 0.5))
        self.push_popup(p)

    def load(self, path, filename):
        self.close_graph()
        self.working_dir = path

        try:
            f = os.path.join(path, filename[0])
            # Temporal line storage. Its contents are arranged as follows:
            # { line_id: (graph, hook_list) , ... }
            lines = {}
            with open(f, 'r') as stream:
                for line in stream:
                    if line.startswith(NameParser.TOKENS['name']):
                        name, hooks, is_constant = NameParser.parse_name(line)
                        self.register_atom(name, hooks, is_constant)
                    if line.startswith(NameParser.TOKENS['line']):
                        line_id, graph = NameParser.parse_line(line)
                        lines[line_id] = (graph, [None] * len(graph))

            new_graph = lang.Builder.load_file(f)
            self.ids.stencilview.add_widget(new_graph)
            self.active_graph = new_graph
            #self.graph_list.pop()
            self.graph_list.append(new_graph)
            for w in self.active_graph.walk(restrict=True):
                if isinstance(w, asp.AtomWidget):
                    w._deferred_init()
                    for i in w.get_line_info():
                        line_id = i[0]
                        hook_index = i[1]
                        lines[line_id][1][hook_index] = i[2]
                elif isinstance(w, asp.NexusWidget):
                    for i in w.line_info:
                        line_id = i[0]
                        hook_index = i[1]
                        lines[line_id][1][hook_index] = w

            for line, info in lines.iteritems():
                print line, info
                asp.Line.build_from_graph(info[0], info[1])

            self.set_mode(self.modestr)
            self.set_item(self.itemstr)
            self.dismiss_popup()
        except (KeyboardInterrupt, SystemExit):
            raise
        except:
            self.dismiss_popup()
            self.close_graph()
            self.new_graph()
            self.show_error('Corrupted file.')

    def save(self, path, filename):
        self.working_dir = path
        with open(os.path.join(path, filename), 'w') as stream:
            stream.write('#:kivy 1.0.9\n\n')
            for (name, atom) in self.name_manager.get_all():
                stream.write(
                    NameParser.get_name_str(name, atom.hook_points,
                                            atom.is_constant))
            for line in asp.Line.get_all_lines():
                stream.write(
                    NameParser.get_line_str(line.line_id,
                                            line.get_full_graph()))
            stream.write('\n')
            stream.write(self.active_graph.get_tree(0))
        self.dismiss_popup()

    def export(self, path, filename):
        _, ext = os.path.splitext(filename)
        if ext == '.png':
            self.active_graph.export_to_png(os.path.join(path, filename))
        elif ext == '.lp':
            rpn = self.active_graph.get_formula_RPN()
            constants = self.active_graph.get_constants()
            solver = eg_solver.Solver()
            solver.set_formula(rpn, constants)
            rules = solver.generate_asp_rules()
            with open(os.path.join(path, filename), 'w') as stream:
                for r in rules:
                    stream.write(r)
                    stream.write('\n')
        else:
            error_str = 'File extension not supported.'
            print error_str
            self.show_error(error_str)
            return
        self.dismiss_popup()

    def highlight_variables(self):
        self.active_graph.highlight_variables()

    def view_symbolic_formula(self):
        print self.active_graph.get_formula()

    def gringo_query(self, show_predicates):
        def generate_show_statements(predicates):
            pred_list = predicates.split(',')
            pred_list = map(lambda s: s.strip(), pred_list)
            n_args = (lambda name: self.name_manager.get(name).hook_points.
                      count(True))
            pred_list = [p + '/' + str(n_args(p)) for p in pred_list]
            show_list = ['#show {0}.'.format(p) for p in pred_list]
            return show_list

        self.dismiss_popup()

        rpn = self.active_graph.get_formula_RPN()
        rpn = norm.LIT.TRUE if rpn == '' else rpn
        constants = self.active_graph.get_constants()
        print 80 * '-'
        print 'RPN formula:\n', rpn

        solver = eg_solver.Solver()
        result = ''
        try:
            show_statements = []
            if show_predicates:
                try:
                    show_statements = generate_show_statements(show_predicates)
                except Exception:
                    pass
            solver.set_formula(rpn, constants)
            result = solver.solve(show=show_statements)
        except norm.MalformedFormulaError:
            self.show_error('Malformed formula.')
            return
        except RuntimeError, e:
            print e
            self.show_error(str(e))
            return
        self.show_stable_models(solver)