Beispiel #1
0
    def present(self, client, pos):
        client = client or get_root()
        self.topleft = client.local_to_global(pos)
        focus = get_focus()
        font = self.font
        h = font.get_linesize()
        items = self._items
        margin = self.margin
        if self.scrolling:
            height = h * self.scroll_items + h
        else:
            height = h * len(items) + h
        w1 = w2 = 0
        for item in items:
            item.enabled = self.command_is_enabled(item, focus)
            w1 = max(w1, font.size(item.text)[0])
            w2 = max(w2, font.size(item.keyname)[0])
        width = w1 + 2 * margin
        self._key_margin = width
        if w2 > 0:
            width += w2 + margin
        if self.scrolling:
            width += self.scroll_button_size
        self.size = (width, height)
        self._hilited = None

        root = get_root()
        self.rect.clamp_ip(root.rect)

        return Dialog.present(self, centered=False)
Beispiel #2
0
    def present(self, client, pos):
        client = client or self.root
        self.topleft = client.local_to_global(pos)
        focus = self.handler or get_focus()
        font = self.font
        h = font.get_linesize()
        items = self._items
        margin = self.margin
        if self.scrolling:
            height = h * self.scroll_items + h
        else:
            height = h * len(items) + h
        w1 = w2 = 0
        for item in items:
            item.enabled = self.command_is_enabled(item, focus)
            w1 = max(w1, font.size(item.text)[0])
            w2 = max(w2, font.size(item.keyname)[0])
        width = w1 + 2 * margin
        self._key_margin = width
        if w2 > 0:
            width += w2 + margin
        if self.scrolling:
            width += self.scroll_button_size
        self.size = (width, height)
        self._hilited = None

        self.rect.clamp_ip(self.root.rect)

        return Dialog.present(self, centered=False)
Beispiel #3
0
	def present(self, client, pos):
		client = client or get_root()
		self.topleft = client.local_to_global(pos)
		focus = get_focus()
		font = self.font
		h = font.get_linesize()
		items = self._items
		margin = self.margin
		height = h * len(items) + h
		w1 = w2 = 0
		for item in items:
			item.enabled = self.command_is_enabled(item, focus)
			w1 = max(w1, font.size(item.text)[0])
			w2 = max(w2, font.size(item.keyname)[0])
		width = w1 + 2 * margin
		self._key_margin = width
		if w2 > 0:
			width += w2 + margin
		self.size = (width, height)
		self._hilited = None
		return Dialog.present(self, centered = False)
