added preview to properties

This commit is contained in:
aedhcarrick 2022-12-19 15:08:45 -06:00
parent eefb4de6ce
commit 6368d1edfe
6 changed files with 168 additions and 92 deletions

View File

@ -171,28 +171,28 @@ asset_manager = AssetManager(
content = ft.Row( content = ft.Row(
controls = [ controls = [
ft.Column( ft.Column(
controls = [ controls = [
ft.Tabs( ft.Tabs(
selected_index = 0, selected_index = 0,
animation_duration = 300, animation_duration = 300,
tabs = [ tabs = [
ft.Tab( ft.Tab(
content = layer_panel, content = layer_panel,
tab_content = ft.Text( tab_content = ft.Text(
value = "Layers", value = "Layers",
), ),
), ),
ft.Tab( ft.Tab(
content = asset_panel, content = asset_panel,
tab_content = ft.Text( tab_content = ft.Text(
value = "Assets", value = "Assets",
), ),
), ),
], ],
), ),
], ],
alignment = 'start', alignment = 'start',
expand = True expand = True
), ),
asset_manager_dragbar, asset_manager_dragbar,
], ],

View File

@ -17,17 +17,18 @@ class Canvas(ft.Container):
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
self.overlay.canvas_size.content.color = self.page.text_color self.overlay.size_display.content.color = self.page.text_color
self.overlay.canvas_size.content.size = self.page.text_size self.overlay.size_display.content.size = self.page.text_size
self.add_canvas_background() self.add_canvas_background()
self.center_canvas(self) self.center_canvas(self)
self.refresh_canvas() self.refresh_canvas()
self.update()
def lock_canvas(self): def lock_canvas(self):
self.overlay.canvas_cover.lock_canvas() self.overlay.cover.lock_canvas()
def unlock_canvas(self): def unlock_canvas(self):
self.overlay.canvas_cover.unlock_canvas() self.overlay.cover.unlock_canvas()
def refresh_canvas(self): def refresh_canvas(self):
self.overlay.refresh_canvas_overlay() self.overlay.refresh_canvas_overlay()
@ -42,18 +43,25 @@ class Canvas(ft.Container):
self.image_stack.add_layer_image(image) self.image_stack.add_layer_image(image)
self.update() self.update()
def get_image_stack_preview(self):
return self.image_stack.get_preview()
def center_canvas(self, e): def center_canvas(self, e):
width, height = self.page.get_viewport_size() width, height = self.page.get_viewport_size()
self.image_stack.offset_x = 0 self.image_stack.offset_x = 0
self.image_stack.offset_y = 0 self.image_stack.offset_y = 0
self.image_stack.left = (width * 0.5) - (self.image_stack.width * 0.5) self.image_stack.left = (width * 0.5) - (self.image_stack.width * 0.5)
self.image_stack.top = (height * 0.5) - (self.image_stack.height * 0.5) self.image_stack.top = (height * 0.5) - (self.image_stack.height * 0.5)
self.overlay.preview.left = self.image_stack.left
self.overlay.preview.top = self.image_stack.top
self.update() self.update()
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.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.height * 0.5) + self.image_stack.offset_y
self.overlay.preview.left = self.image_stack.left
self.overlay.preview.top = self.image_stack.top
self.update() self.update()
def pan_canvas(self, e: ft.DragUpdateEvent): def pan_canvas(self, e: ft.DragUpdateEvent):
@ -72,6 +80,7 @@ class Canvas(ft.Container):
else: else:
self.image_stack.scale += 0.05 self.image_stack.scale += 0.05
self.image_stack.get_scaled_size() self.image_stack.get_scaled_size()
self.overlay.preview.scale = self.image_stack.scale
self.align_canvas(e) self.align_canvas(e)
def zoom_out(self, e): def zoom_out(self, e):
@ -79,6 +88,7 @@ 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.overlay.preview.scale = self.image_stack.scale
self.image_stack.get_scaled_size() self.image_stack.get_scaled_size()
self.align_canvas(e) self.align_canvas(e)
@ -101,6 +111,7 @@ class ImageStack(ft.Container):
gapless_playback = True, gapless_playback = True,
), ),
) )
canvas_bg.image = image
self.canvas_bg = canvas_bg self.canvas_bg = canvas_bg
self.content.controls.append(canvas_bg) self.content.controls.append(canvas_bg)
@ -111,15 +122,22 @@ class ImageStack(ft.Container):
width = image.width, width = image.width,
height = image.height, height = image.height,
content = ft.Image( content = ft.Image(
src = f'assets/uploads/{image.filename}', src = f'{image.path}',
width = image.width, width = image.width,
height = image.height, height = image.height,
gapless_playback = True, gapless_playback = True,
), ),
) )
layer_image.image = image
self.center_layer(layer_image) self.center_layer(layer_image)
self.content.controls.append(layer_image) self.content.controls.append(layer_image)
canvas.layers.append(layer_image) canvas.refresh_canvas()
def get_preview(self):
stack = []
for layer in self.content.controls:
stack.append(layer.image)
return flet_utils.get_preview_from_stack(self.page.canvas_size, stack)
def get_scaled_size(self): def get_scaled_size(self):
self.scaled_width = self.width * self.scale self.scaled_width = self.width * self.scale
@ -151,11 +169,20 @@ class LayerImage(ft.Container):
class CanvasOverlay(ft.Stack): class CanvasOverlay(ft.Stack):
def refresh_canvas_overlay(self): def refresh_canvas_overlay(self):
self.refresh_canvas_size_display() self.refresh_canvas_size_display()
self.refresh_canvas_preview()
def refresh_canvas_size_display(self): def refresh_canvas_size_display(self):
self.canvas_size.content.value = str(self.page.canvas_size) self.size_display.content.value = str(self.page.canvas_size)
self.update() self.update()
def refresh_canvas_preview(self):
preview = canvas.get_image_stack_preview()
self.preview.content.src_base64 = flet_utils.convert_image_to_base64(preview)
self.preview.content.width = preview.width
self.preview.content.height = preview.height
self.preview.image = preview
self.page.property_manager.set_preview_image(preview)
def pan_canvas(e): def pan_canvas(e):
canvas.pan_canvas(e) canvas.pan_canvas(e)
@ -175,40 +202,33 @@ image_stack.scaled_width = image_stack.width
image_stack.scaled_height = image_stack.height image_stack.scaled_height = image_stack.height
class CanvasCover(ft.Container): canvas_cover = ft.Container(
def lock_canvas(self): content = None,
self.bgcolor = 'black' expand = True,
self.opacity = 0.5, bgcolor = 'black',
self.content = self.loading opacity = 0.5,
)
def unlock_canvas(self): canvas_preview = LayerImage(
self.bgcolor = None width = 4096,
self.opacity = 1.0, height = 4096,
self.content = self.detector padding = 0,
margin = 0,
image_fit = ft.ImageFit.CONTAIN,
alignment = ft.alignment.center,
content = ft.Image(
src_base64 = None,
gapless_playback = True,
),
)
gesture_detector = ft.GestureDetector(
canvas_gestures = ft.GestureDetector(
mouse_cursor = ft.MouseCursor.MOVE, mouse_cursor = ft.MouseCursor.MOVE,
drag_interval = 10, drag_interval = 10,
on_pan_update = pan_canvas, 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(
value = "test", value = "test",
@ -273,13 +293,16 @@ canvas_tools.zoom_out = zoom_out_button
canvas_overlay = CanvasOverlay( canvas_overlay = CanvasOverlay(
[ [
canvas_cover, canvas_cover,
canvas_preview,
canvas_gestures,
canvas_size_display, canvas_size_display,
canvas_tools, canvas_tools,
], ],
) )
canvas_overlay.canvas_cover = canvas_cover canvas_overlay.cover = canvas_cover
canvas_overlay.canvas_size = canvas_size_display canvas_overlay.preview = canvas_preview
canvas_overlay.size_display = canvas_size_display
canvas_overlay.tools = canvas_tools canvas_overlay.tools = canvas_tools
@ -298,4 +321,4 @@ canvas = Canvas(
canvas.image_stack = image_stack canvas.image_stack = image_stack
canvas.overlay = canvas_overlay canvas.overlay = canvas_overlay
canvas.layers = []

View File

@ -85,16 +85,22 @@ class GalleryDisplay(ft.Container):
if 'info_path' in image[image_name]: if 'info_path' in image[image_name]:
image_data = image[image_name]['info_path'] image_data = image[image_name]['info_path']
self.content.controls[0].controls.append( self.content.controls[0].controls.append(
ft.Image( ft.Container(
src = image_path, content = ft.Image(
tooltip = image_name, src = image_path,
gapless_playback = True, tooltip = image_name,
gapless_playback = True,
),
image_fit = ft.ImageFit.CONTAIN,
padding = 0,
margin = 0,
on_click =
) )
) )
def add_as_new_layer(e): def add_as_new_layer(e):
pass e.page.asset_manager.add_image_as_layer(gallery_window.selected_image)
def save_to_disk(e): def save_to_disk(e):
pass pass
@ -153,4 +159,4 @@ gallery_window = GalleryWindow(
gallery_window.uploads_gallery = uploads_gallery gallery_window.uploads_gallery = uploads_gallery
gallery_window.outputs_gallery = outputs_gallery gallery_window.outputs_gallery = outputs_gallery
gallery_window.selected_image = None

View File

@ -19,6 +19,9 @@ class PropertyManager(ft.Container):
self.set_tab_margin(self.page.container_margin) self.set_tab_margin(self.page.container_margin)
self.dragbar.content.width = self.page.vertical_divider_width self.dragbar.content.width = self.page.vertical_divider_width
self.dragbar.content.color = self.page.tertiary_color self.dragbar.content.color = self.page.tertiary_color
self.property_panel.preview.width = self.page.right_panel_width
self.property_panel.preview_dragbar.content.content.height = self.page.divider_height
self.property_panel.preview_dragbar.content.content.color = self.page.tertiary_color
def set_tab_text_size(self, size): def set_tab_text_size(self, size):
for tab in self.tabs: for tab in self.tabs:
@ -36,33 +39,69 @@ class PropertyManager(ft.Container):
for tab in self.tabs: for tab in self.tabs:
tab.content.margin = margin tab.content.margin = margin
def set_preview_size(self, width):
self.property_panel.preview.width = width
def set_preview_image(self, image):
self.property_panel.preview.content.src_base64 = flet_utils.convert_image_to_base64(image)
self.property_panel.update()
class PropertyPanel(ft.Container): class PropertyPanel(ft.Container):
pass def resize_preview(self, e):
self.page.preview_height = max(200, self.page.preview_height + e.delta_y)
self.preview.height = self.page.preview_height
self.update()
preview_pane = ft.Container(
content = ft.Image(
src_base64 = None,
gapless_playback = True,
),
image_fit = ft.ImageFit.CONTAIN,
bgcolor = 'black',
height = 200,
padding = 0,
margin = 0,
)
def resize_preview(e):
property_panel.resize_preview(e)
preview_dragbar = ft.GestureDetector(
mouse_cursor = ft.MouseCursor.RESIZE_ROW,
drag_interval = 50,
on_pan_update = resize_preview,
content = ft.Container(
content = ft.Divider(),
margin = 0,
padding = 0,
),
)
property_panel = PropertyPanel( property_panel = PropertyPanel(
content = ft.Column( content = ft.Column(
spacing = 0,
controls = [ controls = [
ft.Text("Under Construction"), preview_pane,
preview_dragbar,
], ],
), ),
clip_behavior = 'antiAlias',
) )
property_panel.preview = preview_pane
property_panel.preview_dragbar = preview_dragbar
output_panel = PropertyPanel( output_panel = PropertyPanel(
content = ft.Column( content = ft.Column(
spacing = 0,
controls = [ controls = [
ft.Text("Under Construction."), ft.Text("Under Construction."),
], ],
), ),
clip_behavior = 'antiAlias',
) )
def resize_property_manager(e: ft.DragUpdateEvent): def resize_property_manager(e: ft.DragUpdateEvent):
e.page.right_panel_width = max(250, e.page.right_panel_width - e.delta_x) e.page.right_panel_width = max(250, e.page.right_panel_width - e.delta_x)
property_manager.width = e.page.right_panel_width property_manager.width = e.page.right_panel_width
property_panel.preview.width = e.page.right_panel_width
e.page.update() e.page.update()
property_manager_dragbar = ft.GestureDetector( property_manager_dragbar = ft.GestureDetector(
@ -82,24 +121,28 @@ property_manager = PropertyManager(
selected_index = 0, selected_index = 0,
animation_duration = 300, animation_duration = 300,
tabs = [ tabs = [
ft.Tab( ft.Tab(
content = property_panel, content = property_panel,
tab_content = ft.Text( tab_content = ft.Text(
value = "Properties", value = "Properties",
), ),
), ),
ft.Tab( ft.Tab(
content = output_panel, content = output_panel,
tab_content = ft.Text( tab_content = ft.Text(
value = "Output", value = "Output",
), ),
), ),
], ],
), ),
], ],
alignment = 'start', alignment = 'start',
expand = True expand = True
), ),
ft.VerticalDivider(
width = 4,
opacity = 0,
),
], ],
expand = True, expand = True,
), ),

