Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Map snapshot #183

Closed
wants to merge 23 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions packages/map_editor/classes/Commands/DeepCopyLayerCommand.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from dt_maps import MapLayer
from classes.basic.command import Command


class DeepCopyLayerCommand(Command):
_layer_name: str

def __init__(self, layer_name: str):
self._layer_name = layer_name

def execute(self, layer: MapLayer, layer_name: str, *args,
**kwargs) -> None:
if layer_name == self._layer_name:
get_deepcopy = kwargs["get_deepcopy"]
return get_deepcopy(layer)
20 changes: 16 additions & 4 deletions packages/map_editor/classes/layers.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
from mapStorage import MapStorage
from utils.constants import LAYER_NAME
from utils.maps import create_layer
from typing import Dict, Any
from copy import deepcopy
from typing import Dict, Any, Optional
from copy import deepcopy, copy


class AbstractLayer(ABC):
Expand Down Expand Up @@ -44,6 +44,17 @@ def check_config(self, config: Dict[str, Any]) -> bool:
def set_layer_handler(self, handler: EntityHelper) -> None:
self._layer_handler = handler

def get_layer_deepcopy(self, layer: MapLayer) -> Optional[Dict[str, Any]]:
if not len(layer):
return {}
new_layer = {}
for name, item in layer.items():
new_item = {}
for item_filed in self._default_conf:
new_item[item_filed] = deepcopy(layer[name][item_filed])
new_layer[name] = new_item
return new_layer


class BasicLayerHandler(AbstractHandler, AbstractLayer):
def __init__(self, **kwargs) -> None:
Expand All @@ -52,7 +63,8 @@ def __init__(self, **kwargs) -> None:
def handle(self, command: Command) -> Any:
response = command.execute(self._data, self._layer_name,
deepcopy(self._default_conf),
check_config=self.check_config)
check_config=self.check_config,
get_deepcopy=self.get_layer_deepcopy)
if response:
return response
return super().handle(command)
Expand All @@ -62,7 +74,7 @@ class DynamicLayer(EntityHelper):
_fields: Dict[str, Any] = {}
_layer_name: str = ""

def __init__(self, **kwargs):
def __init__(self, **kwargs) -> None:
super(DynamicLayer, self).__init__(kwargs["map"], kwargs[LAYER_NAME])
self._layer_name = kwargs[LAYER_NAME]
for field_name, field_val in kwargs["conf"].items():
Expand Down
8 changes: 1 addition & 7 deletions packages/map_editor/editorState.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,12 @@

DEFAULT_TILE_SIZE = 0.585


# TODO is draw state set draw state
class EditorState(metaclass=SingletonMeta):
drawState = ''
copyBuffer = [[]]
debug_mode = False

def __init__(self) -> None:
self.distortion_view_one_string_mode = True
self.region_create = False
self.active_items = []
self.active_group = None
self.name_of_editable_obj = None
self.tile_size = DEFAULT_TILE_SIZE
self.is_move = False

Expand Down
64 changes: 64 additions & 0 deletions packages/map_editor/history.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
from typing import Optional

MAX_BUFFER_LENGTH = 100


class Memento:
_state = None

def __init__(self, state) -> None:
self._state = state

def get_state(self):
return self._state


class EditorHistory:
buffer: [Memento] = []
current_state_index: int = -1

def delete(self, start_index: int) -> None:
"""
Delete objects from current_state_index to max_length.
If buffer is full, delete old states.
"""
del self.buffer[start_index:]

def clear_history(self) -> None:
self.delete(0)

def push(self, m: Memento) -> None:
"""
Add new state to the end of buffer.
"""
if self.current_state_index + 1 == MAX_BUFFER_LENGTH:
self.buffer.pop(0)
self.current_state_index -= 1

if self.current_state_index + 1 < MAX_BUFFER_LENGTH:
self.buffer.append(m)
self.current_state_index = len(self.buffer) - 1

def undo(self) -> Optional[Memento]:
"""
Return state from history at index current_state_index - 1.
"""
if self.current_state_index - 1 >= 0:
self.current_state_index -= 1
return self.buffer[self.current_state_index]
elif self.current_state_index == 0:
return self.buffer[0]
else:
return None

def shift_undo(self) -> Optional[Memento]:
"""
Return state from history at index current_state_index + 1.
"""
if self.current_state_index == len(self.buffer) - 1:
return self.buffer[self.current_state_index]
elif self.current_state_index + 1 < len(self.buffer):
self.current_state_index += 1
return self.buffer[self.current_state_index]
else:
return None
Binary file added packages/map_editor/img/icons/shift_undo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion packages/map_editor/layers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
from __future__ import annotations
from pathlib import Path
from typing import Any, Dict
from utils.constants import TILE_SIZE
Expand Down
1 change: 1 addition & 0 deletions packages/map_editor/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ def main(args):

