Пример #1
0
class SelectableTile(QtGui.QLabel):

    def __init__(self, parent, callback, tileset, tile):
        super(SelectableTile, self).__init__(parent)
        self.config = Config()
        self.current_file = Config().current_file()
        tile_infos = self.current_file['tilesets'][tileset][tile]
        self.setPixmap(
            QtGui.QPixmap(self.current_file['pathes'][tileset]).copy(
                tile_infos['crop_x'], tile_infos['crop_y'],
                tile_infos['crop_width'], tile_infos['crop_height']
            ).scaled(50, 50)
        )
        self.config.set_cache('tiles/%s/%s' % (tileset, tile), self.pixmap())
        self._callback = callback
        self._tileset = tileset
        self._tile = tile

    def tile(self):
        return self._tile

    def tileset(self):
        return self._tileset

    def mousePressEvent(self, event):
        self._callback(self)
Пример #2
0
 def __init__(self, parent, actor_name, animation_name):
     super(AnimationArea, self).__init__(parent)
     self._parent = parent
     self.config = Config()
     self.current_conf = Config().current_file()[
         'actors'
     ][actor_name]['animations'][animation_name]
     self._current_frame = 0
     self._actor_name = actor_name
     self._animation_name = animation_name
     self.setGeometry(0, 0, 480, 450)
     self._frames_list = QtGui.QComboBox(self)
     self._frames_list.setGeometry(5, 420, 100, 20)
     self._frames_list.currentIndexChanged.connect(self.on_change_frame)
     self._add_frame_button = IconButton(self, 'add_frame', 50, 50)
     self._add_frame_button.setGeometry(110, 420, 20, 20)
     self._add_frame_button.clicked.connect(self.on_add_frame)
     self._remove_frame_button = IconButton(self, 'remove_frame', 50, 50)
     self._remove_frame_button.setGeometry(135, 420, 20, 20)
     self._remove_frame_button.clicked.connect(self.on_remove_frame)
     self._scroll_areas = {}
     self._add_picture_button = IconButton(self, 'add_picture', 50, 50)
     self._add_picture_button.setGeometry(402, 2, 50, 50)
     self._add_picture_button.clicked.connect(self.on_new_picture)
     self._remove_animation_button = IconButton(
         self, 'remove_animation', 50, 50
     )
     self._remove_animation_button.setGeometry(402, 54, 50, 50)
     self._remove_animation_button.clicked.connect(self.on_remove_animation)
     self._resize_button = QtGui.QRadioButton('Resize', self)
     self._resize_button.setGeometry(170, 420, 70, 20)
     self._move_button = QtGui.QRadioButton('Move', self)
     self._move_button.setGeometry(240, 420, 70, 20)
     self._move_button.setChecked(True)
     self._multiplier = QtGui.QComboBox(self)
     self._multiplier.setGeometry(402, 380, 50, 20)
     for multiplier in range(1, self.NB_MULTIPLIERS + 1):
         self._multiplier.addItem('x' + str(multiplier))
     self._pos_label = QtGui.QLabel(self)
     self._pos_label.setGeometry(402, 100, 50, 100)
     self._play_animation = IconButton(self, 'play_animation', 50, 50)
     self._play_animation.setGeometry(402, 210, 50, 50)
     self._play_animation.clicked.connect(self.on_play_animation)
     self._fps_choice = QtGui.QComboBox(self)
     self._fps_choice.setGeometry(310, 420, 150, 20)
     if not len(self.current_conf):
         self._scroll_areas[0] = QtGui.QScrollArea(self)
         self._scroll_areas[0].setGeometry(0, 0, 400, 400)
         self._scroll_areas[0].setWidget(SpriteGridWidget(self))
         self._frames_list.addItem('Frame 0')
         self.current_conf['fps'] = 40
     for value in self.FPS_VALUES:
         period = 1000 / value
         self._fps_choice.addItem('%d FPS - %d ms' % (value, period))
     self._fps_choice.setCurrentIndex(self.FPS_VALUES.index(
         self.current_conf['fps']
     ))
     self._fps_choice.currentIndexChanged.connect(self.on_change_fps)
     self._multiplier.currentIndexChanged.connect(self.on_change_multiplier)
Пример #3
0
 def __init__(self, resolution, title):
     super(MainWindow, self).__init__()
     self.config = Config()
     self.config.init_from_file(settings.CONFIG_FILE_PATH)
     self._timer = QtCore.QTimer(self)
     self.setWindowIcon(QtGui.QIcon(os.path.join(
         settings.IMAGES_PATH, 'mqme.png'
     )))
     MainWindow._subscriptions = {
         'config.save': self.on_save_config_request,
         'menu.trigger.save_project': self.on_save_project_request,
         'menu.trigger.new_project': self.on_new_project_request,
         'menu.trigger.open_project': self.on_open_project_request,
         'menu.trigger.export_to_resources': self.on_export_request
     }
     self.connect(self._timer, QtCore.SIGNAL("timeout()"), self.update)
     self.workspace = QtGui.QWorkspace()
     width, height = resolution
     self.resize(width, height)
     self.setWindowTitle(title)
     self.setCentralWidget(self.workspace)
     self.setMenuBar(MenuBar(self, self.on_menu_triggered))
     self._children = []
     for child_type in self.CHILDREN:
         child = child_type()
         self.workspace.addWindow(child)
         child.set_queue(MainWindow.queue)
         self._children.append(child)
     self._timer.start(settings.QUEUE_READ_LOOP_DELAY)
Пример #4
0
 def __init__(self, name):
     super(ActorWorkspace, self).__init__()
     self._actor_name = name
     self._current_conf = Config().current_file()["actors"][name]
     self.setGeometry(0, 50, 640, 430)
     self._animations_list = QtGui.QListWidget(self)
     self._animations_list.setGeometry(485, 40, 150, 405)
     self._animations_list.itemClicked.connect(self.on_choose_animation)
     self._new_animation_button = QtGui.QPushButton("New animation", self)
     self._new_animation_button.setGeometry(485, 2, 150, 36)
     self._new_animation_button.clicked.connect(self.on_new_animation)
     self._animation_areas = {}
Пример #5
0
 def __init__(self):
     super(SpritesEditor, self).__init__()
     self.setFixedSize(640, 480)
     self.setWindowTitle("Sprites Editor")
     self._tabs_widget = QtGui.QTabWidget(self)
     self._tabs_widget.setGeometry(0, 0, 640, 480)
     self._tabs_widget.setTabsClosable(True)
     self._tabs_widget.tabCloseRequested.connect(self.on_actor_delete)
     self._current_file = Config().current_file()
     self.subscribe("menu.trigger.new_actor", self.on_new_actor)
     self.subscribe("open_project", self.on_open_file)
     self.subscribe("new_project", self.on_new_file)
