mirror of
https://code.gri.mw/GUI/grim.git
synced 2026-07-15 19:29:04 +00:00
ui: keyboard language switch
This commit is contained in:
+46
-1
@@ -291,4 +291,49 @@ modal:
|
||||
add: Hinzufügen
|
||||
modal_exit:
|
||||
description: Sind Sie sicher, dass Sie die Anwendung beenden wollen?
|
||||
exit: Schließen
|
||||
exit: Schließen
|
||||
keyboard:
|
||||
1: 1
|
||||
2: 2
|
||||
3: 3
|
||||
4: 4
|
||||
5: 5
|
||||
6: 6
|
||||
7: 7
|
||||
8: 8
|
||||
9: 9
|
||||
0: 0
|
||||
01: '-'
|
||||
q: q
|
||||
w: w
|
||||
e: e
|
||||
r: r
|
||||
t: t
|
||||
y: y
|
||||
u: u
|
||||
i: i
|
||||
o: o
|
||||
p: p
|
||||
p1: '"'
|
||||
a: a
|
||||
s: s
|
||||
d: d
|
||||
f: f
|
||||
g: g
|
||||
h: h
|
||||
j: j
|
||||
k: k
|
||||
l: l
|
||||
l1: \
|
||||
l2: '?'
|
||||
z1: ','
|
||||
z: z
|
||||
x: x
|
||||
c: c
|
||||
v: v
|
||||
b: b
|
||||
n: n
|
||||
m: m
|
||||
m1: .
|
||||
m2: ':'
|
||||
m3: /
|
||||
+46
-1
@@ -291,4 +291,49 @@ modal:
|
||||
add: Add
|
||||
modal_exit:
|
||||
description: Are you sure you want to quit the application?
|
||||
exit: Exit
|
||||
exit: Exit
|
||||
keyboard:
|
||||
1: 1
|
||||
2: 2
|
||||
3: 3
|
||||
4: 4
|
||||
5: 5
|
||||
6: 6
|
||||
7: 7
|
||||
8: 8
|
||||
9: 9
|
||||
0: 0
|
||||
01: '-'
|
||||
q: q
|
||||
w: w
|
||||
e: e
|
||||
r: r
|
||||
t: t
|
||||
y: y
|
||||
u: u
|
||||
i: i
|
||||
o: o
|
||||
p: p
|
||||
p1: '"'
|
||||
a: a
|
||||
s: s
|
||||
d: d
|
||||
f: f
|
||||
g: g
|
||||
h: h
|
||||
j: j
|
||||
k: k
|
||||
l: l
|
||||
l1: \
|
||||
l2: '?'
|
||||
z1: ','
|
||||
z: z
|
||||
x: x
|
||||
c: c
|
||||
v: v
|
||||
b: b
|
||||
n: n
|
||||
m: m
|
||||
m1: .
|
||||
m2: ':'
|
||||
m3: /
|
||||
+46
-1
@@ -291,4 +291,49 @@ modal:
|
||||
add: Ajouter
|
||||
modal_exit:
|
||||
description: "Êtes-vous sûr de vouloir quitter l'application ?"
|
||||
exit: Quitter
|
||||
exit: Quitter
|
||||
keyboard:
|
||||
1: 1
|
||||
2: 2
|
||||
3: 3
|
||||
4: 4
|
||||
5: 5
|
||||
6: 6
|
||||
7: 7
|
||||
8: 8
|
||||
9: 9
|
||||
0: 0
|
||||
01: '-'
|
||||
q: q
|
||||
w: w
|
||||
e: e
|
||||
r: r
|
||||
t: t
|
||||
y: y
|
||||
u: u
|
||||
i: i
|
||||
o: o
|
||||
p: p
|
||||
p1: '"'
|
||||
a: a
|
||||
s: s
|
||||
d: d
|
||||
f: f
|
||||
g: g
|
||||
h: h
|
||||
j: j
|
||||
k: k
|
||||
l: l
|
||||
l1: \
|
||||
l2: '?'
|
||||
z1: ','
|
||||
z: z
|
||||
x: x
|
||||
c: c
|
||||
v: v
|
||||
b: b
|
||||
n: n
|
||||
m: m
|
||||
m1: .
|
||||
m2: ':'
|
||||
m3: /
|
||||
+46
-1
@@ -291,4 +291,49 @@ modal:
|
||||
add: Добавить
|
||||
modal_exit:
|
||||
description: Вы уверены, что хотите выйти из приложения?
|
||||
exit: Выход
|
||||
exit: Выход
|
||||
keyboard:
|
||||
1: 1
|
||||
2: 2
|
||||
3: 3
|
||||
4: 4
|
||||
5: 5
|
||||
6: 6
|
||||
7: 7
|
||||
8: 8
|
||||
9: 9
|
||||
0: 0
|
||||
01: '-'
|
||||
q: й
|
||||
w: ц
|
||||
e: у
|
||||
r: к
|
||||
t: е
|
||||
y: н
|
||||
u: г
|
||||
i: ш
|
||||
o: щ
|
||||
p: з
|
||||
p1: х
|
||||
a: ф
|
||||
s: ы
|
||||
d: в
|
||||
f: а
|
||||
g: п
|
||||
h: р
|
||||
j: о
|
||||
k: л
|
||||
l: д
|
||||
l1: ж
|
||||
l2: э
|
||||
z1: я
|
||||
z: ч
|
||||
x: с
|
||||
c: м
|
||||
v: и
|
||||
b: т
|
||||
n: ь
|
||||
m: б
|
||||
m1: ю
|
||||
m2: ё
|
||||
m3: ъ
|
||||
+46
-1
@@ -291,4 +291,49 @@ modal:
|
||||
add: Ekle
|
||||
modal_exit:
|
||||
description: Uygulamadan cikmak için exit, emin misiniz?
|
||||
exit: Exit
|
||||
exit: Exit
|
||||
keyboard:
|
||||
1: 1
|
||||
2: 2
|
||||
3: 3
|
||||
4: 4
|
||||
5: 5
|
||||
6: 6
|
||||
7: 7
|
||||
8: 8
|
||||
9: 9
|
||||
0: 0
|
||||
01: '-'
|
||||
q: q
|
||||
w: w
|
||||
e: e
|
||||
r: r
|
||||
t: t
|
||||
y: y
|
||||
u: u
|
||||
i: i
|
||||
o: o
|
||||
p: p
|
||||
p1: '"'
|
||||
a: a
|
||||
s: s
|
||||
d: d
|
||||
f: f
|
||||
g: g
|
||||
h: h
|
||||
j: j
|
||||
k: k
|
||||
l: l
|
||||
l1: \
|
||||
l2: '?'
|
||||
z1: ','
|
||||
z: z
|
||||
x: x
|
||||
c: c
|
||||
v: v
|
||||
b: b
|
||||
n: n
|
||||
m: m
|
||||
m1: .
|
||||
m2: ':'
|
||||
m3: /
|
||||
+46
-1
@@ -291,4 +291,49 @@ modal:
|
||||
add: 添加
|
||||
modal_exit:
|
||||
description: 您确定要退出应用程序吗?
|
||||
exit: 退出
|
||||
exit: 退出手
|
||||
keyboard:
|
||||
1: 1
|
||||
2: 2
|
||||
3: 3
|
||||
4: 4
|
||||
5: 5
|
||||
6: 6
|
||||
7: 7
|
||||
8: 8
|
||||
9: 9
|
||||
0: 0
|
||||
01: '-'
|
||||
q: 手
|
||||
w: 田
|
||||
e: 水
|
||||
r: 口
|
||||
t: 廿
|
||||
y: 卜
|
||||
u: 山
|
||||
i: 戈
|
||||
o: 人
|
||||
p: 心
|
||||
p1: '"'
|
||||
a: 日
|
||||
s: 尸
|
||||
d: 木
|
||||
f: 火
|
||||
g: 土
|
||||
h: 竹
|
||||
j: 十
|
||||
k: 大
|
||||
l: 中
|
||||
l1: \
|
||||
l2: '?'
|
||||
z1: ','
|
||||
z: 重
|
||||
x: 難
|
||||
c: 金
|
||||
v: 女
|
||||
b: 月
|
||||
n: 弓
|
||||
m: 一
|
||||
m1: .
|
||||
m2: ':'
|
||||
m3: /
|
||||
+2
-6
@@ -78,12 +78,8 @@ impl<Platform: PlatformCallbacks> App<Platform> {
|
||||
// Handle Esc keyboard key event and platform Back button key event.
|
||||
let back_pressed = BACK_BUTTON_PRESSED.load(Ordering::Relaxed);
|
||||
if back_pressed || ctx.input_mut(|i| i.consume_key(Modifiers::NONE, egui::Key::Escape)) {
|
||||
// Hide keyboard or pass event to content.
|
||||
if KeyboardContent::showing() {
|
||||
KeyboardContent::hide();
|
||||
} else {
|
||||
self.content.on_back(&self.platform);
|
||||
}
|
||||
// Pass event to content.
|
||||
self.content.on_back(&self.platform);
|
||||
if back_pressed {
|
||||
BACK_BUTTON_PRESSED.store(false, Ordering::Relaxed);
|
||||
}
|
||||
|
||||
@@ -162,7 +162,7 @@ impl TextEdit {
|
||||
if self.enter_pressed {
|
||||
KeyboardContent::unshift();
|
||||
}
|
||||
KeyboardContent::show(self.numeric);
|
||||
KeyboardContent::show_window(self.numeric);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
+138
-114
@@ -12,23 +12,24 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use eframe::emath::Align;
|
||||
use eframe::epaint::{Margin, Shadow};
|
||||
use egui::{Align2, Button, Color32, CursorIcon, Layout, Rect, Response, RichText, Stroke, Vec2, Widget};
|
||||
use parking_lot::RwLock;
|
||||
use egui::{Align2, Button, Color32, CursorIcon, Layout, Rect, Response, RichText, Vec2, Widget};
|
||||
use lazy_static::lazy_static;
|
||||
use crate::AppConfig;
|
||||
use crate::gui::Colors;
|
||||
use crate::gui::icons::{ARROW_FAT_UP, BACKSPACE, KEY_RETURN, TRANSLATE};
|
||||
use parking_lot::RwLock;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::gui::icons::{ARROW_FAT_UP, BACKSPACE, GLOBE_SIMPLE, KEY_RETURN};
|
||||
use crate::gui::views::{KeyboardEvent, KeyboardLayout, View};
|
||||
use crate::gui::Colors;
|
||||
use crate::AppConfig;
|
||||
|
||||
lazy_static! {
|
||||
/// Last input event.
|
||||
static ref LAST_EVENT: Arc<RwLock<Option<KeyboardEvent >>> = Arc::new(RwLock::new(None));
|
||||
/// Flag to show keyboard.
|
||||
static ref SHOW_KEYBOARD: AtomicBool = AtomicBool::new(false);
|
||||
/// Flag to show keyboard [`egui::Window`].
|
||||
static ref SHOW_WINDOW: AtomicBool = AtomicBool::new(false);
|
||||
/// Flag to enable text shifting.
|
||||
static ref UPPERCASE: AtomicBool = AtomicBool::new(false);
|
||||
/// Flag to show numeric layout.
|
||||
@@ -52,12 +53,10 @@ impl Default for KeyboardContent {
|
||||
impl KeyboardContent {
|
||||
/// Maximum keyboard content width.
|
||||
const MAX_WIDTH: f32 = 600.0;
|
||||
/// Buttons content margin.
|
||||
const MARGIN: f32 = 5.0;
|
||||
|
||||
/// Draw keyboard content as separate [`Window`].
|
||||
pub fn window_ui(&mut self, ctx: &egui::Context) {
|
||||
if !KeyboardContent::showing() {
|
||||
if !KeyboardContent::window_showing() {
|
||||
return;
|
||||
}
|
||||
let width = ctx.screen_rect().width();
|
||||
@@ -76,10 +75,10 @@ impl KeyboardContent {
|
||||
color: Color32::from_black_alpha(32),
|
||||
},
|
||||
inner_margin: Margin {
|
||||
left: View::get_left_inset() + Self::MARGIN,
|
||||
right: View::get_right_inset() + Self::MARGIN,
|
||||
top: Self::MARGIN,
|
||||
bottom: View::get_bottom_inset() + Self::MARGIN,
|
||||
left: View::get_left_inset(),
|
||||
right: View::get_right_inset(),
|
||||
top: 1.0,
|
||||
bottom: View::get_bottom_inset() + 1.0,
|
||||
},
|
||||
fill: Colors::fill(),
|
||||
..Default::default()
|
||||
@@ -88,7 +87,7 @@ impl KeyboardContent {
|
||||
ui.set_min_width(width);
|
||||
// Calculate content width.
|
||||
let side_insets = View::get_left_inset() + View::get_right_inset();
|
||||
let available_width = width - (side_insets + Self::MARGIN * 2.0);
|
||||
let available_width = width - side_insets;
|
||||
let w = f32::min(available_width, Self::MAX_WIDTH);
|
||||
View::max_width_ui(ui, w, |ui| {
|
||||
self.ui(ui);
|
||||
@@ -102,15 +101,15 @@ impl KeyboardContent {
|
||||
/// Draw keyboard content.
|
||||
pub fn ui(&mut self, ui: &mut egui::Ui) {
|
||||
// Setup spacing between buttons.
|
||||
ui.style_mut().spacing.item_spacing = egui::vec2(Self::MARGIN, 0.0);
|
||||
ui.style_mut().spacing.item_spacing = egui::vec2(0.0, 0.0);
|
||||
// Setup vertical padding inside buttons.
|
||||
ui.style_mut().spacing.button_padding = egui::vec2(Self::MARGIN, 8.0);
|
||||
ui.style_mut().spacing.button_padding = egui::vec2(0.0, 8.0);
|
||||
|
||||
let button_rect = match self.mode {
|
||||
KeyboardLayout::TEXT => Self::text_ui(ui),
|
||||
KeyboardLayout::SYMBOLS => Self::symbols_ui(ui),
|
||||
};
|
||||
ui.add_space(View::TAB_ITEMS_PADDING);
|
||||
ui.add_space(2.0);
|
||||
|
||||
// Draw bottom keyboard buttons.
|
||||
let bottom_size = {
|
||||
@@ -118,42 +117,82 @@ impl KeyboardContent {
|
||||
r.set_width(ui.available_width());
|
||||
r.size()
|
||||
};
|
||||
let button_width = button_rect.width();
|
||||
ui.allocate_ui_with_layout(bottom_size, Layout::right_to_left(Align::Max), |ui| {
|
||||
let button_width = ui.available_width() / if self.mode != KeyboardLayout::SYMBOLS {
|
||||
11.0
|
||||
} else {
|
||||
10.0
|
||||
};
|
||||
ui.allocate_ui_with_layout(bottom_size, Layout::right_to_left(Align::Center), |ui| {
|
||||
// Enter key input.
|
||||
ui.horizontal_centered(|ui| {
|
||||
ui.set_max_width(button_width * 2.0 + Self::MARGIN);
|
||||
Self::button_ui(KEY_RETURN,
|
||||
Colors::white_or_black(false),
|
||||
Some(Colors::green()),
|
||||
ui,
|
||||
|_| {
|
||||
Self::input_event(KeyboardEvent::ENTER);
|
||||
});
|
||||
ui.set_max_width(button_width * 2.0 + 1.0);
|
||||
Self::custom_button_ui(KEY_RETURN.to_string(),
|
||||
Colors::white_or_black(false),
|
||||
Some(Colors::green()),
|
||||
ui,
|
||||
|_| {
|
||||
Self::input_event(KeyboardEvent::ENTER);
|
||||
});
|
||||
});
|
||||
// Backspace key input.
|
||||
ui.horizontal_centered(|ui| {
|
||||
ui.set_max_width(button_width * 5.0 + 4.0 * Self::MARGIN);
|
||||
Self::button_ui(" ", Colors::inactive_text(), None, ui, |l| {
|
||||
ui.set_max_width(button_width * 1.0);
|
||||
Self::custom_button_ui(BACKSPACE.to_string(),
|
||||
Colors::red(),
|
||||
Some(Colors::fill_lite()),
|
||||
ui,
|
||||
|_| {
|
||||
Self::input_event(KeyboardEvent::CLEAR);
|
||||
});
|
||||
});
|
||||
// Space key input.
|
||||
ui.horizontal_centered(|ui| {
|
||||
ui.set_max_width(button_width * 4.0);
|
||||
Self::custom_button_ui(" ".to_string(), Colors::inactive_text(), None, ui, |l| {
|
||||
Self::input_event(KeyboardEvent::TEXT(l));
|
||||
});
|
||||
});
|
||||
ui.horizontal_centered(|ui| {
|
||||
ui.set_max_width(button_width);
|
||||
Self::button_ui(TRANSLATE,
|
||||
Colors::text_button(),
|
||||
Some(Colors::fill_lite()),
|
||||
ui,
|
||||
|_| {
|
||||
AppConfig::toggle_english_keyboard()
|
||||
});
|
||||
});
|
||||
if self.mode != KeyboardLayout::SYMBOLS {
|
||||
// Switch to english and back.
|
||||
ui.horizontal_centered(|ui| {
|
||||
ui.set_max_width(button_width);
|
||||
Self::custom_button_ui(GLOBE_SIMPLE.to_string(),
|
||||
Colors::text_button(),
|
||||
Some(Colors::fill_lite()),
|
||||
ui,
|
||||
|_| {
|
||||
AppConfig::toggle_english_keyboard()
|
||||
});
|
||||
});
|
||||
// Shift key input.
|
||||
ui.horizontal_centered(|ui| {
|
||||
ui.set_max_width(button_width);
|
||||
let uppercase = UPPERCASE.load(Ordering::Relaxed);
|
||||
let color = if uppercase {
|
||||
Colors::yellow_dark()
|
||||
} else {
|
||||
Colors::inactive_text()
|
||||
};
|
||||
Self::custom_button_ui(ARROW_FAT_UP.to_string(),
|
||||
color,
|
||||
Some(Colors::fill_lite()),
|
||||
ui, |_| {
|
||||
UPPERCASE.store(!uppercase, Ordering::Relaxed);
|
||||
});
|
||||
});
|
||||
}
|
||||
// Switch to symbols and back.
|
||||
ui.horizontal_centered(|ui| {
|
||||
let label = if self.mode == KeyboardLayout::SYMBOLS {
|
||||
"ABC"
|
||||
let q = t!("keyboard.q", locale = Self::locale().as_str());
|
||||
let w = t!("keyboard.w", locale = Self::locale().as_str());
|
||||
let e = t!("keyboard.e", locale = Self::locale().as_str());
|
||||
format!("{}{}{}", q, w, e).to_uppercase()
|
||||
} else {
|
||||
"?/ツ"
|
||||
"?/ツ".to_string()
|
||||
};
|
||||
let mut mode = self.mode.clone();
|
||||
Self::button_ui(label, Colors::text_button(), Some(Colors::fill_lite()), ui, |_| {
|
||||
Self::custom_button_ui(label, Colors::text(false), Some(Colors::fill_lite()), ui, |_| {
|
||||
if self.mode == KeyboardLayout::SYMBOLS {
|
||||
mode = KeyboardLayout::TEXT;
|
||||
} else {
|
||||
@@ -168,58 +207,37 @@ impl KeyboardContent {
|
||||
/// Draw text content returning button [`Rect`].
|
||||
fn text_ui(ui: &mut egui::Ui) -> Rect {
|
||||
let mut button_rect = ui.available_rect_before_wrap();
|
||||
let tl_0: Vec<&str> = vec!["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"];
|
||||
let tl_0: Vec<&str> = vec!["1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "01"];
|
||||
ui.columns(tl_0.len(), |columns| {
|
||||
for (index, s) in tl_0.iter().enumerate() {
|
||||
button_rect = Self::input_button_ui(s, &mut columns[index]);
|
||||
button_rect = Self::input_button_ui(s, true, &mut columns[index]);
|
||||
}
|
||||
});
|
||||
ui.add_space(View::TAB_ITEMS_PADDING);
|
||||
ui.add_space(2.0);
|
||||
|
||||
let tl_1: Vec<&str> = vec!["q", "w", "e", "r", "t", "y", "u", "i", "o", "p"];
|
||||
let tl_1: Vec<&str> = vec!["q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "p1"];
|
||||
ui.columns(tl_1.len(), |columns| {
|
||||
for (index, s) in tl_1.iter().enumerate() {
|
||||
Self::input_button_ui(s, &mut columns[index]);
|
||||
Self::input_button_ui(s, true, &mut columns[index]);
|
||||
}
|
||||
});
|
||||
ui.add_space(View::TAB_ITEMS_PADDING);
|
||||
ui.add_space(2.0);
|
||||
|
||||
let tl_2: Vec<&str> = vec!["a", "s", "d", "f", "g", "h", "j", "k", "l", ":"];
|
||||
let tl_2: Vec<&str> = vec!["a", "s", "d", "f", "g", "h", "j", "k", "l", "l1", "l2"];
|
||||
ui.columns(tl_2.len(), |columns| {
|
||||
for (index, s) in tl_2.iter().enumerate() {
|
||||
Self::input_button_ui(s, &mut columns[index]);
|
||||
Self::input_button_ui(s, true, &mut columns[index]);
|
||||
}
|
||||
});
|
||||
ui.add_space(View::TAB_ITEMS_PADDING);
|
||||
ui.add_space(2.0);
|
||||
|
||||
let tl_3: Vec<&str> = vec![ARROW_FAT_UP, "z", "x", "c", "v", "b", "n", "m", ".", BACKSPACE];
|
||||
let tl_3: Vec<&str> = vec!["z1", "z", "x", "c", "v", "b", "n", "m", "m1", "m2", "m3"];
|
||||
ui.columns(tl_3.len(), |columns| {
|
||||
for (index, s) in tl_3.iter().enumerate() {
|
||||
if index == 0 {
|
||||
// Check for shift input.
|
||||
let uppercase = UPPERCASE.load(Ordering::Relaxed);
|
||||
let color = if uppercase {
|
||||
Colors::yellow_dark()
|
||||
} else {
|
||||
Colors::inactive_text()
|
||||
};
|
||||
Self::button_ui(s, color, Some(Colors::fill_lite()), &mut columns[index], |_| {
|
||||
UPPERCASE.store(!uppercase, Ordering::Relaxed);
|
||||
});
|
||||
} else if index == tl_3.len() - 1 {
|
||||
// Check for backspace input.
|
||||
Self::button_ui(s,
|
||||
Colors::red(),
|
||||
Some(Colors::fill_lite()),
|
||||
&mut columns[index],
|
||||
|_| {
|
||||
Self::input_event(KeyboardEvent::CLEAR);
|
||||
});
|
||||
} else {
|
||||
Self::input_button_ui(s, &mut columns[index]);
|
||||
}
|
||||
Self::input_button_ui(s, true, &mut columns[index]);
|
||||
}
|
||||
});
|
||||
|
||||
button_rect
|
||||
}
|
||||
|
||||
@@ -229,53 +247,43 @@ impl KeyboardContent {
|
||||
let tl_0: Vec<&str> = vec!["[", "]", "{", "}", "#", "%", "^", "*", "+", "="];
|
||||
ui.columns(tl_0.len(), |columns| {
|
||||
for (index, s) in tl_0.iter().enumerate() {
|
||||
button_rect = Self::input_button_ui(s, &mut columns[index]);
|
||||
button_rect = Self::input_button_ui(s, false, &mut columns[index]);
|
||||
}
|
||||
});
|
||||
ui.add_space(View::TAB_ITEMS_PADDING);
|
||||
ui.add_space(2.0);
|
||||
|
||||
let tl_1: Vec<&str> = vec!["_", "\\", "|", "~", "<", ">", "`", "√", "π", "•"];
|
||||
let tl_1: Vec<&str> = vec!["_", "\\", "|", "~", "<", ">", "№", "√", "π", "•"];
|
||||
ui.columns(tl_1.len(), |columns| {
|
||||
for (index, s) in tl_1.iter().enumerate() {
|
||||
Self::input_button_ui(s, &mut columns[index]);
|
||||
Self::input_button_ui(s, false, &mut columns[index]);
|
||||
}
|
||||
});
|
||||
ui.add_space(View::TAB_ITEMS_PADDING);
|
||||
ui.add_space(2.0);
|
||||
|
||||
let tl_2: Vec<&str> = vec!["-", "/", ":", ";", "(", ")", "$", "&", "@", "\""];
|
||||
let tl_2: Vec<&str> = vec!["-", "/", ":", ";", "(", ")", "`", "&", "@", "\""];
|
||||
ui.columns(tl_2.len(), |columns| {
|
||||
for (index, s) in tl_2.iter().enumerate() {
|
||||
Self::input_button_ui(s, &mut columns[index]);
|
||||
Self::input_button_ui(s, false, &mut columns[index]);
|
||||
}
|
||||
});
|
||||
ui.add_space(View::TAB_ITEMS_PADDING);
|
||||
ui.add_space(2.0);
|
||||
|
||||
let tl_3: Vec<&str> = vec![".", ",", "?", "!", "€", "£", "¥", "¢", "ツ", BACKSPACE];
|
||||
let tl_3: Vec<&str> = vec![".", ",", "?", "!", "€", "£", "¥", "$", "¢", "ツ"];
|
||||
ui.columns(tl_3.len(), |columns| {
|
||||
for (index, s) in tl_3.iter().enumerate() {
|
||||
if index == tl_3.len() - 1 {
|
||||
// Check for backspace input.
|
||||
Self::button_ui(s,
|
||||
Colors::red(),
|
||||
Some(Colors::fill_lite()),
|
||||
&mut columns[index], |_| {
|
||||
Self::input_event(KeyboardEvent::CLEAR);
|
||||
});
|
||||
} else {
|
||||
Self::input_button_ui(s, &mut columns[index]);
|
||||
}
|
||||
Self::input_button_ui(s, false, &mut columns[index]);
|
||||
}
|
||||
});
|
||||
|
||||
button_rect
|
||||
}
|
||||
|
||||
/// Draw keyboard button.
|
||||
fn button_ui(s: &str,
|
||||
color: Color32,
|
||||
bg: Option<Color32>,
|
||||
ui: &mut egui::Ui,
|
||||
mut cb: impl FnMut(String)) -> Response {
|
||||
/// Draw custom keyboard button.
|
||||
fn custom_button_ui(s: String,
|
||||
color: Color32,
|
||||
bg: Option<Color32>,
|
||||
ui: &mut egui::Ui,
|
||||
mut cb: impl FnMut(String)) -> Response {
|
||||
ui.vertical_centered_justified(|ui| {
|
||||
// Disable expansion on click/hover.
|
||||
ui.style_mut().visuals.widgets.hovered.expansion = 0.0;
|
||||
@@ -286,15 +294,16 @@ impl KeyboardContent {
|
||||
ui.visuals_mut().widgets.active.weak_bg_fill = Colors::fill();
|
||||
// Setup stroke colors.
|
||||
ui.visuals_mut().widgets.inactive.bg_stroke = View::item_stroke();
|
||||
ui.visuals_mut().widgets.hovered.bg_stroke = View::hover_stroke();
|
||||
ui.visuals_mut().widgets.active.bg_stroke = Stroke::NONE;
|
||||
ui.visuals_mut().widgets.hovered.bg_stroke = View::item_stroke();
|
||||
ui.visuals_mut().widgets.active.bg_stroke = View::hover_stroke();
|
||||
|
||||
let label = if UPPERCASE.load(Ordering::Relaxed) {
|
||||
s.to_uppercase()
|
||||
} else {
|
||||
s.to_string()
|
||||
};
|
||||
let mut button = Button::new(RichText::new(label.clone()).size(17.0).color(color));
|
||||
let mut button = Button::new(RichText::new(label.clone()).size(17.0).color(color))
|
||||
.rounding(egui::Rounding::ZERO);
|
||||
if let Some(bg) = bg {
|
||||
button = button.fill(bg);
|
||||
}
|
||||
@@ -306,14 +315,29 @@ impl KeyboardContent {
|
||||
}
|
||||
|
||||
/// Draw input button.
|
||||
fn input_button_ui(s: &str, ui: &mut egui::Ui) -> Rect {
|
||||
let rect = Self::button_ui(s, Colors::text_button(), None, ui, |l| {
|
||||
fn input_button_ui(s: &str, translate: bool, ui: &mut egui::Ui) -> Rect {
|
||||
let value = if translate {
|
||||
t!(format!("keyboard.{}", s).as_str(), locale = Self::locale().as_str())
|
||||
} else {
|
||||
s.to_string()
|
||||
};
|
||||
let rect = Self::custom_button_ui(value, Colors::text_button(), None, ui, |l| {
|
||||
Self::input_event(KeyboardEvent::TEXT(l));
|
||||
UPPERCASE.store(false, Ordering::Relaxed);
|
||||
}).rect;
|
||||
rect
|
||||
}
|
||||
|
||||
/// Get input locale.
|
||||
fn locale() -> String {
|
||||
let english = AppConfig::english_keyboard();
|
||||
if english {
|
||||
"en".to_string()
|
||||
} else {
|
||||
AppConfig::locale().unwrap_or("en".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
/// Save keyboard event to consume later.
|
||||
fn input_event(event: KeyboardEvent) {
|
||||
let mut w_input = LAST_EVENT.write();
|
||||
@@ -336,14 +360,14 @@ impl KeyboardContent {
|
||||
}
|
||||
|
||||
/// Check if keyboard is showing.
|
||||
pub fn showing() -> bool {
|
||||
SHOW_KEYBOARD.load(Ordering::Relaxed)
|
||||
pub fn window_showing() -> bool {
|
||||
SHOW_WINDOW.load(Ordering::Relaxed)
|
||||
}
|
||||
|
||||
/// Show keyboard.
|
||||
pub fn show(numeric: bool) {
|
||||
pub fn show_window(numeric: bool) {
|
||||
NUMERIC.store(numeric, Ordering::Relaxed);
|
||||
SHOW_KEYBOARD.store(true, Ordering::Relaxed);
|
||||
SHOW_WINDOW.store(true, Ordering::Relaxed);
|
||||
}
|
||||
|
||||
/// Emulate Shift key pressing.
|
||||
@@ -358,6 +382,6 @@ impl KeyboardContent {
|
||||
|
||||
/// Hide keyboard.
|
||||
pub fn hide() {
|
||||
SHOW_KEYBOARD.store(false, Ordering::Relaxed);
|
||||
SHOW_WINDOW.store(false, Ordering::Relaxed);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user