128 lines
4.2 KiB
Rust
128 lines
4.2 KiB
Rust
use std::vec;
|
|
use std::vec::Vec;
|
|
use std::boxed::Box;
|
|
|
|
use ming_wm_lib::window_manager_types::{ DrawInstructions, WindowLike, WindowLikeType, TASKBAR_HEIGHT };
|
|
use ming_wm_lib::messages::{ WindowMessage, WindowMessageResponse, WindowManagerRequest, ShortcutType, InfoType, WindowsVec };
|
|
use ming_wm_lib::framebuffer_types::Dimensions;
|
|
use ming_wm_lib::themes::ThemeInfo;
|
|
use ming_wm_lib::components::Component;
|
|
use ming_wm_lib::components::toggle_button::ToggleButton;
|
|
|
|
const PADDING: usize = 4;
|
|
const META_WIDTH: usize = 175; //of the window button
|
|
|
|
#[derive(Clone)]
|
|
enum TaskbarMessage {
|
|
ShowStartMenu,
|
|
HideStartMenu,
|
|
Nothing,
|
|
//
|
|
}
|
|
|
|
pub struct Taskbar {
|
|
dimensions: Dimensions,
|
|
components: Vec<Box<dyn Component<TaskbarMessage> + Send>>,
|
|
windows_in_workspace: WindowsVec,
|
|
focused_id: usize,
|
|
}
|
|
|
|
impl WindowLike for Taskbar {
|
|
fn handle_message(&mut self, message: WindowMessage) -> WindowMessageResponse {
|
|
match message {
|
|
WindowMessage::Init(dimensions) => {
|
|
self.dimensions = dimensions;
|
|
self.components = vec![
|
|
Box::new(ToggleButton::new("start-button".to_string(), [PADDING, PADDING], [44, self.dimensions[1] - (PADDING * 2)], "Start".to_string(), TaskbarMessage::ShowStartMenu, TaskbarMessage::HideStartMenu)),
|
|
];
|
|
WindowMessageResponse::JustRedraw
|
|
},
|
|
WindowMessage::Shortcut(shortcut) => {
|
|
match shortcut {
|
|
ShortcutType::StartMenu => {
|
|
let start_index = self.components.iter().position(|c| c.name() == "start-button").unwrap();
|
|
let start_response = self.components[start_index].handle_message(WindowMessage::FocusClick);
|
|
self.handle_taskbar_message(start_response)
|
|
}
|
|
_ => WindowMessageResponse::DoNothing,
|
|
}
|
|
},
|
|
WindowMessage::Info(info) => {
|
|
if let InfoType::WindowsInWorkspace(windows, focused_id) = info {
|
|
self.windows_in_workspace = windows;
|
|
self.focused_id = focused_id;
|
|
WindowMessageResponse::JustRedraw
|
|
} else {
|
|
WindowMessageResponse::DoNothing
|
|
}
|
|
},
|
|
_ => WindowMessageResponse::DoNothing,
|
|
}
|
|
}
|
|
|
|
//simple
|
|
fn draw(&self, theme_info: &ThemeInfo) -> Vec<DrawInstructions> {
|
|
let mut instructions = vec![
|
|
//top thin white border
|
|
DrawInstructions::Rect([0, 0], [self.dimensions[0], 1], theme_info.border_left_top),
|
|
//the actual taskbar background
|
|
DrawInstructions::Rect([0, 1], [self.dimensions[0], self.dimensions[1] - 1], theme_info.background),
|
|
];
|
|
for component in &self.components {
|
|
instructions.extend(component.draw(theme_info));
|
|
}
|
|
for wi in 0..self.windows_in_workspace.len() {
|
|
//if too many windows to fit in taskbar...
|
|
if wi > (self.dimensions[0] - 200) / META_WIDTH {
|
|
//
|
|
break;
|
|
}
|
|
let info = &self.windows_in_workspace[wi];
|
|
let name = &info.1;
|
|
let mut b = ToggleButton::new(name.to_string() + "-window", [PADDING * 2 + 44 + (META_WIDTH + PADDING) * wi, PADDING], [META_WIDTH, self.dimensions[1] - (PADDING * 2)], name.to_string(), TaskbarMessage::Nothing, TaskbarMessage::Nothing);
|
|
b.inverted = info.0 == self.focused_id;
|
|
instructions.extend(b.draw(theme_info));
|
|
}
|
|
instructions
|
|
}
|
|
|
|
//properties
|
|
fn subtype(&self) -> WindowLikeType {
|
|
WindowLikeType::Taskbar
|
|
}
|
|
|
|
fn ideal_dimensions(&self, dimensions: Dimensions) -> Dimensions {
|
|
[dimensions[0], TASKBAR_HEIGHT]
|
|
}
|
|
}
|
|
|
|
impl Taskbar {
|
|
pub fn new() -> Self {
|
|
Self {
|
|
dimensions: [0, 0],
|
|
components: Vec::new(),
|
|
windows_in_workspace: Vec::new(),
|
|
focused_id: 0,
|
|
}
|
|
}
|
|
|
|
fn handle_taskbar_message(&mut self, message: Option<TaskbarMessage>) -> WindowMessageResponse {
|
|
if let Some(message) = message {
|
|
match message {
|
|
TaskbarMessage::ShowStartMenu => {
|
|
WindowMessageResponse::Request(WindowManagerRequest::OpenWindow("StartMenu".to_string()))
|
|
},
|
|
TaskbarMessage::HideStartMenu => {
|
|
WindowMessageResponse::Request(WindowManagerRequest::CloseStartMenu)
|
|
},
|
|
_ => WindowMessageResponse::DoNothing,
|
|
}
|
|
} else {
|
|
//maybe should be JustRedraw?
|
|
WindowMessageResponse::DoNothing
|
|
}
|
|
}
|
|
}
|
|
|
|
|