Пример #6
0
 def __init__(self):
     super(TilesEditor, self).__init__()
     self.config = Config()
     self.setWindowTitle('Tiles Editor')
     self.setFixedSize(640, 480)
     self._tab_widget = QtGui.QTabWidget(self)
     self._tab_widget.setGeometry(0, 0, 640, 480)
     self.subscribe('menu.trigger.import_tileset', self.on_import_tileset)
     self.subscribe('picture.mousemove', self.on_picture_mouse_move)
     self.subscribe('new_project', self.on_new_file)
     self.subscribe('open_project', self.on_open_file)
     self._workspaces = []
 def __init__(self):
     super(FightEnvironmentEditor, self).__init__()
     self.setWindowTitle('Fight Environment Editor')
     self.setFixedSize(320, 240)
     self._tabs_widget = QtGui.QTabWidget(self)
     self._tabs_widget.setGeometry(0, 0, 320, 240)
     self._tabs_widget.setTabsClosable(True)
     self._tabs_widget.tabCloseRequested.connect(self.on_environment_delete)
     self.subscribe(
         'menu.trigger.new_fight_environment', self.on_new_environment
     )
     self._current_file = Config().current_file()
     self.subscribe('open_project', self.on_open_file)
class FightEnvironmentEditor(ChildWindow):

    def __init__(self):
        super(FightEnvironmentEditor, self).__init__()
        self.setWindowTitle('Fight Environment Editor')
        self.setFixedSize(320, 240)
        self._tabs_widget = QtGui.QTabWidget(self)
        self._tabs_widget.setGeometry(0, 0, 320, 240)
        self._tabs_widget.setTabsClosable(True)
        self._tabs_widget.tabCloseRequested.connect(self.on_environment_delete)
        self.subscribe(
            'menu.trigger.new_fight_environment', self.on_new_environment
        )
        self._current_file = Config().current_file()
        self.subscribe('open_project', self.on_open_file)

    def on_open_file(self, message):
        self._current_file = Config().current_file()
        for name in self._current_file.get('fightenv', {}):
            workspace = FightEnvironmentWorkspace(name)
            workspace.read_conf()
            self._tabs_widget.addTab(workspace, name)

    def on_environment_delete(self, index):
        name = self._tabs_widget.widget(index).name()
        msg_box = QtGui.QMessageBox(self)
        msg_box.setWindowTitle('Delete Fight Environment')
        msg_box.setText('Do you want to delete "%s" ?' % name)
        msg_box.setStandardButtons(
            QtGui.QMessageBox.Ok | QtGui.QMessageBox.Cancel
        )
        msg_box.setDefaultButton(QtGui.QMessageBox.Cancel)
        status = msg_box.exec_()
        if status == QtGui.QMessageBox.Ok:
            del self._current_file['fightenv'][name]
            self._tabs_widget.removeTab(index)

    def on_new_environment(self, message):
        name, status = QtGui.QInputDialog.getText(
            self, 'Fight Environment name', 'Name :'
        )
        if status:
            name = str(name)
            if not 'fightenv' in self._current_file:
                self._current_file['fightenv'] = {}
            self._current_file['fightenv'][name] = {}
            self._tabs_widget.addTab(FightEnvironmentWorkspace(name), name)
Пример #9
0
class SpritesEditor(ChildWindow):
    def __init__(self):
        super(SpritesEditor, self).__init__()
        self.setFixedSize(640, 480)
        self.setWindowTitle("Sprites Editor")
        self._tabs_widget = QtGui.QTabWidget(self)
        self._tabs_widget.setGeometry(0, 0, 640, 480)
        self._tabs_widget.setTabsClosable(True)
        self._tabs_widget.tabCloseRequested.connect(self.on_actor_delete)
        self._current_file = Config().current_file()
        self.subscribe("menu.trigger.new_actor", self.on_new_actor)
        self.subscribe("open_project", self.on_open_file)
        self.subscribe("new_project", self.on_new_file)

    def on_actor_delete(self, index):
        actor_name = self._tabs_widget.widget(index).actor_name()
        msg_box = QtGui.QMessageBox(self)
        msg_box.setWindowTitle("Delete Actor")
        msg_box.setText('Do you want to delete "%s" ?' % actor_name)
        msg_box.setStandardButtons(QtGui.QMessageBox.Ok | QtGui.QMessageBox.Cancel)
        msg_box.setDefaultButton(QtGui.QMessageBox.Cancel)
        status = msg_box.exec_()
        if status == QtGui.QMessageBox.Ok:
            self._tabs_widget.widget(index).remove_actor()
            self._tabs_widget.removeTab(index)

    def on_new_actor(self, message):
        name, status = QtGui.QInputDialog.getText(self, "Actor name", "Name :")
        if status:
            name = str(name)
            if not "actors" in self._current_file:
                self._current_file["actors"] = {}
            self._current_file["actors"][name] = {}
            self._tabs_widget.addTab(ActorWorkspace(name), name)

    def on_new_file(self, message):
        self._tabs_widget.clear()

    def on_open_file(self, message):
        self._current_file = Config().current_file()
        for name in self._current_file.get("actors", {}):
            workspace = ActorWorkspace(name)
            workspace.read_conf()
            self._tabs_widget.addTab(workspace, name)
Пример #10
0
 def __init__(self, parent, picture_path, queue):
     super(TileSetPicture, self).__init__(parent)
     self._parent = parent
     self._queue = queue
     self._items = []
     self._base_pixmap = QtGui.QPixmap(picture_path)
     self.config = Config()
     self.current_file = self.config.current_file()
     path_elements = os.path.split(picture_path)
     self._base_name = os.path.splitext(
         path_elements[len(path_elements) - 1]
     )[0]
     if not 'tilesets' in self.current_file:
         self.current_file['tilesets'] = {}
     if not 'pathes' in self.current_file:
         self.current_file['pathes'] = {}
     self.current_file['pathes'][self._base_name] = picture_path
     if not self._base_name in self.current_file['tilesets']:
         self.current_file['tilesets'][self._base_name] = {}
     self._current_item = None
Пример #11
0
 def __init__(self):
     super(MapEditor, self).__init__()
     self.config = Config()
     self.setFixedSize(900, 600)
     self.setWindowTitle('Map Editor')
     self.subscribe('menu.trigger.new_map', self.on_new_map)
     self.subscribe('tileset_editor.new_tileset', self.on_new_tileset)
     self.subscribe('tileset.update', self.on_tileset_update)
     self.subscribe('open_maps', self.on_open_maps)
     self.subscribe('hide_map_layer', self.on_hide_layer)
     self.subscribe('show_map_layer', self.on_show_layer)
     self._toolbox = QtGui.QToolBar(self)
     self._toolbox.setGeometry(0, 0, 100, 600)
     self._actions = {}
     for tool in MapSpecialsLayer.TOOLS:
         ref, name = tool
         action = MenuAction(self._toolbox, ref, self.on_action_checked)
         action.setIcon(QtGui.QIcon(os.path.join(
             settings.IMAGES_PATH, '%s.png' % ref
         )))
         action.setText(name)
         action.setCheckable(True)
         self._toolbox.addAction(action)
         self._actions[ref] = action
     self._tab_widget = QtGui.QTabWidget(self)
     self._tab_widget.setTabsClosable(True)
     self._tab_widget.tabCloseRequested.connect(self.on_map_delete)
     self._tab_widget.setGeometry(100, 0, 550, 550)
     self._zoom_in = IconButton(self, 'zoom_in', 30, 30)
     self._zoom_in.setGeometry(150, 560, 30, 30)
     self._zoom_in.clicked.connect(self.on_zoom_in)
     self._zoom_out = IconButton(self, 'zoom_out', 30, 30)
     self._zoom_out.setGeometry(110, 560, 30, 30)
     self._zoom_out.clicked.connect(self.on_zoom_out)
     self._tileset_cb = QtGui.QComboBox(self)
     self._tileset_cb.setGeometry(665, 5, 220, 20)
     self._tileset_cb.currentIndexChanged.connect(self.update)
     self._tiles_widgets = {}
     self._current_tool = None
 def __init__(self, name):
     super(FightEnvironmentWorkspace, self).__init__()
     self._name = name
     self._height_ratio = 1.0
     self.config = Config()
     self.setGeometry(0, 0, 320, 220)
     self._layers = {}
     self._buttons = []
     self._current_conf = Config().current_file()['fightenv'][name]
     for layer_name in self.LAYERS:
         self._layers[layer_name] = self.new_layer()
     self._layers['screen'].setStyleSheet(
         'QLabel {'
         'background-color: black;'
         'border: 3px solid #ccccff;'
         '}'
     )
     self.new_button('Set background 1', 2, self.on_choose_background1, False)
     self.new_button('Set background 2', 104, self.on_choose_background2, False)
     self.new_button('Set background 3', 206, self.on_choose_background3)
     self._play_animation = IconButton(self, 'play_animation', 30, 30)
     self._play_animation.setGeometry(145, 182, 30, 30)
     self._play_animation.clicked.connect(self.on_play_animation)
