Skip to content

Commit cd9db28

Browse files
committed
feat(language): implement language menu and keyboard layout switching
- Added functionality to toggle a language menu for available keyboard layouts.
1 parent a7fbdba commit cd9db28

4 files changed

Lines changed: 469 additions & 11 deletions

File tree

126 KB
Loading

docs/widgets/(Widget)-Language.md

Lines changed: 117 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,35 @@
99
| `container_padding` | dict | `{'top': 0, 'left': 0, 'bottom': 0, 'right': 0}` | Explicitly set padding inside widget container. |
1010
| `container_shadow` | dict | `None` | Container shadow options. |
1111
| `label_shadow` | dict | `None` | Label shadow options. |
12+
| `language_menu` | dict | [See below](#language-menu-configuration) | Options for the language menu. |
1213

13-
## Example Configuration
14+
## Callbacks
15+
The `callbacks` option allows you to define custom actions for mouse events on the widget. The keys are:
16+
- `on_left`: Action when the left mouse button is clicked.
17+
- `on_middle`: Action when the middle mouse button is clicked.
18+
- `on_right`: Action when the right mouse button is clicked.
19+
- The values are the names of the callback functions that will be executed when the respective mouse button is clicked.
20+
- `toggle_label`: A function to toggle the label between the main and alternative formats.
21+
- `toggle_menu`: A function to toggle the visibility of the language selection menu.
22+
- `do_nothing`: A placeholder function that does nothing when the mouse button is clicked.
23+
24+
## Language Menu Configuration
25+
The `language_menu` option allows you to configure the popup menu for language selection. It accepts the following keys:
26+
27+
| Option | Type | Default | Description |
28+
|---------------------|----------|--------------|-----------------------------------------------------------------------------|
29+
| `blur` | boolean | `true` | Enables a blur effect in the menu popup. |
30+
| `round_corners` | boolean | `true` | If `true`, the menu has rounded corners. |
31+
| `round_corners_type`| string | `"normal"` | Determines the corner style; allowed values are `normal` and `small`. |
32+
| `border_color` | string | `"system"` | Sets the border color for the menu. Can be `"system"`, `None` or HEX color. |
33+
| `alignment` | string | `"right"` | Horizontal alignment of the menu relative to the widget (`left`, `right`, `center`). |
34+
| `direction` | string | `"down"` | Direction in which the menu opens (`down` or `up`). |
35+
| `offset_top` | integer | `6` | Vertical offset for fine positioning of the menu. |
36+
| `offset_left` | integer | `0` | Horizontal offset for fine positioning of the menu. |
37+
| `layout_icon` | string | `"\uf11c"` | Icon displayed next to layout names in the menu. |
38+
| `show_layout_icon` | boolean | `true` | Whether to show the layout icon next to each language entry. |
1439

40+
## Example Configuration
1541
```yaml
1642
language:
1743
type: "yasb.language.LanguageWidget"
@@ -20,9 +46,20 @@ language:
2046
label_alt: "{lang[full_name]}"
2147
update_interval: 5
2248
callbacks:
23-
on_left: "toggle_label"
49+
on_left: "toggle_menu"
2450
on_middle: "do_nothing"
25-
on_right: "do_nothing"
51+
on_right: "toggle_label"
52+
language_menu:
53+
blur: true
54+
round_corners: true
55+
round_corners_type: "normal"
56+
border_color: "system"
57+
alignment: "right"
58+
direction: "down"
59+
offset_top: 6
60+
offset_left: 0
61+
show_layout_icon: true
62+
layout_icon: "\uf11c"
2663
label_shadow:
2764
enabled: true
2865
color: "black"
@@ -39,6 +76,7 @@ language:
3976
- **container_padding**: Explicitly set padding inside widget container. Use this option to set padding inside the widget container. You can set padding for top, left, bottom and right sides of the widget container.
4077
- **container_shadow:** Container shadow options.
4178
- **label_shadow:** Label shadow options.
79+
- **language_menu:** A dictionary containing options for the language selection menu. It includes options like `blur`, `round_corners`, `round_corners_type`, `border_color`, `alignment`, `direction`, `offset_top`, `offset_left`, `layout_icon`, and `show_layout_icon`.
4280

4381
## Example Style
4482
```css
@@ -47,4 +85,79 @@ language:
4785
.language-widget .label {}
4886
.language-widget .label.alt {}
4987
.language-widget .icon {}
50-
```
88+
/* Language Menu */
89+
.language-menu {}
90+
.language-menu .header {}
91+
.language-menu .footer {}
92+
.language-menu .language-item {}
93+
.language-menu .language-item.active {}
94+
.language-menu .language-item .code {}
95+
.language-menu .language-item .name {}
96+
.language-menu .language-item .layout {}
97+
98+
```
99+
100+
## Example Style for Menu
101+
```css
102+
.language-menu {
103+
background-color: rgba(17, 17, 27, 0.4);
104+
min-width: 300px;
105+
}
106+
.language-menu .header {
107+
font-family: 'Segoe UI';
108+
font-size: 14px;
109+
font-weight: 600;
110+
margin-bottom: 2px;
111+
padding: 12px;
112+
background-color: rgba(17, 17, 27, 0.6);
113+
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
114+
}
115+
.language-menu .footer {
116+
font-family: 'Segoe UI';
117+
font-size: 12px;
118+
font-weight: 600;
119+
padding: 12px;
120+
margin-top: 2px;
121+
color: #9399b2;
122+
background-color: rgba(17, 17, 27, 0.6);
123+
border-top: 1px solid rgba(255, 255, 255, 0.1);
124+
}
125+
.language-menu .footer:hover {
126+
background-color: rgba(36, 36, 51, 0.6);
127+
color: #fff;
128+
}
129+
.language-menu .language-item {
130+
padding: 6px 12px;
131+
margin: 2px 4px;
132+
}
133+
.language-menu .language-item.active {
134+
background-color:rgba(255, 255, 255, 0.1);
135+
border-radius: 4px;
136+
}
137+
.language-menu .language-item:hover {
138+
background-color: rgba(255, 255, 255, 0.05);
139+
}
140+
.language-menu .language-item.active:hover {
141+
background-color:rgba(255, 255, 255, 0.1);
142+
border-radius: 4px;
143+
}
144+
.language-menu .language-item .code {
145+
font-weight: 900;
146+
font-size: 14px;
147+
min-width: 40px;
148+
text-transform: uppercase;
149+
}
150+
.language-menu .language-item .name {
151+
font-weight: 600;
152+
font-family: 'Segoe UI';
153+
font-size: 14px;
154+
}
155+
.language-menu .language-item .layout {
156+
font-weight: 600;
157+
font-family: 'Segoe UI';
158+
font-size: 12px;
159+
}
160+
```
161+
162+
## Preview of the Widget
163+
![GitHub YASB Widget](assets/6b646834-fc98abfe-b297-ce61-4bce3683223c.png)

src/core/validation/widgets/yasb/language.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,18 @@
88
'duration': 200
99
},
1010
'container_padding': {'top': 0, 'left': 0, 'bottom': 0, 'right': 0},
11+
'language_menu': {
12+
'blur': True,
13+
'round_corners': True,
14+
'round_corners_type': 'normal',
15+
'border_color': 'system',
16+
'alignment': 'right',
17+
'direction': 'down',
18+
'offset_top': 6,
19+
'offset_left': 0,
20+
'layout_icon': '\uf11c',
21+
'show_layout_icon': True
22+
},
1123
'callbacks': {
1224
'on_left': 'toggle_label',
1325
'on_middle': 'do_nothing',
@@ -94,6 +106,53 @@
94106
},
95107
'default': {'enabled': False, 'color': 'black', 'offset': [1, 1], 'radius': 3}
96108
},
109+
'language_menu': {
110+
'type': 'dict',
111+
'required': False,
112+
'schema': {
113+
'blur': {
114+
'type': 'boolean',
115+
'default': DEFAULTS['language_menu']['blur']
116+
},
117+
'round_corners': {
118+
'type': 'boolean',
119+
'default': DEFAULTS['language_menu']['round_corners']
120+
},
121+
'round_corners_type': {
122+
'type': 'string',
123+
'default': DEFAULTS['language_menu']['round_corners_type']
124+
},
125+
'border_color': {
126+
'type': 'string',
127+
'default': DEFAULTS['language_menu']['border_color']
128+
},
129+
'alignment': {
130+
'type': 'string',
131+
'default': DEFAULTS['language_menu']['alignment']
132+
},
133+
'direction': {
134+
'type': 'string',
135+
'default': DEFAULTS['language_menu']['direction']
136+
},
137+
'offset_top': {
138+
'type': 'integer',
139+
'default': DEFAULTS['language_menu']['offset_top']
140+
},
141+
'offset_left': {
142+
'type': 'integer',
143+
'default': DEFAULTS['language_menu']['offset_left']
144+
},
145+
'layout_icon': {
146+
'type': 'string',
147+
'default': DEFAULTS['language_menu']['layout_icon']
148+
},
149+
'show_layout_icon': {
150+
'type': 'boolean',
151+
'default': DEFAULTS['language_menu']['show_layout_icon']
152+
}
153+
},
154+
'default': DEFAULTS['language_menu']
155+
},
97156
'callbacks': {
98157
'type': 'dict',
99158
'schema': {

0 commit comments

Comments
 (0)