# Create main window
window = DuckWindow(args)
window.map_viewer.save_viewer_state()

window.show()
app.exec_()
Expand Down
89 changes: 64 additions & 25 deletions packages/map_editor/mainWindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import json
import codecs
from PyQt5.QtGui import QResizeEvent, QKeyEvent, QMouseEvent
from history import Memento
from mapAPI import MapAPI
from mapViewer import MapViewer
from utils.debug import DebugLine
Expand Down Expand Up @@ -61,7 +62,6 @@ def get_translation(self, elem):
return elem['lang']['en']

def init_ui(self):
self.center()
self.show()

# Initialize button objects
Expand Down Expand Up @@ -96,17 +96,38 @@ def init_ui(self):
a3 = QtWidgets.QAction(QtGui.QIcon("img/icons/save.png"), _translate("MainWindow", "Save map (Ctrl+S)"), self)
a4 = QtWidgets.QAction(QtGui.QIcon("img/icons/save_as.png"), _translate("MainWindow", "Save map as (Ctrl+Alt+S)"), self)
a5 = QtWidgets.QAction(QtGui.QIcon("img/icons/png.png"), _translate("MainWindow", "Export to PNG (Ctrl+P)"), self)
a6 = QtWidgets.QAction(QtGui.QIcon("img/icons/leftup.png"),
a6 = QtWidgets.QAction(QtGui.QIcon("img/icons/leftup.png"), _translate("MainWindow", "To the corner of the map (Ctrl+M)"), self)
a7 = QtWidgets.QAction(QtGui.QIcon("img/icons/undo.png"), _translate("MainWindow", "Undo (Ctrl+Z)"), self)
a8 = QtWidgets.QAction(QtGui.QIcon("img/icons/shift_undo.png"), _translate("MainWindow", "Shift undo (Ctrl+Shift+Z)"), self)
a9 = QtWidgets.QAction(QtGui.QIcon("img/icons/delete.png"),
_translate("MainWindow",
"To the corner of the map (Ctrl+M)"), self)
"Delete (Ctrl+D or Delete)"), self)
a9.setShortcuts(["Ctrl+D", "Delete"])
a6.setShortcut("Ctrl+M")
a7 = QtWidgets.QAction(QtGui.QIcon("img/icons/delete.png"),
_translate("MainWindow", "Delete (Ctrl+D or Delete)"), self)
a7.setShortcuts(["Ctrl+D", "Delete"])
a7.setShortcut("Ctrl+Z")
a8.setShortcut("Ctrl+Shift+Z")


# TODO
'''
b1 = QtWidgets.QAction(QtGui.QIcon("img/icons/copy.png"), _translate("MainWindow", "Copy"), self)
b2 = QtWidgets.QAction(QtGui.QIcon("img/icons/cut.png"), _translate("MainWindow", "Cut"), self)
b3 = QtWidgets.QAction(QtGui.QIcon("img/icons/insert.png"), _translate("MainWindow", "Paste"), self)
b4 = QtWidgets.QAction(QtGui.QIcon("img/icons/delete.png"), _translate("MainWindow", "Delete"), self)
b1.setShortcut("Ctrl+C")
b2.setShortcut("Ctrl+X")
b3.setShortcut("Ctrl+V")
b4.setShortcut("Delete")
'''

c1 = QtWidgets.QAction(QtGui.QIcon("img/icons/rotate.png"), _translate("MainWindow", "Rotate (Ctrl+R)"), self)
c1.setShortcut("Ctrl+R")

# TODO
#c2 = QtWidgets.QAction(QtGui.QIcon("img/icons/trim.png"),
# _translate("MainWindow", "Delete extreme empty blocks"), self)
#c2.setShortcut("Ctrl+F")

self.brush_button.setIcon(QtGui.QIcon("img/icons/brush.png"))
self.brush_button.setCheckable(True)
self.brush_button.setToolTip("Brush tool (Ctrl+B)")
Expand All @@ -118,21 +139,43 @@ def init_ui(self):
a4.triggered.connect(self.save_map_as_triggered)
a5.triggered.connect(self.save_map_as_png)
a6.triggered.connect(self.to_the_map_corner)
a7.triggered.connect(self.delete_selected_objects)

c1.triggered.connect(self.rotate_selected_tiles)
a7.triggered.connect(self.undo_button_clicked)
a8.triggered.connect(self.shift_undo_button_clicked)
a9.triggered.connect(self.delete_selected_objects)

# TODO
'''
b1.triggered.connect(self.copy_button_clicked)
b2.triggered.connect(self.cut_button_clicked)
b3.triggered.connect(self.insert_button_clicked)
b4.triggered.connect(self.delete_button_clicked)
b5.triggered.connect(self.undo_button_clicked)
'''

c1.triggered.connect(self.rotate_selected_objects)
# TODO
#c2.triggered.connect(self.trimClicked)