Пример #13
0
class SpritesGenerator(object):

    def __init__(self, actor_name):
        self._actor_name = actor_name
        self.current_conf = Config().current_file()['actors'][actor_name]
        self._sps_infos = {}
        self._crop_x = 0
        self._crop_y = 0

    def save(self, directory):
        animation_images = {}
        width = 0
        for animation_name in self.current_conf.get('animations', {}):
            animation_images[animation_name] = self.get_animation_as_image(
                animation_name
            )
            im_width, im_height = animation_images[animation_name].size
            if width < im_width:
                width = im_width
        sprites_image = Image.new('RGBA', (width, self._crop_y))
        y_offset = 0
        for animation_name in self.current_conf.get('animations', {}):
            sprites_image.paste(
                animation_images[animation_name], (0, y_offset)
            )
            im_width, im_height = animation_images[animation_name].size
            y_offset += im_height
        base_path = os.path.join(directory, self._actor_name)
        sprites_image.save(base_path + '.png')
        with open(base_path + '.sps', 'w') as sps:
            sps.write(json.dumps(self._sps_infos))

    def infos(self):
        return self._sps_infos

    def get_animation_as_image(self, animation_name):
        self._crop_x = 0
        max_crop_height = 0
        n_frame = len(self.current_conf['animations'][animation_name]) - 1
        self._sps_infos[animation_name] = {
            'fps': self.current_conf['animations'][animation_name]['fps'],
            'count': n_frame
        }
        frames_images = {}
        for frame_index in range(n_frame):
            frames_images[frame_index] = self.get_frame_as_image(
                animation_name, frame_index
            )
            current_sps = self._sps_infos[
                '%s_%s' % (animation_name, frame_index)
            ]
            current_sps.update({
                'crop_x': self._crop_x,
                'crop_y': self._crop_y,
                'crop_width': int(current_sps['width'] * 32),
                'crop_height': int(current_sps['height'] * 32),
            })
            if max_crop_height < current_sps['crop_height']:
                max_crop_height = current_sps['crop_height']
            self._crop_x += current_sps['crop_width']
        animation_image = Image.new('RGBA', (self._crop_x, max_crop_height))
        for frame_index in range(n_frame):
            current_sps = self._sps_infos[
                '%s_%s' % (animation_name, frame_index)
            ]
            animation_image.paste(frames_images[frame_index], (
                current_sps['crop_x'], 0
            ))
        self._crop_y += max_crop_height
        return animation_image

    def get_frame_as_image(self, animation_name, frame_index):
        frame_key = 'frame_%d' % frame_index
        if not len(self.current_conf['animations'][animation_name][frame_key]):
            return None
        left = None
        top = None
        right = None
        bottom = None
        conf = None
        for obj in self.current_conf['animations'][animation_name][frame_key]:
            if obj.get('type', None) != 'conf':
                if left is None or left > obj['x']:
                    left = obj['x']
                if top is None or top > obj['y']:
                    top = obj['y']
                if right is None or right < obj['x'] + obj['width']:
                    right = obj['x'] + obj['width']
                if bottom is None or bottom < obj['y'] + obj['height']:
                    bottom = obj['y'] + obj['height']
        image = Image.new('RGBA', (
            int((right - left) * 32), int((bottom - top) * 32)
        ))
        for obj in self.current_conf['animations'][animation_name][frame_key]:
            if obj.get('type', None) != 'conf':
                sub_image = Image.open(
                    Config().current_file()['pathes'][obj['id']]
                )
                sub_image = sub_image.resize(
                    (int(obj['width'] * 32), int(obj['height'] * 32))
                )
                image.paste(sub_image, (
                    int((obj['x'] - left) * 32), int((obj['y'] - top) * 32)
                ))
            else:
                conf = obj
        self._sps_infos['%s_%s' % (animation_name, frame_index)] = {
            'x': left,
            'y': top,
            'width': right - left,
            'height': bottom - top
        }
        if conf is not None:
            self._sps_infos[
                '%s_%s' % (animation_name, frame_index)
            ].update(conf)
        return image
Пример #14
0
class TilesEditor(ChildWindow):

    def __init__(self):
        super(TilesEditor, self).__init__()
        self.config = Config()
        self.setWindowTitle('Tiles Editor')
        self.setFixedSize(640, 480)
        self._tab_widget = QtGui.QTabWidget(self)
        self._tab_widget.setGeometry(0, 0, 640, 480)
        self.subscribe('menu.trigger.import_tileset', self.on_import_tileset)
        self.subscribe('picture.mousemove', self.on_picture_mouse_move)
        self.subscribe('new_project', self.on_new_file)
        self.subscribe('open_project', self.on_open_file)
        self._workspaces = []

    def on_new_file(self, message):
        self._workspaces = []
        self._tab_widget.clear()

    def on_open_file(self, message):
        self.current_file = self.config.current_file()
        for tileset in self.current_file.get('tilesets', []):
            workspace = TileSetWorkspace(
                self, self.current_file['pathes'][tileset], self._queue
            )
            workspace.show()
            self._tab_widget.addTab(workspace, workspace.base_name())
            self._workspaces.append(workspace)
            self.send('tileset_editor.new_tileset', {
                'tileset': workspace.base_name()
            })
            self.send('tileset.update', {
                'tileset': workspace.base_name()
            })
            workspace.read_tilesets_config()
        self.send('open_maps')

    def on_import_tileset(self, message):
        file_name = QtGui.QFileDialog.getOpenFileName(
            self, filter='Tilesets (*.png)',
            directory=self.config.get(
                'tilesets_images_dir', os.path.expanduser('~')
            )
        )
        if file_name:
            self.config.set(
                'tilesets_images_dir',
                os.path.dirname(str(file_name))
            )
            self.send('config.save')
            workspace = TileSetWorkspace(
                self, str(file_name), self._queue
            )
            workspace.show()
            self._tab_widget.addTab(workspace, workspace.base_name())
            self._workspaces.append(workspace)
            self.send('tileset_editor.new_tileset', {
                'tileset': workspace.base_name()
            })

    def on_picture_mouse_move(self, message):
        for workspace in self._workspaces:
            workspace.on_picture_mouse_move(message)

    def remove_current(self):
        self._workspaces.pop(self._tab_widget.currentIndex())
        self._tab_widget.removeTab(self._tab_widget.currentIndex())
