better menus

This commit is contained in:
klemek
2021-08-26 17:11:18 +02:00
parent cbc988d4ee
commit 7c26c5a39d
7 changed files with 133 additions and 165 deletions
View File
+127 -159
View File
@@ -1,15 +1,57 @@
import tkinter as tk import tkinter as tk
from tkinter import ttk, filedialog from tkinter import ttk, filedialog
from typing import Optional from typing import Optional
from enum import Enum
import os.path
from .explorer import Explorer from explorer import Explorer
from .image_view import ImageView from image_view import ImageView
from .file import File from file import File
from .image import Image from image import Image
from .bitmap import Bitmap from bitmap import Bitmap
class MenuEntryType(Enum):
DEFAULT = 0
NEED_FILE = 1
NEED_IMAGE = 2
SEPARATOR = 4
class App(ttk.Frame): class App(ttk.Frame):
MENU_ENTRIES = {
"File": [
("New File", "_file_new", MenuEntryType.DEFAULT),
("Open File...", "_file_open", MenuEntryType.DEFAULT),
("", "", MenuEntryType.SEPARATOR),
("Save File", "_file_save", MenuEntryType.NEED_FILE),
("Save File As...", "_file_save_as", MenuEntryType.NEED_FILE),
("Close File", "_file_close", MenuEntryType.NEED_FILE),
("", "", MenuEntryType.SEPARATOR),
("New image...", "_file_new_image", MenuEntryType.NEED_FILE), # TODO _file_new_image
("", "", MenuEntryType.SEPARATOR),
("Quit", "_file_quit", MenuEntryType.DEFAULT), # TODO _file_quit
],
"Image": [
("Edit Image Name...", "_image_edit_name", MenuEntryType.NEED_IMAGE), # TODO _image_edit_name
("Edit Image Size...", "_image_edit_size", MenuEntryType.NEED_IMAGE), # TODO _image_edit_size
("Move Image Up", "_image_move_up", MenuEntryType.NEED_IMAGE), # TODO _image_move_up
("Move Image Down", "_image_move_down", MenuEntryType.NEED_IMAGE), # TODO _image_move_down
("Delete Image", "_image_delete", MenuEntryType.NEED_IMAGE), # TODO _image_delete
],
"Bitmap": [
("Bulk .bmp Import...", "_bmp_import_all", MenuEntryType.NEED_FILE), # TODO _bmp_import_all
("Export All To .bmp...", "_bmp_export_all", MenuEntryType.NEED_FILE), # TODO _bmp_export_all
("", "", MenuEntryType.SEPARATOR),
(
"Import .bmp Into Image...",
"_bmp_import_image",
MenuEntryType.NEED_IMAGE,
),
("Export Image To .bmp...", "_bmp_export_image", MenuEntryType.NEED_IMAGE),
],
}
def __init__(self, parent) -> None: def __init__(self, parent) -> None:
super().__init__(parent) super().__init__(parent)
@@ -63,141 +105,58 @@ class App(ttk.Frame):
self.menubar = tk.Menu(self.parent) self.menubar = tk.Menu(self.parent)
self.parent["menu"] = self.menubar self.parent["menu"] = self.menubar
self.menu_file = tk.Menu(self.menubar) self.menus = {}
self.menubar.add_cascade(menu=self.menu_file, label="File")
# TODO better handling of menu items for menu_name in self.MENU_ENTRIES:
self.menus[menu_name] = tk.Menu(self.menubar)
self.menubar.add_cascade(menu=self.menus[menu_name], label=menu_name)
self.menu_file_need_file = [] for entry_name, entry_action_name, entry_type in self.MENU_ENTRIES[
menu_name
self.menu_file.add_command(label="New File", command=lambda: self.open_file("")) ]:
i = 0 if entry_type == MenuEntryType.SEPARATOR:
self.menu_file.add_command( self.menus[menu_name].add_separator()
label="Open File...", else:
command=lambda: self.open_file( try:
filedialog.askopenfilename( entry_action = getattr(self, entry_action_name)
filetypes=File.FILE_TYPES, except AttributeError:
defaultextension=File.FILE_TYPES, entry_action = lambda: print("missing menu action")
) self.menus[menu_name].add_command(
), label=entry_name, command=entry_action
) )
i += 1
self.menu_file.add_command(
label="Save File",
command=lambda: self.save_file(self.current_file.path),
)
i += 1
self.menu_file_need_file += [i]
self.menu_file.add_command(
label="Save File As...",
command=lambda: self.save_file(
filedialog.asksaveasfilename(
filetypes=File.FILE_TYPES, defaultextension=File.FILE_TYPES
)
),
)
i += 1
self.menu_file_need_file += [i]
self.menu_file.add_command(
label="Close File",
command=lambda: self.open_file(None),
)
i += 1
self.menu_file_need_file += [i]
self.menu_file.add_separator()
i += 1
self.menu_file.add_command(
label="New image...",
command=self.add_image,
state="disabled",
)
i += 1
self.menu_file_need_file += [i]
self.menu_image = tk.Menu(self.menubar)
self.menubar.add_cascade(menu=self.menu_image, label="Image")
self.menu_image.add_command(
label="Edit name...",
command=self.edit_image_name,
state="disabled",
)
self.menu_image.add_command(
label="Edit size...",
command=self.edit_image_size,
state="disabled",
)
self.menu_image.add_command(
label="Move up",
command=self.move_image_up,
state="disabled",
)
self.menu_image.add_command(
label="Move down",
command=self.move_image_down,
state="disabled",
)
self.menu_image.add_command(
label="Delete",
command=self.delete_image,
state="disabled",
)
self.menu_bmp = tk.Menu(self.menubar)
self.menubar.add_cascade(menu=self.menu_bmp, label="Bitmap")
self.menu_bmp_need_image = []
self.menu_bmp.add_command(
label="Bulk .bmp import...",
command=self.import_all_bmp,
)
i = 0
self.menu_bmp.add_command(
label="Export all to .bmp...",
command=self.export_all_bmp,
)
i += 1
self.menu_bmp.add_separator()
i += 1
self.menu_bmp.add_command(
label="Import .bmp into image...",
command=self.import_bmp,
state="disabled",
)
i += 1
self.menu_bmp_need_image += [i]
self.menu_bmp.add_command(
label="Export image to .bmp...",
command=self.export_bmp,
state="disabled",
)
i += 1
self.menu_bmp_need_image += [i]
def update_menus(self) -> None: def update_menus(self) -> None:
for index in self.menu_file_need_file: for menu_name in self.MENU_ENTRIES:
self.menu_file.entryconfigure( any_enabled = False
index, for entry_name, entry_action, entry_type in self.MENU_ENTRIES[menu_name]:
state=("normal" if self.current_file is not None else "disabled"), if entry_type == MenuEntryType.NEED_FILE:
) self.menus[menu_name].entryconfigure(
self.menubar.entryconfigure( entry_name,
"Image", state=("normal" if self.current_image is not None else "disabled") state=(
) "normal" if self.current_file is not None else "disabled"
self.menubar.entryconfigure( ),
"Bitmap", state=("normal" if self.current_file is not None else "disabled") )
) any_enabled |= self.current_file is not None
for index in self.menu_bmp_need_image: elif entry_type == MenuEntryType.NEED_IMAGE:
self.menu_bmp.entryconfigure( self.menus[menu_name].entryconfigure(
index, entry_name,
state=("normal" if self.current_image is not None else "disabled"), state=(
"normal" if self.current_image is not None else "disabled"
),
)
any_enabled |= self.current_image is not None
elif entry_type == MenuEntryType.DEFAULT:
any_enabled = True
self.menubar.entryconfigure(
menu_name, state=("normal" if any_enabled else "disabled")
) )
def open_file(self, path: Optional[str]) -> None: def open_file(self, path: Optional[str], new: bool = False) -> None:
if path is None: if path is None and not new:
self.current_file = None self.current_file = None
else: else:
self.current_file = File(path if path != "" else None) self.current_file = File(path)
self.update(force=True) self.update(force=True)
def save_file(self, path: Optional[str] = None) -> None: def save_file(self, path: Optional[str] = None) -> None:
@@ -206,49 +165,58 @@ class App(ttk.Frame):
self.current_file.export(path) self.current_file.export(path)
self.open_file(path) self.open_file(path)
def add_image(self) -> None: def _file_new(self) -> None:
pass # TODO add image action self.open_file(None, True)
def edit_image_name(self) -> None: def _file_open(self) -> None:
pass # TODO edit image name action path = filedialog.askopenfilename(
filetypes=File.FILE_TYPES,
defaultextension=File.FILE_TYPES,
initialfile=(
os.path.basename(self.current_file.path)
if self.current_file is not None
else None
),
initialdir=(
os.path.dirname(self.current_file.path)
if self.current_file is not None
else None
),
)
if path:
self.open_file(path)
def edit_image_size(self) -> None: def _file_save(self) -> None:
pass # TODO edit image size action self.save_file()
def move_image_up(self) -> None: def _file_save_as(self) -> None:
pass # TODO move image actions path = filedialog.asksaveasfilename(
filetypes=File.FILE_TYPES,
defaultextension=File.FILE_TYPES,
initialfile=os.path.basename(self.current_file.path),
initialdir=os.path.dirname(self.current_file.path),
)
if path:
self.save_file(path)
def move_image_down(self) -> None: def _file_close(self) -> None:
pass # TODO move image actions self.open_file(None)
def delete_image(self) -> None: def _bmp_import_image(self) -> None:
pass # TODO delete image action
def import_all_bmp(self) -> None:
pass # TODO import all bmp action
def export_all_bmp(self) -> None:
pass # TODO export all bmp action
def import_bmp(self) -> None:
if self.current_image is None:
return
path = filedialog.askopenfilename( path = filedialog.askopenfilename(
filetypes=Bitmap.FILE_TYPES, filetypes=Bitmap.FILE_TYPES,
defaultextension=Bitmap.FILE_TYPES, defaultextension=Bitmap.FILE_TYPES,
) )
if path is not None: if path:
# TODO error handling # TODO error handling
self.current_image.import_bmp(path) self.current_image.import_bmp(path)
self.update() self.update()
def export_bmp(self) -> None: def _bmp_export_image(self) -> None:
if self.current_image is None:
return
path = filedialog.asksaveasfilename( path = filedialog.asksaveasfilename(
filetypes=Bitmap.FILE_TYPES, filetypes=Bitmap.FILE_TYPES,
defaultextension=Bitmap.FILE_TYPES, defaultextension=Bitmap.FILE_TYPES,
initialfile=f"{self.current_image.name}.bmp", initialfile=f"{self.current_image.name}.bmp",
) )
if path is not None: if path:
self.current_image.export_bmp(path) self.current_image.export_bmp(path)
+2 -2
View File
@@ -1,8 +1,8 @@
from tkinter import ttk from tkinter import ttk
from typing import Optional from typing import Optional
from .file import File from file import File
from .image import Image from image import Image
class Explorer(ttk.Frame): class Explorer(ttk.Frame):
+1 -1
View File
@@ -2,7 +2,7 @@ from typing import List
import re import re
import os.path import os.path
from .image import Image from image import Image
class File: class File:
+1 -1
View File
@@ -1,7 +1,7 @@
from typing import List from typing import List
from math import sqrt from math import sqrt
from .bitmap import Bitmap from bitmap import Bitmap
class Image: class Image:
+1 -1
View File
@@ -1,7 +1,7 @@
import tkinter as tk import tkinter as tk
from tkinter import ttk from tkinter import ttk
from .image import Image from image import Image
class ImageView(ttk.Frame): class ImageView(ttk.Frame):
+1 -1
View File
@@ -1,6 +1,6 @@
import tkinter as tk import tkinter as tk
from .app import App from app import App
if __name__ == "__main__": if __name__ == "__main__":
app = App(tk.Tk()) app = App(tk.Tk())