v1.2
random lockscreen message, remove rand dep for audio player, add version to about window, add o/O to malvim, add circles to draw, bug fixes, minor byte savings for font .alpha format
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ming-wm"
|
name = "ming-wm"
|
||||||
version = "1.2.0-beta.0"
|
version = "1.2.0"
|
||||||
repository = "https://github.com/stjet/ming-wm"
|
repository = "https://github.com/stjet/ming-wm"
|
||||||
license = "GPL-3.0-or-later"
|
license = "GPL-3.0-or-later"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
@@ -20,7 +20,6 @@ ming-wm-lib = { path = "ming-wm-lib" }
|
|||||||
wm = { path = "wm", optional = true }
|
wm = { path = "wm", optional = true }
|
||||||
linux = { path = "linux", optional = true }
|
linux = { path = "linux", optional = true }
|
||||||
rodio = { version = "0.19.0", default-features = false, features = [ "flac", "mp3", "symphonia-vorbis", "wav" ], optional = true }
|
rodio = { version = "0.19.0", default-features = false, features = [ "flac", "mp3", "symphonia-vorbis", "wav" ], optional = true }
|
||||||
rand = { version = "0.9.0", default-features = false, features = [ "small_rng" ], optional = true }
|
|
||||||
id3 = { version = "1.10.0", optional = true }
|
id3 = { version = "1.10.0", optional = true }
|
||||||
mp4ameta = { version = "0.11.0", optional = true }
|
mp4ameta = { version = "0.11.0", optional = true }
|
||||||
metaflac = { version = "0.2.5", optional = true }
|
metaflac = { version = "0.2.5", optional = true }
|
||||||
@@ -28,7 +27,7 @@ metaflac = { version = "0.2.5", optional = true }
|
|||||||
[features]
|
[features]
|
||||||
default = [ "wm", "terminal" ]
|
default = [ "wm", "terminal" ]
|
||||||
terminal = [ "linux" ]
|
terminal = [ "linux" ]
|
||||||
audio_player = [ "id3", "mp4ameta", "metaflac", "rand", "rodio" ]
|
audio_player = [ "id3", "mp4ameta", "metaflac", "rodio" ]
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
lto = true
|
lto = true
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 378 B After Width: | Height: | Size: 378 B |
BIN
bmps/shippori-mincho/ー6.bmp
Normal file
BIN
bmps/shippori-mincho/ー6.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 94 B |
BIN
bmps/shippori-mincho/中0.bmp
Normal file
BIN
bmps/shippori-mincho/中0.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 534 B |
BIN
bmps/shippori-mincho/合0.bmp
Normal file
BIN
bmps/shippori-mincho/合0.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 630 B |
4
build.rs
4
build.rs
@@ -35,7 +35,7 @@ fn font_chars_to_alphas(dir: &str) {
|
|||||||
ch.push(row);
|
ch.push(row);
|
||||||
}
|
}
|
||||||
let ch: Vec<String> = ch.into_iter().map(|row| {
|
let ch: Vec<String> = ch.into_iter().map(|row| {
|
||||||
row.join(",")
|
row.join(",").replace(",,,,", ":").replace(",,,", ";").replace(",,", ".")
|
||||||
}).collect();
|
}).collect();
|
||||||
let chars: Vec<char> = file_name[0].chars().collect();
|
let chars: Vec<char> = file_name[0].chars().collect();
|
||||||
File::create(dir.to_string() + "/" + &chars[0].to_string() + ".alpha").unwrap().write_all(
|
File::create(dir.to_string() + "/" + &chars[0].to_string() + ".alpha").unwrap().write_all(
|
||||||
@@ -61,7 +61,9 @@ fn main() {
|
|||||||
}
|
}
|
||||||
//copy bmp folders to target
|
//copy bmp folders to target
|
||||||
let profile = env::var_os("PROFILE").unwrap().to_string_lossy().to_string();
|
let profile = env::var_os("PROFILE").unwrap().to_string_lossy().to_string();
|
||||||
|
Command::new("rm").arg("-rf").arg(format!("./target/{}/ming_bmps", profile)).output().unwrap(); //delete at target first so cp works
|
||||||
Command::new("cp").arg("-r").arg("./bmps").arg(format!("./target/{}/ming_bmps", profile)).output().unwrap();
|
Command::new("cp").arg("-r").arg("./bmps").arg(format!("./target/{}/ming_bmps", profile)).output().unwrap();
|
||||||
//also copy the docs folder
|
//also copy the docs folder
|
||||||
|
Command::new("rm").arg("-rf").arg(format!("./target/{}/ming_docs", profile)).output().unwrap();
|
||||||
Command::new("cp").arg("-r").arg("./docs").arg(format!("./target/{}/ming_docs", profile)).output().unwrap();
|
Command::new("cp").arg("-r").arg("./docs").arg(format!("./target/{}/ming_docs", profile)).output().unwrap();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,9 +6,10 @@ Arrow keys or hjkl. `i` to enter input mode. Use the enter key to finish a line
|
|||||||
|
|
||||||
## Input Commands
|
## Input Commands
|
||||||
|
|
||||||
- `line`: Start line with current point as start. Move and hit enter to determine line endpoint
|
- `line/l`: Start line with current point as start. Move and hit enter to determine line endpoint
|
||||||
- `rect`: Start rect with current point as a corner. Move and hit enter to determine the opposite corner
|
- `rect/r`: Start rect with current point as a corner. Move and hit enter to determine the opposite corner
|
||||||
- `color/c/colour [lowercase 6 char hex string]`: Set current colour
|
- `circle/c`: Start circle with current point as centre. Move and hit enter to determine radius
|
||||||
|
- `color/co/colour [lowercase 6 char hex string]`: Set current colour
|
||||||
- `linewidth/lw [int]`: Set current line width
|
- `linewidth/lw [int]`: Set current line width
|
||||||
- `undo`: Undo last draw
|
- `undo`: Undo last draw
|
||||||
- `clear`: Clear all drawings
|
- `clear`: Clear all drawings
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ming-wm-lib"
|
name = "ming-wm-lib"
|
||||||
version = "0.2.0"
|
version = "0.2.1"
|
||||||
repository = "https://github.com/stjet/ming-wm"
|
repository = "https://github.com/stjet/ming-wm"
|
||||||
description = "library for building windows for ming-wm in rust"
|
description = "library for building windows for ming-wm in rust"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
|||||||
@@ -7,6 +7,14 @@ pub fn min(one: usize, two: usize) -> usize {
|
|||||||
if one > two { two } else { one }
|
if one > two { two } else { one }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn random_u32(seed: u32) -> u32 {
|
||||||
|
let mut seed = seed;
|
||||||
|
seed ^= seed << 13;
|
||||||
|
seed ^= seed >> 17;
|
||||||
|
seed ^= seed >> 5;
|
||||||
|
seed
|
||||||
|
}
|
||||||
|
|
||||||
pub trait Substring {
|
pub trait Substring {
|
||||||
fn substring(&self, start: usize, end: usize) -> &str;
|
fn substring(&self, start: usize, end: usize) -> &str;
|
||||||
fn remove(&self, index: usize, len: usize) -> String;
|
fn remove(&self, index: usize, len: usize) -> String;
|
||||||
@@ -88,18 +96,6 @@ pub fn calc_actual_lines<'a>(lines: impl Iterator<Item = &'a String>, max_chars_
|
|||||||
actual_lines
|
actual_lines
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn calc_new_cursor_pos(cursor_pos: usize, new_length: usize) -> usize {
|
|
||||||
if cursor_pos >= new_length {
|
|
||||||
if new_length == 0 {
|
|
||||||
0
|
|
||||||
} else {
|
|
||||||
new_length - 1
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
cursor_pos
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn concat_paths(current_path: &str, add_path: &str) -> Result<PathBuf, ()> {
|
pub fn concat_paths(current_path: &str, add_path: &str) -> Result<PathBuf, ()> {
|
||||||
let mut new_path = PathBuf::from(current_path);
|
let mut new_path = PathBuf::from(current_path);
|
||||||
//if current_path is a file, automatically uses it's parent (a directory)
|
//if current_path is a file, automatically uses it's parent (a directory)
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ use std::vec::Vec;
|
|||||||
use std::vec;
|
use std::vec;
|
||||||
use std::io::BufReader;
|
use std::io::BufReader;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::fs::{ read_to_string, File };
|
use std::fs::{ read_to_string, File };
|
||||||
use std::time::{ Duration, SystemTime, UNIX_EPOCH };
|
use std::time::{ Duration, SystemTime, UNIX_EPOCH };
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::sync::{ Arc, Mutex };
|
use std::sync::{ Arc, Mutex };
|
||||||
|
|
||||||
use rodio::{ Decoder, OutputStream, Sink, Source };
|
use rodio::{ Decoder, OutputStream, Sink, Source };
|
||||||
use rand::{ SeedableRng, prelude::SliceRandom, rngs::SmallRng };
|
|
||||||
use id3::TagLike;
|
use id3::TagLike;
|
||||||
use mp4ameta;
|
use mp4ameta;
|
||||||
use metaflac;
|
use metaflac;
|
||||||
@@ -17,7 +17,7 @@ use ming_wm_lib::window_manager_types::{ DrawInstructions, WindowLike, WindowLik
|
|||||||
use ming_wm_lib::messages::{ WindowMessage, WindowMessageResponse, WindowManagerRequest, ShortcutType };
|
use ming_wm_lib::messages::{ WindowMessage, WindowMessageResponse, WindowManagerRequest, ShortcutType };
|
||||||
use ming_wm_lib::framebuffer_types::Dimensions;
|
use ming_wm_lib::framebuffer_types::Dimensions;
|
||||||
use ming_wm_lib::themes::ThemeInfo;
|
use ming_wm_lib::themes::ThemeInfo;
|
||||||
use ming_wm_lib::utils::{ concat_paths, get_all_files, path_autocomplete, format_seconds, Substring };
|
use ming_wm_lib::utils::{ concat_paths, random_u32, get_all_files, path_autocomplete, format_seconds, Substring };
|
||||||
use ming_wm_lib::dirs::home;
|
use ming_wm_lib::dirs::home;
|
||||||
use ming_wm_lib::ipc::listen;
|
use ming_wm_lib::ipc::listen;
|
||||||
|
|
||||||
@@ -253,8 +253,13 @@ impl AudioPlayer {
|
|||||||
} else {
|
} else {
|
||||||
get_all_files(PathBuf::from(new_path))
|
get_all_files(PathBuf::from(new_path))
|
||||||
};
|
};
|
||||||
let mut rng = SmallRng::seed_from_u64(SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs());
|
let mut seed = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().subsec_millis();
|
||||||
queue.shuffle(&mut rng);
|
let mut q_weights: HashMap<PathBuf, u32> = HashMap::new();
|
||||||
|
for q in &queue {
|
||||||
|
seed = random_u32(seed);
|
||||||
|
q_weights.insert(q.to_path_buf(), seed);
|
||||||
|
}
|
||||||
|
queue.sort_by(|a, b| q_weights[a].cmp(&q_weights[b]));
|
||||||
if self.command.starts_with("p ") {
|
if self.command.starts_with("p ") {
|
||||||
let mut locked_internal = self.internal.lock().unwrap();
|
let mut locked_internal = self.internal.lock().unwrap();
|
||||||
(*locked_internal).sink.clear();
|
(*locked_internal).sink.clear();
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use ming_wm_lib::ipc::listen;
|
|||||||
enum DrawAction {
|
enum DrawAction {
|
||||||
Line(Point, Option<Point>, usize, RGBColor),
|
Line(Point, Option<Point>, usize, RGBColor),
|
||||||
Rect(Point, Option<Dimensions>, RGBColor),
|
Rect(Point, Option<Dimensions>, RGBColor),
|
||||||
//
|
Circle(Point, Option<usize>, RGBColor),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DrawAction {
|
impl DrawAction {
|
||||||
@@ -19,6 +19,7 @@ impl DrawAction {
|
|||||||
match self {
|
match self {
|
||||||
DrawAction::Line(_, _, _, _) => "Line",
|
DrawAction::Line(_, _, _, _) => "Line",
|
||||||
DrawAction::Rect(_, _, _) => "Rect",
|
DrawAction::Rect(_, _, _) => "Rect",
|
||||||
|
DrawAction::Circle(_, _, _) => "Circle",
|
||||||
}.to_string()
|
}.to_string()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -49,6 +50,10 @@ impl WindowLike for Draw {
|
|||||||
self.dimensions = dimensions;
|
self.dimensions = dimensions;
|
||||||
WindowMessageResponse::JustRedraw
|
WindowMessageResponse::JustRedraw
|
||||||
},
|
},
|
||||||
|
WindowMessage::ChangeDimensions(dimensions) => {
|
||||||
|
self.dimensions = dimensions;
|
||||||
|
WindowMessageResponse::JustRedraw
|
||||||
|
},
|
||||||
WindowMessage::KeyPress(key_press) => {
|
WindowMessage::KeyPress(key_press) => {
|
||||||
if key_press.is_escape() && (self.current_action.is_some() || self.mode != Mode::Move) {
|
if key_press.is_escape() && (self.current_action.is_some() || self.mode != Mode::Move) {
|
||||||
self.current_action = None;
|
self.current_action = None;
|
||||||
@@ -69,7 +74,10 @@ impl WindowLike for Draw {
|
|||||||
"rect" | "r" => {
|
"rect" | "r" => {
|
||||||
self.current_action = Some(DrawAction::Rect(self.current_location, None, self.current_color));
|
self.current_action = Some(DrawAction::Rect(self.current_location, None, self.current_color));
|
||||||
},
|
},
|
||||||
"colour" | "color" | "c" => {
|
"circle" | "c" => {
|
||||||
|
self.current_action = Some(DrawAction::Circle(self.current_location, None, self.current_color));
|
||||||
|
},
|
||||||
|
"colour" | "color" | "co" => {
|
||||||
//hex to u8
|
//hex to u8
|
||||||
if let Some(hex_color) = parts.next() {
|
if let Some(hex_color) = parts.next() {
|
||||||
if hex_color.len() == 6 && hex_color.chars().all(|c| HEX_CHARS.contains(&c)) {
|
if hex_color.len() == 6 && hex_color.chars().all(|c| HEX_CHARS.contains(&c)) {
|
||||||
@@ -135,6 +143,10 @@ impl WindowLike for Draw {
|
|||||||
];
|
];
|
||||||
DrawAction::Rect(tl, Some(d), *r)
|
DrawAction::Rect(tl, Some(d), *r)
|
||||||
},
|
},
|
||||||
|
DrawAction::Circle(p, _, c) => {
|
||||||
|
let r = ((self.current_location[1] as f64 - p[1] as f64).powi(2) + (self.current_location[0] as f64 - p[0] as f64).powi(2)).sqrt();
|
||||||
|
DrawAction::Circle(*p, Some(r.round() as usize), *c)
|
||||||
|
},
|
||||||
});
|
});
|
||||||
self.current_action = None;
|
self.current_action = None;
|
||||||
WindowMessageResponse::JustRedraw
|
WindowMessageResponse::JustRedraw
|
||||||
@@ -184,6 +196,7 @@ impl WindowLike for Draw {
|
|||||||
instructions.push(match action {
|
instructions.push(match action {
|
||||||
DrawAction::Line(p1, p2, lw, c) => DrawInstructions::Line(*p1, p2.unwrap(), *lw, *c),
|
DrawAction::Line(p1, p2, lw, c) => DrawInstructions::Line(*p1, p2.unwrap(), *lw, *c),
|
||||||
DrawAction::Rect(p, d, c) => DrawInstructions::Rect(*p, d.unwrap(), *c),
|
DrawAction::Rect(p, d, c) => DrawInstructions::Rect(*p, d.unwrap(), *c),
|
||||||
|
DrawAction::Circle(p, r, c) => DrawInstructions::Circle(*p, r.unwrap(), *c),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
//draw cursor (crosshair)
|
//draw cursor (crosshair)
|
||||||
@@ -220,6 +233,10 @@ impl WindowLike for Draw {
|
|||||||
fn ideal_dimensions(&self, _dimensions: Dimensions) -> Dimensions {
|
fn ideal_dimensions(&self, _dimensions: Dimensions) -> Dimensions {
|
||||||
[410, 410]
|
[410, 410]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn resizable(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Draw {
|
impl Draw {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use ming_wm_lib::messages::{ WindowMessage, WindowMessageResponse, WindowManager
|
|||||||
use ming_wm_lib::themes::ThemeInfo;
|
use ming_wm_lib::themes::ThemeInfo;
|
||||||
use ming_wm_lib::framebuffer_types::Dimensions;
|
use ming_wm_lib::framebuffer_types::Dimensions;
|
||||||
use ming_wm_lib::window_manager_types::{ DrawInstructions, WindowLike, WindowLikeType };
|
use ming_wm_lib::window_manager_types::{ DrawInstructions, WindowLike, WindowLikeType };
|
||||||
use ming_wm_lib::utils::{ calc_actual_lines, calc_new_cursor_pos, Substring };
|
use ming_wm_lib::utils::{ calc_actual_lines, Substring };
|
||||||
use ming_wm_lib::dirs::home;
|
use ming_wm_lib::dirs::home;
|
||||||
use ming_wm_lib::utils::{ get_rest_of_split, path_autocomplete };
|
use ming_wm_lib::utils::{ get_rest_of_split, path_autocomplete };
|
||||||
use ming_wm_lib::ipc::listen;
|
use ming_wm_lib::ipc::listen;
|
||||||
@@ -103,10 +103,22 @@ impl WindowLike for Malvim {
|
|||||||
self.mode = Mode::Command;
|
self.mode = Mode::Command;
|
||||||
self.command = Some(String::new());
|
self.command = Some(String::new());
|
||||||
changed = false;
|
changed = false;
|
||||||
} else if (key_press.key == 'i' || key_press.key == 'A') && self.mode == Mode::Normal && self.state == State::None && self.files.len() > 0 {
|
} else if (key_press.key == 'i' || key_press.key == 'A' || key_press.key == 'o' || key_press.key == 'O') && self.mode == Mode::Normal && self.state == State::None && self.files.len() > 0 {
|
||||||
|
let current_file = &mut self.files[self.current_file_index];
|
||||||
if key_press.key == 'A' {
|
if key_press.key == 'A' {
|
||||||
let current_file = &mut self.files[self.current_file_index];
|
|
||||||
current_file.cursor_pos = current_file.content[current_file.line_pos].chars().count();
|
current_file.cursor_pos = current_file.content[current_file.line_pos].chars().count();
|
||||||
|
} else if key_press.key == 'o' || key_press.key == 'O' {
|
||||||
|
let current_line = ¤t_file.content[current_file.line_pos];
|
||||||
|
let spaces = Malvim::calc_spaces(self.autoindent, current_line);
|
||||||
|
let n = if key_press.key == 'o' {
|
||||||
|
current_file.line_pos + 1
|
||||||
|
} else {
|
||||||
|
current_file.line_pos
|
||||||
|
};
|
||||||
|
current_file.content.insert(n, " ".repeat(spaces));
|
||||||
|
current_file.line_pos = n;
|
||||||
|
current_file.cursor_pos = spaces;
|
||||||
|
new = true;
|
||||||
}
|
}
|
||||||
self.mode = Mode::Insert;
|
self.mode = Mode::Insert;
|
||||||
changed = false;
|
changed = false;
|
||||||
@@ -120,20 +132,7 @@ impl WindowLike for Malvim {
|
|||||||
let left = left.into_iter().map(|c| c.to_string()).collect::<Vec<String>>().join("");
|
let left = left.into_iter().map(|c| c.to_string()).collect::<Vec<String>>().join("");
|
||||||
let right = right.into_iter().map(|c| c.to_string()).collect::<Vec<String>>().join("");
|
let right = right.into_iter().map(|c| c.to_string()).collect::<Vec<String>>().join("");
|
||||||
current_file.content[current_file.line_pos] = left.to_string();
|
current_file.content[current_file.line_pos] = left.to_string();
|
||||||
let spaces = if self.autoindent {
|
let spaces = Malvim::calc_spaces(self.autoindent, &left);
|
||||||
//find out how many spaces the line starts with, copy that to the new line
|
|
||||||
let mut spaces = 0;
|
|
||||||
for c in left.chars() {
|
|
||||||
if c == ' ' {
|
|
||||||
spaces += 1;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
spaces
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
};
|
|
||||||
current_file.content.insert(current_file.line_pos + 1, " ".repeat(spaces) + &right);
|
current_file.content.insert(current_file.line_pos + 1, " ".repeat(spaces) + &right);
|
||||||
current_file.line_pos += 1;
|
current_file.line_pos += 1;
|
||||||
current_file.cursor_pos = spaces;
|
current_file.cursor_pos = spaces;
|
||||||
@@ -178,7 +177,7 @@ impl WindowLike for Malvim {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let new_length = current_file.content[current_file.line_pos].chars().count();
|
let new_length = current_file.content[current_file.line_pos].chars().count();
|
||||||
current_file.cursor_pos = calc_new_cursor_pos(current_file.cursor_pos, new_length);
|
current_file.cursor_pos = Malvim::calc_new_cursor_pos(current_file.cursor_pos, new_length);
|
||||||
} else if key_press.key == 'w' || key_press.key == '$' {
|
} else if key_press.key == 'w' || key_press.key == '$' {
|
||||||
let line = ¤t_file.content[current_file.line_pos];
|
let line = ¤t_file.content[current_file.line_pos];
|
||||||
let line_len = line.chars().count();
|
let line_len = line.chars().count();
|
||||||
@@ -198,7 +197,7 @@ impl WindowLike for Malvim {
|
|||||||
};
|
};
|
||||||
current_file.content[current_file.line_pos] = line.remove(current_file.cursor_pos, offset);
|
current_file.content[current_file.line_pos] = line.remove(current_file.cursor_pos, offset);
|
||||||
let new_length = current_file.content[current_file.line_pos].chars().count();
|
let new_length = current_file.content[current_file.line_pos].chars().count();
|
||||||
current_file.cursor_pos = calc_new_cursor_pos(current_file.cursor_pos, new_length);
|
current_file.cursor_pos = Malvim::calc_new_cursor_pos(current_file.cursor_pos, new_length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.state = State::None;
|
self.state = State::None;
|
||||||
@@ -209,7 +208,7 @@ impl WindowLike for Malvim {
|
|||||||
current_file.line_pos = current_file.content.len() - 1;
|
current_file.line_pos = current_file.content.len() - 1;
|
||||||
}
|
}
|
||||||
let new_length = current_file.content[current_file.line_pos].chars().count();
|
let new_length = current_file.content[current_file.line_pos].chars().count();
|
||||||
current_file.cursor_pos = calc_new_cursor_pos(current_file.cursor_pos, new_length);
|
current_file.cursor_pos = Malvim::calc_new_cursor_pos(current_file.cursor_pos, new_length);
|
||||||
}
|
}
|
||||||
changed = false;
|
changed = false;
|
||||||
self.state = State::None;
|
self.state = State::None;
|
||||||
@@ -265,7 +264,7 @@ impl WindowLike for Malvim {
|
|||||||
current_file.line_pos = current_file.line_pos.checked_sub(self.maybe_num.unwrap_or(1)).unwrap_or(0);
|
current_file.line_pos = current_file.line_pos.checked_sub(self.maybe_num.unwrap_or(1)).unwrap_or(0);
|
||||||
}
|
}
|
||||||
let new_length = current_file.content[current_file.line_pos].chars().count();
|
let new_length = current_file.content[current_file.line_pos].chars().count();
|
||||||
current_file.cursor_pos = calc_new_cursor_pos(current_file.cursor_pos, new_length);
|
current_file.cursor_pos = Malvim::calc_new_cursor_pos(current_file.cursor_pos, new_length);
|
||||||
changed = false;
|
changed = false;
|
||||||
} else if key_press.key == 'l' || key_press.is_right_arrow() {
|
} else if key_press.key == 'l' || key_press.is_right_arrow() {
|
||||||
if current_length > 0 {
|
if current_length > 0 {
|
||||||
@@ -298,7 +297,7 @@ impl WindowLike for Malvim {
|
|||||||
} else if key_press.key == 'G' {
|
} else if key_press.key == 'G' {
|
||||||
current_file.line_pos = current_file.content.len() - 1;
|
current_file.line_pos = current_file.content.len() - 1;
|
||||||
let new_length = current_file.content[current_file.line_pos].chars().count();
|
let new_length = current_file.content[current_file.line_pos].chars().count();
|
||||||
current_file.cursor_pos = calc_new_cursor_pos(current_file.cursor_pos, new_length);
|
current_file.cursor_pos = Malvim::calc_new_cursor_pos(current_file.cursor_pos, new_length);
|
||||||
changed = false;
|
changed = false;
|
||||||
} else if key_press.key == 'f' {
|
} else if key_press.key == 'f' {
|
||||||
self.state = State::Find;
|
self.state = State::Find;
|
||||||
@@ -424,7 +423,7 @@ impl WindowLike for Malvim {
|
|||||||
}
|
}
|
||||||
} else if key_press.is_backspace() {
|
} else if key_press.is_backspace() {
|
||||||
if command.len() > 0 {
|
if command.len() > 0 {
|
||||||
self.command = Some(command[..command.len() - 1].to_string());
|
self.command = Some(command.remove_last());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.command = Some(command.to_string() + &key_press.key.to_string());
|
self.command = Some(command.to_string() + &key_press.key.to_string());
|
||||||
@@ -594,6 +593,34 @@ impl Malvim {
|
|||||||
Default::default()
|
Default::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn calc_spaces(autoindent: bool, left: &str) -> usize {
|
||||||
|
if autoindent {
|
||||||
|
let mut spaces = 0;
|
||||||
|
for c in left.chars() {
|
||||||
|
if c == ' ' {
|
||||||
|
spaces += 1;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spaces
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn calc_new_cursor_pos(cursor_pos: usize, new_length: usize) -> usize {
|
||||||
|
if cursor_pos >= new_length {
|
||||||
|
if new_length == 0 {
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
new_length - 1
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cursor_pos
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn calc_top_line_pos(&mut self) {
|
fn calc_top_line_pos(&mut self) {
|
||||||
if self.files.len() == 0 {
|
if self.files.len() == 0 {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use ming_wm_lib::window_manager_types::{ DrawInstructions, WindowLike, WindowLik
|
|||||||
use ming_wm_lib::messages::{ WindowMessage, WindowMessageResponse };
|
use ming_wm_lib::messages::{ WindowMessage, WindowMessageResponse };
|
||||||
use ming_wm_lib::framebuffer_types::Dimensions;
|
use ming_wm_lib::framebuffer_types::Dimensions;
|
||||||
use ming_wm_lib::themes::ThemeInfo;
|
use ming_wm_lib::themes::ThemeInfo;
|
||||||
use ming_wm_lib::utils::{ u8_to_hex, hex_to_u8, HEX_CHARS };
|
use ming_wm_lib::utils::{ random_u32, u8_to_hex, hex_to_u8, HEX_CHARS };
|
||||||
use ming_wm_lib::ipc::listen;
|
use ming_wm_lib::ipc::listen;
|
||||||
|
|
||||||
//16x16 with 40 mines
|
//16x16 with 40 mines
|
||||||
@@ -252,11 +252,7 @@ impl Minesweeper {
|
|||||||
//https://en.wikipedia.org/wiki/Xorshift
|
//https://en.wikipedia.org/wiki/Xorshift
|
||||||
//from 0 to 15
|
//from 0 to 15
|
||||||
pub fn random(&mut self) -> usize {
|
pub fn random(&mut self) -> usize {
|
||||||
let mut x = self.random_seed;
|
self.random_seed = random_u32(self.random_seed);
|
||||||
x ^= x << 13;
|
|
||||||
x ^= x >> 17;
|
|
||||||
x ^= x << 5;
|
|
||||||
self.random_seed = x;
|
|
||||||
self.random_seed as usize % 16
|
self.random_seed as usize % 16
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ fn init(framebuffer: Framebuffer, framebuffer_info: FramebufferInfo) {
|
|||||||
|
|
||||||
writer.init(framebuffer_info.clone());
|
writer.init(framebuffer_info.clone());
|
||||||
|
|
||||||
let mut wm: WindowManager = WindowManager::new(writer, framebuffer, dimensions, rotate, grayscale, PASSWORD_HASH);
|
let mut wm: WindowManager = WindowManager::new(writer, framebuffer, dimensions, rotate, grayscale, env!("CARGO_PKG_VERSION").to_string(), PASSWORD_HASH);
|
||||||
|
|
||||||
let mut stdout = RawStdout::new(stdout());
|
let mut stdout = RawStdout::new(stdout());
|
||||||
stdout.enter_raw_mode().unwrap();
|
stdout.enter_raw_mode().unwrap();
|
||||||
@@ -110,7 +110,6 @@ fn init(framebuffer: Framebuffer, framebuffer_info: FramebufferInfo) {
|
|||||||
|
|
||||||
//read touchscreen presses (hopefully)
|
//read touchscreen presses (hopefully)
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
//spawn evtest, parse it for touch coords
|
|
||||||
if touch {
|
if touch {
|
||||||
let mut events = Input::new("/dev/input/by-path/first-touchscreen").unwrap(); //panics in threads don't matter in this case
|
let mut events = Input::new("/dev/input/by-path/first-touchscreen").unwrap(); //panics in threads don't matter in this case
|
||||||
let mut x: Option<usize> = None;
|
let mut x: Option<usize> = None;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "wm"
|
name = "wm"
|
||||||
version = "1.0.3"
|
version = "1.2.0"
|
||||||
repository = "https://github.com/stjet/ming-wm"
|
repository = "https://github.com/stjet/ming-wm"
|
||||||
license = "GPL-3.0-or-later"
|
license = "GPL-3.0-or-later"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ use ming_wm_lib::components::paragraph::Paragraph;
|
|||||||
pub struct About {
|
pub struct About {
|
||||||
dimensions: Dimensions,
|
dimensions: Dimensions,
|
||||||
components: Vec<Box<dyn Component<()> + Send>>,
|
components: Vec<Box<dyn Component<()> + Send>>,
|
||||||
|
version: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WindowLike for About {
|
impl WindowLike for About {
|
||||||
@@ -40,7 +41,7 @@ impl WindowLike for About {
|
|||||||
|
|
||||||
//properties
|
//properties
|
||||||
fn title(&self) -> String {
|
fn title(&self) -> String {
|
||||||
"About".to_string()
|
"About".to_string() + " - v" + &self.version
|
||||||
}
|
}
|
||||||
|
|
||||||
fn subtype(&self) -> WindowLikeType {
|
fn subtype(&self) -> WindowLikeType {
|
||||||
@@ -53,10 +54,11 @@ impl WindowLike for About {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl About {
|
impl About {
|
||||||
pub fn new() -> Self {
|
pub fn new(version: String) -> Self {
|
||||||
Self {
|
Self {
|
||||||
dimensions: [0, 0],
|
dimensions: [0, 0],
|
||||||
components: Vec::new(),
|
components: Vec::new(),
|
||||||
|
version,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use std::vec;
|
use std::vec;
|
||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
|
use std::time::{ SystemTime, UNIX_EPOCH }; //for psuedo-randomness
|
||||||
|
|
||||||
use ming_wm_lib::framebuffer_types::Dimensions;
|
use ming_wm_lib::framebuffer_types::Dimensions;
|
||||||
use ming_wm_lib::themes::ThemeInfo;
|
use ming_wm_lib::themes::ThemeInfo;
|
||||||
@@ -7,12 +8,11 @@ use ming_wm_lib::messages::{ WindowMessage, WindowMessageResponse, WindowManager
|
|||||||
use ming_wm_lib::window_manager_types::{ DrawInstructions, WindowLike, WindowLikeType };
|
use ming_wm_lib::window_manager_types::{ DrawInstructions, WindowLike, WindowLikeType };
|
||||||
use bitcoin_hashes::Sha512;
|
use bitcoin_hashes::Sha512;
|
||||||
|
|
||||||
//const PASSWORD_HASH: [u8; 64] = [220, 88, 183, 188, 240, 27, 107, 181, 58, 191, 198, 170, 114, 38, 7, 148, 6, 179, 75, 128, 231, 171, 172, 220, 85, 38, 36, 113, 116, 146, 70, 197, 163, 179, 158, 192, 130, 53, 247, 48, 47, 209, 95, 96, 179, 211, 4, 122, 254, 127, 21, 165, 139, 199, 151, 226, 216, 176, 123, 41, 194, 221, 58, 69];
|
|
||||||
|
|
||||||
pub struct LockScreen {
|
pub struct LockScreen {
|
||||||
dimensions: Dimensions,
|
dimensions: Dimensions,
|
||||||
input_password: String,
|
input_password: String,
|
||||||
password_hash: [u8; 64],
|
password_hash: [u8; 64],
|
||||||
|
lines: [String; 3],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WindowLike for LockScreen {
|
impl WindowLike for LockScreen {
|
||||||
@@ -51,9 +51,11 @@ impl WindowLike for LockScreen {
|
|||||||
fn draw(&self, _theme_info: &ThemeInfo) -> Vec<DrawInstructions> {
|
fn draw(&self, _theme_info: &ThemeInfo) -> Vec<DrawInstructions> {
|
||||||
vec![
|
vec![
|
||||||
DrawInstructions::Rect([0, 0], self.dimensions, [0, 0, 0]),
|
DrawInstructions::Rect([0, 0], self.dimensions, [0, 0, 0]),
|
||||||
DrawInstructions::Text([4, 4], vec!["nimbus-roman".to_string()], "The bulldozer outside the kitchen window was quite a big one.".to_string(), [255, 255, 255], [0, 0, 0], None, None),
|
DrawInstructions::Text([4, 4], vec!["nimbus-roman".to_string()], self.lines[0].clone(), [255, 255, 255], [0, 0, 0], None, None),
|
||||||
DrawInstructions::Text([4, 4 + 16], vec!["nimbus-roman".to_string()], "\"Yellow,\" he thought, and stomped off back to his bedroom to get dressed.".to_string(), [255, 255, 255], [0, 0, 0], None, None),
|
//He is my brother.
|
||||||
DrawInstructions::Text([4, 4 + 16 * 2], vec!["nimbus-roman".to_string()], "He stared at it.".to_string(), [255, 255, 255], [0, 0, 0], None, None),
|
DrawInstructions::Text([4, 4 + 16], vec!["nimbus-roman".to_string()], self.lines[1].clone(), [255, 255, 255], [0, 0, 0], None, None),
|
||||||
|
//But I must kill him and keep strong to do it.
|
||||||
|
DrawInstructions::Text([4, 4 + 16 * 2], vec!["nimbus-roman".to_string()], self.lines[2].clone(), [255, 255, 255], [0, 0, 0], None, None),
|
||||||
DrawInstructions::Text([4, 4 + 16 * 3], vec!["nimbus-roman".to_string()], "Password: ".to_string(), [255, 255, 255], [0, 0, 0], None, None),
|
DrawInstructions::Text([4, 4 + 16 * 3], vec!["nimbus-roman".to_string()], "Password: ".to_string(), [255, 255, 255], [0, 0, 0], None, None),
|
||||||
DrawInstructions::Text([80, 4 + 16 * 3], vec!["nimbus-roman".to_string()], "*".repeat(self.input_password.len()), [255, 255, 255], [0, 0, 0], None, None),
|
DrawInstructions::Text([80, 4 + 16 * 3], vec!["nimbus-roman".to_string()], "*".repeat(self.input_password.len()), [255, 255, 255], [0, 0, 0], None, None),
|
||||||
]
|
]
|
||||||
@@ -71,10 +73,24 @@ impl WindowLike for LockScreen {
|
|||||||
|
|
||||||
impl LockScreen {
|
impl LockScreen {
|
||||||
pub fn new(password_hash: [u8; 64]) -> Self {
|
pub fn new(password_hash: [u8; 64]) -> Self {
|
||||||
|
let possible_lines = [
|
||||||
|
[
|
||||||
|
"\"He took about forty pounds,\" the old man said aloud.".to_string(),
|
||||||
|
"He took my harpoon too and all the rope, he thought, and now my fish bleeds again and there will be others.".to_string(),
|
||||||
|
"He did not like to look at the fish anymore since it had been mutilated.".to_string()
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"The bulldozer outside the kitchen window was quite a big one.".to_string(),
|
||||||
|
"\"Yellow,\" he thought, and stomped off back to his bedroom to get dressed.".to_string(),
|
||||||
|
"He stared at it.".to_string()
|
||||||
|
],
|
||||||
|
];
|
||||||
|
let rand_index = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() as usize % possible_lines.len();
|
||||||
Self {
|
Self {
|
||||||
dimensions: [0, 0],
|
dimensions: [0, 0],
|
||||||
input_password: String::new(),
|
input_password: String::new(),
|
||||||
password_hash,
|
password_hash,
|
||||||
|
lines: possible_lines[rand_index].clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -148,7 +148,9 @@ impl FramebufferWriter {
|
|||||||
|
|
||||||
pub fn draw_pixel(&mut self, point: Point, color: RGBColor) {
|
pub fn draw_pixel(&mut self, point: Point, color: RGBColor) {
|
||||||
let start_pos = (point[1] * self.info.stride + point[0]) * self.info.bytes_per_pixel;
|
let start_pos = (point[1] * self.info.stride + point[0]) * self.info.bytes_per_pixel;
|
||||||
self._draw_pixel(start_pos, color);
|
if self.info.byte_len > start_pos {
|
||||||
|
self._draw_pixel(start_pos, color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//shapes
|
//shapes
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ fn get_font_char(dir: &str, c: char) -> Option<(char, Vec<Vec<u8>>, u8)> {
|
|||||||
let mut contents = String::new();
|
let mut contents = String::new();
|
||||||
file.read_to_string(&mut contents).unwrap();
|
file.read_to_string(&mut contents).unwrap();
|
||||||
let lines: Vec<&str> = contents.split("\n").collect();
|
let lines: Vec<&str> = contents.split("\n").collect();
|
||||||
for l in 1..lines.len() {
|
for ln in 1..lines.len() {
|
||||||
//.unwrap_or(0) is important because zeroes are just empty
|
//.unwrap_or(0) is important because zeroes are just empty
|
||||||
ch.push(lines[l].split(",").map(|n| n.parse().unwrap_or(0)).collect());
|
ch.push(lines[ln].replace(":", ",,,,").replace(";", ",,,").replace(".", ",,").split(",").map(|n| n.parse().unwrap_or(0)).collect());
|
||||||
}
|
}
|
||||||
return Some((c, ch, lines[0].parse().unwrap()));
|
return Some((c, ch, lines[0].parse().unwrap()));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ impl fmt::Debug for WindowLikeInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub struct WindowManager {
|
pub struct WindowManager {
|
||||||
writer: RefCell<FramebufferWriter>,
|
writer: RefCell<FramebufferWriter>,
|
||||||
rotate: bool,
|
rotate: bool,
|
||||||
@@ -65,13 +66,14 @@ pub struct WindowManager {
|
|||||||
current_workspace: u8,
|
current_workspace: u8,
|
||||||
framebuffer: Framebuffer,
|
framebuffer: Framebuffer,
|
||||||
clipboard: Option<String>,
|
clipboard: Option<String>,
|
||||||
|
version: String,
|
||||||
password_hash: [u8; 64],
|
password_hash: [u8; 64],
|
||||||
}
|
}
|
||||||
|
|
||||||
//1 is up, 2 is down
|
//1 is up, 2 is down
|
||||||
|
|
||||||
impl WindowManager {
|
impl WindowManager {
|
||||||
pub fn new(writer: FramebufferWriter, framebuffer: Framebuffer, dimensions: Dimensions, rotate: bool, grayscale: bool, password_hash: [u8; 64]) -> Self {
|
pub fn new(writer: FramebufferWriter, framebuffer: Framebuffer, dimensions: Dimensions, rotate: bool, grayscale: bool, version: String, password_hash: [u8; 64]) -> Self {
|
||||||
//println!("bg: {}x{}", dimensions[0], dimensions[1] - TASKBAR_HEIGHT - INDICATOR_HEIGHT);
|
//println!("bg: {}x{}", dimensions[0], dimensions[1] - TASKBAR_HEIGHT - INDICATOR_HEIGHT);
|
||||||
let mut wm = WindowManager {
|
let mut wm = WindowManager {
|
||||||
writer: RefCell::new(writer),
|
writer: RefCell::new(writer),
|
||||||
@@ -87,6 +89,7 @@ impl WindowManager {
|
|||||||
current_workspace: 0,
|
current_workspace: 0,
|
||||||
framebuffer,
|
framebuffer,
|
||||||
clipboard: None,
|
clipboard: None,
|
||||||
|
version,
|
||||||
password_hash,
|
password_hash,
|
||||||
};
|
};
|
||||||
wm.lock();
|
wm.lock();
|
||||||
@@ -594,7 +597,7 @@ impl WindowManager {
|
|||||||
}
|
}
|
||||||
let w: Option<WindowBox> = match w.as_str() {
|
let w: Option<WindowBox> = match w.as_str() {
|
||||||
"StartMenu" => Some(Box::new(StartMenu::new())),
|
"StartMenu" => Some(Box::new(StartMenu::new())),
|
||||||
"About" => Some(Box::new(About::new())),
|
"About" => Some(Box::new(About::new(self.version.clone()))),
|
||||||
"Help" => Some(Box::new(Help::new())),
|
"Help" => Some(Box::new(Help::new())),
|
||||||
_ => Some(Box::new(ProxyWindowLike::new(&w))),
|
_ => Some(Box::new(ProxyWindowLike::new(&w))),
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user