Пример #15
0
class AnimationArea(QtGui.QFrame):

    FPS_VALUES = [40, 35, 30, 25, 20, 15, 10, 5, 2, 1]
    NB_MULTIPLIERS = 100

    def __init__(self, parent, actor_name, animation_name):
        super(AnimationArea, self).__init__(parent)
        self._parent = parent
        self.config = Config()
        self.current_conf = Config().current_file()[
            'actors'
        ][actor_name]['animations'][animation_name]
        self._current_frame = 0
        self._actor_name = actor_name
        self._animation_name = animation_name
        self.setGeometry(0, 0, 480, 450)
        self._frames_list = QtGui.QComboBox(self)
        self._frames_list.setGeometry(5, 420, 100, 20)
        self._frames_list.currentIndexChanged.connect(self.on_change_frame)
        self._add_frame_button = IconButton(self, 'add_frame', 50, 50)
        self._add_frame_button.setGeometry(110, 420, 20, 20)
        self._add_frame_button.clicked.connect(self.on_add_frame)
        self._remove_frame_button = IconButton(self, 'remove_frame', 50, 50)
        self._remove_frame_button.setGeometry(135, 420, 20, 20)
        self._remove_frame_button.clicked.connect(self.on_remove_frame)
        self._scroll_areas = {}
        self._add_picture_button = IconButton(self, 'add_picture', 50, 50)
        self._add_picture_button.setGeometry(402, 2, 50, 50)
        self._add_picture_button.clicked.connect(self.on_new_picture)
        self._remove_animation_button = IconButton(
            self, 'remove_animation', 50, 50
        )
        self._remove_animation_button.setGeometry(402, 54, 50, 50)
        self._remove_animation_button.clicked.connect(self.on_remove_animation)
        self._resize_button = QtGui.QRadioButton('Resize', self)
        self._resize_button.setGeometry(170, 420, 70, 20)
        self._move_button = QtGui.QRadioButton('Move', self)
        self._move_button.setGeometry(240, 420, 70, 20)
        self._move_button.setChecked(True)
        self._multiplier = QtGui.QComboBox(self)
        self._multiplier.setGeometry(402, 380, 50, 20)
        for multiplier in range(1, self.NB_MULTIPLIERS + 1):
            self._multiplier.addItem('x' + str(multiplier))
        self._pos_label = QtGui.QLabel(self)
        self._pos_label.setGeometry(402, 100, 50, 100)
        self._play_animation = IconButton(self, 'play_animation', 50, 50)
        self._play_animation.setGeometry(402, 210, 50, 50)
        self._play_animation.clicked.connect(self.on_play_animation)
        self._fps_choice = QtGui.QComboBox(self)
        self._fps_choice.setGeometry(310, 420, 150, 20)
        if not len(self.current_conf):
            self._scroll_areas[0] = QtGui.QScrollArea(self)
            self._scroll_areas[0].setGeometry(0, 0, 400, 400)
            self._scroll_areas[0].setWidget(SpriteGridWidget(self))
            self._frames_list.addItem('Frame 0')
            self.current_conf['fps'] = 40
        for value in self.FPS_VALUES:
            period = 1000 / value
            self._fps_choice.addItem('%d FPS - %d ms' % (value, period))
        self._fps_choice.setCurrentIndex(self.FPS_VALUES.index(
            self.current_conf['fps']
        ))
        self._fps_choice.currentIndexChanged.connect(self.on_change_fps)
        self._multiplier.currentIndexChanged.connect(self.on_change_multiplier)

    def on_change_multiplier(self):
        frame_key = 'frame_%d' % self._current_frame
        conf = None
        for elem in self.current_conf[frame_key]:
            if elem.get('type', None) == 'conf':
                conf = elem
                break
        if conf is None:
            conf = {'type': 'conf'}
            self.current_conf[frame_key].append(conf)
        multiplier = self._multiplier.currentIndex() + 1
        conf['multiplier'] = multiplier

    def on_play_animation(self):
        preview = AnimationPreview(
            self, self._actor_name, self._animation_name
        )
        preview.show()

    def read_conf(self):
        for index in range(len(self.current_conf) - 1):
            frame_key = 'frame_%d' % index
            self._scroll_areas[index] = QtGui.QScrollArea(self)
            self._scroll_areas[index].setGeometry(0, 0, 400, 400)
            self._scroll_areas[index].setWidget(SpriteGridWidget(self))
            for obj in self.current_conf[frame_key]:
                if obj.get('type', None) != 'conf':
                    frame_image = FrameImage(
                        self._scroll_areas[index].widget(),
                        self.config.current_file()['pathes'][obj['id']],
                        obj['id'], frame_key
                    )
                    frame_image.setGeometry(
                        200 + obj['x'] * 100,
                        200 + obj['y'] * 100,
                        obj['width'] * 100,
                        obj['height'] * 100,
                    )
                    frame_image.show()
                    self._frames_list.addItem('Frame %d' % index)
            self._scroll_areas[index].hide()
        self._current_frame = 0
        self._scroll_areas[0].show()
        self._frames_list.setCurrentIndex(0)
        frame_key = 'frame_%d' % self._current_frame
        conf = None
        for elem in self.current_conf[frame_key]:
            if elem.get('type', None) == 'conf':
                conf = elem
                break
        if conf is None:
            conf = {'type': 'conf'}
            self.current_conf[frame_key].append(conf)
        multiplier = conf.get('multiplier', 1)
        self._multiplier.setCurrentIndex(multiplier - 1)

    def remove_animation(self):
        animations = Config().current_file()[
            'actors'][self._actor_name]['animations']
        del animations[self._animation_name]

    def on_remove_animation(self):
        self._parent.remove_animation(self._animation_name)

    def on_change_fps(self):
        self.current_conf['fps'] = self.FPS_VALUES[
            self._fps_choice.currentIndex()
        ]

    def on_remove_frame(self):
        if len(self._scroll_areas) > 1:
            if self._current_frame == len(self._scroll_areas) - 1:
                frame_key = self.get_frame_key()
                if frame_key in self.current_conf:
                    del self.current_conf[frame_key]
                self._scroll_areas[self._current_frame].hide()
                del self._scroll_areas[self._current_frame]
                self._current_frame -= 1
                self._frames_list.setCurrentIndex(self._current_frame)
                self._frames_list.removeItem(len(self._scroll_areas))

    def move_image(self, image, gap):
        gap_x, gap_y = gap
        obj = None
        rect = image.geometry()
        for image_obj in self.current_conf[image.frame_key()]:
            if image_obj.get('type', None) != 'conf':
                if image_obj['id'] == image.image_id():
                    obj = image_obj
        if self._move_button.isChecked():
            x, y = rect.x() + gap_x, rect.y() + gap_y
            image.setGeometry(x, y, rect.width(), rect.height())
            obj['x'] = (x - 200.0) / 100.0
            obj['y'] = (y - 200.0) / 100.0
        else:
            width = rect.width() + gap_x
            height = width * rect.height() / rect.width()
            image.setGeometry(rect.x(), rect.y(), width, height)
            obj['width'] = width / 100.0
            obj['height'] = height / 100.0
        self.update_label(obj)

    def update_label(self, image_obj):
        self._pos_label.setText(
            'X : %s\nY : %s\nW : %s\nH : %s' % (
                str(image_obj['x']),
                str(image_obj['y']),
                str(image_obj['width']),
                str(image_obj['height'])
            )
        )

    def on_change_frame(self):
        self._scroll_areas[self._current_frame].hide()
        self._current_frame = self._frames_list.currentIndex()
        frame_key = 'frame_%d' % self._current_frame
        if frame_key in self.current_conf:
            conf = None
            for elem in self.current_conf.get(frame_key, []):
                if elem.get('type', None) == 'conf':
                    conf = elem
                    break
            if conf is None:
                conf = {'type': 'conf'}
                self.current_conf[frame_key].append(conf)
            multiplier = conf.get('multiplier', 1)
        else:
            multiplier = 1
        self._multiplier.setCurrentIndex(multiplier - 1)
        self._scroll_areas[self._current_frame].show()

    def on_add_frame(self):
        if self._current_frame == len(self._scroll_areas) - 1:
            self._scroll_areas[self._current_frame].hide()
            self._current_frame += 1
            frame_label = 'Frame %d' % self._current_frame
            self._scroll_areas[self._current_frame] = QtGui.QScrollArea(self)
            self._scroll_areas[self._current_frame].setGeometry(0, 0, 400, 400)
            self._scroll_areas[self._current_frame].setWidget(
                SpriteGridWidget(self)
            )
            self._frames_list.addItem(frame_label)
            self._frames_list.setCurrentIndex(self._current_frame)
            frame_key = self.get_frame_key()
            if not frame_key in self.current_conf:
                self.current_conf[frame_key] = []

    def get_frame_key(self):
        return 'frame_%d' % self._current_frame

    def remove_image(self, frame_image):
        frame_image.hide()
        index = 0

        for image_obj in self.current_conf[frame_image.frame_key()]:
            if not 'type' in image_obj or image_obj['type'] != 'conf':
                if image_obj['id'] == frame_image.image_id():
                    self.current_conf[frame_image.frame_key()].pop(index)
            index += 1

    def on_new_picture(self):
        file_name = QtGui.QFileDialog.getOpenFileName(
            self, filter='Image (*.png)',
            directory=self.config.get(
                'frame_image_dir', os.path.expanduser('~')
            )
        )
        if file_name:
            from mqme.mainwindow import MainWindow
            file_name = unicode(file_name)
            self.config.set('frame_image_dir', os.path.dirname(file_name))
            MainWindow.queue.put({'name': 'config.save'})
            if not 'pathes' in Config().current_file():
                Config().current_file()['pathes'] = {}
            image_id = str(uuid.uuid1())
            Config().current_file()['pathes'][image_id] = file_name
            frame_key = self.get_frame_key()
            if not frame_key in self.current_conf:
                self.current_conf[frame_key] = []
            frame_image = FrameImage(
                self._scroll_areas[self._current_frame].widget(),
                file_name, image_id, frame_key
            )
            frame_image.show()
            width, height = frame_image.ratio()
            x = 0.5 - (width / 2.0)
            y = 1.0 - height
            self.current_conf[frame_key].append({
                'id': image_id,
                'width': width, 'height': height,
                'x': x, 'y': y
            })
            frame_image.setGeometry(
                200 + x * 100, 200 + y * 100, width * 100, height * 100
            )
