Add custom on-screen keyboard feature and fix installation
- Added custom half-width on-screen keyboard widget (keyboard_widget.py) - Keyboard appears at bottom center when input fields are active - Integrated keyboard in exit popup and settings popup - Fixed install.sh: added --break-system-packages flag for pip3 - Fixed install.sh: added fallback to online installation for version mismatches - Removed old Kivy 2.1.0 tar.gz that was causing conflicts - Keyboard includes close button for intuitive dismissal - All input fields trigger keyboard on touch - Keyboard automatically cleans up on popup dismiss
This commit is contained in:
@@ -1,5 +1,193 @@
|
||||
#:kivy 2.1.0
|
||||
|
||||
# Custom On-Screen Keyboard Widget
|
||||
<CustomKeyboard@FloatLayout>:
|
||||
size_hint: None, None
|
||||
width: root.parent.width * 0.5 if root.parent else dp(600)
|
||||
height: self.width / 3
|
||||
pos: (root.parent.width - self.width) / 2 if root.parent else 0, 0
|
||||
opacity: 0
|
||||
|
||||
canvas.before:
|
||||
Color:
|
||||
rgba: 0.1, 0.1, 0.1, 0.95
|
||||
RoundedRectangle:
|
||||
size: self.size
|
||||
pos: self.pos
|
||||
radius: [dp(15), dp(15), 0, 0]
|
||||
|
||||
BoxLayout:
|
||||
orientation: 'vertical'
|
||||
padding: dp(5)
|
||||
spacing: dp(5)
|
||||
|
||||
# Close button bar
|
||||
BoxLayout:
|
||||
size_hint: 1, None
|
||||
height: dp(40)
|
||||
padding: [dp(5), 0]
|
||||
|
||||
Widget:
|
||||
|
||||
Button:
|
||||
text: '✕'
|
||||
size_hint: None, 1
|
||||
width: dp(40)
|
||||
background_color: 0.8, 0.2, 0.2, 0.9
|
||||
font_size: sp(20)
|
||||
bold: True
|
||||
on_press: root.parent.hide_keyboard() if root.parent and hasattr(root.parent, 'hide_keyboard') else None
|
||||
|
||||
# Number row
|
||||
BoxLayout:
|
||||
size_hint: 1, 1
|
||||
spacing: dp(3)
|
||||
Button:
|
||||
text: '1'
|
||||
on_press: root.parent.key_pressed('1') if root.parent and hasattr(root.parent, 'key_pressed') else None
|
||||
Button:
|
||||
text: '2'
|
||||
on_press: root.parent.key_pressed('2') if root.parent and hasattr(root.parent, 'key_pressed') else None
|
||||
Button:
|
||||
text: '3'
|
||||
on_press: root.parent.key_pressed('3') if root.parent and hasattr(root.parent, 'key_pressed') else None
|
||||
Button:
|
||||
text: '4'
|
||||
on_press: root.parent.key_pressed('4') if root.parent and hasattr(root.parent, 'key_pressed') else None
|
||||
Button:
|
||||
text: '5'
|
||||
on_press: root.parent.key_pressed('5') if root.parent and hasattr(root.parent, 'key_pressed') else None
|
||||
Button:
|
||||
text: '6'
|
||||
on_press: root.parent.key_pressed('6') if root.parent and hasattr(root.parent, 'key_pressed') else None
|
||||
Button:
|
||||
text: '7'
|
||||
on_press: root.parent.key_pressed('7') if root.parent and hasattr(root.parent, 'key_pressed') else None
|
||||
Button:
|
||||
text: '8'
|
||||
on_press: root.parent.key_pressed('8') if root.parent and hasattr(root.parent, 'key_pressed') else None
|
||||
Button:
|
||||
text: '9'
|
||||
on_press: root.parent.key_pressed('9') if root.parent and hasattr(root.parent, 'key_pressed') else None
|
||||
Button:
|
||||
text: '0'
|
||||
on_press: root.parent.key_pressed('0') if root.parent and hasattr(root.parent, 'key_pressed') else None
|
||||
|
||||
# Top letter row (QWERTYUIOP)
|
||||
BoxLayout:
|
||||
size_hint: 1, 1
|
||||
spacing: dp(3)
|
||||
Button:
|
||||
text: 'Q'
|
||||
on_press: root.parent.key_pressed('q') if root.parent and hasattr(root.parent, 'key_pressed') else None
|
||||
Button:
|
||||
text: 'W'
|
||||
on_press: root.parent.key_pressed('w') if root.parent and hasattr(root.parent, 'key_pressed') else None
|
||||
Button:
|
||||
text: 'E'
|
||||
on_press: root.parent.key_pressed('e') if root.parent and hasattr(root.parent, 'key_pressed') else None
|
||||
Button:
|
||||
text: 'R'
|
||||
on_press: root.parent.key_pressed('r') if root.parent and hasattr(root.parent, 'key_pressed') else None
|
||||
Button:
|
||||
text: 'T'
|
||||
on_press: root.parent.key_pressed('t') if root.parent and hasattr(root.parent, 'key_pressed') else None
|
||||
Button:
|
||||
text: 'Y'
|
||||
on_press: root.parent.key_pressed('y') if root.parent and hasattr(root.parent, 'key_pressed') else None
|
||||
Button:
|
||||
text: 'U'
|
||||
on_press: root.parent.key_pressed('u') if root.parent and hasattr(root.parent, 'key_pressed') else None
|
||||
Button:
|
||||
text: 'I'
|
||||
on_press: root.parent.key_pressed('i') if root.parent and hasattr(root.parent, 'key_pressed') else None
|
||||
Button:
|
||||
text: 'O'
|
||||
on_press: root.parent.key_pressed('o') if root.parent and hasattr(root.parent, 'key_pressed') else None
|
||||
Button:
|
||||
text: 'P'
|
||||
on_press: root.parent.key_pressed('p') if root.parent and hasattr(root.parent, 'key_pressed') else None
|
||||
|
||||
# Middle letter row (ASDFGHJKL)
|
||||
BoxLayout:
|
||||
size_hint: 1, 1
|
||||
spacing: dp(3)
|
||||
Widget:
|
||||
size_hint: 0.5, 1
|
||||
Button:
|
||||
text: 'A'
|
||||
on_press: root.parent.key_pressed('a') if root.parent and hasattr(root.parent, 'key_pressed') else None
|
||||
Button:
|
||||
text: 'S'
|
||||
on_press: root.parent.key_pressed('s') if root.parent and hasattr(root.parent, 'key_pressed') else None
|
||||
Button:
|
||||
text: 'D'
|
||||
on_press: root.parent.key_pressed('d') if root.parent and hasattr(root.parent, 'key_pressed') else None
|
||||
Button:
|
||||
text: 'F'
|
||||
on_press: root.parent.key_pressed('f') if root.parent and hasattr(root.parent, 'key_pressed') else None
|
||||
Button:
|
||||
text: 'G'
|
||||
on_press: root.parent.key_pressed('g') if root.parent and hasattr(root.parent, 'key_pressed') else None
|
||||
Button:
|
||||
text: 'H'
|
||||
on_press: root.parent.key_pressed('h') if root.parent and hasattr(root.parent, 'key_pressed') else None
|
||||
Button:
|
||||
text: 'J'
|
||||
on_press: root.parent.key_pressed('j') if root.parent and hasattr(root.parent, 'key_pressed') else None
|
||||
Button:
|
||||
text: 'K'
|
||||
on_press: root.parent.key_pressed('k') if root.parent and hasattr(root.parent, 'key_pressed') else None
|
||||
Button:
|
||||
text: 'L'
|
||||
on_press: root.parent.key_pressed('l') if root.parent and hasattr(root.parent, 'key_pressed') else None
|
||||
Widget:
|
||||
size_hint: 0.5, 1
|
||||
|
||||
# Bottom letter row (ZXCVBNM)
|
||||
BoxLayout:
|
||||
size_hint: 1, 1
|
||||
spacing: dp(3)
|
||||
Widget:
|
||||
size_hint: 1, 1
|
||||
Button:
|
||||
text: 'Z'
|
||||
on_press: root.parent.key_pressed('z') if root.parent and hasattr(root.parent, 'key_pressed') else None
|
||||
Button:
|
||||
text: 'X'
|
||||
on_press: root.parent.key_pressed('x') if root.parent and hasattr(root.parent, 'key_pressed') else None
|
||||
Button:
|
||||
text: 'C'
|
||||
on_press: root.parent.key_pressed('c') if root.parent and hasattr(root.parent, 'key_pressed') else None
|
||||
Button:
|
||||
text: 'V'
|
||||
on_press: root.parent.key_pressed('v') if root.parent and hasattr(root.parent, 'key_pressed') else None
|
||||
Button:
|
||||
text: 'B'
|
||||
on_press: root.parent.key_pressed('b') if root.parent and hasattr(root.parent, 'key_pressed') else None
|
||||
Button:
|
||||
text: 'N'
|
||||
on_press: root.parent.key_pressed('n') if root.parent and hasattr(root.parent, 'key_pressed') else None
|
||||
Button:
|
||||
text: 'M'
|
||||
on_press: root.parent.key_pressed('m') if root.parent and hasattr(root.parent, 'key_pressed') else None
|
||||
Widget:
|
||||
size_hint: 1, 1
|
||||
|
||||
# Bottom row (Space, Backspace)
|
||||
BoxLayout:
|
||||
size_hint: 1, 1
|
||||
spacing: dp(3)
|
||||
Button:
|
||||
text: '←'
|
||||
size_hint: 0.3, 1
|
||||
font_size: sp(24)
|
||||
on_press: root.parent.key_pressed('backspace') if root.parent and hasattr(root.parent, 'key_pressed') else None
|
||||
Button:
|
||||
text: 'Space'
|
||||
size_hint: 0.7, 1
|
||||
on_press: root.parent.key_pressed(' ') if root.parent and hasattr(root.parent, 'key_pressed') else None
|
||||
|
||||
<SignagePlayer@FloatLayout>:
|
||||
size: root.screen_width, root.screen_height
|
||||
canvas.before:
|
||||
@@ -126,6 +314,9 @@
|
||||
font_size: sp(16)
|
||||
size_hint_y: None
|
||||
height: dp(40)
|
||||
write_tab: False
|
||||
readonly: True
|
||||
on_focus: root.on_input_focus(self, self.focus)
|
||||
|
||||
Label:
|
||||
id: error_label
|
||||
@@ -180,6 +371,8 @@
|
||||
size_hint_x: 0.7
|
||||
multiline: False
|
||||
font_size: sp(14)
|
||||
write_tab: False
|
||||
on_touch_down: root.on_input_touch(self, args[1]) if self.collide_point(*args[1].pos) else None
|
||||
|
||||
# Screen name
|
||||
BoxLayout:
|
||||
@@ -200,6 +393,8 @@
|
||||
size_hint_x: 0.7
|
||||
multiline: False
|
||||
font_size: sp(14)
|
||||
write_tab: False
|
||||
on_touch_down: root.on_input_touch(self, args[1]) if self.collide_point(*args[1].pos) else None
|
||||
|
||||
# Quickconnect key
|
||||
BoxLayout:
|
||||
@@ -220,6 +415,8 @@
|
||||
size_hint_x: 0.7
|
||||
multiline: False
|
||||
font_size: sp(14)
|
||||
write_tab: False
|
||||
on_touch_down: root.on_input_touch(self, args[1]) if self.collide_point(*args[1].pos) else None
|
||||
|
||||
# Orientation
|
||||
BoxLayout:
|
||||
@@ -240,6 +437,8 @@
|
||||
size_hint_x: 0.7
|
||||
multiline: False
|
||||
font_size: sp(14)
|
||||
write_tab: False
|
||||
on_touch_down: root.on_input_touch(self, args[1]) if self.collide_point(*args[1].pos) else None
|
||||
|
||||
# Touch
|
||||
BoxLayout:
|
||||
@@ -260,6 +459,8 @@
|
||||
size_hint_x: 0.7
|
||||
multiline: False
|
||||
font_size: sp(14)
|
||||
write_tab: False
|
||||
on_touch_down: root.on_input_touch(self, args[1]) if self.collide_point(*args[1].pos) else None
|
||||
|
||||
# Resolution
|
||||
BoxLayout:
|
||||
@@ -281,6 +482,8 @@
|
||||
multiline: False
|
||||
font_size: sp(14)
|
||||
hint_text: '1920x1080 or auto'
|
||||
write_tab: False
|
||||
on_touch_down: root.on_input_touch(self, args[1]) if self.collide_point(*args[1].pos) else None
|
||||
|
||||
Widget:
|
||||
size_hint_y: 0.05
|
||||
|
||||
Reference in New Issue
Block a user