self.brush_button.clicked.connect(self.brush_mode)

for elem in [[a1, a2, a3, a4, a5]]:
for act in elem:
tool_bar.addAction(act)
tool_bar.addSeparator()
tool_bar.addAction(a9)
tool_bar.addAction(a7)
tool_bar.addAction(a8)
tool_bar.addWidget(self.brush_button)
tool_bar.addAction(c1)
tool_bar.addAction(a6)

# TODO
#tool_bar.addAction(c2)

# TODO
# Setup Layer Tree menu
#self.ui.layer_tree.setModel(QtGui.QStandardItemModel()) # set item model for tree

# Customize the Blocks menu
block_list_widget = self.ui.block_list
block_list_widget.itemClicked.connect(self.item_list_clicked)
Expand Down Expand Up @@ -166,12 +209,6 @@ def init_ui(self):

default_fill.setCurrentText(self.get_translation(information["grass"])['name'])

def change_env(self):
pass

def center(self):
pass

def to_the_map_corner(self) -> None:
self.map_api.to_the_map_corner()

Expand All @@ -186,12 +223,6 @@ def import_old_format(self):
def create_map_triggered(self) -> None:
self.map_api.create_map_form()

def create_region(self):
pass

def change_distortion_view_triggered(self):
pass

# Save map
def save_map_triggered(self):
self.map_api.save_map_triggered()
Expand Down Expand Up @@ -284,9 +315,17 @@ def insert_button_clicked(self):
def delete_selected_objects(self) -> None:
self.map_api.delete_selected_objects()

# Undo
def undo_button_clicked(self):
pass
def undo_button_clicked(self) -> None:
self.map_api.undo_button_clicked()

def shift_undo_button_clicked(self) -> None:
self.map_api.shift_button_clicked()

def push_state(self, m: Memento) -> None:
self.map_api.push_state(m)

def clear_editor_history(self) -> None:
self.map_api.clear_editor_history()

# Brush mode
def brush_mode(self) -> None:
Expand All @@ -307,7 +346,7 @@ def keyReleaseEvent(self, event: QKeyEvent) -> None:
def mousePressEvent(self, event: QMouseEvent):
self.map_api.mouse_press_event(event)

def rotate_selected_tiles(self) -> None:
def rotate_selected_objects(self) -> None:
self.map_api.rotate_selected_objects()

def update_debug_info(self, event: Dict[str, Any]) -> None:
Expand Down
24 changes: 21 additions & 3 deletions packages/map_editor/mapAPI.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from utils.qtWindowAPI import QtWindowAPI
from mapStorage import MapStorage
from mapViewer import MapViewer
from history import Memento, EditorHistory
from utils.debug import DebugLine
from typing import Dict, Any
from pathlib import Path
Expand All @@ -30,13 +31,15 @@ class MapAPI:
_map_viewer: MapViewer = None
_editor_state: EditorState = None
_debug_line: DebugLine = None
_history: EditorHistory = None

def __init__(self, info_json: dict, map_viewer: MapViewer, args) -> None:
self._map_storage = MapStorage()
self._qt_api = QtWindowAPI(args.wkdir)
self.info_json = info_json
self._map_viewer = map_viewer
self._editor_state = EditorState()
self._history = EditorHistory()
self.change_obj_info_form = None
self.init_info_form = NewMapInfoForm(args.wkdir)
self.init_info_form.send_info.connect(self.create_map_triggered)
Expand Down Expand Up @@ -226,8 +229,21 @@ def delete_button_clicked(self):
pass

# Undo
def undo_button_clicked(self):
pass
def undo_button_clicked(self) -> None:
m = self._history.undo()
if m:
self._map_viewer.restore_state(m)

def shift_button_clicked(self) -> None:
m = self._history.shift_undo()
if m:
self._map_viewer.restore_state(m)

def push_state(self, m: Memento) -> None:
self._history.push(m)

def clear_editor_history(self) -> None:
self._history.clear_history()

# Brush mode
def brush_mode(self, brush_button_is_checked: bool) -> None:
Expand All @@ -237,7 +253,8 @@ def brush_mode(self, brush_button_is_checked: bool) -> None:
self._editor_state.drawState = ''

def selection_update(self, default_fill: str) -> None:
if self._editor_state.drawState == 'brush':
if self._editor_state.drawState == 'brush' and \
self._map_viewer.have_selected_tiles():
self._map_viewer.painting_tiles(default_fill)

def key_press_event(self, event: QKeyEvent) -> None:
Expand All @@ -258,6 +275,7 @@ def key_release_event(self, event: QKeyEvent) -> None:
def rotate_selected_objects(self) -> None:
self._map_viewer.rotate_tiles()
self._map_viewer.rotate_objects()
self._map_viewer.save_viewer_state()

def set_debug_mode(self, debug_line: DebugLine) -> None:
self._editor_state.debug_mode = True
Expand Down
Loading