Beispiel #4
0
class RootWidget(Widget):
    #  surface   Pygame display surface
    #  is_gl     True if OpenGL surface

    redraw_every_frame = False
    bonus_draw_time = False
    _is_gl_container = True

    def __init__(self, surface):
        global root_widget
        Widget.__init__(self, surface.get_rect())
        self.surface = surface
        root_widget = self
        widget.root_widget = self
        self.is_gl = surface.get_flags() & OPENGL != 0
        self.idle_handlers = []
        self.editor = None
        self.selectTool = None
        self.movementMath = [-1, 1, 1, -1, 1, -1]
        self.movementNum = [0, 0, 2, 2, 1, 1]
        self.cameraMath = [-1., 1., -1., 1.]
        self.cameraNum = [0, 0, 1, 1]
        self.notMove = False
        self.nudge = None
        self.testTime = None
        self.testTimeBack = 0.4
        self.nudgeDirection = None
        self.sessionStolen = False
        self.sprint = False
        self.filesToChange = []

    def get_modifiers(self):
        """Returns the 'modifiers' global object."""
        return modifiers

    def get_nudge_block(self):
        return self.selectTool.panel.nudgeBlocksButton

    def take_screenshot(self):
        try:
            os.mkdir(os.path.join(directories.getCacheDir(), "screenshots"))
        except OSError:
            pass
        screenshot_name = os.path.join(directories.getCacheDir(), "screenshots", time.strftime("%Y-%m-%d (%I-%M-%S-%p)") + ".png")
        pygame.image.save(pygame.display.get_surface(), screenshot_name)
        self.diag = Dialog()
        lbl = Label(_("Screenshot taken and saved as '%s'") % screenshot_name, doNotTranslate=True)
        folderBtn = Button("Open Folder", action=self.open_screenshots_folder)
        btn = Button("Ok", action=self.screenshot_notify)
        buttonsRow = Row((btn, folderBtn))
        col = Column((lbl, buttonsRow))
        self.diag.add(col)
        self.diag.shrink_wrap()
        self.diag.present()

    def open_screenshots_folder(self):
        from mcplatform import platform_open
        platform_open(os.path.join(directories.getCacheDir(), "screenshots"))
        self.screenshot_notify()

    def screenshot_notify(self):
        self.diag.dismiss()

    @staticmethod
    def set_timer(ms):
        pygame.time.set_timer(USEREVENT, ms)

    def run(self):
        self.run_modal(None)

    captured_widget = None

    def capture_mouse(self, widget):
        # put the mouse in "virtual mode" and pass mouse moved events to the
        # specified widget
        if widget:
            pygame.mouse.set_visible(False)
            pygame.event.set_grab(True)
            self.captured_widget = widget
        else:
            pygame.mouse.set_visible(True)
            pygame.event.set_grab(False)
            self.captured_widget = None

    frames = 0
    hover_widget = None

    def fix_sticky_ctrl(self):
        self.ctrlClicked = -1

    def run_modal(self, modal_widget):
        if self.editor is None:
            self.editor = self.mcedit.editor
            self.selectTool = self.editor.toolbar.tools[0]
        old_captured_widget = None

        if self.captured_widget:
            old_captured_widget = self.captured_widget
            self.capture_mouse(None)

        global last_mouse_event, last_mouse_event_handler
        global top_widget, clicked_widget
        is_modal = modal_widget is not None
        modal_widget = modal_widget or self
        #from OpenGL import GL

        try:
            old_top_widget = top_widget
            top_widget = modal_widget
            was_modal = modal_widget.is_modal
            modal_widget.is_modal = True
            modal_widget.modal_result = None
            if not modal_widget.focus_switch:
                modal_widget.tab_to_first()
            if clicked_widget:
                clicked_widget = modal_widget
            num_clicks = 0
            last_click_time = start_time
            last_click_button = False
            self.bonus_draw_time = False

            while modal_widget.modal_result is None:
                try:
                    if not self.mcedit.version_checked:
                        if not self.mcedit.version_lock.locked():
                            self.mcedit.version_checked = True
                            self.mcedit.check_for_version()

                    self.hover_widget = self.find_widget(pygame.mouse.get_pos())
                    if not self.bonus_draw_time:
                        self.bonus_draw_time = True
                        if self.is_gl:
                            self.gl_clear()
                            self.gl_draw_all(self, (0, 0))
                            GL.glFlush()
                        else:
                            self.draw_all(self.surface)
                        pygame.display.flip()
                        self.frames += 1

                    events = pygame.event.get()
                    if not events:
                        self.call_idle_handlers()

                    for event in events:
                        type = event.type
                        if type == QUIT:
                            self.quit()
                        elif type == MOUSEBUTTONDOWN:
                            self.bonus_draw_time = False
                            t = datetime.now()
                            if t - last_click_time <= double_click_time and event.button == last_click_button:
                                num_clicks += 1
                            else:
                                num_clicks = 1
                            last_click_button = event.button
                            last_click_time = t
                            event.dict['num_clicks'] = num_clicks
                            add_modifiers(event)
                            mouse_widget = self.find_widget(event.pos)
                            if self.captured_widget:
                                mouse_widget = self.captured_widget

                            if not mouse_widget.is_inside(modal_widget):
                                mouse_widget = modal_widget
                            clicked_widget = mouse_widget
                            last_mouse_event_handler = mouse_widget
                            last_mouse_event = event
                            mouse_widget.notify_attention_loss()
                            mouse_widget.handle_mouse('mouse_down', event)
                        elif type == MOUSEMOTION:
                            self.bonus_draw_time = False
                            add_modifiers(event)
                            modal_widget.dispatch_key('mouse_delta', event)
                            last_mouse_event = event

                            mouse_widget = self.update_tooltip(event.pos)

                            if clicked_widget:
                                last_mouse_event_handler = clicked_widget
                                clicked_widget.handle_mouse('mouse_drag', event)
                            else:
                                if not mouse_widget.is_inside(modal_widget):
                                    mouse_widget = modal_widget
                                last_mouse_event_handler = mouse_widget
                                mouse_widget.handle_mouse('mouse_move', event)
                        elif type == MOUSEBUTTONUP:
                            add_modifiers(event)
                            self.bonus_draw_time = False
                            mouse_widget = self.find_widget(event.pos)
                            if self.captured_widget:
                                mouse_widget = self.captured_widget
                            if clicked_widget:
                                last_mouse_event_handler = clicked_widget
                                event.dict['clicked_widget'] = clicked_widget
                            else:
                                last_mouse_event_handler = mouse_widget
                                event.dict['clicked_widget'] = None

                            last_mouse_event = event
                            clicked_widget = None
                            last_mouse_event_handler.handle_mouse('mouse_up', event)
                        elif type == KEYDOWN:
                            key_down = event.key
                            set_modifier(key_down, True)
                            add_modifiers(event)
                            self.bonus_draw_time = False
                            keyname = self.getKey(event)
                            if keyname == config.keys.takeAScreenshot.get():
                                self.take_screenshot()

                            self.send_key(modal_widget, 'key_down', event)
                            if last_mouse_event_handler:
                                event.dict['pos'] = last_mouse_event.pos
                                event.dict['local'] = last_mouse_event.local
                                last_mouse_event_handler.setup_cursor(event)
                        elif type == KEYUP:
                            key_up = event.key
                            set_modifier(key_up, False)
                            add_modifiers(event)
                            self.bonus_draw_time = False
                            keyname = self.getKey(event)
                            if keyname == config.keys.showBlockInfo.get() and self.editor.toolbar.tools[0].infoKey == 1:
                                self.editor.toolbar.tools[0].infoKey = 0
                                self.editor.mainViewport.showCommands()
                            if self.nudgeDirection is not None:
                                keyname = self.getKey(movement=True, keyname=key.name(key_up))
                                for i, move_key in enumerate(self.editor.movements):
                                    if keyname == move_key and i == self.nudgeDirection:
                                        self.nudgeDirection = None
                                        self.testTime = None
                                        self.testTimeBack = 0.4

                            self.send_key(modal_widget, 'key_up', event)
                            if last_mouse_event_handler:
                                event.dict['pos'] = last_mouse_event.pos
                                event.dict['local'] = last_mouse_event.local
                                last_mouse_event_handler.setup_cursor(event)
                        elif type == MUSIC_END_EVENT:
                            self.music_end()
                        elif type == USEREVENT:
                            make_scheduled_calls()
                            if not is_modal:
                                if self.redraw_every_frame:
                                    self.bonus_draw_time = False
                                else:
                                    self.bonus_draw_time = True
                                if last_mouse_event_handler:
                                    event.dict['pos'] = last_mouse_event.pos
                                    event.dict['local'] = last_mouse_event.local
                                    add_modifiers(event)
                                    last_mouse_event_handler.setup_cursor(event)
                                self.begin_frame()
                        elif type == VIDEORESIZE:
                            self.bonus_draw_time = False
                            self.size = (event.w, event.h)
                        elif type == VIDEOEXPOSE:
                            if self.mcedit.displayContext.win and self.mcedit.displayContext.win.get_state() == 1:
                                x, y = config.settings.windowX.get(), config.settings.windowY.get()
                                pos = self.mcedit.displayContext.win.get_position()
                                if pos[0] != x:
                                    config.settings.windowX.set(pos[0])
                                if pos[1] != y:
                                    config.settings.windowY.set(pos[1])
                        elif type == ACTIVEEVENT:
                            add_modifiers(event)
                            self.dispatch_key('activeevent', event)

                    if not self.sessionStolen:
                        try:
                            if self.editor.level is not None and hasattr(self.editor.level, "checkSessionLock"):
                                self.editor.level.checkSessionLock()
                        except Exception as e:
                            log.warn(u"Error reading chunk (?): %s", e)
                            traceback.print_exc()
                            if not config.session.override.get():
                                self.sessionStolen = True
                            else:
                                self.editor.level.acquireSessionLock()

                    if self.editor.level is not None:
                        self.editor.cameraInputs = [0., 0., 0., 0., 0., 0.]
                        self.editor.cameraPanKeys = [0., 0., 0., 0.]

                        def useKeys(i):
                            keyName = self.getKey(movement=True, keyname=key.name(i))
                            if keyName == self.editor.sprintKey:
                                self.sprint = True
                            if allKeys[K_LCTRL] or allKeys[K_RCTRL] or allKeys[K_RMETA] or allKeys[K_LMETA]:
                                return
                            if keyName in self.editor.movements:
                                self.changeMovementKeys(self.editor.movements.index(keyName), keyName)
                            if keyName in self.editor.cameraPan:
                                self.changeCameraKeys(self.editor.cameraPan.index(keyName))

                        allKeys = key.get_pressed()
                        for x in enumerate(allKeys):
                            if x[1]:
                                useKeys(x[0])

                        for edit in self.filesToChange:
                            newTime = os.path.getmtime(edit.filename)
                            if newTime > edit.timeChanged:
                                edit.timeChanged = newTime
                                edit.makeChanges()

                except Cancel:
                    pass
        finally:
            modal_widget.is_modal = was_modal
            top_widget = old_top_widget
            if old_captured_widget:
                self.capture_mouse(old_captured_widget)

        clicked_widget = None

    @staticmethod
    def getKey(evt=None, movement=False, keyname=None):
        if keyname is None:
            keyname = key.name(evt.key)
        keyname = keyname.replace("right ", "").replace("left ", "").replace("Meta", "Ctrl").replace("Enter", "Return").replace("Delete", "Del")
        try:
            keyname = keyname.replace(keyname[0], keyname[0].upper(), 1)
        except:
            pass
        if movement:
            return keyname

        newKeyname = ""
        if evt.shift and keyname != "Shift":
            newKeyname += "Shift-"
        if (evt.ctrl or evt.cmd) and keyname != "Ctrl":
             newKeyname += "Ctrl-"
        if evt.alt and keyname != "Alt":
            newKeyname += "Alt-"

        keyname = newKeyname + keyname

        if newKeyname:
            return keyname

        if sys.platform == 'linux2':
            test_key = getattr(evt, 'scancode', None)
            tool_keys = [10, 11, 12, 13, 14, 15, 16, 17, 18]
        else:
            test_key = keyname
            tool_keys = ['1', '2', '3', '4', '5', '6', '7', '8', '9']
        if test_key in tool_keys:
            keyname = str(tool_keys.index(test_key) + 1)
        elif test_key == 19:
            keyname = '0'
        return keyname

    def changeMovementKeys(self, keyNum, keyname):
        if self.editor.level is not None and not self.notMove:
            self.editor.cameraInputs[self.movementNum[keyNum]] += self.movementMath[keyNum]
        elif self.notMove and self.nudge is not None and (self.testTime is None or datetime.now() - self.testTime >= timedelta(seconds=self.testTimeBack)):
            if self.testTimeBack > 0.1:
                self.testTimeBack -= 0.1
            self.bonus_draw_time = False
            self.testTime = datetime.now()
            if keyname == self.editor.movements[4]:
                self.nudge.nudge(Vector(0, 1, 0))
            if keyname == self.editor.movements[5]:
                self.nudge.nudge(Vector(0, -1, 0))

            Z = self.editor.mainViewport.cameraVector
            absZ = map(abs, Z)
            if absZ[0] < absZ[2]:
                forward = (0, 0, (-1 if Z[2] < 0 else 1))
            else:
                forward = ((-1 if Z[0] < 0 else 1), 0, 0)

            back = map(int.__neg__, forward)
            left = forward[2], forward[1], -forward[0]
            right = map(int.__neg__, left)

            if keyname == self.editor.movements[2]:
                self.nudge.nudge(Vector(*forward))
            if keyname == self.editor.movements[3]:
                self.nudge.nudge(Vector(*back))
            if keyname == self.editor.movements[0]:
                self.nudge.nudge(Vector(*left))
            if keyname == self.editor.movements[1]:
                self.nudge.nudge(Vector(*right))

            for i, move_key in enumerate(self.editor.movements):
                if move_key == keyname:
                    self.nudgeDirection = i

    def changeCameraKeys(self, keyNum):
        if self.editor.level is not None and not self.notMove:
            self.editor.cameraPanKeys[self.cameraNum[keyNum]] = self.cameraMath[keyNum]

    def RemoveEditFiles(self):
        self.filesToChange = []

    def call_idle_handlers(self):
        def call(ref):
            widget = ref()
            if widget:
                widget.idleevent()
            else:
                print "Idle ref died!"
            return bool(widget)

        self.idle_handlers = filter(call, self.idle_handlers)

    def add_idle_handler(self, widget):
        from weakref import ref

        self.idle_handlers.append(ref(widget))

    def remove_idle_handler(self, widget):
        from weakref import ref

        self.idle_handlers.remove(ref(widget))

    @staticmethod
    def send_key(widget, name, event):
        widget.dispatch_key(name, event)

    def begin_frame(self):
        pass

    def get_root(self):
        return self

    labelClass = lambda s, t: wrapped_label(t, 45)

    def show_tooltip(self, widget, pos):

        if hasattr(self, 'currentTooltip'):
            if self.currentTooltip is not None:
                self.remove(self.currentTooltip)

            self.currentTooltip = None

        def TextTooltip(text, name):
            tooltipBacking = Panel(name=name)
            tooltipBacking.bg_color = (0.0, 0.0, 0.0, 0.8)
            tooltipBacking.add(self.labelClass(text))
            tooltipBacking.shrink_wrap()
            return tooltipBacking

        def showTip(tip):
            tip.topleft = pos
            tip.top += 20
            if (tip.bottom > self.bottom) or hasattr(widget, 'tooltipsUp'):
                tip.bottomleft = pos
                tip.top -= 4
            if tip.right > self.right:
                tip.right = pos[0]

            self.add(tip)
            self.currentTooltip = tip

        if widget.tooltip is not None:
            tip = widget.tooltip
            showTip(tip)

        else:
            ttext = widget.tooltipText
            if ttext is not None:
                tip = TextTooltip(ttext, 'Panel.%s' % (repr(widget)))
                showTip(tip)

    def update_tooltip(self, pos=None):
        if pos is None:
            pos = pygame.mouse.get_pos()
        if self.captured_widget:
            mouse_widget = self.captured_widget
            pos = mouse_widget.center
        else:
            mouse_widget = self.find_widget(pos)

        self.show_tooltip(mouse_widget, pos)
        return mouse_widget

    def has_focus(self):
        return True

    def quit(self):
        if self.confirm_quit():
            self.capture_mouse(None)
            sys.exit(0)

    @staticmethod
    def confirm_quit():
        return True

    @staticmethod
    def get_mouse_for(widget):
        last = last_mouse_event
        event = Event(0, last.dict)
        event.dict['local'] = widget.global_to_local(event.pos)
        add_modifiers(event)
        return event

    def gl_clear(self):
        #from OpenGL import GL
        
        bg = self.bg_color
        if bg:
            r = bg[0] / 255.0
            g = bg[1] / 255.0
            b = bg[2] / 255.0
            GL.glClearColor(r, g, b, 0.0)
        GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)

    @staticmethod
    def music_end():
        import music

        music.music_end()
