Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ mod macos {
pub use iced_custom as iced;
}

use iced_winit::winit::dpi::{ PhysicalPosition, PhysicalSize };
#[cfg(target_os = "linux")]
use other_os::*;

Expand Down Expand Up @@ -114,8 +115,9 @@ pub struct DataViewer {
pub coco_disable_simplification: bool, // COCO: Disable polygon simplification for RLE masks
#[cfg(feature = "coco")]
pub coco_mask_render_mode: crate::settings::CocoMaskRenderMode, // COCO: Mask rendering mode (Polygon or Pixel)
pub window_size: PhysicalSize<u32>,
pub window_position: PhysicalPosition<i32>,
}

// Implement Deref to expose RuntimeSettings fields directly on DataViewer
impl std::ops::Deref for DataViewer {
type Target = RuntimeSettings;
Expand Down Expand Up @@ -198,11 +200,13 @@ impl DataViewer {
#[cfg(feature = "selection")]
selection_manager: SelectionManager::new(),
#[cfg(feature = "coco")]
annotation_manager: crate::coco::annotation_manager::AnnotationManager::new(),
#[cfg(feature = "coco")]
coco_disable_simplification: settings.coco_disable_simplification,
#[cfg(feature = "coco")]
coco_mask_render_mode: settings.coco_mask_render_mode,
window_position: PhysicalPosition { x: 0, y: 0 },
window_size: PhysicalSize { width: settings.window_width,
height: settings.window_height },
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/app/keyboard_handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ impl DataViewer {
Key::Character("q") => {
// Terminate the app
if is_platform_modifier(&modifiers) {
std::process::exit(0);
tasks.push(Task::done(Message::Quit));
}
}

Expand Down
3 changes: 3 additions & 0 deletions src/app/message.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use iced_core::Event;
use iced_core::image::Handle;
use iced_core::Color;
use iced_winit::winit::dpi::{PhysicalPosition, PhysicalSize};

use crate::cache::img_cache::{CachedData, CacheStrategy, LoadOperation};
use crate::menu::PaneLayout;
Expand Down Expand Up @@ -73,4 +74,6 @@ pub enum Message {
// Advanced settings input
AdvancedSettingChanged(String, String), // (field_name, value)
ResetAdvancedSettings,
SizeChanged(PhysicalSize<u32>),
PositionChanged(PhysicalPosition<i32>),
}
22 changes: 17 additions & 5 deletions src/app/message_handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,11 @@ pub fn handle_message(app: &mut DataViewer, message: Message) -> Task<Message> {
// Toggle and UI control messages
Message::OnSplitResize(_) | Message::ResetSplit(_) | Message::ToggleSliderType(_) |
Message::TogglePaneLayout(_) | Message::ToggleFooter(_) | Message::ToggleSyncedZoom(_) |
Message::ToggleMouseWheelZoom(_) | Message::ToggleCopyButtons(_) |
Message::ToggleFullScreen(_) | Message::ToggleFpsDisplay(_) | Message::ToggleSplitOrientation(_) |
Message::ToggleMouseWheelZoom(_) | Message::ToggleCopyButtons(_) | Message::ToggleFullScreen(_) |
Message::ToggleFpsDisplay(_) | Message::ToggleSplitOrientation(_) |
Message::CursorOnTop(_) | Message::CursorOnMenu(_) | Message::CursorOnFooter(_) |
Message::PaneSelected(_, _) | Message::SetCacheStrategy(_) | Message::SetCompressionStrategy(_) => {
Message::PaneSelected(_, _) | Message::SetCacheStrategy(_) | Message::SetCompressionStrategy(_) |
Message::SizeChanged(_) | Message::PositionChanged(_) => {
handle_toggle_messages(app, message)
}

Expand Down Expand Up @@ -582,6 +583,14 @@ pub fn handle_toggle_messages(app: &mut DataViewer, message: Message) -> Task<Me
app.update_compression_strategy(strategy);
Task::none()
}
Message::SizeChanged(size) => {
app.window_size = size;
Task::none()
}
Message::PositionChanged(position) => {
app.window_position = position;
Task::none()
}
_ => Task::none()
}
}
Expand Down Expand Up @@ -923,8 +932,8 @@ fn handle_save_settings(app: &mut DataViewer) -> Task<Message> {
cache_size,
max_loading_queue_size,
max_being_loaded_queue_size,
window_width,
window_height,
window_width: app.window_size.width,
window_height: app.window_size.height,
atlas_size,
double_click_threshold_ms,
archive_cache_size,
Expand All @@ -937,6 +946,9 @@ fn handle_save_settings(app: &mut DataViewer) -> Task<Message> {
coco_mask_render_mode: app.coco_mask_render_mode,
#[cfg(not(feature = "coco"))]
coco_mask_render_mode: crate::settings::CocoMaskRenderMode::default(),
is_fullscreen: app.is_fullscreen,
window_position_x: app.window_position.x,
window_position_y: app.window_position.y,
};

let old_settings = UserSettings::load(None);
Expand Down
6 changes: 6 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ pub struct Config {
pub window_height: u32, // Default window height
pub atlas_size: u32, // Size of the square texture atlas used in iced_wgpu (affects slider performance)
pub double_click_threshold_ms: u16, // Double-click detection threshold in milliseconds
pub window_position_x: i32,
pub window_position_y: i32,
pub is_fullscreen: bool,
}

pub static CONFIG: Lazy<Config> = Lazy::new(|| {
Expand All @@ -36,5 +39,8 @@ pub static CONFIG: Lazy<Config> = Lazy::new(|| {
window_height: settings.window_height,
atlas_size: settings.atlas_size,
double_click_threshold_ms: settings.double_click_threshold_ms,
window_position_x: settings.window_position_x,
window_position_y: settings.window_position_y,
is_fullscreen: settings.is_fullscreen,
}
});
29 changes: 27 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ mod settings_modal;
mod macos_file_access;
mod archive_cache;

use iced_winit::winit::dpi::PhysicalPosition;
#[allow(unused_imports)]
use log::{Level, trace, debug, info, warn, error};

Expand Down Expand Up @@ -491,16 +492,19 @@ pub fn main() -> Result<(), winit::error::EventLoopError> {
}
WindowEvent::Resized(size) => {
if size.width > 0 && size.height > 0 {
state.queue_message(Message::SizeChanged(size));
*resized = true;
} else {
// Skip resizing and avoid configuring the surface
*resized = false;
}
}
WindowEvent::Moved(_) => {
WindowEvent::Moved(position) => {
state.queue_message(Message::PositionChanged(position));
*moved = true;
}
WindowEvent::CloseRequested => {
state.queue_message(Message::SaveSettings);
#[cfg(target_os = "macos")]
{
// Clean up all active security-scoped access before shutdown
Expand Down Expand Up @@ -914,6 +918,7 @@ pub fn main() -> Result<(), winit::error::EventLoopError> {
}
}
Control::Exit => {
state.queue_message(Message::SaveSettings);
#[cfg(target_os = "macos")]
{
// Clean up all active security-scoped access before shutdown
Expand Down Expand Up @@ -975,6 +980,14 @@ pub fn main() -> Result<(), winit::error::EventLoopError> {
)
.expect("Create window"),
);
window.set_outer_position(PhysicalPosition::new(CONFIG.window_position_x, CONFIG.window_position_y));

let size = window.current_monitor().unwrap_or(
window.available_monitors().collect::<Vec<_>>().first().unwrap().clone()).size();
// If window size is larger than current monitor size, simply maximized the window
if CONFIG.window_width >= size.width && CONFIG.window_height > (size.height - 80) {
window.set_maximized(true);
}

if let Some(icon) = load_icon() {
window.set_window_icon(Some(icon));
Expand Down Expand Up @@ -1097,13 +1110,25 @@ pub fn main() -> Result<(), winit::error::EventLoopError> {

// Update state creation to lock renderer
let mut renderer_guard = renderer.lock().unwrap();
let state = program::State::new(
let mut state = program::State::new(
shader_widget,
viewport.logical_size(),
&mut *renderer_guard,
&mut debug_tool,
);

if CONFIG.is_fullscreen {
let fullscreen = Some(winit::window::Fullscreen::Borderless(None));
state.queue_message(Message::ToggleFullScreen(true));
#[cfg(target_os = "macos")] {
use iced_winit::winit::platform::macos::WindowExtMacOS;
window.set_simple_fullscreen(fullscreen.is_some());
}
#[cfg(not(target_os = "macos"))] {
window.set_fullscreen(fullscreen);
}
}

// Set control flow
event_loop.set_control_flow(ControlFlow::Poll);

Expand Down
23 changes: 19 additions & 4 deletions src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ pub struct UserSettings {
#[serde(default = "default_double_click_threshold_ms")]
pub double_click_threshold_ms: u16,

/// Max size for compressed file cache (bytes)
/// Max size for compressed file cache (MB)
#[serde(default = "default_archive_cache_size")]
pub archive_cache_size: u64,

Expand All @@ -89,6 +89,15 @@ pub struct UserSettings {
/// COCO: Mask rendering mode
#[serde(default)]
pub coco_mask_render_mode: CocoMaskRenderMode,

// Window position and state
#[serde(default)]
pub window_position_x: i32,
#[serde(default)]
pub window_position_y: i32,
#[serde(default)]
pub is_fullscreen: bool,

}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
Expand Down Expand Up @@ -185,6 +194,9 @@ impl Default for UserSettings {
archive_warning_threshold_mb: config::DEFAULT_ARCHIVE_WARNING_THRESHOLD_MB,
coco_disable_simplification: false,
coco_mask_render_mode: CocoMaskRenderMode::default(),
window_position_x: 0,
window_position_y: 0,
is_fullscreen: false,
}
}
}
Expand Down Expand Up @@ -309,14 +321,17 @@ impl UserSettings {
result = Self::replace_yaml_value_or_track(&result, "double_click_threshold_ms", &self.double_click_threshold_ms.to_string(), &mut missing_keys);
result = Self::replace_yaml_value_or_track(&result, "archive_cache_size", &self.archive_cache_size.to_string(), &mut missing_keys);
result = Self::replace_yaml_value_or_track(&result, "archive_warning_threshold_mb", &self.archive_warning_threshold_mb.to_string(), &mut missing_keys);

// Update COCO settings
result = Self::replace_yaml_value_or_track(&result, "coco_disable_simplification", &self.coco_disable_simplification.to_string(), &mut missing_keys);
result = Self::replace_yaml_value_or_track(&result, "coco_mask_render_mode", &format!("\"{}\"", match self.coco_mask_render_mode {
CocoMaskRenderMode::Polygon => "Polygon",
CocoMaskRenderMode::Pixel => "Pixel",
}), &mut missing_keys);

result = Self::replace_yaml_value_or_track(&result, "window_position_x", &self.window_position_x.to_string(), &mut missing_keys);
result = Self::replace_yaml_value_or_track(&result, "window_position_y", &self.window_position_y.to_string(), &mut missing_keys);
result = Self::replace_yaml_value_or_track(&result, "is_fullscreen", &self.is_fullscreen.to_string(), &mut missing_keys);

// Append missing keys with comments
if !missing_keys.is_empty() {
// Check if we need to add the advanced settings header
Expand Down Expand Up @@ -356,7 +371,7 @@ impl UserSettings {
"window_height" => "# Default window height (pixels)".to_string(),
"atlas_size" => "# Texture atlas size (affects slider performance, power of 2)".to_string(),
"double_click_threshold_ms" => "# Double-click detection threshold (milliseconds)".to_string(),
"archive_cache_size" => "# Max size for compressed file cache (bytes)".to_string(),
"archive_cache_size" => "# Max size for compressed file cache (MB)".to_string(),
"archive_warning_threshold_mb" => "# Warning threshold for solid archives (megabytes)".to_string(),
"coco_disable_simplification" => "# COCO: Disable polygon simplification (more accurate but slower)".to_string(),
"coco_mask_render_mode" => "# COCO: Mask rendering mode (Polygon or Pixel)".to_string(),
Expand Down Expand Up @@ -451,7 +466,7 @@ atlas_size: {}
# Double-click detection threshold (milliseconds)
double_click_threshold_ms: {}

# Max size for compressed file cache (bytes)
# Max size for compressed file cache (MB)
archive_cache_size: {}

# Warning threshold for solid archives (megabytes)
Expand Down