Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
63 changes: 46 additions & 17 deletions amulet_map_editor/api/wx/ui/select_world.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,33 @@
from sys import platform
from typing import List, Dict, Tuple, Callable, TYPE_CHECKING
import traceback
import logging

from amulet import load_format
from amulet.api.errors import FormatError

from amulet_map_editor import lang, log, CONFIG
from amulet_map_editor import lang, CONFIG
from amulet_map_editor.api.wx.ui import simple
from amulet_map_editor.api.wx.util.ui_preferences import preserve_ui_preferences
from amulet_map_editor.api.framework import app


if TYPE_CHECKING:
from amulet.api.wrapper import WorldFormatWrapper

log = logging.getLogger(__name__)


# Windows %APPDATA%\.minecraft
# macOS ~/Library/Application Support/minecraft
# Linux ~/.minecraft


def get_java_dir():
if platform == "win32":
return os.path.join(os.getenv("APPDATA"), ".minecraft")
elif platform == "darwin":
return os.path.expanduser("~/Library/Application Support/minecraft")
else:
return os.path.expanduser("~/.minecraft")


def get_java_saves_dir():
return os.path.join(get_java_dir(), "saves")


minecraft_world_paths = {lang.get("world.java_platform"): get_java_saves_dir()}
minecraft_world_paths = {}

if platform == "win32":
minecraft_world_paths[lang.get("world.java_platform")] = os.path.join(
os.getenv("APPDATA"), ".minecraft", "saves"
)
minecraft_world_paths[lang.get("world.bedrock_platform")] = os.path.join(
os.getenv("LOCALAPPDATA"),
"Packages",
Expand All @@ -47,6 +40,35 @@ def get_java_saves_dir():
"com.mojang",
"minecraftWorlds",
)
minecraft_world_paths[lang.get("world.bedrock_education_store")] = os.path.join(
os.getenv("LOCALAPPDATA"),
"Packages",
"Microsoft.MinecraftEducationEdition_8wekyb3d8bbwe",
"LocalState",
"games",
"com.mojang",
"minecraftWorlds",
)
minecraft_world_paths[lang.get("world.bedrock_education_desktop")] = os.path.join(
os.getenv("APPDATA"),
"Minecraft Education Edition",
"games",
"com.mojang",
"minecraftWorlds",
)
minecraft_world_paths[lang.get("world.bedrock_netease")] = os.path.join(
os.getenv("APPDATA"),
"MinecraftPE_Netease",
"minecraftWorlds",
)
elif platform == "darwin":
minecraft_world_paths[lang.get("world.java_platform")] = os.path.join(
os.path.expanduser("~"), "Library", "Application Support", "minecraft", "saves"
)
elif platform == "linux":
minecraft_world_paths[lang.get("world.java_platform")] = os.path.join(
os.path.expanduser("~"), ".minecraft", "saves"
)

world_images: Dict[str, Tuple[int, wx.Bitmap, int]] = {}

Expand All @@ -57,7 +79,7 @@ def get_world_image(image_path: str) -> Tuple[wx.Bitmap, int]:
or world_images[image_path][0] != os.stat(image_path)[8]
):
img = wx.Image(image_path, wx.BITMAP_TYPE_ANY)
width = min((img.GetWidth() / img.GetHeight()) * 128, 300)
width = min(int((img.GetWidth() / img.GetHeight()) * 128), 300)