Beispiel #5
0
class RootWidget(Widget):
    #  surface   Pygame display surface
    #  is_gl     True if OpenGL surface

    redraw_every_frame = False
    bonus_draw_time = False
    _is_gl_container = True

    def __init__(self, surface):
        global root_widget
        Widget.__init__(self, surface.get_rect())
        self.surface = surface
        root_widget = self
        widget.root_widget = self
        self.is_gl = surface.get_flags() & OPENGL != 0
        self.idle_handlers = []
        self.editor = None
        self.selectTool = None
        self.movementMath = [-1, 1, 1, -1, 1, -1]
        self.movementNum = [0, 0, 2, 2, 1, 1]
        self.cameraMath = [-1., 1., -1., 1.]
        self.cameraNum = [0, 0, 1, 1]
        self.notMove = False
        self.nudge = None
        self.testTime = None
        self.testTimeBack = 0.4
        self.nudgeDirection = None
        self.sessionStolen = False
        self.sprint = False
        self.filesToChange = []

    def get_nudge_block(self):
        return self.selectTool.panel.nudgeBlocksButton

    def take_screenshot(self):
        try:
            os.mkdir(os.path.join(directories.getCacheDir(), "screenshots"))
        except OSError:
            pass
        screenshot_name = os.path.join(directories.getCacheDir(), "screenshots", time.strftime("%Y-%m-%d (%I-%M-%S-%p)")+".png")
        pygame.image.save(pygame.display.get_surface(), screenshot_name)
        self.diag = Dialog()
        lbl = Label(_("Screenshot taken and saved as '%s'")%screenshot_name, doNotTranslate=True)
        folderBtn = Button("Open Folder", action=self.open_screenshots_folder)
        btn = Button("Ok", action=self.screenshot_notify)
        buttonsRow = Row((btn,folderBtn))
        col = Column((lbl,buttonsRow))
        self.diag.add(col)
        self.diag.shrink_wrap()
        self.diag.present()

    def open_screenshots_folder(self):
        from mcplatform import platform_open
        platform_open(os.path.join(directories.getCacheDir(), "screenshots"))
        self.screenshot_notify()

    def screenshot_notify(self):
        self.diag.dismiss()

    @staticmethod
    def set_timer(ms):
        pygame.time.set_timer(USEREVENT, ms)

    def run(self):
        self.run_modal(None)

    captured_widget = None

    def capture_mouse(self, widget):
        #put the mouse in "virtual mode" and pass mouse moved events to the
        #specified widget
        if widget:
            pygame.mouse.set_visible(False)
            pygame.event.set_grab(True)
            self.captured_widget = widget
        else:
            pygame.mouse.set_visible(True)
            pygame.event.set_grab(False)
            self.captured_widget = None

    frames = 0
    hover_widget = None

    def fix_sticky_ctrl(self):
        self.ctrlClicked = -1

    def run_modal(self, modal_widget):
        if self.editor is None:
            self.editor = self.mcedit.editor
            self.selectTool = self.editor.toolbar.tools[0]
        old_captured_widget = None

        if self.captured_widget:
            old_captured_widget = self.captured_widget
            self.capture_mouse(None)

        global last_mouse_event, last_mouse_event_handler
        global top_widget, clicked_widget
        is_modal = modal_widget is not None
        modal_widget = modal_widget or self
        from OpenGL import GL

        try:
            old_top_widget = top_widget
            top_widget = modal_widget
            was_modal = modal_widget.is_modal
            modal_widget.is_modal = True
            modal_widget.modal_result = None
            if not modal_widget.focus_switch:
                modal_widget.tab_to_first()
            if clicked_widget:
                clicked_widget = modal_widget
            num_clicks = 0
            last_click_time = start_time
            last_click_button = False
            self.bonus_draw_time = False

            while modal_widget.modal_result is None:
                try:
                    if not self.mcedit.version_checked:
                        if not self.mcedit.version_lock.locked():
                            self.mcedit.version_checked = True
                            self.mcedit.check_for_version()

                    self.hover_widget = self.find_widget(pygame.mouse.get_pos())
                    if not self.bonus_draw_time:
                        self.bonus_draw_time = True
                        if self.is_gl:
                            self.gl_clear()
                            self.gl_draw_all(self, (0, 0))
                            GL.glFlush()
                        else:
                            self.draw_all(self.surface)
                        pygame.display.flip()
                        self.frames += 1
                    #events = [pygame.event.wait()]
                    events = [pygame.event.poll()]
                    events.extend(pygame.event.get())

                    for event in events:
                        #if event.type:
                        #log.debug("%s", event)
                        type = event.type
                        if type == QUIT:
                            self.quit()
                        elif type == MOUSEBUTTONDOWN:
                            self.bonus_draw_time = False
                            t = datetime.now()
                            if t - last_click_time <= double_click_time and event.button == last_click_button:
                                num_clicks += 1
                            else:
                                num_clicks = 1
                            last_click_button = event.button
                            last_click_time = t
                            event.dict['num_clicks'] = num_clicks
                            add_modifiers(event)
                            mouse_widget = self.find_widget(event.pos)
                            if self.captured_widget:
                                mouse_widget = self.captured_widget

                            if not mouse_widget.is_inside(modal_widget):
                                mouse_widget = modal_widget
                            #if event.button == 1:
                            clicked_widget = mouse_widget
                            last_mouse_event_handler = mouse_widget
                            last_mouse_event = event
                            mouse_widget.notify_attention_loss()
                            mouse_widget.handle_mouse('mouse_down', event)
                        elif type == MOUSEMOTION:
                            self.bonus_draw_time = False
                            add_modifiers(event)
                            modal_widget.dispatch_key('mouse_delta', event)
                            last_mouse_event = event

                            mouse_widget = self.update_tooltip(event.pos)

                            if clicked_widget:
                                last_mouse_event_handler = clicked_widget
                                clicked_widget.handle_mouse('mouse_drag', event)
                            else:
                                if not mouse_widget.is_inside(modal_widget):
                                    mouse_widget = modal_widget
                                last_mouse_event_handler = mouse_widget
                                mouse_widget.handle_mouse('mouse_move', event)
                        elif type == MOUSEBUTTONUP:
                            add_modifiers(event)
                            self.bonus_draw_time = False
                            mouse_widget = self.find_widget(event.pos)
                            if self.captured_widget:
                                mouse_widget = self.captured_widget
                            if clicked_widget:
                                last_mouse_event_handler = clicked_widget
                                event.dict['clicked_widget'] = clicked_widget
                            else:
                                last_mouse_event_handler = mouse_widget
                                event.dict['clicked_widget'] = None

                            last_mouse_event = event
                            clicked_widget = None
                            last_mouse_event_handler.handle_mouse('mouse_up', event)
                        elif type == KEYDOWN:
                            key = event.key
                            set_modifier(key, True)
                            add_modifiers(event)
                            self.bonus_draw_time = False
                            keyname = self.getKey(event)
                            if keyname == config.keys.takeAScreenshot.get():
                                self.take_screenshot()

                            self.send_key(modal_widget, 'key_down', event)
                            if last_mouse_event_handler:
                                event.dict['pos'] = last_mouse_event.pos
                                event.dict['local'] = last_mouse_event.local
                                last_mouse_event_handler.setup_cursor(event)
                        elif type == KEYUP:
                            key = event.key
                            set_modifier(key, False)
                            add_modifiers(event)
                            self.bonus_draw_time = False
                            keyname = self.getKey(event)
                            if keyname == config.keys.showBlockInfo.get() and self.editor.toolbar.tools[0].infoKey == 1:
                                self.editor.toolbar.tools[0].infoKey = 0
                                self.editor.mainViewport.showCommands()
                            if self.nudgeDirection is not None:
                                keyname = self.getKey(movement=True, keyname=pygame.key.name(key))
                                for i, key in enumerate(self.editor.movements):
                                    if keyname == key and i == self.nudgeDirection:
                                        self.nudgeDirection = None
                                        self.testTime = None
                                        self.testTimeBack = 0.4

                            self.send_key(modal_widget, 'key_up', event)
                            if last_mouse_event_handler:
                                event.dict['pos'] = last_mouse_event.pos
                                event.dict['local'] = last_mouse_event.local
                                last_mouse_event_handler.setup_cursor(event)
                        elif type == MUSIC_END_EVENT:
                            self.music_end()
                        elif type == USEREVENT:
                            make_scheduled_calls()
                            if not is_modal:
                                if self.redraw_every_frame:
                                    self.bonus_draw_time = False
                                else:
                                    self.bonus_draw_time = True
                                if last_mouse_event_handler:
                                    event.dict['pos'] = last_mouse_event.pos
                                    event.dict['local'] = last_mouse_event.local
                                    add_modifiers(event)
                                    last_mouse_event_handler.setup_cursor(event)
                                self.begin_frame()
                        elif type == VIDEORESIZE:
                            #add_modifiers(event)
                            self.bonus_draw_time = False
                            self.size = (event.w, event.h)
                            #self.dispatch_key('reshape', event)
                        elif type == ACTIVEEVENT:
                            add_modifiers(event)
                            self.dispatch_key('activeevent', event)
                        elif type == NOEVENT:
                            add_modifiers(event)
                            self.call_idle_handlers(event)

                    if not self.sessionStolen:
                        try:
                            if self.editor.level is not None and hasattr(self.editor.level, "checkSessionLock"):
                                self.editor.level.checkSessionLock()
                        except Exception, e:
                            log.warn(u"Error reading chunk: %s", e)
                            if not config.session.override.get():
                                self.sessionStolen = True
                            else:
                                self.editor.level.acquireSessionLock()

                    if self.editor.level is not None:
                        self.editor.cameraInputs = [0., 0., 0., 0., 0., 0.]
                        self.editor.cameraPanKeys = [0., 0., 0., 0.]
                        allKeys = pygame.key.get_pressed()
                        allKeysWithData = enumerate(allKeys)

                        def useKeys((i, keys)):
                            if not keys:
                                return
                            keyName = self.getKey(movement=True, keyname=pygame.key.name(i))
                            if keyName == self.editor.sprintKey:
                                self.sprint = True
                            if self.editor.level:
                                for j, key in enumerate(self.editor.movements):
                                    if keyName == key and not allKeys[pygame.K_LCTRL] and not allKeys[pygame.K_RCTRL] and not allKeys[pygame.K_RMETA] and not allKeys[pygame.K_LMETA]:
                                        self.changeMovementKeys(j, keyName)

                                for k, key in enumerate(self.editor.cameraPan):
                                    if keyName == key and not allKeys[pygame.K_LCTRL] and not allKeys[pygame.K_RCTRL] and not allKeys[pygame.K_RMETA] and not allKeys[pygame.K_LMETA]:
                                        self.changeCameraKeys(k)
                        map(useKeys, allKeysWithData)

                        for edit in self.filesToChange:
                            newTime = os.path.getmtime(edit.filename)
                            if newTime > edit.timeChanged:
                                edit.timeChanged = newTime
                                edit.makeChanges()


                except Cancel:
                    pass
