more menu actions
This commit is contained in:
@@ -1,14 +1,15 @@
|
||||
import tkinter as tk
|
||||
from tkinter import ttk, filedialog
|
||||
from tkinter import ttk, filedialog, messagebox
|
||||
from typing import Optional
|
||||
from enum import Enum
|
||||
import os.path
|
||||
|
||||
from explorer import Explorer
|
||||
from image_view import ImageView
|
||||
from input_popup import InputPopup
|
||||
from file import File
|
||||
from image import Image
|
||||
from bitmap import Bitmap
|
||||
from bitmap import Bitmap, BitmapError
|
||||
|
||||
|
||||
class MenuEntryType(Enum):
|
||||
@@ -32,16 +33,16 @@ class App(ttk.Frame):
|
||||
"New image...",
|
||||
"_file_new_image",
|
||||
MenuEntryType.NEED_FILE,
|
||||
), # TODO _file_new_image
|
||||
),
|
||||
("", "", MenuEntryType.SEPARATOR),
|
||||
("Quit", "_file_quit", MenuEntryType.DEFAULT), # TODO _file_quit
|
||||
("Quit", "_file_quit", MenuEntryType.DEFAULT),
|
||||
],
|
||||
"Image": [
|
||||
(
|
||||
"Edit Image Name...",
|
||||
"_image_edit_name",
|
||||
MenuEntryType.NEED_IMAGE,
|
||||
), # TODO _image_edit_name
|
||||
),
|
||||
(
|
||||
"Edit Image Size...",
|
||||
"_image_edit_size",
|
||||
@@ -51,17 +52,17 @@ class App(ttk.Frame):
|
||||
"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": [
|
||||
(
|
||||
@@ -234,15 +235,50 @@ class App(ttk.Frame):
|
||||
def _file_close(self) -> 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:
|
||||
path = filedialog.askopenfilename(
|
||||
filetypes=Bitmap.FILE_TYPES,
|
||||
defaultextension=Bitmap.FILE_TYPES,
|
||||
)
|
||||
if path:
|
||||
# TODO error handling
|
||||
try:
|
||||
self.current_image.import_bmp(path)
|
||||
self.update()
|
||||
except BitmapError as e:
|
||||
messagebox.showerror(title="Bitmap import error", message=str(e))
|
||||
|
||||
def _bmp_export_image(self) -> None:
|
||||
path = filedialog.asksaveasfilename(
|
||||
|
||||
@@ -16,8 +16,8 @@ class Explorer(ttk.Frame):
|
||||
self.explorer = ttk.Treeview(self, columns=("size"))
|
||||
self.explorer.heading("#0", text="name")
|
||||
self.explorer.heading("size", text="size")
|
||||
self.explorer.column("#0", width=100, anchor="w")
|
||||
self.explorer.column("size", width=100, anchor="w")
|
||||
self.explorer.column("#0", width=150, anchor="w")
|
||||
self.explorer.column("size", width=80, anchor="w")
|
||||
self.explorer.grid(row=0, column=0, sticky="nsw")
|
||||
self.explorer.bind("<<TreeviewSelect>>", self.explorer_item_click)
|
||||
|
||||
@@ -47,6 +47,29 @@ class Explorer(ttk.Frame):
|
||||
self.current_id = 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):
|
||||
focus_id = self.current_id
|
||||
|
||||
@@ -77,7 +100,7 @@ class Explorer(ttk.Frame):
|
||||
text=f"{image.name}{'*' if image.modified else ''}",
|
||||
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)
|
||||
|
||||
def explorer_item_click(self, event) -> None:
|
||||
|
||||
@@ -11,7 +11,7 @@ class Image:
|
||||
self.height = height
|
||||
self.modified = False
|
||||
if empty:
|
||||
self.data = [0] * (width * height) // 8
|
||||
self.data = [0] * ((width * height) // 8)
|
||||
self.modified = True
|
||||
else:
|
||||
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