Пример #16
0
class MapEditor(ChildWindow):

    LAYERS = [
        MapBackgroundLayer,
        MapBlockMatrixLayer,
        MapForegroundLayer,
        MapSpecialsLayer
    ]

    def __init__(self):
        super(MapEditor, self).__init__()
        self.config = Config()
        self.setFixedSize(900, 600)
        self.setWindowTitle('Map Editor')
        self.subscribe('menu.trigger.new_map', self.on_new_map)
        self.subscribe('tileset_editor.new_tileset', self.on_new_tileset)
        self.subscribe('tileset.update', self.on_tileset_update)
        self.subscribe('open_maps', self.on_open_maps)
        self.subscribe('hide_map_layer', self.on_hide_layer)
        self.subscribe('show_map_layer', self.on_show_layer)
        self._toolbox = QtGui.QToolBar(self)
        self._toolbox.setGeometry(0, 0, 100, 600)
        self._actions = {}
        for tool in MapSpecialsLayer.TOOLS:
            ref, name = tool
            action = MenuAction(self._toolbox, ref, self.on_action_checked)
            action.setIcon(QtGui.QIcon(os.path.join(
                settings.IMAGES_PATH, '%s.png' % ref
            )))
            action.setText(name)
            action.setCheckable(True)
            self._toolbox.addAction(action)
            self._actions[ref] = action
        self._tab_widget = QtGui.QTabWidget(self)
        self._tab_widget.setTabsClosable(True)
        self._tab_widget.tabCloseRequested.connect(self.on_map_delete)
        self._tab_widget.setGeometry(100, 0, 550, 550)
        self._zoom_in = IconButton(self, 'zoom_in', 30, 30)
        self._zoom_in.setGeometry(150, 560, 30, 30)
        self._zoom_in.clicked.connect(self.on_zoom_in)
        self._zoom_out = IconButton(self, 'zoom_out', 30, 30)
        self._zoom_out.setGeometry(110, 560, 30, 30)
        self._zoom_out.clicked.connect(self.on_zoom_out)
        self._tileset_cb = QtGui.QComboBox(self)
        self._tileset_cb.setGeometry(665, 5, 220, 20)
        self._tileset_cb.currentIndexChanged.connect(self.update)
        self._tiles_widgets = {}
        self._current_tool = None

    def on_map_delete(self, index):
        map_name = self._tab_widget.widget(index).map_name()
        msg_box = QtGui.QMessageBox(self)
        msg_box.setWindowTitle('Delete Map')
        msg_box.setText('Do you want to delete "%s" ?' % map_name)
        msg_box.setStandardButtons(
            QtGui.QMessageBox.Ok | QtGui.QMessageBox.Cancel
        )
        msg_box.setDefaultButton(QtGui.QMessageBox.Cancel)
        status = msg_box.exec_()
        if status == QtGui.QMessageBox.Ok:
            self._tab_widget.widget(index).remove_map()
            self._tab_widget.removeTab(index)

    def on_hide_layer(self, message):
        index = 0
        while index < self._tab_widget.count():
            self._tab_widget.widget(index).hide_layer(message['layer_type'])
            index += 1

    def on_show_layer(self, message):
        index = 0
        while index < self._tab_widget.count():
            self._tab_widget.widget(index).show_layer(message['layer_type'])
            index += 1

    def on_action_checked(self, action_ref):
        for ref, action in self._actions.items():
            if ref != action_ref:
                action.setChecked(False)
        if self._actions[action_ref].isChecked():
            self._current_tool = action_ref
        else:
            self._current_tool = None
        self._tab_widget.currentWidget().set_current_tool(self._current_tool)

    def on_open_maps(self, message):
        current_file = self.config.current_file()
        for map_name, map_obj in current_file.get('maps', {}).items():
            map_grid = MapGrid(self, map_obj, self.LAYERS)
            map_grid.read_map_conf()
            map_grid.show_layer(MapBackgroundLayer)
            self._tab_widget.addTab(map_grid, map_name)

    def on_new_project(self, message):
        self._current_tool = None
        for widget in self._tiles_widgets.values():
            widget.hide()
        self._tileset_cb.clear()
        self._tiles_widgets = {}
        self._tab_widget.clear()

    def on_select_tile(self, tile):
        for selector in self._tiles_widgets.values():
            selector.unselect_all()
        self._current_tool = tile
        self._tab_widget.currentWidget().set_current_tool(tile)

    def on_new_tileset(self, message):
        self._tileset_cb.addItem(message['tileset'])
        self._tiles_widgets[message['tileset']] = TilesSelector(
            self, self.on_select_tile, message['tileset']
        )
        self._tiles_widgets[message['tileset']].setGeometry(665, 30, 220, 560)
        self.update()

    def update(self, index=None):
        for name in self._tiles_widgets.keys():
            self._tiles_widgets[name].hide()
        current_tileset = str(self._tileset_cb.currentText())
        if current_tileset in self._tiles_widgets:
            self._tiles_widgets[current_tileset].show()

    def on_tileset_update(self, message):
        if message['tileset'] in self._tiles_widgets:
            self._tiles_widgets[message['tileset']].update()

    def on_new_map(self, message):
        map_obj = NewMapDialog.get_new_map(self)
        if map_obj is not None:
            self._tab_widget.addTab(MapGrid(
                self, map_obj, self.LAYERS), map_obj['name']
            )

    def on_zoom_in(self):
        self._tab_widget.currentWidget().on_zoom_in()

    def on_zoom_out(self):
        self._tab_widget.currentWidget().on_zoom_out()
 def on_open_file(self, message):
     self._current_file = Config().current_file()
     for name in self._current_file.get('fightenv', {}):
         workspace = FightEnvironmentWorkspace(name)
         workspace.read_conf()
         self._tabs_widget.addTab(workspace, name)
