bug in canvas.update()

This commit is contained in:
aedhcarrick 2022-12-18 16:22:38 -06:00
parent 942e0c3ed6
commit 3f8ab89d7c
3 changed files with 131 additions and 68 deletions

View File

@ -13,6 +13,7 @@ class Canvas(ft.Container):
self.padding = self.page.container_padding self.padding = self.page.container_padding
self.margin = self.page.container_margin self.margin = self.page.container_margin
self.overlay.tools.center = self.page.icon_size
self.overlay.tools.zoom_in = self.page.icon_size self.overlay.tools.zoom_in = self.page.icon_size
self.overlay.tools.zoom_out = self.page.icon_size self.overlay.tools.zoom_out = self.page.icon_size
@ -22,6 +23,12 @@ class Canvas(ft.Container):
self.center_canvas(self) self.center_canvas(self)
self.refresh_canvas() self.refresh_canvas()
def lock_canvas(self):
self.overlay.canvas_cover.lock_canvas()
def unlock_canvas(self):
self.overlay.canvas_cover.unlock_canvas()
def refresh_canvas(self): def refresh_canvas(self):
self.overlay.refresh_canvas_overlay() self.overlay.refresh_canvas_overlay()
@ -44,14 +51,18 @@ class Canvas(ft.Container):
def align_canvas(self, e): def align_canvas(self, e):
width, height = self.page.get_viewport_size() width, height = self.page.get_viewport_size()
self.image_stack.left = (width * 0.5) - (self.image_stack.width * 0.5) + self.image_stack.offset_x self.image_stack.left = (width * 0.5) - (self.image_stack.scaled_width * 0.5) + self.image_stack.offset_x
self.image_stack.top = (height * 0.5) - (self.image_stack.height * 0.5) + self.image_stack.offset_y self.image_stack.top = (height * 0.5) - (self.image_stack.scaled_height * 0.5) + self.image_stack.offset_y
self.update() self.update()
def pan_canvas(self, e: ft.DragUpdateEvent): def pan_canvas(self, e: ft.DragUpdateEvent):
self.image_stack.offset_x += e.delta_x self.image_stack.offset_x += e.delta_x
self.image_stack.offset_y += e.delta_y self.image_stack.offset_y += e.delta_y
width, height = self.page.get_viewport_size()
self.image_stack.offset_x = max(self.image_stack.offset_x, (width - self.image_stack.scaled_width) * 0.5)
self.image_stack.offset_y = max(self.image_stack.offset_y, (height - self.image_stack.scaled_height) * 0.5)
self.image_stack.offset_x = min(self.image_stack.offset_x, (self.image_stack.scaled_width - width) * 0.5)
self.image_stack.offset_y = min(self.image_stack.offset_y, (self.image_stack.scaled_height - height) * 0.5)
self.align_canvas(e) self.align_canvas(e)
def zoom_in(self, e): def zoom_in(self, e):
@ -59,6 +70,7 @@ class Canvas(ft.Container):
self.image_stack.scale = 4.0 self.image_stack.scale = 4.0
else: else:
self.image_stack.scale += 0.05 self.image_stack.scale += 0.05
self.image_stack.get_scaled_size()
self.align_canvas(e) self.align_canvas(e)
def zoom_out(self, e): def zoom_out(self, e):
@ -66,26 +78,16 @@ class Canvas(ft.Container):
self.image_stack.scale = 0.1 self.image_stack.scale = 0.1
else: else:
self.image_stack.scale -= 0.05 self.image_stack.scale -= 0.05
self.image_stack.get_scaled_size()
self.align_canvas(e) self.align_canvas(e)
class CanvasOverlay(ft.Stack):
def refresh_canvas_overlay(self):
self.refresh_canvas_size_display()
def refresh_canvas_size_display(self):
self.canvas_size.content.value = str(self.page.canvas_size)
self.update()
def pan_canvas(e): def pan_canvas(e):
canvas.pan_canvas(e) canvas.pan_canvas(e)
class ImageStack(ft.GestureDetector): class ImageStack(ft.Container):
def add_canvas_background(self): def add_canvas_background(self):
image = self.page.canvas_background image = self.page.canvas_background
canvas_bg = LayerImage( canvas_bg = LayerImage(
mouse_cursor = ft.MouseCursor.MOVE,
drag_interval = 50,
on_pan_update = pan_canvas,
left = 0, left = 0,
top = 0, top = 0,
width = self.width, width = self.width,
@ -98,16 +100,11 @@ class ImageStack(ft.GestureDetector):
gapless_playback = True, gapless_playback = True,
), ),
) )
canvas_offset_x = 0
canvas_offset_y = 0
self.canvas_bg = canvas_bg self.canvas_bg = canvas_bg
self.content.controls.append(canvas_bg) self.content.controls.append(canvas_bg)
def add_layer_image(self, image): def add_layer_image(self, image):
layer_image = LayerImage( layer_image = LayerImage(
mouse_cursor = ft.MouseCursor.GRAB,
drag_interval = 50,
on_pan_update = self.drag_layer,
left = 0, left = 0,
top = 0, top = 0,
width = image.width, width = image.width,
@ -123,15 +120,17 @@ class ImageStack(ft.GestureDetector):
self.content.controls.append(layer_image) self.content.controls.append(layer_image)
canvas.layers.append(layer_image) canvas.layers.append(layer_image)
def get_scaled_size(self):
self.scaled_width = self.width * self.scale
self.scaled_height = self.height * self.scale
def center_layer(self, layer_image): def center_layer(self, layer_image):
layer_image.offset_x = 0
layer_image.offset_y = 0
layer_image.left = (self.width * 0.5) - (layer_image.width * 0.5) layer_image.left = (self.width * 0.5) - (layer_image.width * 0.5)
layer_image.top = (self.height * 0.5) - (layer_image.height * 0.5) layer_image.top = (self.height * 0.5) - (layer_image.height * 0.5)
def align_layer(self, layer_image): def align_layer(self, layer_image):
layer_image.left = (self.width * 0.5) - (layer_image.width * 0.5) + layer_image.offset_x layer_image.left = (self.width * 0.5) - (layer_image.width * 0.5)
layer_image.top = (self.height * 0.5) - (layer_image.height * 0.5) + layer_image.offset_y layer_image.top = (self.height * 0.5) - (layer_image.height * 0.5)
def drag_layer(self, e): def drag_layer(self, e):
pass pass
@ -145,16 +144,22 @@ class ImageStack(ft.GestureDetector):
def paint_on_layer(self, e): def paint_on_layer(self, e):
pass pass
class LayerImage(ft.GestureDetector): class LayerImage(ft.Container):
pass pass
class CanvasOverlay(ft.Stack):
def refresh_canvas_overlay(self):
self.refresh_canvas_size_display()
def refresh_canvas_size_display(self):
self.canvas_size.content.value = str(self.page.canvas_size)
self.update()
def pan_canvas(e): def pan_canvas(e):
canvas.pan_canvas(e) canvas.pan_canvas(e)
image_stack = ImageStack( image_stack = ImageStack(
# mouse_cursor = ft.MouseCursor.GRAB,
drag_interval = 50,
on_pan_update = pan_canvas,
width = 4096, width = 4096,
height = 4096, height = 4096,
left = 0, left = 0,
@ -165,6 +170,43 @@ image_stack = ImageStack(
image_stack.offset_x = 0 image_stack.offset_x = 0
image_stack.offset_y = 0 image_stack.offset_y = 0
image_stack.scaled_width = image_stack.width
image_stack.scaled_height = image_stack.height
class CanvasCover(ft.Container):
def lock_canvas(self):
self.bgcolor = 'black'
self.opacity = 0.5,
self.content = self.loading
def unlock_canvas(self):
self.bgcolor = None
self.opacity = 1.0,
self.content = self.detector
gesture_detector = ft.GestureDetector(
mouse_cursor = ft.MouseCursor.MOVE,
drag_interval = 10,
on_pan_update = pan_canvas,
)
canvas_loading = ft.ProgressRing(
width = 50,
height = 50,
stroke_width = 4,
value = None,
)
canvas_cover = CanvasCover(
content = gesture_detector,
expand = True,
bgcolor = None,
opacity = 1.0,
)
canvas_cover.detector = gesture_detector
canvas_cover.loading = canvas_loading
canvas_size_display = ft.Container( canvas_size_display = ft.Container(
content = ft.Text( content = ft.Text(
@ -220,21 +262,27 @@ canvas_tools = ft.Container(
border_radius = 10, border_radius = 10,
opacity = 0.5, opacity = 0.5,
bgcolor = 'black', bgcolor = 'black',
disabled = False,
) )
canvas_tools.center = center_canvas_button
canvas_tools.zoom_in = zoom_in_button canvas_tools.zoom_in = zoom_in_button
canvas_tools.zoom_out = zoom_out_button canvas_tools.zoom_out = zoom_out_button
canvas_overlay = CanvasOverlay( canvas_overlay = CanvasOverlay(
[ [
canvas_cover,
canvas_size_display, canvas_size_display,
canvas_tools, canvas_tools,
], ],
) )
canvas_overlay.canvas_cover = canvas_cover
canvas_overlay.canvas_size = canvas_size_display canvas_overlay.canvas_size = canvas_size_display
canvas_overlay.tools = canvas_tools canvas_overlay.tools = canvas_tools
canvas = Canvas( canvas = Canvas(
content = ft.Stack( content = ft.Stack(
[ [

View File

@ -3,6 +3,11 @@
# Flet imports # Flet imports
import flet as ft import flet as ft
# other imports
from math import pi
from typing import Dict
from loguru import logger
# utils imports # utils imports
from scripts import flet_utils from scripts import flet_utils
@ -18,27 +23,37 @@ class UploadWindow(ft.AlertDialog):
file_picker.upload(file_list) file_picker.upload(file_list)
def upload_complete(self, e): def upload_complete(self, e):
e.page.progress_bars.clear() self.progress_bars.clear()
e.page.selected_files.controls.clear() self.selected_files.controls.clear()
e.page.close_uploads(e) e.page.close_uploads(e)
e.page.message('File upload(s) complete.')
e.page.asset_manager.add_images_as_layers(file_picker.images) e.page.asset_manager.add_images_as_layers(file_picker.images)
file_picker.images.clear() file_picker.images.clear()
e.page.refresh_gallery('uploads') e.page.message('File upload(s) complete.')
e.page.update()
def get_image_from_uploads(self, name): def get_image_from_uploads(self, name):
return flet_utils.get_image_from_uploads(name) return flet_utils.get_image_from_uploads(name)
def get_file_display(self, name, progress): def get_file_display(self, name, progress):
display = ft.Column( display = ft.Row(
controls = [ controls = [
ft.Row([ft.Text(name)]),
progress, progress,
ft.Text(name),
], ],
) )
return display return display
class ImportWindow(ft.AlertDialog):
pass
selected_files = ft.Column(
scroll = 'auto',
tight = True,
controls = [],
);
progress_bars: Dict[str, ft.ProgressBar] = {}
def upload_file(e): def upload_file(e):
uploads.upload_file(e) uploads.upload_file(e)
@ -47,7 +62,7 @@ def close_upload_window(e):
uploads = UploadWindow( uploads = UploadWindow(
title = ft.Text("Confirm file upload(s)"), title = ft.Text("Confirm file upload(s)"),
content = None, content = selected_files,
actions_alignment = "center", actions_alignment = "center",
actions = [ actions = [
ft.ElevatedButton("UPLOAD", on_click = upload_file), ft.ElevatedButton("UPLOAD", on_click = upload_file),
@ -55,8 +70,8 @@ uploads = UploadWindow(
], ],
) )
class ImportWindow(ft.AlertDialog): uploads.selected_files = selected_files
pass uploads.progress_bars = progress_bars
def import_file(e): def import_file(e):
e.page.close_imports(e) e.page.close_imports(e)
@ -66,7 +81,7 @@ def close_import_window(e):
imports = ImportWindow( imports = ImportWindow(
title = ft.Text("Confirm file import(s)"), title = ft.Text("Confirm file import(s)"),
content = None, content = selected_files,
actions_alignment = "center", actions_alignment = "center",
actions = [ actions = [
ft.ElevatedButton("IMPORT", on_click = import_file), ft.ElevatedButton("IMPORT", on_click = import_file),
@ -74,24 +89,31 @@ imports = ImportWindow(
], ],
) )
imports.selected_files = selected_files
imports.progress_bars = progress_bars
def pick_images(e: ft.FilePickerResultEvent): def pick_images(e: ft.FilePickerResultEvent):
e.page.progress_bars.clear() progress_bars.clear()
e.page.selected_files.controls.clear() selected_files.controls.clear()
file_picker.images.clear()
# check to see if files or directory were chosen # check to see if files or directory were chosen
if e.files is not None and e.path is None: if e.files is not None and e.path is None:
for f in e.files: for f in e.files:
prog = ft.ProgressBar( prog = ft.ProgressRing(
width = 12,
height = 12,
stroke_width = 2,
value = 0, value = 0,
color = 'blue', color = 'blue',
) )
e.page.progress_bars[f.name] = prog progress_bars[f.name] = prog
e.page.selected_files.controls.append(uploads.get_file_display(f.name,prog)) selected_files.controls.append(uploads.get_file_display(f.name,prog))
file_picker.pending += 1 file_picker.pending += 1
# import if local, upload if remote # upload if remote, import if local
if not e.page.web: if e.page.web:
e.page.open_imports(e)
else:
e.page.open_uploads(e) e.page.open_uploads(e)
else:
e.page.open_imports(e)
def on_image_upload(e: ft.FilePickerUploadEvent): def on_image_upload(e: ft.FilePickerUploadEvent):
if e.error: if e.error:
@ -99,8 +121,8 @@ def on_image_upload(e: ft.FilePickerUploadEvent):
file_picker.pending -= 1 file_picker.pending -= 1
else: else:
# update progress bars # update progress bars
e.page.progress_bars[e.file_name].value = e.progress progress_bars[e.file_name].value = e.progress
e.page.progress_bars[e.file_name].update() progress_bars[e.file_name].update()
if e.progress >= 1: if e.progress >= 1:
file_picker.pending -= 1 file_picker.pending -= 1
file_picker.images.append(uploads.get_image_from_uploads(e.file_name)) file_picker.images.append(uploads.get_image_from_uploads(e.file_name))

View File

@ -5,6 +5,8 @@ import flet as ft
from math import pi from math import pi
from typing import Optional from typing import Optional
from loguru import logger from loguru import logger
import logging
#logging.basicConfig(level=logging.DEBUG)
# utils imports # utils imports
from scripts import flet_utils from scripts import flet_utils
@ -66,13 +68,13 @@ def main(page: ft.Page):
def change_theme_mode(e): def change_theme_mode(e):
page.theme_mode = "dark" if page.theme_mode == "light" else "light" page.theme_mode = "dark" if page.theme_mode == "light" else "light"
if "(Light theme)" in appbar.theme_switcher.tooltip: if "(Light theme)" in titlebar.theme_switcher.tooltip:
appbar.theme_switcher.tooltip = appbar.theme_switcher.tooltip.replace("(Light theme)", '') titlebar.theme_switcher.tooltip = titlebar.theme_switcher.tooltip.replace("(Light theme)", '')
if "(Dark theme)" in appbar.theme_switcher.tooltip: if "(Dark theme)" in titlebar.theme_switcher.tooltip:
appbar.theme_switcher.tooltip = appbar.theme_switcher.tooltip.replace("(Dark theme)", '') titlebar.theme_switcher.tooltip = titlebar.theme_switcher.tooltip.replace("(Dark theme)", '')
appbar.theme_switcher.tooltip += "(Light theme)" if page.theme_mode == "light" else "(Dark theme)" titlebar.theme_switcher.tooltip += "(Light theme)" if page.theme_mode == "light" else "(Dark theme)"
page.update() page.update()
page.change_theme_mode = change_theme_mode page.change_theme_mode = change_theme_mode
@ -199,7 +201,6 @@ def main(page: ft.Page):
def open_upload_window(e): def open_upload_window(e):
page.dialog = uploads page.dialog = uploads
uploads.content = page.selected_files
uploads.open = True uploads.open = True
page.update() page.update()
@ -213,19 +214,11 @@ def main(page: ft.Page):
def open_import_window(e): def open_import_window(e):
page.dialog = imports page.dialog = imports
imports.content = page.selected_files
imports.open = True imports.open = True
page.update() page.update()
page.open_imports = open_import_window page.open_imports = open_import_window
page.selected_files = ft.Column(
scroll = 'auto',
tight = True,
controls = [],
);
page.progress_bars: Dict[str, ft.ProgressBar] = {}
page.uploads = uploads page.uploads = uploads
page.imports = imports page.imports = imports
page.file_picker = file_picker page.file_picker = file_picker