Beispiel #6
0
class RootWidget(Widget):
    #  surface   Pygame display surface
    #  is_gl     True if OpenGL surface

    redraw_every_frame = False
    bonus_draw_time = False
    _is_gl_container = True

    def __init__(self, surface):
        global root_widget
        Widget.__init__(self, surface.get_rect())
        self.surface = surface
        root_widget = self
        widget.root_widget = self
        self.is_gl = surface.get_flags() & OPENGL != 0
        self.idle_handlers = []
        self.editor = None
        self.selectTool = None
        self.movementMath = [-1, 1, 1, -1, 1, -1]
        self.movementNum = [0, 0, 2, 2, 1, 1]
        self.cameraMath = [-1., 1., -1., 1.]
        self.cameraNum = [0, 0, 1, 1]
        self.notMove = False
        self.nudge = None
        self.testTime = None
        self.testTimeBack = 0.4
        self.nudgeDirection = None
        self.sessionStolen = False
        self.sprint = False
        self.filesToChange = []

    def get_nudge_block(self):
        return self.selectTool.panel.nudgeBlocksButton

    def take_screenshot(self):
        try:
            os.mkdir(os.path.join(directories.getCacheDir(), "screenshots"))
        except OSError:
            pass
        screenshot_name = os.path.join(
            directories.getCacheDir(), "screenshots",
            time.strftime("%Y-%m-%d (%I-%M-%S-%p)") + ".png")
        pygame.image.save(pygame.display.get_surface(), screenshot_name)
        self.diag = Dialog()
        lbl = Label(_("Screenshot taken and saved as '%s'") % screenshot_name,
                    doNotTranslate=True)
        folderBtn = Button("Open Folder", action=self.open_screenshots_folder)
        btn = Button("Ok", action=self.screenshot_notify)
        buttonsRow = Row((btn, folderBtn))
        col = Column((lbl, buttonsRow))
        self.diag.add(col)
        self.diag.shrink_wrap()
        self.diag.present()

    def open_screenshots_folder(self):
        from mcplatform import platform_open
        platform_open(os.path.join(directories.getCacheDir(), "screenshots"))
        self.screenshot_notify()

    def screenshot_notify(self):
        self.diag.dismiss()

    @staticmethod
    def set_timer(ms):
        pygame.time.set_timer(USEREVENT, ms)

    def run(self):
        self.run_modal(None)

    captured_widget = None

    def capture_mouse(self, widget):
        # put the mouse in "virtual mode" and pass mouse moved events to the
        # specified widget
        if widget:
            pygame.mouse.set_visible(False)
            pygame.event.set_grab(True)
            self.captured_widget = widget
        else:
            pygame.mouse.set_visible(True)
            pygame.event.set_grab(False)
            self.captured_widget = None

    frames = 0
    hover_widget = None

    def fix_sticky_ctrl(self):
        self.ctrlClicked = -1

    def run_modal(self, modal_widget):
        if self.editor is None:
            self.editor = self.mcedit.editor
            self.selectTool = self.editor.toolbar.tools[0]
        old_captured_widget = None

        if self.captured_widget:
            old_captured_widget = self.captured_widget
            self.capture_mouse(None)

        global last_mouse_event, last_mouse_event_handler
        global top_widget, clicked_widget
        is_modal = modal_widget is not None
        modal_widget = modal_widget or self
        #from OpenGL import GL

        try:
            old_top_widget = top_widget
            top_widget = modal_widget
            was_modal = modal_widget.is_modal
            modal_widget.is_modal = True
            modal_widget.modal_result = None
            if not modal_widget.focus_switch:
                modal_widget.tab_to_first()
            if clicked_widget:
                clicked_widget = modal_widget
            num_clicks = 0
            last_click_time = start_time
            last_click_button = False
            self.bonus_draw_time = False

            while modal_widget.modal_result is None:
                try:
                    if not self.mcedit.version_checked:
                        if not self.mcedit.version_lock.locked():
                            self.mcedit.version_checked = True
                            self.mcedit.check_for_version()

                    self.hover_widget = self.find_widget(
                        pygame.mouse.get_pos())
                    if not self.bonus_draw_time:
                        self.bonus_draw_time = True
                        if self.is_gl:
                            self.gl_clear()
                            self.gl_draw_all(self, (0, 0))
                            GL.glFlush()
                        else:
                            self.draw_all(self.surface)
                        pygame.display.flip()
                        self.frames += 1

                    events = pygame.event.get()
                    if not events:
                        self.call_idle_handlers()

                    for event in events:
                        type = event.type
                        if type == QUIT:
                            self.quit()
                        elif type == MOUSEBUTTONDOWN:
                            self.bonus_draw_time = False
                            t = datetime.now()
                            if t - last_click_time <= double_click_time and event.button == last_click_button:
                                num_clicks += 1
                            else:
                                num_clicks = 1
                            last_click_button = event.button
                            last_click_time = t
                            event.dict['num_clicks'] = num_clicks
                            add_modifiers(event)
                            mouse_widget = self.find_widget(event.pos)
                            if self.captured_widget:
                                mouse_widget = self.captured_widget

                            if not mouse_widget.is_inside(modal_widget):
                                mouse_widget = modal_widget
                            clicked_widget = mouse_widget
                            last_mouse_event_handler = mouse_widget
                            last_mouse_event = event
                            mouse_widget.notify_attention_loss()
                            mouse_widget.handle_mouse('mouse_down', event)
                        elif type == MOUSEMOTION:
                            self.bonus_draw_time = False
                            add_modifiers(event)
                            modal_widget.dispatch_key('mouse_delta', event)
                            last_mouse_event = event

                            mouse_widget = self.update_tooltip(event.pos)

                            if clicked_widget:
                                last_mouse_event_handler = clicked_widget
                                clicked_widget.handle_mouse(
                                    'mouse_drag', event)
                            else:
                                if not mouse_widget.is_inside(modal_widget):
                                    mouse_widget = modal_widget
                                last_mouse_event_handler = mouse_widget
                                mouse_widget.handle_mouse('mouse_move', event)
                        elif type == MOUSEBUTTONUP:
                            add_modifiers(event)
                            self.bonus_draw_time = False
                            mouse_widget = self.find_widget(event.pos)
                            if self.captured_widget:
                                mouse_widget = self.captured_widget
                            if clicked_widget:
                                last_mouse_event_handler = clicked_widget
                                event.dict['clicked_widget'] = clicked_widget
                            else:
                                last_mouse_event_handler = mouse_widget
                                event.dict['clicked_widget'] = None

                            last_mouse_event = event
                            clicked_widget = None
                            last_mouse_event_handler.handle_mouse(
                                'mouse_up', event)
                        elif type == KEYDOWN:
                            key_down = event.key
                            set_modifier(key_down, True)
                            add_modifiers(event)
                            self.bonus_draw_time = False
                            keyname = self.getKey(event)
                            if keyname == config.keys.takeAScreenshot.get():
                                self.take_screenshot()

                            self.send_key(modal_widget, 'key_down', event)
                            if last_mouse_event_handler:
                                event.dict['pos'] = last_mouse_event.pos
                                event.dict['local'] = last_mouse_event.local
                                last_mouse_event_handler.setup_cursor(event)
                        elif type == KEYUP:
                            key_up = event.key
                            set_modifier(key_up, False)
                            add_modifiers(event)
                            self.bonus_draw_time = False
                            keyname = self.getKey(event)
                            if keyname == config.keys.showBlockInfo.get(
                            ) and self.editor.toolbar.tools[0].infoKey == 1:
                                self.editor.toolbar.tools[0].infoKey = 0
                                self.editor.mainViewport.showCommands()
                            if self.nudgeDirection is not None:
                                keyname = self.getKey(movement=True,
                                                      keyname=key.name(key_up))
                                for i, move_key in enumerate(
                                        self.editor.movements):
                                    if keyname == move_key and i == self.nudgeDirection:
                                        self.nudgeDirection = None
                                        self.testTime = None
                                        self.testTimeBack = 0.4

                            self.send_key(modal_widget, 'key_up', event)
                            if last_mouse_event_handler:
                                event.dict['pos'] = last_mouse_event.pos
                                event.dict['local'] = last_mouse_event.local
                                last_mouse_event_handler.setup_cursor(event)
                        elif type == MUSIC_END_EVENT:
                            self.music_end()
                        elif type == USEREVENT:
                            make_scheduled_calls()
                            if not is_modal:
                                if self.redraw_every_frame:
                                    self.bonus_draw_time = False
                                else:
                                    self.bonus_draw_time = True
                                if last_mouse_event_handler:
                                    event.dict['pos'] = last_mouse_event.pos
                                    event.dict[
                                        'local'] = last_mouse_event.local
                                    add_modifiers(event)
                                    last_mouse_event_handler.setup_cursor(
                                        event)
                                self.begin_frame()
                        elif type == VIDEORESIZE:
                            self.bonus_draw_time = False
                            self.size = (event.w, event.h)
                        elif type == VIDEOEXPOSE:
                            if self.mcedit.displayContext.win and self.mcedit.displayContext.win.get_state(
                            ) == 1:
                                x, y = config.settings.windowX.get(
                                ), config.settings.windowY.get()
                                pos = self.mcedit.displayContext.win.get_position(
                                )
                                if pos[0] != x:
                                    config.settings.windowX.set(pos[0])
                                if pos[1] != y:
                                    config.settings.windowY.set(pos[1])
                        elif type == ACTIVEEVENT:
                            add_modifiers(event)
                            self.dispatch_key('activeevent', event)

                    if not self.sessionStolen:
                        try:
                            if self.editor.level is not None and hasattr(
                                    self.editor.level, "checkSessionLock"):
                                self.editor.level.checkSessionLock()
                        except Exception as e:
                            log.warn(u"Error reading chunk (?): %s", e)
                            if not config.session.override.get():
                                self.sessionStolen = True
                            else:
                                self.editor.level.acquireSessionLock()

                    if self.editor.level is not None:
                        self.editor.cameraInputs = [0., 0., 0., 0., 0., 0.]
                        self.editor.cameraPanKeys = [0., 0., 0., 0.]

                        def useKeys(i):
                            keyName = self.getKey(movement=True,
                                                  keyname=key.name(i))
                            if keyName == self.editor.sprintKey:
                                self.sprint = True
                            if allKeys[K_LCTRL] or allKeys[K_RCTRL] or allKeys[
                                    K_RMETA] or allKeys[K_LMETA]:
                                return
                            if keyName in self.editor.movements:
                                self.changeMovementKeys(
                                    self.editor.movements.index(keyName),
                                    keyName)
                            if keyName in self.editor.cameraPan:
                                self.changeCameraKeys(
                                    self.editor.cameraPan.index(keyName))

                        allKeys = key.get_pressed()
                        for x in enumerate(allKeys):
                            if x[1]:
                                useKeys(x[0])

                        for edit in self.filesToChange:
                            newTime = os.path.getmtime(edit.filename)
                            if newTime > edit.timeChanged:
                                edit.timeChanged = newTime
                                edit.makeChanges()

                except Cancel:
                    pass
        finally:
            modal_widget.is_modal = was_modal
            top_widget = old_top_widget
            if old_captured_widget:
                self.capture_mouse(old_captured_widget)

        clicked_widget = None

    @staticmethod
    def getKey(evt=None, movement=False, keyname=None):
        if keyname is None:
            keyname = key.name(evt.key)
        keyname = keyname.replace("right ", "").replace("left ", "").replace(
            "Meta", "Ctrl").replace("Enter",
                                    "Return").replace("Delete", "Del")
        try:
            keyname = keyname.replace(keyname[0], keyname[0].upper(), 1)
        except:
            pass
        if movement:
            return keyname

        newKeyname = ""
        if evt.shift and keyname != "Shift":
            newKeyname += "Shift-"
        if (evt.ctrl or evt.cmd) and keyname != "Ctrl":
            newKeyname += "Ctrl-"
        if evt.alt and keyname != "Alt":
            newKeyname += "Alt-"

        keyname = newKeyname + keyname

        if newKeyname:
            return keyname

        if sys.platform == 'linux2':
            test_key = getattr(evt, 'scancode', None)
            tool_keys = [10, 11, 12, 13, 14, 15, 16, 17, 18]
        else:
            test_key = keyname
            tool_keys = ['1', '2', '3', '4', '5', '6', '7', '8', '9']
        if test_key in tool_keys:
            keyname = str(tool_keys.index(test_key) + 1)
        elif test_key == 19:
            keyname = '0'
        return keyname

    def changeMovementKeys(self, keyNum, keyname):
        if self.editor.level is not None and not self.notMove:
            self.editor.cameraInputs[
                self.movementNum[keyNum]] += self.movementMath[keyNum]
        elif self.notMove and self.nudge is not None and (
                self.testTime is None or datetime.now() - self.testTime >=
                timedelta(seconds=self.testTimeBack)):
            if self.testTimeBack > 0.1:
                self.testTimeBack -= 0.1
            self.bonus_draw_time = False
            self.testTime = datetime.now()
            if keyname == self.editor.movements[4]:
                self.nudge.nudge(Vector(0, 1, 0))
            if keyname == self.editor.movements[5]:
                self.nudge.nudge(Vector(0, -1, 0))

            Z = self.editor.mainViewport.cameraVector
            absZ = map(abs, Z)
            if absZ[0] < absZ[2]:
                forward = (0, 0, (-1 if Z[2] < 0 else 1))
            else:
                forward = ((-1 if Z[0] < 0 else 1), 0, 0)

            back = map(int.__neg__, forward)
            left = forward[2], forward[1], -forward[0]
            right = map(int.__neg__, left)

            if keyname == self.editor.movements[2]:
                self.nudge.nudge(Vector(*forward))
            if keyname == self.editor.movements[3]:
                self.nudge.nudge(Vector(*back))
            if keyname == self.editor.movements[0]:
                self.nudge.nudge(Vector(*left))
            if keyname == self.editor.movements[1]:
                self.nudge.nudge(Vector(*right))

            for i, move_key in enumerate(self.editor.movements):
                if move_key == keyname:
                    self.nudgeDirection = i

    def changeCameraKeys(self, keyNum):
        if self.editor.level is not None and not self.notMove:
            self.editor.cameraPanKeys[
                self.cameraNum[keyNum]] = self.cameraMath[keyNum]

    def RemoveEditFiles(self):
        self.filesToChange = []

    def call_idle_handlers(self):
        def call(ref):
            widget = ref()
            if widget:
                widget.idleevent()
            else:
                print "Idle ref died!"
            return bool(widget)

        self.idle_handlers = filter(call, self.idle_handlers)

    def add_idle_handler(self, widget):
        from weakref import ref

        self.idle_handlers.append(ref(widget))

    def remove_idle_handler(self, widget):
        from weakref import ref

        self.idle_handlers.remove(ref(widget))

    @staticmethod
    def send_key(widget, name, event):
        widget.dispatch_key(name, event)

    def begin_frame(self):
        pass

    def get_root(self):
        return self

    labelClass = lambda s, t: wrapped_label(t, 45)

    def show_tooltip(self, widget, pos):

        if hasattr(self, 'currentTooltip'):
            if self.currentTooltip is not None:
                self.remove(self.currentTooltip)

            self.currentTooltip = None

        def TextTooltip(text, name):
            tooltipBacking = Panel(name=name)
            tooltipBacking.bg_color = (0.0, 0.0, 0.0, 0.8)
            tooltipBacking.add(self.labelClass(text))
            tooltipBacking.shrink_wrap()
            return tooltipBacking

        def showTip(tip):
            tip.topleft = pos
            tip.top += 20
            if (tip.bottom > self.bottom) or hasattr(widget, 'tooltipsUp'):
                tip.bottomleft = pos
                tip.top -= 4
            if tip.right > self.right:
                tip.right = pos[0]

            self.add(tip)
            self.currentTooltip = tip

        if widget.tooltip is not None:
            tip = widget.tooltip
            showTip(tip)

        else:
            ttext = widget.tooltipText
            if ttext is not None:
                tip = TextTooltip(ttext, 'Panel.%s' % (repr(widget)))
                showTip(tip)

    def update_tooltip(self, pos=None):
        if pos is None:
            pos = pygame.mouse.get_pos()
        if self.captured_widget:
            mouse_widget = self.captured_widget
            pos = mouse_widget.center
        else:
            mouse_widget = self.find_widget(pos)

        self.show_tooltip(mouse_widget, pos)
        return mouse_widget

    def has_focus(self):
        return True

    def quit(self):
        if self.confirm_quit():
            self.capture_mouse(None)
            sys.exit(0)

    @staticmethod
    def confirm_quit():
        return True

    @staticmethod
    def get_mouse_for(widget):
        last = last_mouse_event
        event = Event(0, last.dict)
        event.dict['local'] = widget.global_to_local(event.pos)
        add_modifiers(event)
        return event

    def gl_clear(self):
        #from OpenGL import GL

        bg = self.bg_color
        if bg:
            r = bg[0] / 255.0
            g = bg[1] / 255.0
            b = bg[2] / 255.0
            GL.glClearColor(r, g, b, 0.0)
        GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)

    @staticmethod
    def music_end():
        import music

        music.music_end()