Пример #18
0
class MainWindow(QtGui.QMainWindow):

    resources_directories = (
        'fightenv', 'images', 'maps', 'sprites', 'tiles'
    )

    queue = Queue.Queue()

    CHILDREN = (
        TilesEditor, MapEditor,
        LayersDialog, SpritesEditor,
        FightEnvironmentEditor
    )

    def __init__(self, resolution, title):
        super(MainWindow, self).__init__()
        self.config = Config()
        self.config.init_from_file(settings.CONFIG_FILE_PATH)
        self._timer = QtCore.QTimer(self)
        self.setWindowIcon(QtGui.QIcon(os.path.join(
            settings.IMAGES_PATH, 'mqme.png'
        )))
        MainWindow._subscriptions = {
            'config.save': self.on_save_config_request,
            'menu.trigger.save_project': self.on_save_project_request,
            'menu.trigger.new_project': self.on_new_project_request,
            'menu.trigger.open_project': self.on_open_project_request,
            'menu.trigger.export_to_resources': self.on_export_request
        }
        self.connect(self._timer, QtCore.SIGNAL("timeout()"), self.update)
        self.workspace = QtGui.QWorkspace()
        width, height = resolution
        self.resize(width, height)
        self.setWindowTitle(title)
        self.setCentralWidget(self.workspace)
        self.setMenuBar(MenuBar(self, self.on_menu_triggered))
        self._children = []
        for child_type in self.CHILDREN:
            child = child_type()
            self.workspace.addWindow(child)
            child.set_queue(MainWindow.queue)
            self._children.append(child)
        self._timer.start(settings.QUEUE_READ_LOOP_DELAY)

    def keyPressEvent(self, event):
        super(MainWindow, self).keyPressEvent(event)
        self.send('key_press', {'key': event.key()})

    def keyReleaseEvent(self, event):
        super(MainWindow, self).keyReleaseEvent(event)
        self.send('key_release', {'key': event.key()})

    def send(self, name, body=None):
        message = {'name': name}
        if body is not None:
            message.update(body)
        MainWindow.queue.put(message)

    @staticmethod
    def subscribe(message_name, callback):
        MainWindow._subscriptions[message_name] = callback

    def receive(self, message):
        name = message.get('name')
        if name in MainWindow._subscriptions:
            MainWindow._subscriptions[name](message)

    def on_menu_triggered(self, menu_name):
        self.send('menu.trigger.%s' % menu_name)

    def update(self):
        try:
            index = 0
            while index < settings.QUEUE_READ_LOOP_DELAY:
                message = MainWindow.queue.get_nowait()
                self.receive(message)
                for child in self._children:
                    child.receive(message)
                index += 1
        except Queue.Empty:
            pass

    def on_save_config_request(self, message):
        self.config.save(settings.CONFIG_FILE_PATH)

    def on_save_project_request(self, message):
        file_name = QtGui.QFileDialog.getSaveFileName(
            self, filter='MQME Projects (*.mqp)',
            directory=self.config.get(
                'project_dir', os.path.expanduser('~')
            )
        )
        if file_name:
            file_name = unicode(file_name)
            self.config.set(
                'project_dir', os.path.dirname(file_name)
            )
            self.config.save(settings.CONFIG_FILE_PATH)
            self.config.save_current_file(file_name)

    def on_open_project_request(self, message):
        file_name = QtGui.QFileDialog.getOpenFileName(
            self, filter='MQME Projects (*.mqp)',
            directory=self.config.get(
                'project_dir', os.path.expanduser('~')
            )
        )
        if file_name:
            self.send('new_project')
            file_name = unicode(file_name)
            self.config.set(
                'project_dir', os.path.dirname(file_name)
            )
            self.config.save(settings.CONFIG_FILE_PATH)
            self.config.read_current_file(file_name)
            self.send('open_project')

    def on_new_project_request(self, message):
        self.config.reset_current_file()
        self.send('new_project')

    def on_export_request(self, message):
        if self.config.has_changed():
            msg_box = QtGui.QMessageBox(self)
            msg_box.setWindowTitle('Config has changed')
            msg_box.setText(
                'You need to save the project before exporting'
            )
            msg_box.setDefaultButton(QtGui.QMessageBox.Cancel)
            msg_box.exec_()
            return
        current_file = self.config.current_file()
        directory = None
        if 'pathes' in current_file:
            directory = current_file['pathes'].get('resources_dir', None)
        if directory is None:
            directory = QtGui.QFileDialog.getExistingDirectory(
                self, directory=self.config.get(
                    'resources_dir', os.path.expanduser('~')
                )
            )
        if directory is not None:
            directory = str(directory)
            if not 'pathes' in current_file:
                current_file['pathes'] = {}
            current_file['pathes']['resources_dir'] = directory
            self.config.set('resources_dir', directory)
            self.config.save(settings.CONFIG_FILE_PATH)
            for sub_directory in self.resources_directories:
                subpath = os.path.join(directory, sub_directory)
                if not os.path.exists(subpath):
                    os.makedirs(subpath)
            self.export_maps(directory)
            self.export_tilesets(directory)
            self.export_sprites(directory)
            self.export_fight_environments(directory)
            msg_box = QtGui.QMessageBox(self)
            msg_box.setWindowTitle('Export')
            msg_box.setText(
                'Project exported successfully !'
            )
            msg_box.setDefaultButton(QtGui.QMessageBox.Cancel)
            msg_box.exec_()

    def export_physics(self, sps_obj, id, directory):
        svg_path = os.path.join(directory, id + '.svg')
        if os.path.exists(svg_path):
            with open(svg_path) as raw_file:
                dom = parse(raw_file)
                root = dom.getElementsByTagName('svg')[0]
                image = root.getElementsByTagName('image')[0]
                width = float(image.getAttribute('width'))
                height = float(image.getAttribute('height'))
                x = float(image.getAttribute('x'))
                y = float(image.getAttribute('y'))
                for rect in root.getElementsByTagName('rect'):
                    physics_type = rect.getAttribute('id').split('_')[0]
                    if physics_type != 'platform':
                        physics_type = 'ground'
                    sps_obj['physics'][id].append({
                        'x': (float(rect.getAttribute('x')) - x) / width,
                        'y': (float(rect.getAttribute('y')) - y) / height,
                        'width': float(rect.getAttribute('width')) / width,
                        'height': float(rect.getAttribute('height')) / height,
                        'type': physics_type
                    })
                for circle in root.getElementsByTagName('path'):
                    sodipodi_type = circle.getAttribute('sodipodi:type')
                    if sodipodi_type == 'arc':
                        cx = float(circle.getAttribute('sodipodi:cx'))
                        transform_raw = circle.getAttribute('transform')
                        transform_raw = transform_raw.replace('translate(', '').replace(')', '')
                        foe_x = float(transform_raw.split(',')[0]) + cx
                        sps_obj['foes'][id].append({
                            'x': (foe_x - x) / width
                        })
                        if id.find('town_d') > -1:
                            print cx, transform_raw, foe_x, x, (foe_x - x) / width

    def export_fight_environments(self, directory):
        fightenv_directory = os.path.join(directory, 'fightenv')
        environments = self.config.current_file().get('fightenv', {})
        layers = ('background3', 'background2')
        for name, fight_env in environments.items():
            sps_obj = {'backgrounds': [], 'physics': {}, 'foes': {}}
            max_width = 0
            max_height = 0
            images = {}
            bg1_path = self.config.current_file()['pathes'][
                fight_env['background1']
            ]
            bg1_key = os.path.basename(bg1_path).split('_')[0]
            bg1_directory = os.path.dirname(bg1_path)
            for image_name in os.listdir(bg1_directory):
                if image_name.startswith(bg1_key) and image_name.endswith('.png'):
                    image_id = image_name.split('_', 1)[1].split('.')[0]
                    image_path = os.path.join(bg1_directory, image_name)
                    sps_obj['physics'][name + '_' + image_id] = []
                    sps_obj['foes'][name + '_' + image_id] = []
                    self.export_physics(
                        sps_obj, name + '_' + image_id, os.path.dirname(image_path)
                    )
                    image = utils.get_resized_image(image_path)    
                    output_path = os.path.join(
                        fightenv_directory,
                        name + '_' + image_id + '.png'
                    )
                    image.save(output_path)
                    sps_obj['backgrounds'].append('fightenv/' + name + '_' + image_id)
            for layer_index in (2, 3):
                image = utils.get_resized_image(
                    self.config.current_file()['pathes'][
                        fight_env['background' + str(layer_index)]
                    ]
                )
                output_path = os.path.join(
                    fightenv_directory,
                    name + '_bg' + str(layer_index) + '.png'
                )
                image.save(output_path)
                sps_obj['backgrounds'].append(
                    'fightenv/' + name + '_bg' + str(layer_index)
                )
            base_path = os.path.join(fightenv_directory, name)
            with open(base_path + '.sps', 'w') as sps:
                sps.write(json.dumps(sps_obj))

    def export_sprites(self, directory):
        sprites_directory = os.path.join(directory, 'sprites')
        actors = self.config.current_file().get('actors', {})
        for actor_name in actors:
            SpritesGenerator(actor_name).save(sprites_directory)

    def export_maps(self, directory):
        maps = self.config.current_file().get('maps', {})
        for map_name, map_obj in maps.items():
            path = os.path.join(directory, 'maps', map_name + '.map')
            map_obj['camera'] = [
                map_obj['camera_width'],
                map_obj['camera_height']
            ]
            map_obj['size'] = [
                map_obj['width'],
                map_obj['height']
            ]
            x = 0
            for matrix_line in map_obj['specials']:
                y = 0
                for special_conf in matrix_line:
                    if special_conf['class_name'] == 'start_pos':
                        map_obj['start_pos'] = [x, y]
                    y += 1
                x += 1
            with open(path, 'w') as map_file:
                map_file.write(json.dumps(map_obj, sort_keys=True, indent=4))

    def export_tilesets(self, directory):
        tilesets = self.config.current_file().get('tilesets', {})
        for tileset_name, tileset_obj in tilesets.items():
            path = os.path.join(directory, 'tiles', tileset_name + '.sps')
            with open(path, 'w') as tileset_file:
                tileset_file.write(json.dumps(
                    tileset_obj, sort_keys=True, indent=4
                ))