world_images[image_path] = (
os.stat(image_path)[8],
Expand Down Expand Up @@ -357,3 +379,10 @@ def _close(self):
self.EndModal(0)
else:
self.Close()


def open_level_from_dialog(parent: wx.Window):
"""Show the open world dialog and open the selected world."""
select_world = WorldSelectDialog(parent, app.open_level)
select_world.ShowModal()
select_world.Destroy()
16 changes: 15 additions & 1 deletion amulet_map_editor/api/wx/util/button_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,8 @@ def is_key_pressed(self, key: KeyType):

def unpress_all(self):
"""Unpress all keys.
This is useful if the window focus is lost because key release events will not be detected."""
This is useful if the window focus is lost because key release events will not be detected.
"""
self._pressed_keys.clear()
self._clean_up_actions()

Expand Down Expand Up @@ -243,3 +244,16 @@ def _clean_up_actions(self):

def _process_continuous_inputs(self, evt):
wx.PostEvent(self.window, InputHeldEvent(self._continuous_actions.copy()))

# Programmatic control for virtual/touch inputs
def press_action(self, action_id: ActionIDType):
"""Programmatically start an action as if its key was pressed."""
if action_id in self._registered_actions and action_id not in self._continuous_actions:
self._continuous_actions.add(action_id)
wx.PostEvent(self.window, InputPressEvent(action_id))

def release_action(self, action_id: ActionIDType):
"""Programmatically stop an action as if its key was released."""
if action_id in self._continuous_actions:
self._continuous_actions.remove(action_id)
wx.PostEvent(self.window, InputReleaseEvent(action_id))
43 changes: 31 additions & 12 deletions amulet_map_editor/api/wx/util/key_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,6 @@
def serialise_modifier(
evt: Union[wx.KeyEvent, wx.MouseEvent], key: int
) -> ModifierType:

modifier = []
if evt.ControlDown():
if key not in (wx.WXK_SHIFT, wx.WXK_ALT):
Expand Down Expand Up @@ -272,10 +271,9 @@ def serialise_key(evt: Union[wx.KeyEvent, wx.MouseEvent]) -> Optional[KeyType]:


def serialise_key_event(
evt: Union[wx.KeyEvent, wx.MouseEvent]
evt: Union[wx.KeyEvent, wx.MouseEvent],
) -> Optional[SerialisedKeyType]:
if isinstance(evt, wx.KeyEvent):

key = evt.GetUnicodeKey() or evt.GetKeyCode()
if key == wx.WXK_CONTROL:
return
Expand Down Expand Up @@ -314,13 +312,21 @@ def __init__(self, parent: wx.Window, action: str):

self._key = ((), "NONE")

self.Bind(wx.EVT_LEFT_DOWN, self._on_key)
self.Bind(wx.EVT_MIDDLE_DOWN, self._on_key)
self.Bind(wx.EVT_RIGHT_DOWN, self._on_key)
self.Bind(wx.EVT_KEY_DOWN, self._on_key)
self.Bind(wx.EVT_MOUSEWHEEL, self._on_key)
self.Bind(wx.EVT_MOUSE_AUX1_DOWN, self._on_key)
self.Bind(wx.EVT_MOUSE_AUX2_DOWN, self._on_key)
panel = wx.Panel(self)
panel.SetFocus()

panel.Bind(wx.EVT_LEFT_DOWN, self._on_key)
panel.Bind(wx.EVT_MIDDLE_DOWN, self._on_key)
panel.Bind(wx.EVT_RIGHT_DOWN, self._on_key)
panel.Bind(wx.EVT_KEY_DOWN, self._on_key)
panel.Bind(wx.EVT_MOUSEWHEEL, self._on_key)
panel.Bind(wx.EVT_MOUSE_AUX1_DOWN, self._on_key)
panel.Bind(wx.EVT_MOUSE_AUX2_DOWN, self._on_key)

sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(panel, 1, wx.EXPAND)
self.SetSizer(sizer)
self.Layout()

def _on_key(self, evt):
key = serialise_key_event(evt)
Expand Down Expand Up @@ -349,18 +355,31 @@ def __init__(
entries: Sequence[KeyActionType],
fixed_keybinds: KeybindContainer,
user_keybinds: KeybindContainer,
*,
touch_controls_enabled: bool = False,
):
super().__init__(parent, "Key Select")
self._key_config = KeyConfig(
self, selected_group, entries, fixed_keybinds, user_keybinds
)
self.sizer.Add(self._key_config, 1, wx.EXPAND)

# Touch controls toggle (placed at the bottom of this dialog)
bottom = wx.BoxSizer(wx.HORIZONTAL)
self._touch_checkbox = wx.CheckBox(
self, label="Enable touchscreen mode (experemental)"
)
self._touch_checkbox.SetValue(bool(touch_controls_enabled))
bottom.Add(self._touch_checkbox, 0, wx.ALL, 50)
self.sizer.Add(bottom, 0, wx.EXPAND)

self.Layout()
self.Fit()

@property
def options(self) -> Tuple[KeybindContainer, KeybindGroupIdType, KeybindGroup]:
return self._key_config.options
def options(self) -> Tuple[KeybindContainer, KeybindGroupIdType, KeybindGroup, bool]:
user_keybinds, group_id, keybinds = self._key_config.options
return user_keybinds, group_id, keybinds, self._touch_checkbox.GetValue()


class KeyConfig(wx.BoxSizer):
Expand Down
14 changes: 14 additions & 0 deletions amulet_map_editor/lang/en.lang
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,22 @@ program_3d_edit.goto_ui.paste_button_tooltip=Paste a previously copied coordinat
program_3d_edit.file_ui.version_tooltip=Platform and data version of the world
program_3d_edit.file_ui.projection_tooltip=Change view
program_3d_edit.file_ui.location_tooltip=Move camera
program_3d_edit.file_ui.speed_blocks_per_second=b/s
program_3d_edit.file_ui.speed_tooltip=Camera speed in blocks per second
program_3d_edit.file_ui.speed_dialog_name=Set camera speed
program_3d_edit.file_ui.dim_tooltip=Select dimension
program_3d_edit.file_ui.undo_tooltip=Undo
program_3d_edit.file_ui.redo_tooltip=Redo
program_3d_edit.file_ui.save_tooltip=Save changes
program_3d_edit.file_ui.close_tooltip=Close world

# Touch Controls
program_3d_edit.touch_controls.toggle_label=Touch Controls
program_3d_edit.touch_controls.toggle_tooltip=Show/hide on-screen movement buttons
program_3d_edit.mouse_mode.toggle_label=Selector / Camera
program_3d_edit.mouse_mode.toggle_tooltip=Toggle between selection mode and camera rotation mode

# Options
program_3d_edit.options.field_of_view=Field of View
program_3d_edit.options.render_distance=Render Distance
program_3d_edit.options.camera_sensitivity=Camera Sensitivity
Loading
Loading