beta 1: remove framebuffer crate, replace with own code, small fixes/features added
added some kanji, docs
This commit is contained in:
@@ -215,6 +215,8 @@ impl AudioPlayer {
|
||||
}
|
||||
}
|
||||
queue
|
||||
} else if parts[1].ends_with(".mp3") {
|
||||
vec![concat_paths(&self.base_directory, parts[1]).unwrap()]
|
||||
} else {
|
||||
get_all_files(PathBuf::from(new_path))
|
||||
};
|
||||
|
||||
@@ -138,6 +138,10 @@ impl WindowLike for FileExplorer {
|
||||
let bytes_len = metadata.len();
|
||||
instructions.push(DrawInstructions::Text([5, start_y], vec!["nimbus-roman".to_string()], format!("Size: {} mb ({} b)", bytes_len / (1024_u64).pow(2), bytes_len), theme_info.text, theme_info.background, None, None));
|
||||
start_y += HEIGHT;
|
||||
if let Ok(elapsed) = metadata.modified().unwrap().elapsed() {
|
||||
//properly format months, days, hours, minutes, secs instead
|
||||
instructions.push(DrawInstructions::Text([5, start_y], vec!["nimbus-roman".to_string()], format!("Last Modified: {} minutes ago", elapsed.as_secs() / 60), theme_info.text, theme_info.background, None, None));
|
||||
}
|
||||
//todo: other stuff
|
||||
//
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ use std::io::{ stdin, stdout, BufReader, BufRead, Write };
|
||||
use std::process::exit;
|
||||
use std::env;
|
||||
|
||||
use linux_framebuffer::Framebuffer;
|
||||
use linux::fb::Framebuffer;
|
||||
use termion::input::TermRead;
|
||||
use termion::raw::IntoRawMode;
|
||||
use termion::{ clear, cursor };
|
||||
@@ -162,7 +162,7 @@ fn init(framebuffer: Framebuffer, framebuffer_info: FramebufferInfo) {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let fb = Framebuffer::new("/dev/fb0").unwrap();
|
||||
let fb = Framebuffer::open("/dev/fb0").unwrap();
|
||||
let bytes_per_pixel = (fb.var_screen_info.bits_per_pixel as usize) / 8;
|
||||
let fb_info = FramebufferInfo {
|
||||
byte_len: (fb.var_screen_info.yres_virtual * fb.fix_screen_info.line_length) as usize,
|
||||
|
||||
@@ -213,9 +213,9 @@ impl WindowLike for Malvim {
|
||||
} else {
|
||||
//how does this work again? no idea
|
||||
if old_pos != 0 {
|
||||
let found_index = current_file.content[current_file.line_pos].chars().rev().skip(current_length - old_pos + 1).position(|c| c == key_press.key);
|
||||
let found_index = current_file.content[current_file.line_pos].chars().rev().skip(current_length - old_pos).position(|c| c == key_press.key);
|
||||
if let Some(found_index) = found_index {
|
||||
old_pos - found_index - 2
|
||||
old_pos - found_index - 1
|
||||
} else {
|
||||
old_pos
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::vec;
|
||||
use std::sync::mpsc::{ channel, Receiver, Sender };
|
||||
use std::thread;
|
||||
use std::process::{ Child, Stdio };
|
||||
use std::io::{ BufReader, BufRead, Write };
|
||||
use std::io::{ Read, Write };
|
||||
use std::time::Duration;
|
||||
use std::path::PathBuf;
|
||||
use std::fmt;
|
||||
@@ -79,7 +79,8 @@ pub struct Terminal {
|
||||
current_stdin_input: String,
|
||||
current_path: String,
|
||||
running_process: Option<Child>,
|
||||
pty_outerr_rx: Option<Receiver<String>>,
|
||||
process_current_line: Vec<u8>, //bytes of line
|
||||
pty_outerr_rx: Option<Receiver<u8>>,
|
||||
pty_in_tx: Option<Sender<String>>,
|
||||
last_command: Option<String>,
|
||||
}
|
||||
@@ -126,8 +127,17 @@ impl WindowLike for Terminal {
|
||||
//update
|
||||
let mut changed = false;
|
||||
loop {
|
||||
if let Ok(line) = self.pty_outerr_rx.as_mut().unwrap().recv_timeout(Duration::from_millis(5)) {
|
||||
self.lines.push(strip_ansi_escape_codes(line));
|
||||
if let Ok(ci) = self.pty_outerr_rx.as_mut().unwrap().recv_timeout(Duration::from_millis(5)) {
|
||||
if char::from(ci) == '\n' {
|
||||
let pcl_len = self.process_current_line.len();
|
||||
self.lines.push(strip_ansi_escape_codes(String::from_utf8(self.process_current_line.clone()).unwrap_or("?".repeat(pcl_len))));
|
||||
self.process_current_line = Vec::new();
|
||||
} else if char::from(ci) == '\r' {
|
||||
//for now, ignore
|
||||
//
|
||||
} else {
|
||||
self.process_current_line.push(ci);
|
||||
}
|
||||
changed = true;
|
||||
} else {
|
||||
break;
|
||||
@@ -138,6 +148,7 @@ impl WindowLike for Terminal {
|
||||
//process exited
|
||||
self.pty_outerr_rx = None;
|
||||
self.mode = Mode::Input;
|
||||
self.process_current_line = Vec::new();
|
||||
changed = true;
|
||||
} else {
|
||||
if key_press.key == 'i' {
|
||||
@@ -160,7 +171,10 @@ impl WindowLike for Terminal {
|
||||
//enter
|
||||
let _ = self.pty_in_tx.as_mut().unwrap().send(self.current_stdin_input.clone());
|
||||
self.mode = Mode::Running;
|
||||
let pcl_len = self.process_current_line.len();
|
||||
self.lines.push(strip_ansi_escape_codes(String::from_utf8(self.process_current_line.clone()).unwrap_or("?".repeat(pcl_len))) + &self.current_stdin_input);
|
||||
self.current_stdin_input = String::new();
|
||||
self.process_current_line = Vec::new();
|
||||
} else if key_press.key == '𐘁' {
|
||||
//backspace
|
||||
if self.current_stdin_input.len() > 0 {
|
||||
@@ -285,11 +299,9 @@ impl Terminal {
|
||||
self.running_process = Some(blocking::Command::new("sh").arg("-c").arg(&self.current_input).current_dir(&self.current_path).stdin(Stdio::piped()).spawn(pts).unwrap());
|
||||
let (tx1, rx1) = channel();
|
||||
thread::spawn(move || {
|
||||
let reader = BufReader::new(pty);
|
||||
for line in reader.lines() {
|
||||
//panics too much
|
||||
if let Ok(line) = line {
|
||||
tx1.send(line.to_string()).unwrap();
|
||||
for ci in pty.bytes() {
|
||||
if let Ok(ci) = ci {
|
||||
tx1.send(ci).unwrap();
|
||||
} else {
|
||||
//the process has exited. dead process = dead pty = os input/output error
|
||||
break;
|
||||
@@ -310,6 +322,7 @@ impl Terminal {
|
||||
});
|
||||
self.pty_outerr_rx = Some(rx1);
|
||||
self.pty_in_tx = Some(tx2);
|
||||
self.process_current_line = Vec::new();
|
||||
Mode::Running
|
||||
}
|
||||
}
|
||||
@@ -317,18 +330,20 @@ impl Terminal {
|
||||
fn calc_actual_lines(&mut self) {
|
||||
self.actual_lines = Vec::new();
|
||||
let max_chars_per_line = (self.dimensions[0] - PADDING * 2) / MONO_WIDTH as usize;
|
||||
let end = if self.mode != Mode::Running {
|
||||
self.lines.len()
|
||||
let lines_len = self.lines.len();
|
||||
let end = if self.mode != Mode::Running || self.process_current_line.len() > 0 {
|
||||
lines_len
|
||||
} else {
|
||||
self.lines.len() - 1
|
||||
lines_len - 1
|
||||
};
|
||||
for line_num in 0..=end {
|
||||
let mut working_line = if line_num == self.lines.len() {
|
||||
let mut working_line = if line_num >= lines_len {
|
||||
if self.mode == Mode::Input {
|
||||
//must_add_current_line will be false
|
||||
"$ ".to_string() + &self.current_input + "█"
|
||||
} else {
|
||||
//Mode::Stdin
|
||||
self.current_stdin_input.clone() + "█"
|
||||
let pcl_len = self.process_current_line.len();
|
||||
strip_ansi_escape_codes(String::from_utf8(self.process_current_line.clone()).unwrap_or("?".repeat(pcl_len))) + &self.current_stdin_input.clone() + "█"
|
||||
}
|
||||
} else {
|
||||
self.lines[line_num].clone()
|
||||
|
||||
@@ -6,6 +6,7 @@ use ming_wm_lib::window_manager_types::{ DrawInstructions, WindowLike, WindowLik
|
||||
use ming_wm_lib::messages::{ WindowMessage, WindowMessageResponse };
|
||||
use ming_wm_lib::framebuffer_types::Dimensions;
|
||||
use ming_wm_lib::themes::ThemeInfo;
|
||||
use ming_wm_lib::dirs::exe_dir;
|
||||
use crate::components::Component;
|
||||
use crate::components::paragraph::Paragraph;
|
||||
|
||||
@@ -19,7 +20,7 @@ impl WindowLike for About {
|
||||
match message {
|
||||
WindowMessage::Init(dimensions) => {
|
||||
self.dimensions = dimensions;
|
||||
self.components.push(Box::new(Paragraph::new("help".to_string(), [2, 2], [self.dimensions[0] - 4, self.dimensions[1] - 4], read_to_string("docs/system/README.md").unwrap_or("docs/system/README.md not found".to_string()), ())));
|
||||
self.components.push(Box::new(Paragraph::new("help".to_string(), [2, 2], [self.dimensions[0] - 4, self.dimensions[1] - 4], read_to_string(exe_dir(Some("ming_docs/system/README.md"))).unwrap_or("ming_docs/system/README.md not found".to_string()), ())));
|
||||
WindowMessageResponse::JustRedraw
|
||||
},
|
||||
WindowMessage::KeyPress(key_press) => {
|
||||
|
||||
@@ -5,6 +5,7 @@ use std::path::PathBuf;
|
||||
|
||||
use ming_wm_lib::window_manager_types::{ DrawInstructions, WindowLike, WindowLikeType };
|
||||
use ming_wm_lib::messages::{ WindowMessage, WindowMessageResponse };
|
||||
use ming_wm_lib::dirs::exe_dir;
|
||||
use ming_wm_lib::framebuffer_types::Dimensions;
|
||||
use ming_wm_lib::themes::ThemeInfo;
|
||||
use crate::components::paragraph::Paragraph;
|
||||
@@ -40,8 +41,12 @@ impl WindowLike for Help {
|
||||
self.file_index += 1;
|
||||
}
|
||||
}
|
||||
self.paragraph.as_mut().unwrap().new_text(read_to_string(self.files[self.file_index].clone()).unwrap());
|
||||
WindowMessageResponse::JustRedraw
|
||||
if self.files.len() > 0 {
|
||||
self.paragraph.as_mut().unwrap().new_text(read_to_string(self.files[self.file_index].clone()).unwrap());
|
||||
WindowMessageResponse::JustRedraw
|
||||
} else {
|
||||
WindowMessageResponse::DoNothing
|
||||
}
|
||||
} else if self.paragraph.as_mut().unwrap().handle_message(WindowMessage::KeyPress(key_press)).is_some() {
|
||||
WindowMessageResponse::JustRedraw
|
||||
} else {
|
||||
@@ -53,14 +58,17 @@ impl WindowLike for Help {
|
||||
}
|
||||
|
||||
fn draw(&self, theme_info: &ThemeInfo) -> Vec<DrawInstructions> {
|
||||
let mut instructions = vec![DrawInstructions::Text([2, 2], vec!["nimbus-romono".to_string()], self.files[self.file_index].clone().file_name().unwrap().to_string_lossy().to_string(), theme_info.text, theme_info.background, Some(0), None)];
|
||||
let mut instructions = Vec::new();
|
||||
if self.files.len() > 0 {
|
||||
instructions.push(DrawInstructions::Text([2, 2], vec!["nimbus-romono".to_string()], self.files[self.file_index].clone().file_name().unwrap().to_string_lossy().to_string(), theme_info.text, theme_info.background, Some(0), None));
|
||||
}
|
||||
instructions.extend(self.paragraph.as_ref().unwrap().draw(theme_info));
|
||||
instructions
|
||||
}
|
||||
|
||||
//properties
|
||||
fn title(&self) -> String {
|
||||
"About".to_string()
|
||||
"Help".to_string()
|
||||
}
|
||||
|
||||
fn subtype(&self) -> WindowLikeType {
|
||||
@@ -74,9 +82,12 @@ impl WindowLike for Help {
|
||||
|
||||
impl Help {
|
||||
pub fn new() -> Self {
|
||||
let mut files = vec![PathBuf::from("docs/system/shortcuts.md")];
|
||||
for entry in read_dir("docs/window-likes").unwrap() {
|
||||
files.push(entry.unwrap().path());
|
||||
let mut files = Vec::new();
|
||||
if let Ok(contents) = read_dir(exe_dir(Some("ming_docs/window-likes"))) {
|
||||
files.push(exe_dir(Some("ming_docs/system/shortcuts.md")));
|
||||
for entry in contents {
|
||||
files.push(entry.unwrap().path());
|
||||
}
|
||||
}
|
||||
Self {
|
||||
dimensions: [0, 0],
|
||||
|
||||
@@ -11,7 +11,7 @@ use crate::fs::{ ExeWindowInfos, get_all_executable_windows };
|
||||
use crate::components::Component;
|
||||
use crate::components::highlight_button::HighlightButton;
|
||||
|
||||
static CATEGORIES: [&'static str; 9] = ["About", "Utils", "Games", "Editing", "Files", "Internet", "Misc", "Help", "Logout"];
|
||||
static CATEGORIES: [&'static str; 9] = ["About", "Utils", "Games", "Editing", "Files", "Internet", "Misc", "Help", "Lock"];
|
||||
|
||||
#[derive(Clone)]
|
||||
enum StartMenuMessage {
|
||||
@@ -109,7 +109,7 @@ impl WindowLike for StartMenu {
|
||||
//background
|
||||
DrawInstructions::Rect([0, 1], [self.dimensions[0] - 1, self.dimensions[1] - 1], theme_info.background),
|
||||
//mingde logo
|
||||
DrawInstructions::Bmp([2, 2], exe_dir(Some("bmps/mingde.bmp")).to_string_lossy().to_string(), false),
|
||||
DrawInstructions::Bmp([2, 2], exe_dir(Some("ming_bmps/mingde.bmp")).to_string_lossy().to_string(), false),
|
||||
//I truly don't know why, it should be - 44 but - 30 seems to work better :shrug:
|
||||
DrawInstructions::Gradient([2, 42], [40, self.dimensions[1] - 30], [255, 201, 14], [225, 219, 77], 15),
|
||||
];
|
||||
@@ -138,7 +138,7 @@ impl StartMenu {
|
||||
if let Some(message) = message {
|
||||
match message {
|
||||
StartMenuMessage::CategoryClick(name) => {
|
||||
if name == "Logout" {
|
||||
if name == "Lock" {
|
||||
WindowMessageResponse::Request(WindowManagerRequest::Lock)
|
||||
} else if name == "About" || name == "Help" {
|
||||
//todo above: also do the same for Help
|
||||
|
||||
@@ -249,17 +249,19 @@ impl FramebufferWriter {
|
||||
//reverse is workaround for when my bmp lib returns rgba instead of bgra
|
||||
pub fn draw_bmp(&mut self, top_left: Point, path: String, reverse: bool) {
|
||||
let b = BMP::new_from_file(&path);
|
||||
let dib_header = b.get_dib_header().unwrap();
|
||||
let pixel_data = b.get_pixel_data().unwrap();
|
||||
let height = dib_header.height as usize;
|
||||
let width = dib_header.width as usize;
|
||||
let mut start_pos;
|
||||
for row in 0..height {
|
||||
start_pos = ((top_left[1] + row) * self.info.stride + top_left[0]) * self.info.bytes_per_pixel;
|
||||
for column in 0..width {
|
||||
let color = b.get_color_of_pixel_efficient(column, row, &dib_header, &pixel_data).unwrap();
|
||||
self._draw_pixel(start_pos, if reverse { [color[2], color[1], color[0]] } else { [color[0], color[1], color[2]] });
|
||||
start_pos += self.info.bytes_per_pixel;
|
||||
if let Ok(b) = b {
|
||||
let dib_header = b.get_dib_header().unwrap();
|
||||
let pixel_data = b.get_pixel_data().unwrap();
|
||||
let height = dib_header.height as usize;
|
||||
let width = dib_header.width as usize;
|
||||
let mut start_pos;
|
||||
for row in 0..height {
|
||||
start_pos = ((top_left[1] + row) * self.info.stride + top_left[0]) * self.info.bytes_per_pixel;
|
||||
for column in 0..width {
|
||||
let color = b.get_color_of_pixel_efficient(column, row, &dib_header, &pixel_data).unwrap();
|
||||
self._draw_pixel(start_pos, if reverse { [color[2], color[1], color[0]] } else { [color[0], color[1], color[2]] });
|
||||
start_pos += self.info.bytes_per_pixel;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,12 +24,12 @@ fn get_font_char(dir: &str, c: char) -> Option<(char, Vec<Vec<u8>>, u8)> {
|
||||
|
||||
pub fn get_font_char_from_fonts(fonts: &[String], c: char) -> (char, Vec<Vec<u8>>, u8) {
|
||||
for font in fonts {
|
||||
let p = dirs::exe_dir(Some(&("bmps/".to_string() + &font))).to_string_lossy().to_string();
|
||||
let p = dirs::exe_dir(Some(&("ming_bmps/".to_string() + &font))).to_string_lossy().to_string();
|
||||
if let Some(font_char) = get_font_char(&p, c) {
|
||||
return font_char;
|
||||
}
|
||||
}
|
||||
let p = dirs::exe_dir(Some(&("bmps/".to_string() + &fonts[0]))).to_string_lossy().to_string();
|
||||
let p = dirs::exe_dir(Some(&("ming_bmps/".to_string() + &fonts[0]))).to_string_lossy().to_string();
|
||||
//so a ? char must be in every font
|
||||
get_font_char(&p, '?').unwrap()
|
||||
}
|
||||
|
||||
@@ -7,8 +7,7 @@ use std::cell::RefCell;
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
|
||||
use linux_framebuffer::Framebuffer;
|
||||
|
||||
use linux::fb::Framebuffer;
|
||||
use ming_wm_lib::framebuffer_types::{ Point, Dimensions };
|
||||
use ming_wm_lib::themes::{ Themes, get_theme_info };
|
||||
use ming_wm_lib::utils::{ min, point_inside };
|
||||
|
||||
Reference in New Issue
Block a user