class FightEnvironmentWorkspace(QtGui.QFrame):

    LAYERS = ('screen', 'background3', 'background2', 'background1')

    def __init__(self, name):
        super(FightEnvironmentWorkspace, self).__init__()
        self._name = name
        self._height_ratio = 1.0
        self.config = Config()
        self.setGeometry(0, 0, 320, 220)
        self._layers = {}
        self._buttons = []
        self._current_conf = Config().current_file()['fightenv'][name]
        for layer_name in self.LAYERS:
            self._layers[layer_name] = self.new_layer()
        self._layers['screen'].setStyleSheet(
            'QLabel {'
            'background-color: black;'
            'border: 3px solid #ccccff;'
            '}'
        )
        self.new_button('Set background 1', 2, self.on_choose_background1, False)
        self.new_button('Set background 2', 104, self.on_choose_background2, False)
        self.new_button('Set background 3', 206, self.on_choose_background3)
        self._play_animation = IconButton(self, 'play_animation', 30, 30)
        self._play_animation.setGeometry(145, 182, 30, 30)
        self._play_animation.clicked.connect(self.on_play_animation)

    def on_play_animation(self):
        self._preview = FightEnvironmentPreview(self._name)
        self._preview.show()

    def name(self):
        return self._name

    def read_conf(self):
        for layer_name in self.LAYERS:
            if layer_name in self._current_conf:
                path = Config().current_file()['pathes'][self._current_conf[layer_name]]
                pixmap = QtGui.QPixmap(path)
                self.show_background(pixmap, layer_name)

    def show_background(self, pixmap, name):
        height = self._layers[name].height()
        width = (pixmap.width() * height) / pixmap.height()
        self._height_ratio = float(height) / pixmap.height()
        self._layers[name].setPixmap(pixmap.scaled(width, height))
        for button in self._buttons:
            button.setEnabled(True)

    def on_choose_background3(self):
        pixmap = self.choose_and_save_image('background3')
        if pixmap:
            self.show_background(pixmap, 'background3')

    def on_choose_background2(self):
        pixmap = self.choose_and_save_image('background2')
        if pixmap:
            self.show_background(pixmap, 'background2')

    def on_choose_background1(self):
        pixmap = self.choose_and_save_image('background1')
        if pixmap:
            self.show_background(pixmap, 'background1')

    def choose_and_save_image(self, image_name):
        file_name = QtGui.QFileDialog.getOpenFileName(
            self, filter='Image (*.png)',
            directory=self.config.get(
                'fightenv_image_dir', os.path.expanduser('~')
            )
        )
        if file_name:
            from mqme.mainwindow import MainWindow
            file_name = unicode(file_name)
            self.config.set('fightenv_image_dir', os.path.dirname(file_name))
            MainWindow.queue.put({'name': 'config.save'})
            if not 'pathes' in Config().current_file():
                Config().current_file()['pathes'] = {}
            image_id = str(uuid.uuid1())
            Config().current_file()['pathes'][image_id] = file_name
            self._current_conf[image_name] = image_id
            return QtGui.QPixmap(file_name)

    def new_button(self, name, x, callback, enabled=True):
        button = QtGui.QPushButton(name, self)
        button.setGeometry(x, 155, 100, 20)
        button.clicked.connect(callback)
        button.setEnabled(enabled)
        button.setStyleSheet(
            'QPushButton {'
            'font-size: 10px;'
            '}'
        )
        button.show()
        self._buttons.append(button)

    def new_layer(self):
        layer = QtGui.QLabel(self)
        layer.setGeometry(7, 0, 300, 150)
        layer.show()
        return layer