View File

@ -85,6 +85,7 @@ def get_image_from_uploads(name):
image = Image.open(path_to_image) image = Image.open(path_to_image)
image = image.convert("RGBA") image = image.convert("RGBA")
image.filename = name image.filename = name
image.path = path_to_image
return image return image
else: else:
log_message(f'image not found: "{name}"') log_message(f'image not found: "{name}"')
@ -97,16 +98,18 @@ def get_canvas_background(path):
# takes list of Image(s) as arg # takes list of Image(s) as arg
# returns single composite of all images # returns single composite of all images
def get_visible_from_image_stack(image_list): def get_preview_from_stack(size, images):
visible_image = create_blank_image() preview = create_blank_image(size)
for image in image_list: canvas_width = size[0]
canvas_height = size[1]
for image in images:
# need to crop images for composite # need to crop images for composite
x0, y0 = (image.width * 0.5) - 256, (image.height * 0.5) - 256 x0, y0 = (image.width - canvas_width) * 0.5, (image.height - canvas_height) * 0.5
x1, y1 = x0 + 512, y0 + 512 x1, y1 = x0 + canvas_width, y0 + canvas_height
box = (x0, y0, x1, y1) box = (x0, y0, x1, y1)
cropped_image = image.crop(box) cropped_image = image.crop(box)
visible_image = Image.alpha_composite(visible_image,cropped_image) preview = Image.alpha_composite(preview,cropped_image)
return visible_image return preview
# converts Image to base64 string # converts Image to base64 string
def convert_image_to_base64(image): def convert_image_to_base64(image):

View File

@ -7,7 +7,7 @@ from math import pi
from typing import Optional from typing import Optional
from loguru import logger from loguru import logger
import logging import logging
logging.basicConfig(level=logging.DEBUG) #logging.basicConfig(level=logging.DEBUG)
# utils imports # utils imports
from scripts import flet_utils from scripts import flet_utils
@ -110,6 +110,7 @@ def main(page: ft.Page):
# property manager # property manager
page.property_manager = property_manager page.property_manager = property_manager
page.preview_height = 200
# settings # settings
def load_settings(): def load_settings():