import { VRAMArea } from "../vram-components.slint"; import { Button, ComboBox, GroupBox, StandardListView, LineEdit, ScrollView, Slider } from "std-widgets.slint"; struct VRAMImage { full_img: image, img: image, x: int, y: int, encoding_str: string, palette_count: int, is_palette: bool, } export component MainTab inherits Rectangle { property scale: 1.0; in-out property vram_bg; in-out property <[StandardListViewItem]> vram_files: []; in-out property <[VRAMImage]> vram_images: []; callback add_file_clicked(); callback remove_file_clicked(int); callback move_vram_image(int, int, int); width: group.width + group.x*2; height: group.height + group.y*2 + 32px; group := GroupBox { title: "VRAM Layout"; x: 4px; y: 4px; width: main_view.width + 2*main_view.x; VerticalLayout { main_view := ScrollView { width: rect.width/root.scale; height: rect.height/root.scale; viewport-x: 0; viewport-y: 0; viewport-width: rect.width; viewport-height: rect.height; rect := Rectangle { width: background_image.width + root.get_border_width()*2px; height: background_image.height + root.get_border_width()*2px; border-width: root.get_border_width()*1px; border-color: #404040; background: #A0A0A0; background_image := VRAMArea { x: root.get_border_width()*1px; y: root.get_border_width()*1px; img: vram_bg; img_x: 0; img_y: 0; scale: scale; } for vram_image[i] in root.vram_images: VRAMArea { x: root.get_border_width()*1px; y: root.get_border_width()*1px; img: vram_image.img; img_x: vram_image.x; img_y: vram_image.y; scale: scale; TouchArea { x: ((parent.img_x + self.lines_crossed_x())*1px)*scale; y: ((parent.img_y + self.lines_crossed_y())*1px)*scale; width: ((parent.img.width + self.lines_crossed_width())*1px)*scale; height: ((parent.img.height + self.lines_crossed_height())*1px)*scale; mouse-cursor: grab; moved => { self.mouse-cursor = MouseCursor.grabbing; root.move_vram_image(i, ((self.mouse-x - self.pressed-x)/scale)/1px, ((self.mouse-y - self.pressed-y)/scale)/1px); cur_sel_x.text = parent.img_x; cur_sel_y.text = parent.img_y; } pointer-event(event) => { if event.kind == PointerEventKind.up { self.mouse-cursor = MouseCursor.grab; } if event.kind == PointerEventKind.down { cur_sel_x.text = parent.img_x; cur_sel_y.text = parent.img_y; cur_sel_img.source = vram-image.full_img; encoding_text.encoding_str = vram-image.encoding_str; cur_sel_img.visible = true; vram_files_list.current-item = i; } } // Thanks to Cody the white tiger function lines_crossed_x() -> int { return parent.img_x/64; } function lines_crossed_y() -> int { return parent.img_y/256; } function lines_crossed_width() -> int { return ((parent.img_x + parent.img.width)/64) - self.lines_crossed_x(); } function lines_crossed_height() -> int { return ((parent.img_y + parent.img.height)/256) - self.lines_crossed_y(); } } } } function update_viewport() { if abs(self.viewport-x) + self.width > self.viewport-width { self.viewport-x += (self.width + abs(self.viewport-x)) - self.viewport-width; } if abs(self.viewport-y) + self.height > self.viewport-height { self.viewport-y += (self.height + abs(self.viewport-y)) - self.viewport-height; } } } HorizontalLayout { padding: 4px; VerticalLayout { alignment: center; padding-right: 4px; Text { text: "Scale: " + round(slider.value) + "%"; } } slider := Slider { minimum: 100.0; maximum: 400.0; step: 1.0; value: 100.0; changed(value) => { root.scale = round(value)/100.0; main_view.update_viewport(); } } } HorizontalLayout { padding: 4px; GroupBox { title: "Added files"; VerticalLayout { alignment: start; padding: 4px; vram_files_list := StandardListView { width: background_image.width/root.scale/2; height: 128px; model: root.vram_files; current-item-changed(current-item) => { cur_sel_x.text = root.vram_images[current-item].x; cur_sel_y.text = root.vram_images[current-item].y; cur_sel_img.source = root.vram_images[current-item].full_img; encoding_text.encoding_str = root.vram_images[current-item].encoding_str; cur_sel_img.visible = true; } } HorizontalLayout { padding: 4px; Button { text: "Add file"; clicked => {root.add_file_clicked();} } Button { text: "Remove file"; clicked => { root.remove_file_clicked(vram_files_list.current_item); vram_files_list.current-item = -1; cur_sel_x.text = 0; cur_sel_y.text = 0; cur_sel_img.visible = false; } } } } } GroupBox { title: "Current File"; VerticalLayout { padding: 4px; Rectangle { width: 128px; height: 128px; background: #A0A0A0; cur_sel_img := Image { width: 128px; height: 128px; image-fit: contain; image-rendering: pixelated; } } HorizontalLayout { alignment: start; VerticalLayout { alignment: center; Text { text: "X: "; } } cur_sel_x := LineEdit { input-type: number; text: 0; width: 64pt; accepted(text) => { if(vram_files_list.current-item != -1) { root.move_vram_image(vram_files_list.current-item, text.to-float() - vram_images[vram_files_list.current-item].x, 0); self.text = vram_images[vram_files_list.current-item].x; } } } } HorizontalLayout { alignment: start; VerticalLayout { alignment: center; Text { text: "Y: "; } } cur_sel_y := LineEdit { input-type: number; text: 0; width: 64pt; accepted(text) => { if(vram_files_list.current-item != -1) { root.move_vram_image(vram_files_list.current-item, 0, text.to-float() - vram_images[vram_files_list.current-item].y); self.text = vram_images[vram_files_list.current-item].y; } } } } encoding_text := Text { in-out property encoding_str; text: "Encoding: " + encoding_str; } } } } } } FocusScope { key-pressed(event) => { if(vram_files_list.current-item != -1) { if(event.text == Key.LeftArrow) { root.move_vram_image(vram_files_list.current-item, -1, 0); cur_sel_x.text = vram_images[vram_files_list.current-item].x; } if(event.text == Key.RightArrow) { root.move_vram_image(vram_files_list.current-item, 1, 0); cur_sel_x.text = vram_images[vram_files_list.current-item].x; } if(event.text == Key.UpArrow) { root.move_vram_image(vram_files_list.current-item, 0, -1); cur_sel_y.text = vram_images[vram_files_list.current-item].y; } if(event.text == Key.DownArrow) { root.move_vram_image(vram_files_list.current-item, 0, 1); cur_sel_y.text = vram_images[vram_files_list.current-item].y; } } accept } } function get_border_width() -> int { return 4; } }