Implemented window title update functionality for multiwindow.
This commit is contained in:
parent
1944e98f82
commit
ec41918ec4
14 changed files with 270 additions and 243 deletions
|
|
@ -675,7 +675,7 @@ pub fn run_command<A, E>(
|
|||
window::Action::Drag => {
|
||||
let _res = window.drag_window();
|
||||
}
|
||||
window::Action::Spawn { .. } | window::Action::Close => {
|
||||
window::Action::Spawn { .. } => {
|
||||
log::info!(
|
||||
"This is only available on `multi_window::Application`"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ use iced_native::user_interface::{self, UserInterface};
|
|||
|
||||
pub use iced_native::application::{Appearance, StyleSheet};
|
||||
|
||||
use iced_native::window::Action;
|
||||
use std::collections::HashMap;
|
||||
use std::mem::ManuallyDrop;
|
||||
|
||||
|
|
@ -36,7 +37,14 @@ pub enum Event<Message> {
|
|||
/// TODO(derezzedex)
|
||||
// Create a wrapper variant of `window::Event` type instead
|
||||
// (maybe we should also allow users to listen/react to those internal messages?)
|
||||
NewWindow(window::Id, settings::Window),
|
||||
NewWindow {
|
||||
/// The [window::Id] of the newly spawned [`Window`].
|
||||
id: window::Id,
|
||||
/// The [settings::Window] of the newly spawned [`Window`].
|
||||
settings: settings::Window,
|
||||
/// The title of the newly spawned [`Window`].
|
||||
title: String,
|
||||
},
|
||||
/// TODO(derezzedex)
|
||||
CloseWindow(window::Id),
|
||||
/// TODO(derezzedex)
|
||||
|
|
@ -95,11 +103,11 @@ where
|
|||
/// load state from a file, perform an initial HTTP request, etc.
|
||||
fn new(flags: Self::Flags) -> (Self, Command<Self::Message>);
|
||||
|
||||
/// Returns the current title of the [`Application`].
|
||||
/// Returns the current title of the current [`Application`] window.
|
||||
///
|
||||
/// This title can be dynamic! The runtime will automatically update the
|
||||
/// title of your application when necessary.
|
||||
fn title(&self) -> String;
|
||||
fn title(&self, window_id: window::Id) -> String;
|
||||
|
||||
/// Returns the current [`Theme`] of the [`Application`].
|
||||
fn theme(&self) -> <Self::Renderer as crate::Renderer>::Theme;
|
||||
|
|
@ -144,7 +152,7 @@ where
|
|||
false
|
||||
}
|
||||
|
||||
/// TODO(derezzedex)
|
||||
/// Requests that the [`window`] be closed.
|
||||
fn close_requested(&self, window: window::Id) -> Self::Message;
|
||||
}
|
||||
|
||||
|
|
@ -184,7 +192,7 @@ where
|
|||
};
|
||||
|
||||
let builder = settings.window.into_builder(
|
||||
&application.title(),
|
||||
&application.title(window::Id::MAIN),
|
||||
event_loop.primary_monitor(),
|
||||
settings.id,
|
||||
);
|
||||
|
|
@ -253,14 +261,13 @@ where
|
|||
event: winit::event::WindowEvent::Resized(*new_inner_size),
|
||||
window_id,
|
||||
}),
|
||||
winit::event::Event::UserEvent(Event::NewWindow(id, settings)) => {
|
||||
// TODO(derezzedex)
|
||||
winit::event::Event::UserEvent(Event::NewWindow {
|
||||
id,
|
||||
settings,
|
||||
title,
|
||||
}) => {
|
||||
let window = settings
|
||||
.into_builder(
|
||||
"fix window title",
|
||||
event_loop.primary_monitor(),
|
||||
None,
|
||||
)
|
||||
.into_builder(&title, event_loop.primary_monitor(), None)
|
||||
.build(event_loop)
|
||||
.expect("Failed to build window");
|
||||
|
||||
|
|
@ -320,10 +327,7 @@ async fn run_instance<A, E, C>(
|
|||
|
||||
for (&id, window) in windows.keys().zip(windows.values()) {
|
||||
let mut surface = compositor.create_surface(window);
|
||||
println!("Creating surface for window: {:?}", window);
|
||||
|
||||
let state = State::new(&application, window);
|
||||
|
||||
let state = State::new(&application, id, window);
|
||||
let physical_size = state.physical_size();
|
||||
|
||||
compositor.configure_surface(
|
||||
|
|
@ -457,7 +461,11 @@ async fn run_instance<A, E, C>(
|
|||
);
|
||||
|
||||
// Update window
|
||||
state.synchronize(&application, &windows);
|
||||
state.synchronize(
|
||||
&application,
|
||||
id,
|
||||
windows.get(&id).expect("No window found with ID."),
|
||||
);
|
||||
|
||||
let should_exit = application.should_exit();
|
||||
|
||||
|
|
@ -516,72 +524,85 @@ async fn run_instance<A, E, C>(
|
|||
),
|
||||
));
|
||||
}
|
||||
event::Event::UserEvent(event) => {
|
||||
match event {
|
||||
Event::Application(message) => {
|
||||
messages.push(message);
|
||||
}
|
||||
Event::WindowCreated(id, window) => {
|
||||
let mut surface = compositor.create_surface(&window);
|
||||
|
||||
let state = State::new(&application, &window);
|
||||
|
||||
let physical_size = state.physical_size();
|
||||
|
||||
compositor.configure_surface(
|
||||
&mut surface,
|
||||
physical_size.width,
|
||||
physical_size.height,
|
||||
);
|
||||
|
||||
let user_interface = build_user_interface(
|
||||
&application,
|
||||
user_interface::Cache::default(),
|
||||
&mut renderer,
|
||||
state.logical_size(),
|
||||
&mut debug,
|
||||
id,
|
||||
);
|
||||
|
||||
let _ = states.insert(id, state);
|
||||
let _ = surfaces.insert(id, surface);
|
||||
let _ = interfaces.insert(id, user_interface);
|
||||
let _ = window_ids.insert(window.id(), id);
|
||||
let _ = windows.insert(id, window);
|
||||
}
|
||||
Event::CloseWindow(id) => {
|
||||
println!("Closing window {:?}. Total: {}", id, windows.len());
|
||||
|
||||
if let Some(window) = windows.get(&id) {
|
||||
if window_ids.remove(&window.id()).is_none() {
|
||||
log::error!("Failed to remove window with id {:?} from window_ids.", window.id());
|
||||
}
|
||||
} else {
|
||||
log::error!("Could not find window with id {:?} in windows.", id);
|
||||
}
|
||||
if states.remove(&id).is_none() {
|
||||
log::error!("Failed to remove window {:?} from states.", id);
|
||||
}
|
||||
if interfaces.remove(&id).is_none() {
|
||||
log::error!("Failed to remove window {:?} from interfaces.", id);
|
||||
}
|
||||
if windows.remove(&id).is_none() {
|
||||
log::error!("Failed to remove window {:?} from windows.", id);
|
||||
}
|
||||
if surfaces.remove(&id).is_none() {
|
||||
log::error!("Failed to remove window {:?} from surfaces.", id);
|
||||
}
|
||||
|
||||
if windows.is_empty() {
|
||||
log::info!("All windows are closed. Terminating program.");
|
||||
break 'main;
|
||||
} else {
|
||||
log::info!("Remaining windows: {:?}", windows.len());
|
||||
}
|
||||
}
|
||||
Event::NewWindow(_, _) => unreachable!(),
|
||||
event::Event::UserEvent(event) => match event {
|
||||
Event::Application(message) => {
|
||||
messages.push(message);
|
||||
}
|
||||
}
|
||||
Event::WindowCreated(id, window) => {
|
||||
let mut surface = compositor.create_surface(&window);
|
||||
|
||||
let state = State::new(&application, id, &window);
|
||||
|
||||
let physical_size = state.physical_size();
|
||||
|
||||
compositor.configure_surface(
|
||||
&mut surface,
|
||||
physical_size.width,
|
||||
physical_size.height,
|
||||
);
|
||||
|
||||
let user_interface = build_user_interface(
|
||||
&application,
|
||||
user_interface::Cache::default(),
|
||||
&mut renderer,
|
||||
state.logical_size(),
|
||||
&mut debug,
|
||||
id,
|
||||
);
|
||||
|
||||
let _ = states.insert(id, state);
|
||||
let _ = surfaces.insert(id, surface);
|
||||
let _ = interfaces.insert(id, user_interface);
|
||||
let _ = window_ids.insert(window.id(), id);
|
||||
let _ = windows.insert(id, window);
|
||||
}
|
||||
Event::CloseWindow(id) => {
|
||||
if let Some(window) = windows.get(&id) {
|
||||
if window_ids.remove(&window.id()).is_none() {
|
||||
log::error!("Failed to remove window with id {:?} from window_ids.", window.id());
|
||||
}
|
||||
} else {
|
||||
log::error!(
|
||||
"Could not find window with id {:?} in windows.",
|
||||
id
|
||||
);
|
||||
}
|
||||
if states.remove(&id).is_none() {
|
||||
log::error!(
|
||||
"Failed to remove window {:?} from states.",
|
||||
id
|
||||
);
|
||||
}
|
||||
if interfaces.remove(&id).is_none() {
|
||||
log::error!(
|
||||
"Failed to remove window {:?} from interfaces.",
|
||||
id
|
||||
);
|
||||
}
|
||||
if windows.remove(&id).is_none() {
|
||||
log::error!(
|
||||
"Failed to remove window {:?} from windows.",
|
||||
id
|
||||
);
|
||||
}
|
||||
if surfaces.remove(&id).is_none() {
|
||||
log::error!(
|
||||
"Failed to remove window {:?} from surfaces.",
|
||||
id
|
||||
);
|
||||
}
|
||||
|
||||
if windows.is_empty() {
|
||||
log::info!(
|
||||
"All windows are closed. Terminating program."
|
||||
);
|
||||
break 'main;
|
||||
} else {
|
||||
log::info!("Remaining windows: {:?}", windows.len());
|
||||
}
|
||||
}
|
||||
Event::NewWindow { .. } => unreachable!(),
|
||||
},
|
||||
event::Event::RedrawRequested(id) => {
|
||||
let state = window_ids
|
||||
.get(&id)
|
||||
|
|
@ -716,11 +737,10 @@ async fn run_instance<A, E, C>(
|
|||
));
|
||||
}
|
||||
} else {
|
||||
// TODO(derezzedex): log error
|
||||
log::error!("No window state found for id: {:?}", window_id);
|
||||
}
|
||||
} else {
|
||||
// TODO(derezzedex): log error
|
||||
// println!("{:?}: {:?}", window_id, window_event);
|
||||
log::error!("No window found with id: {:?}", window_id);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
|
@ -864,7 +884,11 @@ pub fn run_command<A, E>(
|
|||
command::Action::Window(id, action) => match action {
|
||||
window::Action::Spawn { settings } => {
|
||||
proxy
|
||||
.send_event(Event::NewWindow(id, settings.into()))
|
||||
.send_event(Event::NewWindow {
|
||||
id,
|
||||
settings: settings.into(),
|
||||
title: application.title(id),
|
||||
})
|
||||
.expect("Send message to event loop");
|
||||
}
|
||||
window::Action::Close => {
|
||||
|
|
@ -926,6 +950,16 @@ pub fn run_command<A, E>(
|
|||
let window = windows.get(&id).expect("No window found!");
|
||||
window.set_decorations(!window.is_decorated());
|
||||
}
|
||||
window::Action::RequestUserAttention(attention_type) => {
|
||||
let window = windows.get(&id).expect("No window found!");
|
||||
window.request_user_attention(
|
||||
attention_type.map(conversion::user_attention),
|
||||
);
|
||||
}
|
||||
Action::GainFocus => {
|
||||
let window = windows.get(&id).expect("No window found!");
|
||||
window.focus_window();
|
||||
}
|
||||
},
|
||||
command::Action::System(action) => match action {
|
||||
system::Action::QueryInformation(_tag) => {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ use crate::multi_window::Application;
|
|||
use crate::window;
|
||||
use crate::{Color, Debug, Point, Size, Viewport};
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::marker::PhantomData;
|
||||
use winit::event::{Touch, WindowEvent};
|
||||
use winit::window::Window;
|
||||
|
|
@ -31,8 +30,8 @@ where
|
|||
<A::Renderer as crate::Renderer>::Theme: application::StyleSheet,
|
||||
{
|
||||
/// Creates a new [`State`] for the provided [`Application`] and window.
|
||||
pub fn new(application: &A, window: &Window) -> Self {
|
||||
let title = application.title();
|
||||
pub fn new(application: &A, window_id: window::Id, window: &Window) -> Self {
|
||||
let title = application.title(window_id);
|
||||
let scale_factor = application.scale_factor();
|
||||
let theme = application.theme();
|
||||
let appearance = theme.appearance(&application.style());
|
||||
|
|
@ -65,7 +64,7 @@ where
|
|||
&self.viewport
|
||||
}
|
||||
|
||||
/// TODO(derezzedex)
|
||||
/// Returns whether or not the viewport changed.
|
||||
pub fn viewport_changed(&self) -> bool {
|
||||
self.viewport_changed
|
||||
}
|
||||
|
|
@ -184,12 +183,11 @@ where
|
|||
pub fn synchronize(
|
||||
&mut self,
|
||||
application: &A,
|
||||
windows: &HashMap<window::Id, Window>,
|
||||
window_id: window::Id,
|
||||
window: &Window,
|
||||
) {
|
||||
let window = windows.values().next().expect("No window found");
|
||||
|
||||
// Update window title
|
||||
let new_title = application.title();
|
||||
let new_title = application.title(window_id);
|
||||
|
||||
if self.title != new_title {
|
||||
window.set_title(&new_title);
|
||||
|
|
|
|||
|
|
@ -2,19 +2,19 @@
|
|||
use crate::command::{self, Command};
|
||||
use iced_native::window;
|
||||
|
||||
pub use window::{Id, Event, Mode, UserAttention};
|
||||
pub use window::{Event, Id, Mode, UserAttention};
|
||||
|
||||
/// Closes the current window and exits the application.
|
||||
pub fn close<Message>() -> Command<Message> {
|
||||
Command::single(command::Action::Window(window::Action::Close))
|
||||
/// Closes the window.
|
||||
pub fn close<Message>(id: window::Id) -> Command<Message> {
|
||||
Command::single(command::Action::Window(id, window::Action::Close))
|
||||
}
|
||||
|
||||
/// Begins dragging the window while the left mouse button is held.
|
||||
pub fn drag<Message>() -> Command<Message> {
|
||||
Command::single(command::Action::Window(window::Action::Drag))
|
||||
pub fn drag<Message>(id: window::Id) -> Command<Message> {
|
||||
Command::single(command::Action::Window(id, window::Action::Drag))
|
||||
}
|
||||
|
||||
/// TODO(derezzedex)
|
||||
/// Spawns a new window.
|
||||
pub fn spawn<Message>(
|
||||
id: window::Id,
|
||||
settings: window::Settings,
|
||||
|
|
@ -25,11 +25,6 @@ pub fn spawn<Message>(
|
|||
))
|
||||
}
|
||||
|
||||
/// TODO(derezzedex)
|
||||
pub fn close<Message>(id: window::Id) -> Command<Message> {
|
||||
Command::single(command::Action::Window(id, window::Action::Close))
|
||||
}
|
||||
|
||||
/// Resizes the window to the given logical dimensions.
|
||||
pub fn resize<Message>(
|
||||
id: window::Id,
|
||||
|
|
@ -43,13 +38,19 @@ pub fn resize<Message>(
|
|||
}
|
||||
|
||||
/// Sets the window to maximized or back.
|
||||
pub fn maximize<Message>(value: bool) -> Command<Message> {
|
||||
Command::single(command::Action::Window(window::Action::Maximize(value)))
|
||||
pub fn maximize<Message>(id: window::Id, value: bool) -> Command<Message> {
|
||||
Command::single(command::Action::Window(
|
||||
id,
|
||||
window::Action::Maximize(value),
|
||||
))
|
||||
}
|
||||
|
||||
/// Set the window to minimized or back.
|
||||
pub fn minimize<Message>(value: bool) -> Command<Message> {
|
||||
Command::single(command::Action::Window(window::Action::Minimize(value)))
|
||||
pub fn minimize<Message>(id: window::Id, value: bool) -> Command<Message> {
|
||||
Command::single(command::Action::Window(
|
||||
id,
|
||||
window::Action::Minimize(value),
|
||||
))
|
||||
}
|
||||
|
||||
/// Moves a window to the given logical coordinates.
|
||||
|
|
@ -63,8 +64,8 @@ pub fn set_mode<Message>(id: window::Id, mode: Mode) -> Command<Message> {
|
|||
}
|
||||
|
||||
/// Sets the window to maximized or back.
|
||||
pub fn toggle_maximize<Message>() -> Command<Message> {
|
||||
Command::single(command::Action::Window(window::Action::ToggleMaximize))
|
||||
pub fn toggle_maximize<Message>(id: window::Id) -> Command<Message> {
|
||||
Command::single(command::Action::Window(id, window::Action::ToggleMaximize))
|
||||
}
|
||||
|
||||
/// Fetches the current [`Mode`] of the window.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue