more menu actions
This commit is contained in:
+47
-11
@@ -1,14 +1,15 @@
|
|||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
from tkinter import ttk, filedialog
|
from tkinter import ttk, filedialog, messagebox
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
from explorer import Explorer
|
from explorer import Explorer
|
||||||
from image_view import ImageView
|
from image_view import ImageView
|
||||||
|
from input_popup import InputPopup
|
||||||
from file import File
|
from file import File
|
||||||
from image import Image
|
from image import Image
|
||||||
from bitmap import Bitmap
|
from bitmap import Bitmap, BitmapError
|
||||||
|
|
||||||
|
|
||||||
class MenuEntryType(Enum):
|
class MenuEntryType(Enum):
|
||||||
@@ -32,16 +33,16 @@ class App(ttk.Frame):
|
|||||||
"New image...",
|
"New image...",
|
||||||
"_file_new_image",
|
"_file_new_image",
|
||||||
MenuEntryType.NEED_FILE,
|
MenuEntryType.NEED_FILE,
|
||||||
), # TODO _file_new_image
|
),
|
||||||
("", "", MenuEntryType.SEPARATOR),
|
("", "", MenuEntryType.SEPARATOR),
|
||||||
("Quit", "_file_quit", MenuEntryType.DEFAULT), # TODO _file_quit
|
("Quit", "_file_quit", MenuEntryType.DEFAULT),
|
||||||
],
|
],
|
||||||
"Image": [
|
"Image": [
|
||||||
(
|
(
|
||||||
"Edit Image Name...",
|
"Edit Image Name...",
|
||||||
"_image_edit_name",
|
"_image_edit_name",
|
||||||
MenuEntryType.NEED_IMAGE,
|
MenuEntryType.NEED_IMAGE,
|
||||||
), # TODO _image_edit_name
|
),
|
||||||
(
|
(
|
||||||
"Edit Image Size...",
|
"Edit Image Size...",
|
||||||
"_image_edit_size",
|
"_image_edit_size",
|
||||||
@@ -51,17 +52,17 @@ class App(ttk.Frame):
|
|||||||
"Move Image Up",
|
"Move Image Up",
|
||||||
"_image_move_up",
|
"_image_move_up",
|
||||||
MenuEntryType.NEED_IMAGE,
|
MenuEntryType.NEED_IMAGE,
|
||||||
), # TODO _image_move_up
|
),
|
||||||
(
|
(
|
||||||
"Move Image Down",
|
"Move Image Down",
|
||||||
"_image_move_down",
|
"_image_move_down",
|
||||||
MenuEntryType.NEED_IMAGE,
|
MenuEntryType.NEED_IMAGE,
|
||||||
), # TODO _image_move_down
|
),
|
||||||
(
|
(
|
||||||
"Delete Image",
|
"Delete Image",
|
||||||
"_image_delete",
|
"_image_delete",
|
||||||
MenuEntryType.NEED_IMAGE,
|
MenuEntryType.NEED_IMAGE,
|
||||||
), # TODO _image_delete
|
),
|
||||||
],
|
],
|
||||||
"Bitmap": [
|
"Bitmap": [
|
||||||
(
|
(
|
||||||
@@ -234,15 +235,50 @@ class App(ttk.Frame):
|
|||||||
def _file_close(self) -> None:
|
def _file_close(self) -> None:
|
||||||
self.open_file(None)
|
self.open_file(None)
|
||||||
|
|
||||||
|
def _file_new_image(self) -> None:
|
||||||
|
popup = InputPopup(
|
||||||
|
self,
|
||||||
|
title="New image",
|
||||||
|
message="Please enter image name",
|
||||||
|
)
|
||||||
|
if popup.value:
|
||||||
|
self.current_file.images += [Image(popup.value, 20, 20, empty=True)]
|
||||||
|
self.update()
|
||||||
|
|
||||||
|
def _file_quit(self) -> None:
|
||||||
|
self.parent.destroy()
|
||||||
|
|
||||||
|
def _image_edit_name(self) -> None:
|
||||||
|
popup = InputPopup(
|
||||||
|
self,
|
||||||
|
title="Edit image name",
|
||||||
|
message="Please enter image name",
|
||||||
|
initial_value=self.explorer.current_image.name,
|
||||||
|
)
|
||||||
|
if popup.value:
|
||||||
|
self.explorer.current_image.name = popup.value
|
||||||
|
self.update()
|
||||||
|
|
||||||
|
def _image_move_up(self) -> None:
|
||||||
|
self.explorer.move_up()
|
||||||
|
|
||||||
|
def _image_move_down(self) -> None:
|
||||||
|
self.explorer.move_down()
|
||||||
|
|
||||||
|
def _image_delete(self) -> None:
|
||||||
|
self.explorer.delete()
|
||||||
|
|
||||||
def _bmp_import_image(self) -> None:
|
def _bmp_import_image(self) -> None:
|
||||||
path = filedialog.askopenfilename(
|
path = filedialog.askopenfilename(
|
||||||
filetypes=Bitmap.FILE_TYPES,
|
filetypes=Bitmap.FILE_TYPES,
|
||||||
defaultextension=Bitmap.FILE_TYPES,
|
defaultextension=Bitmap.FILE_TYPES,
|
||||||
)
|
)
|
||||||
if path:
|
if path:
|
||||||
# TODO error handling
|
try:
|
||||||
self.current_image.import_bmp(path)
|
self.current_image.import_bmp(path)
|
||||||
self.update()
|
self.update()
|
||||||
|
except BitmapError as e:
|
||||||
|
messagebox.showerror(title="Bitmap import error", message=str(e))
|
||||||
|
|
||||||
def _bmp_export_image(self) -> None:
|
def _bmp_export_image(self) -> None:
|
||||||
path = filedialog.asksaveasfilename(
|
path = filedialog.asksaveasfilename(
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ class Explorer(ttk.Frame):
|
|||||||
self.explorer = ttk.Treeview(self, columns=("size"))
|
self.explorer = ttk.Treeview(self, columns=("size"))
|
||||||
self.explorer.heading("#0", text="name")
|
self.explorer.heading("#0", text="name")
|
||||||
self.explorer.heading("size", text="size")
|
self.explorer.heading("size", text="size")
|
||||||
self.explorer.column("#0", width=100, anchor="w")
|
self.explorer.column("#0", width=150, anchor="w")
|
||||||
self.explorer.column("size", width=100, anchor="w")
|
self.explorer.column("size", width=80, anchor="w")
|
||||||
self.explorer.grid(row=0, column=0, sticky="nsw")
|
self.explorer.grid(row=0, column=0, sticky="nsw")
|
||||||
self.explorer.bind("<<TreeviewSelect>>", self.explorer_item_click)
|
self.explorer.bind("<<TreeviewSelect>>", self.explorer_item_click)
|
||||||
|
|
||||||
@@ -47,6 +47,29 @@ class Explorer(ttk.Frame):
|
|||||||
self.current_id = id
|
self.current_id = id
|
||||||
self.explorer.selection_set(str(id))
|
self.explorer.selection_set(str(id))
|
||||||
|
|
||||||
|
def move_up(self) -> None:
|
||||||
|
if self.current_id > 0:
|
||||||
|
id = self.current_id
|
||||||
|
images = self.current_file.images
|
||||||
|
images[id], images[id - 1] = images[id - 1], images[id]
|
||||||
|
self.current_id -= 1
|
||||||
|
self.focus(self.current_id)
|
||||||
|
self.update(self.current_file, False)
|
||||||
|
|
||||||
|
def move_down(self) -> None:
|
||||||
|
if self.current_id < self.size - 1:
|
||||||
|
id = self.current_id
|
||||||
|
images = self.current_file.images
|
||||||
|
images[id], images[id + 1] = images[id + 1], images[id]
|
||||||
|
self.current_id += 1
|
||||||
|
self.focus(self.current_id)
|
||||||
|
self.update(self.current_file, False)
|
||||||
|
|
||||||
|
def delete(self) -> None:
|
||||||
|
del self.current_file.images[self.current_id]
|
||||||
|
self.current_id = min(self.current_id, self.size - 1)
|
||||||
|
self.update(self.current_file, True)
|
||||||
|
|
||||||
def update(self, file: File, force: bool):
|
def update(self, file: File, force: bool):
|
||||||
focus_id = self.current_id
|
focus_id = self.current_id
|
||||||
|
|
||||||
@@ -77,7 +100,7 @@ class Explorer(ttk.Frame):
|
|||||||
text=f"{image.name}{'*' if image.modified else ''}",
|
text=f"{image.name}{'*' if image.modified else ''}",
|
||||||
values=[f"{image.width}x{image.height}"],
|
values=[f"{image.width}x{image.height}"],
|
||||||
)
|
)
|
||||||
if self.size > 0 and focus_id != self.current_id:
|
if self.size > 0 and (focus_id != self.current_id or force):
|
||||||
self.focus(focus_id)
|
self.focus(focus_id)
|
||||||
|
|
||||||
def explorer_item_click(self, event) -> None:
|
def explorer_item_click(self, event) -> None:
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ class Image:
|
|||||||
self.height = height
|
self.height = height
|
||||||
self.modified = False
|
self.modified = False
|
||||||
if empty:
|
if empty:
|
||||||
self.data = [0] * (width * height) // 8
|
self.data = [0] * ((width * height) // 8)
|
||||||
self.modified = True
|
self.modified = True
|
||||||
else:
|
else:
|
||||||
self.data = []
|
self.data = []
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import tkinter as tk
|
||||||
|
from tkinter import ttk
|
||||||
|
|
||||||
|
|
||||||
|
class InputPopup(tk.Toplevel):
|
||||||
|
def __init__(self, parent, *, title: str, message: str, initial_value: str = ""):
|
||||||
|
super().__init__(parent)
|
||||||
|
self.title(title)
|
||||||
|
|
||||||
|
self.value = None
|
||||||
|
|
||||||
|
label = ttk.Label(self, text=message)
|
||||||
|
label.pack()
|
||||||
|
|
||||||
|
self.entry = ttk.Entry(self)
|
||||||
|
self.entry.insert(0, initial_value)
|
||||||
|
self.entry.pack()
|
||||||
|
|
||||||
|
button = ttk.Button(self, text="Ok", command=self.cleanup)
|
||||||
|
button.pack()
|
||||||
|
|
||||||
|
parent.wait_window(self)
|
||||||
|
|
||||||
|
def cleanup(self):
|
||||||
|
self.value = self.entry.get()
|
||||||
|
self.destroy()
|
||||||
Reference in New Issue
Block a user