click test, osk test
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
Audio player with playlist and folder support.
|
Audio player with playlist and folder support. Requires the dev version of `alsa` lib.
|
||||||
|
|
||||||
## Commands
|
## Commands
|
||||||
|
|
||||||
|
|||||||
1
docs/window-likes/onscreen-keyboard.md
Normal file
1
docs/window-likes/onscreen-keyboard.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
This is primarily intended for mobile users.
|
||||||
@@ -3,6 +3,7 @@ pub mod taskbar;
|
|||||||
pub mod lock_screen;
|
pub mod lock_screen;
|
||||||
pub mod workspace_indicator;
|
pub mod workspace_indicator;
|
||||||
pub mod start_menu;
|
pub mod start_menu;
|
||||||
|
pub mod onscreen_keyboard;
|
||||||
|
|
||||||
pub mod about;
|
pub mod about;
|
||||||
pub mod help;
|
pub mod help;
|
||||||
|
|||||||
47
src/essential/onscreen_keyboard.rs
Normal file
47
src/essential/onscreen_keyboard.rs
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
use std::vec;
|
||||||
|
use std::vec::Vec;
|
||||||
|
|
||||||
|
use crate::window_manager::{ DrawInstructions, WindowLike, WindowLikeType };
|
||||||
|
use crate::messages::{ WindowMessage, WindowMessageResponse };
|
||||||
|
use crate::framebuffer::Dimensions;
|
||||||
|
use crate::themes::ThemeInfo;
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct OnscreenKeyboard {
|
||||||
|
dimensions: Dimensions,
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WindowLike for OnscreenKeyboard {
|
||||||
|
fn handle_message(&mut self, message: WindowMessage) -> WindowMessageResponse {
|
||||||
|
match message {
|
||||||
|
WindowMessage::Init(dimensions) => {
|
||||||
|
self.dimensions = dimensions;
|
||||||
|
WindowMessageResponse::JustRedraw
|
||||||
|
},
|
||||||
|
//
|
||||||
|
_ => WindowMessageResponse::DoNothing,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw(&self, theme_info: &ThemeInfo) -> Vec<DrawInstructions> {
|
||||||
|
let mut instructions = vec![DrawInstructions::Rect([0, 0], self.dimensions, theme_info.background)];
|
||||||
|
//
|
||||||
|
instructions
|
||||||
|
}
|
||||||
|
//
|
||||||
|
fn subtype(&self) -> WindowLikeType {
|
||||||
|
WindowLikeType::OnscreenKeyboard
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ideal_dimensions(&self, dimensions: Dimensions) -> Dimensions {
|
||||||
|
[dimensions[0] - 175, 250]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OnscreenKeyboard {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
use termion::event::Key;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
|
||||||
pub enum KeyChar {
|
|
||||||
Press(char),
|
|
||||||
Alt(char),
|
|
||||||
Ctrl(char),
|
|
||||||
}
|
|
||||||
|
|
||||||
//use Linear A for escape, backspace, enter
|
|
||||||
pub fn key_to_char(key: Key) -> Option<KeyChar> {
|
|
||||||
match key {
|
|
||||||
Key::Char('\n') => Some(KeyChar::Press('𐘂')),
|
|
||||||
Key::Char(c) => Some(KeyChar::Press(c)),
|
|
||||||
Key::Alt(c) => Some(KeyChar::Alt(c)),
|
|
||||||
Key::Ctrl(c) => Some(KeyChar::Ctrl(c)),
|
|
||||||
Key::Backspace => Some(KeyChar::Press('𐘁')),
|
|
||||||
Key::Esc => Some(KeyChar::Press('𐘃')),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -8,6 +8,5 @@ pub mod utils;
|
|||||||
pub mod logging;
|
pub mod logging;
|
||||||
pub mod ipc;
|
pub mod ipc;
|
||||||
mod proxy_window_like;
|
mod proxy_window_like;
|
||||||
mod keyboard;
|
|
||||||
mod essential;
|
mod essential;
|
||||||
|
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ use std::vec::Vec;
|
|||||||
|
|
||||||
use serde::{ Deserialize, Serialize };
|
use serde::{ Deserialize, Serialize };
|
||||||
|
|
||||||
use crate::keyboard::KeyChar;
|
|
||||||
use crate::framebuffer::Dimensions;
|
use crate::framebuffer::Dimensions;
|
||||||
use crate::window_manager::WindowLike;
|
use crate::window_manager::{ WindowLike, KeyChar };
|
||||||
|
|
||||||
pub enum WindowManagerMessage {
|
pub enum WindowManagerMessage {
|
||||||
KeyChar(KeyChar),
|
KeyChar(KeyChar),
|
||||||
|
Click(u16, u16),
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
21
src/utils.rs
21
src/utils.rs
@@ -1,5 +1,26 @@
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use termion::event::Key;
|
||||||
|
|
||||||
|
use crate::window_manager::KeyChar;
|
||||||
|
|
||||||
|
//use Linear A for escape, backspace, enter
|
||||||
|
pub fn key_to_char(key: Key) -> Option<KeyChar> {
|
||||||
|
match key {
|
||||||
|
Key::Char('\n') => Some(KeyChar::Press('𐘂')),
|
||||||
|
Key::Char(c) => Some(KeyChar::Press(c)),
|
||||||
|
Key::Alt(c) => Some(KeyChar::Alt(c)),
|
||||||
|
Key::Ctrl(c) => Some(KeyChar::Ctrl(c)),
|
||||||
|
Key::Backspace => Some(KeyChar::Press('𐘁')),
|
||||||
|
Key::Esc => Some(KeyChar::Press('𐘃')),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn min(one: usize, two: usize) -> usize {
|
||||||
|
if one > two { two } else { one }
|
||||||
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
|||||||
@@ -8,14 +8,15 @@ use std::process::exit;
|
|||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
|
||||||
use linux_framebuffer::Framebuffer;
|
use linux_framebuffer::Framebuffer;
|
||||||
use termion::input::TermRead;
|
use termion::input::{ MouseTerminal, TermRead };
|
||||||
use termion::raw::IntoRawMode;
|
use termion::raw::IntoRawMode;
|
||||||
use termion::cursor;
|
use termion::cursor;
|
||||||
|
use termion::event::{ Event, MouseEvent };
|
||||||
use serde::{ Deserialize, Serialize };
|
use serde::{ Deserialize, Serialize };
|
||||||
|
|
||||||
use crate::framebuffer::{ FramebufferWriter, FramebufferInfo, Point, Dimensions, RGBColor };
|
use crate::framebuffer::{ FramebufferWriter, FramebufferInfo, Point, Dimensions, RGBColor };
|
||||||
use crate::themes::{ ThemeInfo, Themes, get_theme_info };
|
use crate::themes::{ ThemeInfo, Themes, get_theme_info };
|
||||||
use crate::keyboard::{ KeyChar, key_to_char };
|
use crate::utils::{ min, key_to_char };
|
||||||
use crate::messages::*;
|
use crate::messages::*;
|
||||||
use crate::proxy_window_like::ProxyWindowLike;
|
use crate::proxy_window_like::ProxyWindowLike;
|
||||||
use crate::essential::desktop_background::DesktopBackground;
|
use crate::essential::desktop_background::DesktopBackground;
|
||||||
@@ -25,6 +26,7 @@ use crate::essential::workspace_indicator::WorkspaceIndicator;
|
|||||||
use crate::essential::start_menu::StartMenu;
|
use crate::essential::start_menu::StartMenu;
|
||||||
use crate::essential::about::About;
|
use crate::essential::about::About;
|
||||||
use crate::essential::help::Help;
|
use crate::essential::help::Help;
|
||||||
|
use crate::essential::onscreen_keyboard::OnscreenKeyboard;
|
||||||
//use crate::logging::log;
|
//use crate::logging::log;
|
||||||
|
|
||||||
pub const TASKBAR_HEIGHT: usize = 38;
|
pub const TASKBAR_HEIGHT: usize = 38;
|
||||||
@@ -45,31 +47,43 @@ pub fn init(framebuffer: Framebuffer, framebuffer_info: FramebufferInfo) {
|
|||||||
wm.draw(None, false);
|
wm.draw(None, false);
|
||||||
|
|
||||||
let stdin = stdin().lock();
|
let stdin = stdin().lock();
|
||||||
let mut stdout = stdout().into_raw_mode().unwrap();
|
let mut stdout = MouseTerminal::from(stdout().into_raw_mode().unwrap());
|
||||||
|
|
||||||
write!(stdout, "{}", cursor::Hide).unwrap();
|
write!(stdout, "{}", cursor::Hide).unwrap();
|
||||||
stdout.flush().unwrap();
|
stdout.flush().unwrap();
|
||||||
|
|
||||||
|
for e in stdin.events() {
|
||||||
for c in stdin.keys() {
|
match e.unwrap() {
|
||||||
if let Some(kc) = key_to_char(c.unwrap()) {
|
Event::Key(c) => {
|
||||||
//do not allow exit when locked unless debugging
|
if let Some(kc) = key_to_char(c) {
|
||||||
//if kc == KeyChar::Alt('E') {
|
//do not allow exit when locked unless debugging
|
||||||
if kc == KeyChar::Alt('E') && !wm.locked {
|
//if kc == KeyChar::Alt('E') {
|
||||||
write!(stdout, "{}", cursor::Show).unwrap();
|
if kc == KeyChar::Alt('E') && !wm.locked {
|
||||||
stdout.suspend_raw_mode().unwrap();
|
write!(stdout, "{}", cursor::Show).unwrap();
|
||||||
exit(0);
|
stdout.suspend_raw_mode().unwrap();
|
||||||
} else {
|
exit(0);
|
||||||
wm.handle_message(WindowManagerMessage::KeyChar(kc.clone()));
|
} else {
|
||||||
}
|
wm.handle_message(WindowManagerMessage::KeyChar(kc.clone()));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Event::Mouse(m) => {
|
||||||
|
if let MouseEvent::Press(_, x, y) = m {
|
||||||
|
//We don't care what button
|
||||||
|
//(should also support mobile?)
|
||||||
|
wm.handle_message(WindowManagerMessage::Click(x, y));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => {},
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn min(one: usize, two: usize) -> usize {
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
if one > two { two } else { one }
|
pub enum KeyChar {
|
||||||
|
Press(char),
|
||||||
|
Alt(char),
|
||||||
|
Ctrl(char),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
@@ -89,6 +103,7 @@ pub enum WindowLikeType {
|
|||||||
Taskbar,
|
Taskbar,
|
||||||
StartMenu,
|
StartMenu,
|
||||||
WorkspaceIndicator,
|
WorkspaceIndicator,
|
||||||
|
OnscreenKeyboard,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait WindowLike {
|
pub trait WindowLike {
|
||||||
@@ -215,6 +230,7 @@ impl WindowManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//if off_only is true, also handle request
|
//if off_only is true, also handle request
|
||||||
|
//written confusingly but it works I promise
|
||||||
fn toggle_start_menu(&mut self, off_only: bool) -> WindowMessageResponse {
|
fn toggle_start_menu(&mut self, off_only: bool) -> WindowMessageResponse {
|
||||||
let start_menu_exists = self.window_infos.iter().find(|w| w.window_like.subtype() == WindowLikeType::StartMenu).is_some();
|
let start_menu_exists = self.window_infos.iter().find(|w| w.window_like.subtype() == WindowLikeType::StartMenu).is_some();
|
||||||
if (start_menu_exists && off_only) || !off_only {
|
if (start_menu_exists && off_only) || !off_only {
|
||||||
@@ -518,7 +534,23 @@ impl WindowManager {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
//
|
WindowManagerMessage::Click(x, y) => {
|
||||||
|
//println!("{}, {}", x, y);
|
||||||
|
if x < 10000 && y < 10000 {
|
||||||
|
//toggle onscreen keyboard if top left keyboard clicked
|
||||||
|
let osk_index = self.window_infos.iter().position(|w| w.window_like.subtype() == WindowLikeType::OnscreenKeyboard);
|
||||||
|
if let Some(osk_index) = osk_index {
|
||||||
|
self.window_infos.remove(osk_index);
|
||||||
|
} else {
|
||||||
|
let osk = Box::new(OnscreenKeyboard::new());
|
||||||
|
let ideal_dimensions = osk.ideal_dimensions(self.dimensions);
|
||||||
|
self.add_window_like(osk, [175, self.dimensions[1] - TASKBAR_HEIGHT - 250], Some(ideal_dimensions));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//see if in onscreen keyboard, if so send to it after offsetting coords
|
||||||
|
//
|
||||||
|
WindowMessageResponse::JustRedraw
|
||||||
|
},
|
||||||
};
|
};
|
||||||
if response != WindowMessageResponse::DoNothing {
|
if response != WindowMessageResponse::DoNothing {
|
||||||
match response {
|
match response {
|
||||||
|
|||||||
Reference in New Issue
Block a user