mirror of
https://github.com/aljazceru/notedeck.git
synced 2025-12-17 08:44:20 +01:00
chrome: add virtual keyboard ui
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -3532,6 +3532,7 @@ dependencies = [
|
|||||||
name = "notedeck_chrome"
|
name = "notedeck_chrome"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"bitflags 2.9.1",
|
||||||
"eframe",
|
"eframe",
|
||||||
"egui",
|
"egui",
|
||||||
"egui-winit",
|
"egui-winit",
|
||||||
|
|||||||
@@ -1,12 +1,22 @@
|
|||||||
#[cfg(target_os = "android")]
|
#[cfg(target_os = "android")]
|
||||||
pub mod android;
|
pub mod android;
|
||||||
|
|
||||||
|
const VIRT_HEIGHT: i32 = 400;
|
||||||
|
|
||||||
#[cfg(target_os = "android")]
|
#[cfg(target_os = "android")]
|
||||||
pub fn virtual_keyboard_height() -> i32 {
|
pub fn virtual_keyboard_height(virt: bool) -> i32 {
|
||||||
android::virtual_keyboard_height()
|
if virt {
|
||||||
|
VIRT_HEIGHT
|
||||||
|
} else {
|
||||||
|
android::virtual_keyboard_height()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_os = "android"))]
|
#[cfg(not(target_os = "android"))]
|
||||||
pub fn virtual_keyboard_height() -> i32 {
|
pub fn virtual_keyboard_height(virt: bool) -> i32 {
|
||||||
0
|
if virt {
|
||||||
|
VIRT_HEIGHT
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ license = "GPLv3"
|
|||||||
description = "The nostr browser"
|
description = "The nostr browser"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
bitflags = { workspace = true }
|
||||||
eframe = { workspace = true }
|
eframe = { workspace = true }
|
||||||
egui_tabs = { workspace = true }
|
egui_tabs = { workspace = true }
|
||||||
egui_extras = { workspace = true }
|
egui_extras = { workspace = true }
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
//#[cfg(target_arch = "wasm32")]
|
//#[cfg(target_arch = "wasm32")]
|
||||||
//use wasm_bindgen::prelude::*;
|
//use wasm_bindgen::prelude::*;
|
||||||
use crate::app::NotedeckApp;
|
use crate::app::NotedeckApp;
|
||||||
|
use crate::ChromeOptions;
|
||||||
use eframe::CreationContext;
|
use eframe::CreationContext;
|
||||||
use egui::{vec2, Button, Color32, Label, Layout, Rect, RichText, ThemePreference, Widget};
|
use egui::{vec2, Button, Color32, Label, Layout, Rect, RichText, ThemePreference, Widget};
|
||||||
use egui_extras::{Size, StripBuilder};
|
use egui_extras::{Size, StripBuilder};
|
||||||
@@ -24,33 +25,13 @@ use std::collections::HashMap;
|
|||||||
static ICON_WIDTH: f32 = 40.0;
|
static ICON_WIDTH: f32 = 40.0;
|
||||||
pub static ICON_EXPANSION_MULTIPLE: f32 = 1.2;
|
pub static ICON_EXPANSION_MULTIPLE: f32 = 1.2;
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
pub struct Chrome {
|
pub struct Chrome {
|
||||||
active: i32,
|
active: i32,
|
||||||
open: bool,
|
|
||||||
tab_selected: i32,
|
tab_selected: i32,
|
||||||
|
options: ChromeOptions,
|
||||||
apps: Vec<NotedeckApp>,
|
apps: Vec<NotedeckApp>,
|
||||||
pub repaint_causes: HashMap<egui::RepaintCause, u64>,
|
pub repaint_causes: HashMap<egui::RepaintCause, u64>,
|
||||||
|
|
||||||
#[cfg(feature = "memory")]
|
|
||||||
show_memory_debug: bool,
|
|
||||||
show_repaint_debug: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Chrome {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
active: 0,
|
|
||||||
repaint_causes: Default::default(),
|
|
||||||
tab_selected: 0,
|
|
||||||
// sidemenu is not open by default on mobile/narrow uis
|
|
||||||
open: !notedeck::ui::is_compiled_as_mobile(),
|
|
||||||
apps: vec![],
|
|
||||||
|
|
||||||
#[cfg(feature = "memory")]
|
|
||||||
show_memory_debug: false,
|
|
||||||
show_repaint_debug: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// When you click the toolbar button, these actions
|
/// When you click the toolbar button, these actions
|
||||||
@@ -223,7 +204,7 @@ impl Chrome {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn toggle(&mut self) {
|
pub fn toggle(&mut self) {
|
||||||
self.open = !self.open;
|
self.options.toggle(ChromeOptions::IsOpen);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_app(&mut self, app: NotedeckApp) {
|
pub fn add_app(&mut self, app: NotedeckApp) {
|
||||||
@@ -366,7 +347,9 @@ impl Chrome {
|
|||||||
fn amount_open(&self, ui: &mut egui::Ui) -> f32 {
|
fn amount_open(&self, ui: &mut egui::Ui) -> f32 {
|
||||||
let open_id = egui::Id::new("chrome_open");
|
let open_id = egui::Id::new("chrome_open");
|
||||||
let side_panel_width: f32 = 74.0;
|
let side_panel_width: f32 = 74.0;
|
||||||
ui.ctx().animate_bool(open_id, self.open) * side_panel_width
|
ui.ctx()
|
||||||
|
.animate_bool(open_id, self.options.contains(ChromeOptions::IsOpen))
|
||||||
|
* side_panel_width
|
||||||
}
|
}
|
||||||
|
|
||||||
fn toolbar_height() -> f32 {
|
fn toolbar_height() -> f32 {
|
||||||
@@ -477,12 +460,25 @@ impl Chrome {
|
|||||||
fn show(&mut self, ctx: &mut AppContext, ui: &mut egui::Ui) -> Option<ChromePanelAction> {
|
fn show(&mut self, ctx: &mut AppContext, ui: &mut egui::Ui) -> Option<ChromePanelAction> {
|
||||||
ui.spacing_mut().item_spacing.x = 0.0;
|
ui.spacing_mut().item_spacing.x = 0.0;
|
||||||
|
|
||||||
if notedeck::ui::is_narrow(ui.ctx()) {
|
if ctx.args.options.contains(NotedeckOptions::Debug)
|
||||||
|
&& ui.ctx().input(|i| i.key_pressed(egui::Key::Backtick))
|
||||||
|
{
|
||||||
|
self.options.toggle(ChromeOptions::VirtualKeyboard);
|
||||||
|
}
|
||||||
|
|
||||||
|
let r = if notedeck::ui::is_narrow(ui.ctx()) {
|
||||||
self.toolbar_chrome(ctx, ui)
|
self.toolbar_chrome(ctx, ui)
|
||||||
} else {
|
} else {
|
||||||
let amt_open = self.amount_open(ui);
|
let amt_open = self.amount_open(ui);
|
||||||
self.panel(ctx, StripBuilder::new(ui), amt_open)
|
self.panel(ctx, StripBuilder::new(ui), amt_open)
|
||||||
|
};
|
||||||
|
|
||||||
|
// virtual keyboard
|
||||||
|
if self.options.contains(ChromeOptions::VirtualKeyboard) {
|
||||||
|
virtual_keyboard_ui(ui);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r
|
||||||
}
|
}
|
||||||
|
|
||||||
fn topdown_sidebar(&mut self, ui: &mut egui::Ui, i18n: &mut Localization) {
|
fn topdown_sidebar(&mut self, ui: &mut egui::Ui, i18n: &mut Localization) {
|
||||||
@@ -497,7 +493,7 @@ impl Chrome {
|
|||||||
|
|
||||||
if ui.add(expand_side_panel_button()).clicked() {
|
if ui.add(expand_side_panel_button()).clicked() {
|
||||||
//self.active = (self.active + 1) % (self.apps.len() as i32);
|
//self.active = (self.active + 1) % (self.apps.len() as i32);
|
||||||
self.open = !self.open;
|
self.options.toggle(ChromeOptions::IsOpen);
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.add_space(4.0);
|
ui.add_space(4.0);
|
||||||
@@ -1023,10 +1019,10 @@ fn bottomup_sidebar(
|
|||||||
.on_hover_cursor(egui::CursorIcon::PointingHand);
|
.on_hover_cursor(egui::CursorIcon::PointingHand);
|
||||||
|
|
||||||
if r.clicked() {
|
if r.clicked() {
|
||||||
chrome.show_repaint_debug = !chrome.show_repaint_debug;
|
chrome.options.toggle(ChromeOptions::RepaintDebug);
|
||||||
}
|
}
|
||||||
|
|
||||||
if chrome.show_repaint_debug {
|
if chrome.options.contains(ChromeOptions::RepaintDebug) {
|
||||||
for cause in ui.ctx().repaint_causes() {
|
for cause in ui.ctx().repaint_causes() {
|
||||||
chrome
|
chrome
|
||||||
.repaint_causes
|
.repaint_causes
|
||||||
@@ -1218,3 +1214,21 @@ fn repaint_causes_window(ui: &mut egui::Ui, causes: &HashMap<egui::RepaintCause,
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn virtual_keyboard_ui(ui: &mut egui::Ui) {
|
||||||
|
let height = notedeck::platform::virtual_keyboard_height(true);
|
||||||
|
let screen_rect = ui.ctx().screen_rect();
|
||||||
|
|
||||||
|
let min = egui::Pos2::new(0.0, screen_rect.max.y - height as f32);
|
||||||
|
let rect = Rect::from_min_max(min, screen_rect.max);
|
||||||
|
let painter = ui.painter_at(rect);
|
||||||
|
|
||||||
|
painter.rect_filled(rect, 0.0, Color32::from_black_alpha(200));
|
||||||
|
|
||||||
|
ui.put(rect, |ui: &mut egui::Ui| {
|
||||||
|
ui.centered_and_justified(|ui| {
|
||||||
|
ui.label("This is a keyboard");
|
||||||
|
})
|
||||||
|
.response
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ mod android;
|
|||||||
|
|
||||||
mod app;
|
mod app;
|
||||||
mod chrome;
|
mod chrome;
|
||||||
|
mod options;
|
||||||
|
|
||||||
pub use app::NotedeckApp;
|
pub use app::NotedeckApp;
|
||||||
pub use chrome::Chrome;
|
pub use chrome::Chrome;
|
||||||
|
pub use options::ChromeOptions;
|
||||||
|
|||||||
35
crates/notedeck_chrome/src/options.rs
Normal file
35
crates/notedeck_chrome/src/options.rs
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
use bitflags::bitflags;
|
||||||
|
|
||||||
|
bitflags! {
|
||||||
|
#[repr(transparent)]
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
pub struct ChromeOptions: u64 {
|
||||||
|
/// Is the chrome currently open?
|
||||||
|
const NoOptions = 0;
|
||||||
|
|
||||||
|
/// Is the chrome currently open?
|
||||||
|
const IsOpen = 1 << 0;
|
||||||
|
|
||||||
|
/// Are we simulating a virtual keyboard? This is mostly for debugging
|
||||||
|
/// if we are too lazy to open up a real mobile device with soft
|
||||||
|
/// keyboard
|
||||||
|
const VirtualKeyboard = 1 << 1;
|
||||||
|
|
||||||
|
/// Are we showing the memory debug window?
|
||||||
|
const MemoryDebug = 1 << 2;
|
||||||
|
|
||||||
|
/// Repaint debug
|
||||||
|
const RepaintDebug = 1 << 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ChromeOptions {
|
||||||
|
fn default() -> Self {
|
||||||
|
let mut options = ChromeOptions::NoOptions;
|
||||||
|
options.set(
|
||||||
|
ChromeOptions::IsOpen,
|
||||||
|
!notedeck::ui::is_compiled_as_mobile(),
|
||||||
|
);
|
||||||
|
options
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user