Projects: Inital support for saving and loading projects #22

Merged
cody merged 17 commits from topic/jb/project-files into main 2025-04-05 19:56:33 +00:00
3 changed files with 81 additions and 59 deletions
Showing only changes of commit 6a1b87cdb1 - Show all commits

View File

@ -1,28 +1,28 @@
mod callbacks;
use crate::{gui::{MutexTIMManager, VRAM_HEIGHT, VRAM_WIDTH}, VRAMImage};
use crate::{gui::{MutexTIMManager, VRAM_HEIGHT, VRAM_WIDTH}, VRAMImgData, VRAMInfo, VRAMData};
use super::MainWindowRef;
use slint::{Model, SharedString};
use std::{cell::RefCell, ops::RangeInclusive, rc::Rc, sync::{Arc, Mutex}};
use tim_tool::logic::tim::types::Encoding;
struct VRAM {
count: usize,
file_list: Rc<slint::VecModel<slint::StandardListViewItem>>,
image_list: Rc<slint::VecModel<VRAMImage>>
count: usize,
file_list: Rc<slint::VecModel<slint::StandardListViewItem>>,
info: Rc<slint::VecModel<VRAMData>>
}
impl VRAM {
pub fn push(&mut self, name: slint::StandardListViewItem, image: VRAMImage) {
pub fn push(&mut self, name: slint::StandardListViewItem, image: VRAMData) {
self.file_list.push(name);
self.image_list.push(image);
self.info.push(image);
self.count += 1;
}
pub fn remove(&mut self, idx: usize) {
self.count -= 1;
self.file_list.remove(idx);
self.image_list.remove(idx);
self.info.remove(idx);
}
pub fn pop(&mut self) {
@ -40,12 +40,12 @@ impl MainTab {
pub fn new(main_window: MainWindowRef, tim_manager: MutexTIMManager) -> SharedMainTab {
let vram_file_list:Vec<slint::StandardListViewItem> = main_window.borrow().get_main_tab_vram_file_list().iter().collect();
let vram_file_list = Rc::new(slint::VecModel::from(vram_file_list));
let vram_image_list = Rc::new(slint::VecModel::from(Vec::<VRAMImage>::new()));
let info = Rc::new(slint::VecModel::from(Vec::<VRAMData>::new()));
main_window.borrow().set_main_tab_vram_file_list(vram_file_list.clone().into());
main_window.borrow().set_main_tab_vram_images(vram_image_list.clone().into());
main_window.borrow().set_main_tab_vram_data(info.clone().into());
let object = SharedMainTab::new(MainTab{vram: Arc::new(Mutex::new(VRAM{count: 0, file_list: vram_file_list, image_list: vram_image_list}))}.into());
let object = SharedMainTab::new(MainTab{vram: Arc::new(Mutex::new(VRAM{count: 0, file_list: vram_file_list, info}))}.into());
let (cloned_object, cloned_main_window, mut function) = (object.clone(), main_window.clone(), callbacks::on_move_vram_image());
main_window.borrow().on_move_vram_image(move |idx, dx, dy| {
@ -63,14 +63,18 @@ impl MainTab {
let mut vram_data = self.vram.lock().expect("VRAM already locked");
let mut add_new_image = |file_name: &String, full_image: slint::Image, image: slint::Image, encoding: Encoding, palette_count: i32, is_palette: bool| {
let encoding_str = if is_palette {"<Palette>"} else {encoding.to_str()};
let vram_image = VRAMImage{
full_img: full_image,
img: image,
x: 0,
y: 0,
encoding_str: SharedString::from(encoding_str),
palette_count,
is_palette,
let vram_image = VRAMData {
images: VRAMImgData {
full_image,
image
},
info: VRAMInfo {
x: 0,
y: 0,
encoding_str: SharedString::from(encoding_str),
palette_count,
is_palette,
}
};
vram_data.push(slint::StandardListViewItem::from(file_name.as_str()), vram_image);
@ -91,13 +95,13 @@ impl MainTab {
pub fn remove_vram_file(&mut self, idx: usize) -> Result<RangeInclusive<usize>, &'static str> {
let mut vram_data = self.vram.lock().expect("VRAM already locked");
let extras = {
if let Some(element) = vram_data.image_list.iter().skip(idx).next() {
if element.is_palette {
if let Some(element) = vram_data.info.iter().skip(idx).next() {
if element.info.is_palette {
return Err("Can not remove palette. Delete image instead");
}
else {
element.palette_count as usize
element.info.palette_count as usize
}
}
@ -126,28 +130,38 @@ impl MainTab {
pub fn move_vram_image(&mut self, idx: usize, dx: i32, dy: i32) {
let vram_data = self.vram.lock().expect("VRAM already locked");
if let Some(mut vram_info) = vram_data.image_list.row_data(idx) {
vram_info.x += dx;
vram_info.y += dy;
if let Some(mut vram_info) = vram_data.info.row_data(idx) {
vram_info.info.x += dx;
vram_info.info.y += dy;
if vram_info.x < 0 {
vram_info.x = 0;
if vram_info.info.x < 0 {
vram_info.info.x = 0;
}
if vram_info.y < 0 {
vram_info.y = 0;
if vram_info.info.y < 0 {
vram_info.info.y = 0;
}
let (vram_img_width, vram_img_height) = (vram_info.img.size().width as i32, vram_info.img.size().height as i32);
if (vram_info.x + vram_img_width) > VRAM_WIDTH as i32 {
vram_info.x = VRAM_WIDTH as i32 - vram_img_width;
let (vram_img_width, vram_img_height) = (vram_info.images.image.size().width as i32, vram_info.images.image.size().height as i32);
if (vram_info.info.x + vram_img_width) > VRAM_WIDTH as i32 {
vram_info.info.x = VRAM_WIDTH as i32 - vram_img_width;
}
if (vram_info.y + vram_img_height) > VRAM_HEIGHT as i32 {
vram_info.y = VRAM_HEIGHT as i32 - vram_img_height;
if (vram_info.info.y + vram_img_height) > VRAM_HEIGHT as i32 {
vram_info.info.y = VRAM_HEIGHT as i32 - vram_img_height;
}
vram_data.image_list.set_row_data(idx, vram_info);
vram_data.info.set_row_data(idx, vram_info);
}
}
/*pub fn _clone_vram_images(&self) -> Vec<VRAMInfo> {
let vram_data = self.vram.lock().expect("VRAM already locked");
let mut images = Vec::new();
for image in vram_data.image_list.iter() {
images.push(image.clone());
}
images
}*/
}

View File

@ -7,7 +7,7 @@ export component MainWindow inherits Window {
// Main Tab values
in-out property main_tab_vram_bg <=> main_tab.vram_bg;
in-out property main_tab_vram_file_list <=> main_tab.vram_files;
in-out property main_tab_vram_images <=> main_tab.vram_images;
in-out property main_tab_vram_data <=> main_tab.vram_data;
callback main_tab_remove_file_clicked <=> main_tab.remove_file_clicked;
callback move_vram_image <=> main_tab.move_vram_image;

View File

@ -1,9 +1,12 @@
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,
struct VRAMImgData {
full_image: image,
image: image,
}
struct VRAMInfo {
x: int,
y: int,
encoding_str: string,
@ -11,11 +14,16 @@ struct VRAMImage {
is_palette: bool,
}
struct VRAMData {
images: VRAMImgData,
info: VRAMInfo,
}
export component MainTab inherits Rectangle {
property <float> scale: 1.0;
property <float> scale: 1.0;
in-out property <image> vram_bg;
in-out property <[StandardListViewItem]> vram_files: [];
in-out property <[VRAMImage]> vram_images: [];
in-out property <[StandardListViewItem]> vram_files: [];
in-out property <[VRAMData]> vram_data: [];
callback add_file_clicked();
callback remove_file_clicked(int);
@ -54,12 +62,12 @@ export component MainTab inherits Rectangle {
scale: scale;
}
for vram_image[i] in root.vram_images: VRAMArea {
for vram_data[i] in root.vram_data: 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;
img: vram_data.images.image;
img_x: vram_data.info.x;
img_y: vram_data.info.y;
scale: scale;
TouchArea {
@ -82,8 +90,8 @@ export component MainTab inherits Rectangle {
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.source = vram_data.images.full_image;
encoding_text.encoding_str = vram_data.info.encoding_str;
cur_sel_img.visible = true;
vram_files_list.current-item = i;
@ -154,10 +162,10 @@ export component MainTab inherits Rectangle {
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_x.text = root.vram_data[current-item].info.x;
cur_sel_y.text = root.vram_data[current-item].info.y;
cur_sel_img.source = root.vram_data[current-item].images.full_image;
encoding_text.encoding_str = root.vram_data[current-item].info.encoding_str;
cur_sel_img.visible = true;
}
}
@ -210,8 +218,8 @@ export component MainTab inherits Rectangle {
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;
root.move_vram_image(vram_files_list.current-item, text.to-float() - vram_data[vram_files_list.current-item].info.x, 0);
self.text = vram_data[vram_files_list.current-item].info.x;
}
}
}
@ -231,8 +239,8 @@ export component MainTab inherits Rectangle {
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;
root.move_vram_image(vram_files_list.current-item, 0, text.to-float() - vram_data[vram_files_list.current-item].info.y);
self.text = vram_data[vram_files_list.current-item].info.y;
}
}
}
@ -252,22 +260,22 @@ export component MainTab inherits Rectangle {
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;
cur_sel_x.text = vram_data[vram_files_list.current-item].info.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;
cur_sel_x.text = vram_data[vram_files_list.current-item].info.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;
cur_sel_y.text = vram_data[vram_files_list.current-item].info.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;
cur_sel_y.text = vram_data[vram_files_list.current-item].info.y;
}
}
accept