Пример #20
0
class ActorWorkspace(QtGui.QFrame):
    def __init__(self, name):
        super(ActorWorkspace, self).__init__()
        self._actor_name = name
        self._current_conf = Config().current_file()["actors"][name]
        self.setGeometry(0, 50, 640, 430)
        self._animations_list = QtGui.QListWidget(self)
        self._animations_list.setGeometry(485, 40, 150, 405)
        self._animations_list.itemClicked.connect(self.on_choose_animation)
        self._new_animation_button = QtGui.QPushButton("New animation", self)
        self._new_animation_button.setGeometry(485, 2, 150, 36)
        self._new_animation_button.clicked.connect(self.on_new_animation)
        self._animation_areas = {}

    def read_conf(self):
        for name in self._current_conf.get("animations", {}):
            self._animation_areas[name] = AnimationArea(self, self._actor_name, name)
            self._animation_areas[name].read_conf()
            self._animation_areas[name].hide()
            self._animations_list.addItem(name)

    def on_choose_animation(self, item):
        for name, area in self._animation_areas.items():
            if name == item.text():
                area.show()
            else:
                area.hide()

    def remove_animation(self, animation_name):
        msg_box = QtGui.QMessageBox(self)
        msg_box.setWindowTitle("Remove Animation")
        msg_box.setText('Do you want to remove animation "%s" ?' % animation_name)
        msg_box.setStandardButtons(QtGui.QMessageBox.Ok | QtGui.QMessageBox.Cancel)
        msg_box.setDefaultButton(QtGui.QMessageBox.Cancel)
        status = msg_box.exec_()
        if status == QtGui.QMessageBox.Ok:
            self._animation_areas[animation_name].remove_animation()
            for index in range(self._animations_list.count()):
                item = self._animations_list.item(index)
                if item.text() == animation_name:
                    self._animations_list.takeItem(index)
                    break
            item = self._animations_list.item(0)
            self._animations_list.setCurrentItem(item)
            self._animation_areas[str(item.text())].show()
            del self._animation_areas[animation_name]

    def remove_actor(self):
        actors = Config().current_file()["actors"]
        del actors[self._actor_name]

    def actor_name(self):
        return self._actor_name

    def on_new_animation(self):
        name, status = QtGui.QInputDialog.getText(self, "Animation name", "Name :")
        if status:
            name = str(name)
            if not "animations" in self._current_conf:
                self._current_conf["animations"] = {}
            self._current_conf["animations"][name] = {}
            self._animations_list.addItem(name)
            self._animation_areas[name] = AnimationArea(self, self._actor_name, name)
            self._animation_areas[name].show()
Пример #21
0
 def __init__(self, actor_name):
     self._actor_name = actor_name
     self.current_conf = Config().current_file()['actors'][actor_name]
     self._sps_infos = {}
     self._crop_x = 0
     self._crop_y = 0
Пример #22
0
 def on_open_file(self, message):
     self._current_file = Config().current_file()
     for name in self._current_file.get("actors", {}):
         workspace = ActorWorkspace(name)
         workspace.read_conf()
         self._tabs_widget.addTab(workspace, name)
Пример #23
0
class TileSetPicture(QtGui.QLabel):

    def __init__(self, parent, picture_path, queue):
        super(TileSetPicture, self).__init__(parent)
        self._parent = parent
        self._queue = queue
        self._items = []
        self._base_pixmap = QtGui.QPixmap(picture_path)
        self.config = Config()
        self.current_file = self.config.current_file()
        path_elements = os.path.split(picture_path)
        self._base_name = os.path.splitext(
            path_elements[len(path_elements) - 1]
        )[0]
        if not 'tilesets' in self.current_file:
            self.current_file['tilesets'] = {}
        if not 'pathes' in self.current_file:
            self.current_file['pathes'] = {}
        self.current_file['pathes'][self._base_name] = picture_path
        if not self._base_name in self.current_file['tilesets']:
            self.current_file['tilesets'][self._base_name] = {}
        self._current_item = None

    def base_name(self):
        return self._base_name

    def pixmap(self):
        return self._base_pixmap

    def read_tilesets_config(self):
        self.current_file = self.config.current_file()
        tileset_dict = self.current_file['tilesets'][self._base_name]
        for tile_name, tile in tileset_dict.items():
            item = TileItem(self, self._queue,
                tile['crop_x'], tile['crop_y'],
                tile['crop_width'], tile['crop_height']
            )
            item.set_name(tile_name)
            item.show()
            self._items.append(item)

    def set_height(self, height):
        pixmap = self._base_pixmap.scaledToHeight(height)
        self.setGeometry(0, 0, pixmap.width(), pixmap.height())
        self.setPixmap(pixmap)
        for item in self._items:
            item.update_geometry()

    def mousePressEvent(self, event):
        self._current_item = TileItem(self, self._queue, event.x(), event.y())
        self._current_item.show()

    def mouseReleaseEvent(self, event):
        if self._current_item is not None:
            if self._current_item.real_width() == 1:
                self._current_item.hide()
            else:
                status = False
                while not status:
                    name, status = QtGui.QInputDialog.getText(
                        self._parent, 'Tile name', 'Name :'
                    )
                name = str(name)
                self._current_item.set_name(name)
                self.current_file['tilesets'][
                    self._base_name
                ][name] = self._current_item.to_dict()
                self.current_file['tilesets']
                self._items.append(self._current_item)
                self._queue.put({'name': 'config.save'})
                self._queue.put({
                    'name': 'tileset.update',
                    'tileset': self._base_name
                })
            self._current_item = None

    def mouseMoveEvent(self, event):
        if self._current_item is not None:
            rect = self._current_item.geometry()
            width = event.x() - rect.x()
            if width < 3:
                width = 3
            height = event.y() - rect.y()
            if height < 3:
                height = 3
            self._current_item.set_size(width, height)

    def remove_item(self, item):
        self._items.pop(self._items.index(item))
        item.hide()
        del self.current_file[
            'tilesets'
        ][self._base_name][item.to_dict()['name']]

    def remove(self):
        del self.current_file['tilesets'][self._base_name]