Compare commits
No commits in common. "aae57e47e40a22e325ecbfc88744e2215b7403f1" and "b394330405813f0ddbc2e98173509136c943cdc4" have entirely different histories.
aae57e47e4
...
b394330405
|
@ -3677,9 +3677,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.140"
|
version = "1.0.137"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
|
checksum = "930cfb6e6abf99298aaad7d29abbef7a9999a9a8806a40088f55f0dcec03146b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"memchr",
|
"memchr",
|
||||||
|
@ -4113,8 +4113,6 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"png",
|
"png",
|
||||||
"rfd",
|
"rfd",
|
||||||
"serde",
|
|
||||||
"serde_json",
|
|
||||||
"slint",
|
"slint",
|
||||||
"slint-build",
|
"slint-build",
|
||||||
"tiny-skia",
|
"tiny-skia",
|
||||||
|
|
|
@ -11,8 +11,6 @@ png = "0.17.16"
|
||||||
rfd = "0.15.2"
|
rfd = "0.15.2"
|
||||||
slint = "1.9.2"
|
slint = "1.9.2"
|
||||||
tiny-skia = "0.11.4"
|
tiny-skia = "0.11.4"
|
||||||
serde = {version = "1.0.140", features = ["derive"]}
|
|
||||||
serde_json = "1.0"
|
|
||||||
tool_helper = {path = "../tool_helper"}
|
tool_helper = {path = "../tool_helper"}
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use std::{fs::File, io::Write};
|
use std::fmt::format;
|
||||||
|
|
||||||
use crate::{gui::{self, main_tab::MainTab, MutexTIMManager, VRAM_HEIGHT, VRAM_WIDTH}, MainWindow};
|
use crate::{gui::{main_tab::MainTab, MutexTIMManager, VRAM_HEIGHT, VRAM_WIDTH}, MainWindow, VRAMInfo};
|
||||||
use super::FileTab;
|
use super::FileTab;
|
||||||
use rfd::FileDialog;
|
use rfd::FileDialog;
|
||||||
use slint::SharedString;
|
use slint::SharedString;
|
||||||
use tim_tool::logic::{project::{Job, PaletteRect, Project}, tim::types::Encoding};
|
use tim_tool::logic::{project::{Job, Project}, tim::{self, types::Encoding}};
|
||||||
use tool_helper::Error;
|
use tool_helper::Error;
|
||||||
|
|
||||||
pub(super) fn on_browse_file(tim_manager: MutexTIMManager) -> impl FnMut(&mut FileTab, &MainWindow) -> Result<(), Error> + 'static {
|
pub(super) fn on_browse_file(tim_manager: MutexTIMManager) -> impl FnMut(&mut FileTab, &MainWindow) -> Result<(), Error> + 'static {
|
||||||
|
@ -34,7 +34,7 @@ pub(super) fn on_browse_file(tim_manager: MutexTIMManager) -> impl FnMut(&mut Fi
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn on_update_palette_size(tim_manager: MutexTIMManager) -> impl FnMut(&mut FileTab, &MainWindow, u16, u16) -> Result<(), Error> + 'static {
|
pub(super) fn on_update_palette_size(tim_manager: MutexTIMManager) -> impl FnMut(&mut FileTab, &MainWindow, u32, u32) -> Result<(), Error> + 'static {
|
||||||
return move |file_tab, _main_window, width, height| -> Result<(), Error> {
|
return move |file_tab, _main_window, width, height| -> Result<(), Error> {
|
||||||
file_tab.update_palette(tim_manager.lock().expect("VRAM already locked").change_unadded_tim_palette_size(width, height)?);
|
file_tab.update_palette(tim_manager.lock().expect("VRAM already locked").change_unadded_tim_palette_size(width, height)?);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -68,12 +68,7 @@ pub(super) fn on_load_project_clicked() -> impl FnMut(&mut FileTab, &MainWindow)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn on_save_project_clicked(tim_manager: MutexTIMManager) -> impl FnMut(&mut FileTab, &MainTab, &MainWindow) -> Result<(), Error> + 'static {
|
pub(super) fn on_save_project_clicked(tim_manager: MutexTIMManager) -> impl FnMut(&mut FileTab, &MainTab, &MainWindow) -> Result<(), Error> + 'static {
|
||||||
move |_file_tab, main_tab, main_window| {
|
move |_file_tab, main_tab, _main_window| {
|
||||||
let save_location = main_window.get_project_widget_save_project_path();
|
|
||||||
if save_location.is_empty() {
|
|
||||||
return Err(Error::from_str("Please specify save location for project file"));
|
|
||||||
}
|
|
||||||
|
|
||||||
let tim_info = tim_manager.lock().expect("VRAM already locked").clone_added_tims();
|
let tim_info = tim_manager.lock().expect("VRAM already locked").clone_added_tims();
|
||||||
let vram_info = main_tab.clone_vram_info();
|
let vram_info = main_tab.clone_vram_info();
|
||||||
|
|
||||||
|
@ -82,7 +77,7 @@ pub(super) fn on_save_project_clicked(tim_manager: MutexTIMManager) -> impl FnMu
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut cur_job = None;
|
let mut cur_job = None;
|
||||||
let mut project = Project::new(tim_info.into_iter().zip(vram_info.into_iter()).filter_map(|(tim, (file_name, vram))| {
|
let mut project = Project::new(tim_info.into_iter().zip(vram_info.into_iter()).filter_map(|(tim, vram)| {
|
||||||
if vram.is_palette {
|
if vram.is_palette {
|
||||||
// Add palette to cur_job
|
// Add palette to cur_job
|
||||||
None
|
None
|
||||||
|
@ -90,16 +85,9 @@ pub(super) fn on_save_project_clicked(tim_manager: MutexTIMManager) -> impl FnMu
|
||||||
|
|
||||||
else {
|
else {
|
||||||
// We are done with the old job
|
// We are done with the old job
|
||||||
let prev_job = std::mem::replace(&mut cur_job, None);
|
let prev_job = std::mem::replace(&mut cur_job, None);
|
||||||
|
|
||||||
if let Some(tim) = tim {
|
cur_job = Some(Job::new("Planschi".to_owned(), std::path::PathBuf::from("value")));
|
||||||
let mut job = Job::new(file_name, tim.get_path(), (vram.x as u16, vram.y as u16));
|
|
||||||
|
|
||||||
if let Some((width, height)) = tim.get_palette_size() {
|
|
||||||
job.add_palette(PaletteRect::new(0, 0, width, height));
|
|
||||||
}
|
|
||||||
cur_job = Some(job);
|
|
||||||
}
|
|
||||||
prev_job
|
prev_job
|
||||||
}
|
}
|
||||||
}).collect());
|
}).collect());
|
||||||
|
@ -107,18 +95,7 @@ pub(super) fn on_save_project_clicked(tim_manager: MutexTIMManager) -> impl FnMu
|
||||||
project.push(cur_job);
|
project.push(cur_job);
|
||||||
}
|
}
|
||||||
|
|
||||||
let json_content = match serde_json::to_string(&project) {
|
Err(Error::from_text(format!("Adding {} jobs", project.len())))
|
||||||
Ok(json_content) => json_content,
|
|
||||||
Err(error) => {
|
|
||||||
return Err(Error::from_error(error));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut file = File::create(save_location)?;
|
|
||||||
file.write_all(json_content.as_bytes())?;
|
|
||||||
|
|
||||||
gui::display_information("Saving project", "Project saved successfully");
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,19 +106,7 @@ pub(super) fn on_browse_open_project_clicked() -> impl FnMut(&mut FileTab, &Main
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn on_browse_save_project_clicked() -> impl FnMut(&mut FileTab, &MainWindow) -> Result<(), Error> + 'static {
|
pub(super) fn on_browse_save_project_clicked() -> impl FnMut(&mut FileTab, &MainWindow) -> Result<(), Error> + 'static {
|
||||||
move |_file_tab, main_window| {
|
move |_file_tab, _main_window| {
|
||||||
let file_path = FileDialog::new()
|
Err(Error::not_implemented("on_browse_save_project_clicked"))
|
||||||
.add_filter("TIM project file (.tim_project)", &["tim_project"])
|
|
||||||
.add_filter("JSON file (.json; .jsn)", &["json", "jsn"])
|
|
||||||
.add_filter("All", &["*"])
|
|
||||||
.set_title("Save location for TIM project file")
|
|
||||||
.save_file();
|
|
||||||
|
|
||||||
if let Some(file_path) = file_path {
|
|
||||||
if let Some(file_path) = file_path.to_str() {
|
|
||||||
main_window.set_project_widget_save_project_path(SharedString::from(file_path));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -60,7 +60,7 @@ impl FileTab {
|
||||||
|
|
||||||
let (cloned_object, cloned_main_window, mut function) = (object.clone(), main_window.clone(), callbacks::on_update_palette_size(tim_manager.clone()));
|
let (cloned_object, cloned_main_window, mut function) = (object.clone(), main_window.clone(), callbacks::on_update_palette_size(tim_manager.clone()));
|
||||||
main_window.borrow().on_file_tab_update_palette_size(move |width, height| {
|
main_window.borrow().on_file_tab_update_palette_size(move |width, height| {
|
||||||
if let Err(error) = function(&mut cloned_object.borrow_mut(), &cloned_main_window.borrow(), width as u16, height as u16) {
|
if let Err(error) = function(&mut cloned_object.borrow_mut(), &cloned_main_window.borrow(), width as u32, height as u32) {
|
||||||
display_error("Updating palette failed", &error.to_string());
|
display_error("Updating palette failed", &error.to_string());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -155,11 +155,13 @@ impl MainTab {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clone_vram_info(&self) -> Vec<(String, VRAMInfo)> {
|
pub fn clone_vram_info(&self) -> Vec<VRAMInfo> {
|
||||||
let vram_data = self.vram.lock().expect("VRAM already locked");
|
let vram_data = self.vram.lock().expect("VRAM already locked");
|
||||||
|
let mut infos = Vec::new();
|
||||||
|
|
||||||
vram_data.info.iter().zip(vram_data.file_list.iter()).map(|(vram_data, file_name)| {
|
for vram_data in vram_data.info.iter() {
|
||||||
(file_name.text.to_string(), vram_data.info.clone())
|
infos.push(vram_data.info.clone());
|
||||||
}).collect()
|
}
|
||||||
|
infos
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,68 +1,16 @@
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
|
||||||
struct ImagePosition {
|
|
||||||
pub x: u16,
|
|
||||||
pub y: u16,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::default::Default for ImagePosition {
|
|
||||||
fn default() -> Self {
|
|
||||||
ImagePosition{x: 0, y: 0}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
|
||||||
struct ImageSize {
|
|
||||||
pub width: u16,
|
|
||||||
pub height: u16,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::default::Default for ImageSize {
|
|
||||||
fn default() -> Self {
|
|
||||||
ImageSize{width: 0, height: 0}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
|
||||||
pub struct PaletteRect {
|
|
||||||
pos: ImagePosition,
|
|
||||||
size: ImageSize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PaletteRect {
|
|
||||||
pub fn new(x: u16, y: u16, width: u16, height: u16) -> PaletteRect {
|
|
||||||
PaletteRect{pos: ImagePosition{x, y}, size: ImageSize{width, height}}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::default::Default for PaletteRect {
|
|
||||||
fn default() -> Self {
|
|
||||||
PaletteRect{pos: ImagePosition::default(), size: ImageSize::default()}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
|
||||||
pub struct Job {
|
pub struct Job {
|
||||||
name: String,
|
name: String,
|
||||||
file_path: PathBuf,
|
file_path: PathBuf,
|
||||||
image_pos: ImagePosition,
|
|
||||||
palette_rect: PaletteRect,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Job {
|
impl Job {
|
||||||
pub fn new(name: String, file_path: PathBuf, image_pos: (u16, u16)) -> Job {
|
pub fn new(name: String, file_path: PathBuf) -> Job {
|
||||||
Job{name, file_path, image_pos: ImagePosition{x: image_pos.0, y: image_pos.1}, palette_rect: PaletteRect::default()}
|
Job{name, file_path}
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_palette(&mut self, palette_rect: PaletteRect) -> &mut Self {
|
|
||||||
self.palette_rect = palette_rect;
|
|
||||||
self
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
|
||||||
pub struct Project {
|
pub struct Project {
|
||||||
jobs: Vec<Job>
|
jobs: Vec<Job>
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use types::Encoding;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct TIMInfo {
|
pub struct TIMInfo {
|
||||||
path: PathBuf,
|
_path: PathBuf,
|
||||||
image_data: SharedPixelBuffer<Rgba8Pixel>,
|
image_data: SharedPixelBuffer<Rgba8Pixel>,
|
||||||
palette: Option<PaletteInfo>,
|
palette: Option<PaletteInfo>,
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ impl TIMInfo {
|
||||||
_ => {return Err(Error::from_str("Only 4 and 8bit color depth are supported for indexed color images"));}
|
_ => {return Err(Error::from_str("Only 4 and 8bit color depth are supported for indexed color images"));}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(TIMInfo{path: path.clone(), image_data, palette: Some(PaletteInfo::new(palette_colors))})
|
Ok(TIMInfo{_path: path.clone(), image_data, palette: Some(PaletteInfo::new(palette_colors))})
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
|
@ -71,11 +71,11 @@ impl TIMInfo {
|
||||||
_ => {return Err(Error::from_str("Only 8bit color depth are supported for direct color images"));}
|
_ => {return Err(Error::from_str("Only 8bit color depth are supported for direct color images"));}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(TIMInfo{path: path.clone(), image_data, palette: None})
|
Ok(TIMInfo{_path: path.clone(), image_data, palette: None})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn change_palette_size(&mut self, width: u16, height: u16) -> Result<Option<slint::Image>, Error> {
|
pub fn change_palette_size(&mut self, width: u32, height: u32) -> Result<Option<slint::Image>, Error> {
|
||||||
if let Some(palette) = &mut self.palette {
|
if let Some(palette) = &mut self.palette {
|
||||||
if width == 0 || height == 0 {
|
if width == 0 || height == 0 {
|
||||||
return Err(Error::from_text(format!("{}px x {}px is not a valid size for palette", width, height)));
|
return Err(Error::from_text(format!("{}px x {}px is not a valid size for palette", width, height)));
|
||||||
|
@ -118,27 +118,13 @@ impl TIMInfo {
|
||||||
None
|
None
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_palette_size(&self) -> Option<(u16, u16)> {
|
|
||||||
if let Some(palette_info) = &self.palette {
|
|
||||||
Some((palette_info.width, palette_info.height))
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_path(&self) -> std::path::PathBuf {
|
|
||||||
self.path.clone()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct PaletteInfo {
|
struct PaletteInfo {
|
||||||
data: Vec<Rgba8Pixel>,
|
data: Vec<Rgba8Pixel>,
|
||||||
width: u16,
|
width: u32,
|
||||||
height: u16,
|
height: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PaletteInfo {
|
impl PaletteInfo {
|
||||||
|
@ -148,7 +134,7 @@ impl PaletteInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_image(&self) -> slint::Image {
|
pub fn get_image(&self) -> slint::Image {
|
||||||
let mut image_data = SharedPixelBuffer::new(self.width as u32, self.height as u32);
|
let mut image_data = SharedPixelBuffer::new(self.width, self.height);
|
||||||
let dst_pixels = image_data.make_mut_slice();
|
let dst_pixels = image_data.make_mut_slice();
|
||||||
|
|
||||||
for (idx, byte) in dst_pixels.iter_mut().enumerate() {
|
for (idx, byte) in dst_pixels.iter_mut().enumerate() {
|
||||||
|
|
|
@ -60,7 +60,7 @@ impl TIMManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn change_unadded_tim_palette_size(&mut self, width: u16, height: u16) -> Result<Option<Image>, Error> {
|
pub fn change_unadded_tim_palette_size(&mut self, width: u32, height: u32) -> Result<Option<Image>, Error> {
|
||||||
if let Some(unadded_tim) = &mut self.unadded_tim {
|
if let Some(unadded_tim) = &mut self.unadded_tim {
|
||||||
unadded_tim.change_palette_size(width, height)
|
unadded_tim.change_palette_size(width, height)
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ struct VRAMInfo {
|
||||||
y: int,
|
y: int,
|
||||||
encoding_str: string,
|
encoding_str: string,
|
||||||
palette_count: int,
|
palette_count: int,
|
||||||
is_palette: bool, // < Can we combine the palette into this, instead of having it separate?
|
is_palette: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct VRAMData {
|
struct VRAMData {
|
||||||
|
|
Loading…
Reference in New Issue