change project structure to make more sense
(move wm only stuff to wm dir)
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ming-wm-lib"
|
||||
version = "0.1.6"
|
||||
version = "0.1.7"
|
||||
repository = "https://github.com/stjet/ming-wm"
|
||||
description = "library for building windows for ming-wm in rust"
|
||||
readme = "README.md"
|
||||
|
||||
78
ming-wm-lib/src/components/highlight_button.rs
Normal file
78
ming-wm-lib/src/components/highlight_button.rs
Normal file
@@ -0,0 +1,78 @@
|
||||
use std::vec;
|
||||
use std::vec::Vec;
|
||||
|
||||
use crate::components::Component;
|
||||
use crate::framebuffer_types::{ Dimensions, Point };
|
||||
use crate::themes::ThemeInfo;
|
||||
use crate::messages::WindowMessage;
|
||||
use crate::window_manager_types::DrawInstructions;
|
||||
|
||||
pub struct HighlightButton<T> {
|
||||
name_: String,
|
||||
top_left: Point,
|
||||
size: Dimensions,
|
||||
pub text: String,
|
||||
pub highlighted: bool,
|
||||
click_return: T,
|
||||
toggle_highlight_return: T, //also unhighlight return
|
||||
}
|
||||
|
||||
impl<T: Clone> Component<T> for HighlightButton<T> {
|
||||
fn handle_message(&mut self, message: WindowMessage) -> Option<T> {
|
||||
match message {
|
||||
WindowMessage::Focus | WindowMessage::Unfocus => {
|
||||
self.highlighted = !self.highlighted;
|
||||
Some(self.toggle_highlight_return.clone())
|
||||
},
|
||||
WindowMessage::FocusClick => {
|
||||
//we know this click was for this button, otherwise window wouldn't have given us this message
|
||||
Some(self.click_return.clone())
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn draw(&self, theme_info: &ThemeInfo) -> Vec<DrawInstructions> {
|
||||
let font_height = 15;
|
||||
if self.highlighted {
|
||||
vec![
|
||||
//highlight background
|
||||
DrawInstructions::Rect(self.top_left, self.size, theme_info.top),
|
||||
DrawInstructions::Text([self.top_left[0] + 4, self.top_left[1] + (self.size[1] - font_height) / 2], vec!["nimbus-roman".to_string()], self.text.clone(), theme_info.top_text, theme_info.top, None, None),
|
||||
]
|
||||
} else {
|
||||
vec![
|
||||
DrawInstructions::Rect(self.top_left, self.size, theme_info.background),
|
||||
DrawInstructions::Text([self.top_left[0] + 4, self.top_left[1] + (self.size[1] - font_height) / 2], vec!["nimbus-roman".to_string()], self.text.clone(), theme_info.text, theme_info.background, None, None),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
//properties
|
||||
fn focusable(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn clickable(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn name(&self) -> &String {
|
||||
&self.name_
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> HighlightButton<T> {
|
||||
pub fn new(name_: String, top_left: Point, size: Dimensions, text: String, click_return: T, toggle_highlight_return: T, highlighted: bool) -> Self {
|
||||
Self {
|
||||
name_,
|
||||
top_left,
|
||||
size,
|
||||
text,
|
||||
click_return,
|
||||
toggle_highlight_return,
|
||||
highlighted,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
24
ming-wm-lib/src/components/mod.rs
Normal file
24
ming-wm-lib/src/components/mod.rs
Normal file
@@ -0,0 +1,24 @@
|
||||
use std::vec::Vec;
|
||||
|
||||
use crate::themes::ThemeInfo;
|
||||
use crate::messages::WindowMessage;
|
||||
use crate::window_manager_types::DrawInstructions;
|
||||
|
||||
pub mod toggle_button;
|
||||
pub mod highlight_button;
|
||||
pub mod paragraph;
|
||||
pub mod press_button;
|
||||
|
||||
pub trait Component<T> {
|
||||
fn handle_message(&mut self, message: WindowMessage) -> Option<T>;
|
||||
fn draw(&self, theme_info: &ThemeInfo) -> Vec<DrawInstructions>;
|
||||
|
||||
//properties
|
||||
//focusing is a way for the *window* to know what component to send input, presses, etc
|
||||
//focusing for components is purely to give a visual representation
|
||||
fn focusable(&self) -> bool;
|
||||
fn clickable(&self) -> bool;
|
||||
//fn pressable(&self) -> bool; //touch
|
||||
fn name(&self) -> &String; //should be unique
|
||||
}
|
||||
|
||||
91
ming-wm-lib/src/components/paragraph.rs
Normal file
91
ming-wm-lib/src/components/paragraph.rs
Normal file
@@ -0,0 +1,91 @@
|
||||
use std::vec;
|
||||
use std::vec::Vec;
|
||||
|
||||
use crate::framebuffer_types::{ Dimensions, Point };
|
||||
use crate::themes::ThemeInfo;
|
||||
use crate::messages::WindowMessage;
|
||||
use crate::window_manager_types::DrawInstructions;
|
||||
use crate::utils::calc_actual_lines;
|
||||
use crate::components::Component;
|
||||
|
||||
const MONO_WIDTH: u8 = 10;
|
||||
const LINE_HEIGHT: usize = 18;
|
||||
|
||||
pub struct Paragraph<T> {
|
||||
name_: String,
|
||||
actual_lines: Vec<(bool, usize, String)>, //first, line #, actual line
|
||||
top_left: Point,
|
||||
size: Dimensions,
|
||||
line_pos: usize,
|
||||
key_return: T,
|
||||
}
|
||||
|
||||
impl<T: Copy> Component<T> for Paragraph<T> {
|
||||
fn handle_message(&mut self, message: WindowMessage) -> Option<T> {
|
||||
if let WindowMessage::KeyPress(key_press) = message {
|
||||
if key_press.key == 'j' {
|
||||
//down
|
||||
if self.line_pos != self.actual_lines.len() - 1 {
|
||||
self.line_pos += 1;
|
||||
}
|
||||
Some(self.key_return)
|
||||
} else if key_press.key == 'k' {
|
||||
//up
|
||||
if self.line_pos != 0 {
|
||||
self.line_pos -= 1;
|
||||
}
|
||||
Some(self.key_return)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn draw(&self, theme_info: &ThemeInfo) -> Vec<DrawInstructions> {
|
||||
let mut instructions = Vec::new();
|
||||
let max_lines = self.size[1] / LINE_HEIGHT;
|
||||
let mut start_y = self.top_left[1];
|
||||
for line in self.actual_lines.iter().skip(self.line_pos).take(max_lines) {
|
||||
instructions.push(DrawInstructions::Text([self.top_left[0], start_y], vec!["nimbus-romono".to_string()], line.2.clone(), theme_info.text, theme_info.background, Some(0), Some(MONO_WIDTH)));
|
||||
start_y += LINE_HEIGHT;
|
||||
}
|
||||
instructions
|
||||
}
|
||||
|
||||
//properties
|
||||
fn focusable(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn clickable(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn name(&self) -> &String {
|
||||
&self.name_
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Paragraph<T> {
|
||||
pub fn new(name_: String, top_left: Point, size: Dimensions, text: String, key_return: T) -> Self {
|
||||
let mut s = Self {
|
||||
name_,
|
||||
actual_lines: Vec::new(),
|
||||
top_left,
|
||||
size,
|
||||
line_pos: 0,
|
||||
key_return,
|
||||
};
|
||||
s.new_text(text);
|
||||
s
|
||||
}
|
||||
|
||||
pub fn new_text(&mut self, text: String) {
|
||||
let max_chars_per_line = self.size[0] / MONO_WIDTH as usize;
|
||||
let lines: Vec<String> = text.split("\n").map(|s| s.to_string()).collect();
|
||||
self.actual_lines = calc_actual_lines(lines.iter(), max_chars_per_line, true);
|
||||
}
|
||||
}
|
||||
|
||||
69
ming-wm-lib/src/components/press_button.rs
Normal file
69
ming-wm-lib/src/components/press_button.rs
Normal file
@@ -0,0 +1,69 @@
|
||||
use std::vec;
|
||||
use std::vec::Vec;
|
||||
|
||||
use crate::components::Component;
|
||||
use crate::framebuffer_types::{ Dimensions, Point };
|
||||
use crate::themes::ThemeInfo;
|
||||
use crate::messages::WindowMessage;
|
||||
use crate::window_manager_types::DrawInstructions;
|
||||
|
||||
const MONO_WIDTH: u8 = 10;
|
||||
|
||||
pub struct PressButton<T> {
|
||||
pub top_left: Point,
|
||||
pub size: Dimensions,
|
||||
text: String,
|
||||
press_return: T,
|
||||
}
|
||||
|
||||
impl<T: Clone> Component<T> for PressButton<T> {
|
||||
//
|
||||
fn handle_message(&mut self, message: WindowMessage) -> Option<T> {
|
||||
match message {
|
||||
WindowMessage::Touch(_, _) => {
|
||||
//assume that the parent window-like passed it to us intentionally and checked already
|
||||
//we can check again, but why?
|
||||
Some(self.press_return.clone())
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn draw(&self, theme_info: &ThemeInfo) -> Vec<DrawInstructions> {
|
||||
let half = self.size[0] / 2 - self.text.len() * MONO_WIDTH as usize / 2;
|
||||
vec![
|
||||
DrawInstructions::Rect(self.top_left, [self.size[0], 1], theme_info.border_left_top),
|
||||
DrawInstructions::Rect(self.top_left, [1, self.size[1]], theme_info.border_left_top),
|
||||
DrawInstructions::Rect([self.top_left[0], self.top_left[1] + self.size[1]], [self.size[0], 1], theme_info.border_right_bottom),
|
||||
DrawInstructions::Rect([self.top_left[0] + self.size[0], self.top_left[1]], [1, self.size[1]], theme_info.border_right_bottom),
|
||||
//assume normal background colour
|
||||
DrawInstructions::Text([self.top_left[0] + half, self.top_left[1] + 8], vec!["nimbus-romono".to_string()], self.text.clone(), theme_info.text, theme_info.background, Some(0), Some(MONO_WIDTH)),
|
||||
]
|
||||
}
|
||||
|
||||
//properties
|
||||
fn focusable(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn clickable(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn name(&self) -> &String {
|
||||
//sorry
|
||||
&self.text
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> PressButton<T> {
|
||||
pub fn new(top_left: Point, size: Dimensions, text: String, press_return: T) -> Self {
|
||||
Self {
|
||||
top_left,
|
||||
size,
|
||||
text,
|
||||
press_return,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
80
ming-wm-lib/src/components/toggle_button.rs
Normal file
80
ming-wm-lib/src/components/toggle_button.rs
Normal file
@@ -0,0 +1,80 @@
|
||||
use std::vec;
|
||||
use std::vec::Vec;
|
||||
|
||||
use crate::components::Component;
|
||||
use crate::framebuffer_types::{ Dimensions, Point };
|
||||
use crate::themes::ThemeInfo;
|
||||
use crate::messages::WindowMessage;
|
||||
use crate::window_manager_types::DrawInstructions;
|
||||
|
||||
pub struct ToggleButton<T> {
|
||||
name_: String,
|
||||
top_left: Point,
|
||||
size: Dimensions,
|
||||
text: String,
|
||||
pub inverted: bool, //whether is it clicked or not
|
||||
click_return: T,
|
||||
unclick_return: T,
|
||||
}
|
||||
|
||||
impl<T: Clone> Component<T> for ToggleButton<T> {
|
||||
fn handle_message(&mut self, message: WindowMessage) -> Option<T> {
|
||||
match message {
|
||||
WindowMessage::FocusClick => {
|
||||
//we know this click was for this button, otherwise window wouldn't have given us this message
|
||||
self.inverted = !self.inverted;
|
||||
if self.inverted {
|
||||
Some(self.click_return.clone())
|
||||
} else {
|
||||
Some(self.unclick_return.clone())
|
||||
}
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn draw(&self, theme_info: &ThemeInfo) -> Vec<DrawInstructions> {
|
||||
//to make sure the text gets vertically centred
|
||||
let font_height = 15;
|
||||
vec![
|
||||
//top and left border
|
||||
DrawInstructions::Rect(self.top_left, [self.size[0], 2], if self.inverted { theme_info.border_right_bottom } else { theme_info.border_left_top }),
|
||||
DrawInstructions::Rect(self.top_left, [2, self.size[1]], if self.inverted { theme_info.border_right_bottom } else { theme_info.border_left_top }),
|
||||
//right and bottom border
|
||||
DrawInstructions::Rect([self.top_left[0] + self.size[0] - 2, self.top_left[1]], [2, self.size[1]], if self.inverted { theme_info.border_left_top } else { theme_info.border_right_bottom }),
|
||||
DrawInstructions::Rect([self.top_left[0], self.top_left[1] + self.size[1] - 2], [self.size[0], 2], if self.inverted { theme_info.border_left_top } else { theme_info.border_right_bottom }),
|
||||
//the background if self.draw_bg
|
||||
//DrawInstructions::Rect(),
|
||||
//the text (for now, hardcoded top left)
|
||||
DrawInstructions::Text([self.top_left[0] + 4, self.top_left[1] + (self.size[1] - font_height) / 2], vec!["nimbus-roman".to_string()], self.text.to_string(), theme_info.text, theme_info.background, None, None),
|
||||
]
|
||||
}
|
||||
|
||||
//properties
|
||||
fn focusable(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn clickable(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn name(&self) -> &String {
|
||||
&self.name_
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ToggleButton<T> {
|
||||
pub fn new(name_: String, top_left: Point, size: Dimensions, text: String, click_return: T, unclick_return: T) -> Self {
|
||||
Self {
|
||||
name_,
|
||||
top_left,
|
||||
size,
|
||||
text,
|
||||
click_return,
|
||||
unclick_return,
|
||||
inverted: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ pub mod themes;
|
||||
pub mod serialize;
|
||||
pub mod messages;
|
||||
pub mod ipc;
|
||||
pub mod components;
|
||||
pub mod dirs;
|
||||
pub mod utils;
|
||||
pub mod logging;
|
||||
|
||||
@@ -214,3 +214,16 @@ pub fn path_autocomplete(current_path: &str, partial_path: &str) -> Option<Strin
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_all_files(dir: PathBuf) -> Vec<PathBuf> {
|
||||
let mut files = Vec::new();
|
||||
for entry in read_dir(dir).unwrap() {
|
||||
let path = entry.unwrap().path();
|
||||
if path.is_dir() {
|
||||
files.extend(get_all_files(path));
|
||||
} else {
|
||||
files.push(path);
|
||||
}
|
||||
}
|
||||
files
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user