tangled
alpha
login
or
join now
lesbian.skin
/
nanel
1
fork
atom
[MIRROR] https://codeberg.org/naomi/nanel
1
fork
atom
overview
issues
pulls
pipelines
Refactor Modules into own mod
lesbian.skin
1 year ago
b3cd04cd
4b55b4b6
+403
-301
6 changed files
expand all
collapse all
unified
split
examples
default.toml
src
config.rs
main.rs
modules.rs
panel.rs
styles.rs
+1
-1
examples/default.toml
···
21
21
name = "quick_settings"
22
22
show_connection = true # Default `true`
23
23
show_volume = true # Default `true`
24
24
-
show_power = false # Default `false`
24
24
+
show_power = true # Default `false`
25
25
26
26
[[modules.right]]
27
27
name = "date_time"
+16
-46
src/config.rs
···
1
1
-
use std::path::PathBuf;
2
2
-
3
1
// use iced::Theme;
4
2
use serde::Deserialize;
3
3
+
4
4
+
pub const BUTTON_SIZE: f32 = 40.0;
5
5
+
pub const BUTTON_PADDING: u16 = 6;
6
6
+
pub const GAP: u16 = 4;
7
7
+
pub const CORNER_RADIUS: u16 = 8;
5
8
6
9
#[derive(Default, Deserialize, Debug)]
7
10
pub enum Position {
···
20
23
All,
21
24
}
22
25
23
23
-
impl Monitor {
24
24
-
pub fn from_str(string: &str) -> Monitor {
25
25
-
match string {
26
26
-
"all" => Monitor::All,
27
27
-
_ => Monitor::Single(String::from(string)),
28
28
-
}
29
29
-
}
30
30
-
}
26
26
+
// impl Monitor {
27
27
+
// pub fn from_str(string: &str) -> Monitor {
28
28
+
// match string {
29
29
+
// "all" => Monitor::All,
30
30
+
// _ => Monitor::Single(String::from(string)),
31
31
+
// }
32
32
+
// }
33
33
+
// }
31
34
32
35
#[derive(Default, Deserialize, Debug)]
33
33
-
pub struct Modules {
36
36
+
pub struct Modules<Module> {
34
37
pub left: Option<Vec<Module>>,
35
38
pub middle: Option<Vec<Module>>,
36
39
pub right: Option<Vec<Module>>,
37
40
}
38
41
39
42
#[derive(Default, Deserialize, Debug)]
40
40
-
pub struct Config {
43
43
+
pub struct Config<Module> {
41
44
pub position: Position,
42
45
pub monitor: Monitor,
43
46
// pub theme: Theme,
44
44
-
pub modules: Modules,
47
47
+
pub modules: Modules<Module>,
45
48
}
46
49
47
50
// pub fn theme_from_str(string: &str) -> Theme {
···
57
60
Dotted,
58
61
Handle,
59
62
}
60
60
-
61
61
-
#[derive(Deserialize, Debug)]
62
62
-
pub struct Module {
63
63
-
pub name: String,
64
64
-
/// Used in: `directory_menu`
65
65
-
pub root: Option<PathBuf>,
66
66
-
/// Used in: `vertical_seperator`, `horizonal_seperator`
67
67
-
pub style: Option<SeperatorStyle>,
68
68
-
/// Used in: `taskbar`
69
69
-
pub merge_windows: Option<bool>,
70
70
-
/// Used in: `taskbar`
71
71
-
pub merge_pinned: Option<bool>,
72
72
-
/// Used in: `system_tray`
73
73
-
pub hidden_menu: Option<bool>,
74
74
-
/// Used in: `quick_settings`
75
75
-
pub show_connection: Option<bool>,
76
76
-
/// Used in: `quick_settings`
77
77
-
pub show_volume: Option<bool>,
78
78
-
/// Used in: `quick_settings`
79
79
-
pub show_power: Option<bool>,
80
80
-
/// Used in: `date_time`
81
81
-
pub calendar: Option<bool>,
82
82
-
/// Used in: `date_time`
83
83
-
pub mm_dd_yyyy: Option<bool>,
84
84
-
/// Used in: `date_time`
85
85
-
pub military: Option<bool>,
86
86
-
/// Used in: `date_time`
87
87
-
pub seconds: Option<bool>,
88
88
-
/// Used in: `view_desktop`
89
89
-
pub show_on_hover: Option<bool>,
90
90
-
/// Used in: `view_desktop`
91
91
-
pub thin: Option<bool>,
92
92
-
}
+2
src/main.rs
···
5
5
6
6
mod config;
7
7
mod icons;
8
8
+
mod modules;
8
9
mod panel;
10
10
+
mod styles;
9
11
10
12
#[derive(Parser)]
11
13
#[command(version, about, long_about = None)]
+271
src/modules.rs
···
1
1
+
use std::path::PathBuf;
2
2
+
3
3
+
use chrono::{DateTime, Datelike, Local, Timelike};
4
4
+
use iced::{
5
5
+
Alignment, Element, Length,
6
6
+
widget::{button, column, container, row, text, tooltip},
7
7
+
};
8
8
+
use serde::Deserialize;
9
9
+
10
10
+
use crate::{
11
11
+
config::{BUTTON_PADDING, BUTTON_SIZE, SeperatorStyle},
12
12
+
icons::{
13
13
+
angle_up_solid, bars_solid, battery_full_solid, bell_regular, desktop_solid, folder_solid,
14
14
+
layer_group_solid, volume_high_solid, wifi_solid,
15
15
+
},
16
16
+
panel::label,
17
17
+
styles::{rounded_container, solid, transparent},
18
18
+
};
19
19
+
20
20
+
#[derive(Deserialize, Debug, Default)]
21
21
+
pub struct Module {
22
22
+
pub name: String,
23
23
+
/// Used in: `directory_menu`
24
24
+
pub root: Option<PathBuf>,
25
25
+
/// Used in: `vertical_seperator`, `horizonal_seperator`
26
26
+
pub style: Option<SeperatorStyle>,
27
27
+
/// Used in: `taskbar`
28
28
+
pub merge_windows: Option<bool>,
29
29
+
/// Used in: `taskbar`
30
30
+
pub merge_pinned: Option<bool>,
31
31
+
/// Used in: `system_tray`
32
32
+
pub hidden_menu: Option<bool>,
33
33
+
/// Used in: `quick_settings`
34
34
+
pub show_connection: Option<bool>,
35
35
+
/// Used in: `quick_settings`
36
36
+
pub show_volume: Option<bool>,
37
37
+
/// Used in: `quick_settings`
38
38
+
pub show_power: Option<bool>,
39
39
+
/// Used in: `date_time`
40
40
+
pub calendar: Option<bool>,
41
41
+
/// Used in: `date_time`
42
42
+
pub mm_dd_yyyy: Option<bool>,
43
43
+
/// Used in: `date_time`
44
44
+
pub military: Option<bool>,
45
45
+
/// Used in: `date_time`
46
46
+
pub seconds: Option<bool>,
47
47
+
/// Used in: `view_desktop`
48
48
+
pub show_on_hover: Option<bool>,
49
49
+
/// Used in: `view_desktop`
50
50
+
pub thin: Option<bool>,
51
51
+
}
52
52
+
53
53
+
impl Module {
54
54
+
pub fn get_connection<Message>(&self) -> Option<Element<'static, Message>> {
55
55
+
match self.show_connection.unwrap_or(true) {
56
56
+
true => Some(wifi_solid().size(16).into()),
57
57
+
false => None,
58
58
+
}
59
59
+
}
60
60
+
61
61
+
pub fn get_volume<Message>(&self) -> Option<Element<'static, Message>> {
62
62
+
match self.show_volume.unwrap_or(true) {
63
63
+
true => Some(volume_high_solid().size(16).into()),
64
64
+
false => None,
65
65
+
}
66
66
+
}
67
67
+
68
68
+
pub fn get_power<Message>(&self) -> Option<Element<'static, Message>> {
69
69
+
match self.show_power.unwrap_or(false) {
70
70
+
true => Some(battery_full_solid().size(16).into()),
71
71
+
false => None,
72
72
+
}
73
73
+
}
74
74
+
}
75
75
+
76
76
+
pub fn start_menu<Message>(message: Message) -> Element<'static, Message>
77
77
+
where
78
78
+
Message: Clone + 'static,
79
79
+
{
80
80
+
button(bars_solid())
81
81
+
.width(BUTTON_SIZE)
82
82
+
.height(BUTTON_SIZE)
83
83
+
.padding(BUTTON_PADDING)
84
84
+
.on_press(message)
85
85
+
.style(transparent)
86
86
+
.into()
87
87
+
}
88
88
+
89
89
+
pub fn workspaces<Message>(message: Message) -> Element<'static, Message>
90
90
+
where
91
91
+
Message: Clone + 'static,
92
92
+
{
93
93
+
button(layer_group_solid())
94
94
+
.width(BUTTON_SIZE)
95
95
+
.height(BUTTON_SIZE)
96
96
+
.padding(BUTTON_PADDING)
97
97
+
.on_press(message)
98
98
+
.style(transparent)
99
99
+
.into()
100
100
+
}
101
101
+
102
102
+
pub fn directory_menu<Message>(message: Message) -> Element<'static, Message>
103
103
+
where
104
104
+
Message: Clone + 'static,
105
105
+
{
106
106
+
button(folder_solid())
107
107
+
.height(BUTTON_SIZE)
108
108
+
.padding(BUTTON_PADDING)
109
109
+
.on_press(message)
110
110
+
.style(transparent)
111
111
+
.into()
112
112
+
}
113
113
+
114
114
+
pub fn system_tray<Message>(message: Message, hidden_menu: bool) -> Element<'static, Message>
115
115
+
where
116
116
+
Message: Clone + 'static,
117
117
+
{
118
118
+
match hidden_menu {
119
119
+
false => text!("TODO: systray").into(),
120
120
+
true => tooltip(
121
121
+
button(angle_up_solid().size(16))
122
122
+
.height(BUTTON_SIZE)
123
123
+
.padding(BUTTON_PADDING)
124
124
+
.on_press(message)
125
125
+
.style(transparent),
126
126
+
container("Show hidden icons")
127
127
+
.padding(BUTTON_PADDING)
128
128
+
.style(rounded_container),
129
129
+
tooltip::Position::Left,
130
130
+
)
131
131
+
.snap_within_viewport(false)
132
132
+
.into(),
133
133
+
}
134
134
+
}
135
135
+
136
136
+
pub fn notification_tray<Message>(message: Message) -> Element<'static, Message>
137
137
+
where
138
138
+
Message: Clone + 'static,
139
139
+
{
140
140
+
button(bell_regular().size(16))
141
141
+
.height(BUTTON_SIZE)
142
142
+
.padding(BUTTON_PADDING)
143
143
+
.on_press(message)
144
144
+
.style(transparent)
145
145
+
.into()
146
146
+
}
147
147
+
148
148
+
pub fn quick_settings<Message>(
149
149
+
message: Message,
150
150
+
connection: Option<Element<'static, Message>>,
151
151
+
volume: Option<Element<'static, Message>>,
152
152
+
power: Option<Element<'static, Message>>,
153
153
+
) -> Element<'static, Message>
154
154
+
where
155
155
+
Message: Clone + 'static,
156
156
+
{
157
157
+
button(
158
158
+
row![]
159
159
+
.push_maybe(connection)
160
160
+
.push_maybe(volume)
161
161
+
.push_maybe(power)
162
162
+
.spacing(6)
163
163
+
.align_y(Alignment::Center)
164
164
+
.height(Length::Fill),
165
165
+
)
166
166
+
.height(BUTTON_SIZE)
167
167
+
.padding(BUTTON_PADDING)
168
168
+
.on_press(message)
169
169
+
.style(transparent)
170
170
+
.into()
171
171
+
}
172
172
+
173
173
+
fn get_time(
174
174
+
time: DateTime<Local>,
175
175
+
mm_dd_yyyy: bool,
176
176
+
military: bool,
177
177
+
seconds: bool,
178
178
+
) -> (String, String) {
179
179
+
let dd = time.day();
180
180
+
let dd = match dd {
181
181
+
x if x <= 9 => format!("0{}", x),
182
182
+
x => format!("{}", x),
183
183
+
};
184
184
+
let mm = time.month();
185
185
+
let mm = match mm {
186
186
+
x if x <= 9 => format!("0{}", x),
187
187
+
x => format!("{}", x),
188
188
+
};
189
189
+
let yyyy = time.year();
190
190
+
191
191
+
let date = match mm_dd_yyyy {
192
192
+
true => format!(" {}/{}/{} ", mm, dd, yyyy),
193
193
+
false => format!(" {}/{}/{} ", dd, mm, yyyy),
194
194
+
};
195
195
+
196
196
+
let h = time.hour();
197
197
+
let h = if military {
198
198
+
h
199
199
+
} else {
200
200
+
if h > 12 { h - 12 } else { h }
201
201
+
};
202
202
+
let h = match h {
203
203
+
x if x <= 9 => format!("0{}", x),
204
204
+
x => format!("{}", x),
205
205
+
};
206
206
+
let m = time.minute();
207
207
+
let m = match m {
208
208
+
x if x <= 9 => format!("0{}", x),
209
209
+
x => format!("{}", x),
210
210
+
};
211
211
+
let s = time.second();
212
212
+
let s = match s {
213
213
+
x if x <= 9 => format!("0{}", x),
214
214
+
x => format!("{}", x),
215
215
+
};
216
216
+
217
217
+
let time = match seconds {
218
218
+
true => format!(" {}:{}:{} ", h, m, s),
219
219
+
false => format!(" {}:{} ", h, m),
220
220
+
};
221
221
+
222
222
+
(date, time)
223
223
+
}
224
224
+
225
225
+
pub fn date_time<Message>(
226
226
+
message: Message,
227
227
+
datetime: DateTime<Local>,
228
228
+
mm_dd_yyyy: bool,
229
229
+
military: bool,
230
230
+
seconds: bool,
231
231
+
) -> Element<'static, Message>
232
232
+
where
233
233
+
Message: Clone + 'static,
234
234
+
{
235
235
+
let (date, time) = get_time(datetime, mm_dd_yyyy, military, seconds);
236
236
+
button(
237
237
+
column![label(time.as_str()), label(date.as_str())]
238
238
+
.clip(false)
239
239
+
.align_x(Alignment::End),
240
240
+
)
241
241
+
.padding(1) // Higher padding makes text clip right now
242
242
+
.height(BUTTON_SIZE)
243
243
+
.on_press(message)
244
244
+
.style(transparent)
245
245
+
.into()
246
246
+
}
247
247
+
248
248
+
pub fn view_desktop<Message>(message: Message, thin: bool) -> Element<'static, Message>
249
249
+
where
250
250
+
Message: Clone + 'static,
251
251
+
{
252
252
+
match thin {
253
253
+
true => button(
254
254
+
text("|")
255
255
+
.align_x(Alignment::Center)
256
256
+
.align_y(Alignment::Center),
257
257
+
)
258
258
+
.width(Length::Shrink)
259
259
+
.height(BUTTON_SIZE)
260
260
+
.padding(2) // Higher padding is too thick
261
261
+
.on_press(message)
262
262
+
.style(transparent)
263
263
+
.into(),
264
264
+
false => button(desktop_solid())
265
265
+
.height(BUTTON_SIZE)
266
266
+
.padding(BUTTON_PADDING)
267
267
+
.on_press(message)
268
268
+
.style(solid)
269
269
+
.into(),
270
270
+
}
271
271
+
}
+49
-254
src/panel.rs
···
1
1
use chrono::prelude::*;
2
2
3
3
use iced::{
4
4
-
Alignment, Background, Element, Font, Length, Subscription, Task, Theme, border,
5
5
-
theme::palette::{self},
6
6
-
time,
7
7
-
widget::{Text, button, column, container, row, text, tooltip, vertical_rule},
4
4
+
Alignment, Element, Font, Length, Subscription, Task, Theme, time,
5
5
+
widget::{Text, row, text, vertical_rule},
8
6
};
9
7
use iced_layershell::{
10
8
Application,
···
16
14
// use wayland_client::{protocol::wl_registry, Connection, Dispatch, EventQueue};
17
15
18
16
use crate::{
19
19
-
config::{Config, Module},
20
20
-
icons::{
21
21
-
angle_up_solid, bars_solid, battery_full_solid, bell_regular, desktop_solid, folder_solid,
22
22
-
layer_group_solid, volume_high_solid, wifi_solid,
17
17
+
config::{BUTTON_SIZE, Config, GAP},
18
18
+
modules::{
19
19
+
Module, date_time, directory_menu, notification_tray, quick_settings, start_menu,
20
20
+
system_tray, view_desktop, workspaces,
23
21
},
24
22
};
25
25
-
26
26
-
const BUTTON_SIZE: f32 = 40.0;
27
27
-
const BUTTON_PADDING: u16 = 6;
28
28
-
const GAP: u16 = 4;
29
29
-
const CORNER_RADIUS: u16 = 8;
30
23
31
24
pub struct Nanel {
32
32
-
pub config: Config,
25
25
+
pub config: Config<Module>,
33
26
pub datetime: DateTime<Local>,
34
27
}
35
28
···
54
47
.align_y(Alignment::Center)
55
48
}
56
49
57
57
-
pub fn rounded_container(theme: &Theme) -> container::Style {
58
58
-
let palette = theme.extended_palette();
59
59
-
60
60
-
container::Style {
61
61
-
background: Some(palette.background.weak.color.into()),
62
62
-
border: border::rounded(CORNER_RADIUS),
63
63
-
..container::Style::default()
64
64
-
}
65
65
-
}
66
66
-
67
67
-
fn styled(pair: palette::Pair) -> button::Style {
68
68
-
button::Style {
69
69
-
background: Some(Background::Color(pair.color)),
70
70
-
text_color: pair.text,
71
71
-
border: border::rounded(CORNER_RADIUS),
72
72
-
..button::Style::default()
73
73
-
}
74
74
-
}
75
75
-
76
76
-
fn disabled(style: button::Style) -> button::Style {
77
77
-
button::Style {
78
78
-
background: style
79
79
-
.background
80
80
-
.map(|background| background.scale_alpha(0.5)),
81
81
-
text_color: style.text_color.scale_alpha(0.5),
82
82
-
..style
83
83
-
}
84
84
-
}
85
85
-
86
86
-
pub fn solid(theme: &Theme, status: button::Status) -> button::Style {
87
87
-
let palette = theme.extended_palette();
88
88
-
let base = styled(palette.primary.strong);
89
89
-
90
90
-
match status {
91
91
-
button::Status::Active | button::Status::Pressed => base,
92
92
-
button::Status::Hovered => button::Style {
93
93
-
background: Some(Background::Color(palette.primary.base.color)),
94
94
-
..base
95
95
-
},
96
96
-
button::Status::Disabled => disabled(base),
97
97
-
}
98
98
-
}
99
99
-
100
100
-
pub fn transparent(theme: &Theme, status: button::Status) -> button::Style {
101
101
-
let palette = theme.extended_palette();
102
102
-
let base = styled(palette.background.base);
103
103
-
104
104
-
match status {
105
105
-
button::Status::Active | button::Status::Pressed => base,
106
106
-
button::Status::Hovered => button::Style {
107
107
-
background: Some(Background::Color(palette.background.weak.color)),
108
108
-
..base
109
109
-
},
110
110
-
button::Status::Disabled => disabled(base),
111
111
-
}
112
112
-
}
113
113
-
114
114
-
impl Module {
115
115
-
pub fn get_time(&self, time: DateTime<Local>) -> (String, String) {
116
116
-
let dd = time.day();
117
117
-
let dd = match dd {
118
118
-
x if x <= 9 => format!("0{}", x),
119
119
-
x => format!("{}", x),
120
120
-
};
121
121
-
let mm = time.month();
122
122
-
let mm = match mm {
123
123
-
x if x <= 9 => format!("0{}", x),
124
124
-
x => format!("{}", x),
125
125
-
};
126
126
-
let yyyy = time.year();
127
127
-
128
128
-
let date = match self.mm_dd_yyyy.unwrap_or(false) {
129
129
-
true => format!(" {}/{}/{} ", mm, dd, yyyy),
130
130
-
false => format!(" {}/{}/{} ", dd, mm, yyyy),
131
131
-
};
132
132
-
133
133
-
let h = time.hour();
134
134
-
let h = if !self.military.unwrap_or(false) {
135
135
-
if h > 12 { h - 12 } else { h }
136
136
-
} else {
137
137
-
h
138
138
-
};
139
139
-
let h = match h {
140
140
-
x if x <= 9 => format!("0{}", x),
141
141
-
x => format!("{}", x),
142
142
-
};
143
143
-
let m = time.minute();
144
144
-
let m = match m {
145
145
-
x if x <= 9 => format!("0{}", x),
146
146
-
x => format!("{}", x),
147
147
-
};
148
148
-
let s = time.second();
149
149
-
let s = match s {
150
150
-
x if x <= 9 => format!("0{}", x),
151
151
-
x => format!("{}", x),
152
152
-
};
153
153
-
154
154
-
let time = match self.seconds.unwrap_or(false) {
155
155
-
true => format!(" {}:{}:{} ", h, m, s),
156
156
-
false => format!(" {}:{} ", h, m),
157
157
-
};
158
158
-
159
159
-
(date, time)
160
160
-
}
161
161
-
162
162
-
pub fn get_connection(&self) -> Option<Element<Message>> {
163
163
-
match self.show_connection.unwrap_or(true) {
164
164
-
true => Some(wifi_solid().size(16).into()),
165
165
-
false => None,
166
166
-
}
167
167
-
}
168
168
-
169
169
-
pub fn get_volume(&self) -> Option<Element<Message>> {
170
170
-
match self.show_volume.unwrap_or(true) {
171
171
-
true => Some(volume_high_solid().size(16).into()),
172
172
-
false => None,
173
173
-
}
174
174
-
}
175
175
-
176
176
-
pub fn get_power(&self) -> Option<Element<Message>> {
177
177
-
match self.show_power.unwrap_or(false) {
178
178
-
true => Some(battery_full_solid().size(16).into()),
179
179
-
false => None,
180
180
-
}
181
181
-
}
182
182
-
183
183
-
pub fn get_widget(&self, nanel: &Nanel) -> Option<Element<Message>> {
184
184
-
match self.name.as_str() {
185
185
-
"start_menu" => Some(
186
186
-
button(bars_solid())
187
187
-
.width(BUTTON_SIZE)
188
188
-
.height(BUTTON_SIZE)
189
189
-
.padding(BUTTON_PADDING)
190
190
-
.on_press(Message::UserOpenedStartMenu)
191
191
-
.style(transparent)
192
192
-
.into(),
193
193
-
),
194
194
-
"workspaces" => Some(
195
195
-
button(layer_group_solid())
196
196
-
.width(BUTTON_SIZE)
197
197
-
.height(BUTTON_SIZE)
198
198
-
.padding(BUTTON_PADDING)
199
199
-
.on_press(Message::UserOpenedWorkspaceMenu)
200
200
-
.style(transparent)
201
201
-
.into(),
202
202
-
),
203
203
-
"directory_menu" => Some(
204
204
-
button(folder_solid())
205
205
-
.height(BUTTON_SIZE)
206
206
-
.padding(BUTTON_PADDING)
207
207
-
.on_press(Message::UserOpenedDirectoryMenu)
208
208
-
.style(transparent)
209
209
-
.into(),
210
210
-
),
211
211
-
"vertical_seperator" => Some(vertical_rule(GAP).into()),
212
212
-
"taskbar" => Some(text!("TODO: taskbar").into()),
213
213
-
"system_tray" => Some(match self.hidden_menu.unwrap_or(false) {
214
214
-
false => text!("TODO: systray").into(),
215
215
-
true => tooltip(
216
216
-
button(angle_up_solid().size(16))
217
217
-
.height(BUTTON_SIZE)
218
218
-
.padding(BUTTON_PADDING)
219
219
-
.on_press(Message::UserOpenedSystrayMenu)
220
220
-
.style(transparent),
221
221
-
container("Show hidden icons")
222
222
-
.padding(BUTTON_PADDING)
223
223
-
.style(rounded_container),
224
224
-
tooltip::Position::Left,
225
225
-
)
226
226
-
.snap_within_viewport(false)
227
227
-
.into(),
228
228
-
}),
229
229
-
"notification_tray" => Some(
230
230
-
button(bell_regular().size(16))
231
231
-
.height(BUTTON_SIZE)
232
232
-
.padding(BUTTON_PADDING)
233
233
-
.on_press(Message::UserOpenedNotificationMenu)
234
234
-
.style(transparent)
235
235
-
.into(),
236
236
-
),
237
237
-
"quick_settings" => Some(
238
238
-
button(
239
239
-
row![]
240
240
-
.push_maybe(self.get_connection())
241
241
-
.push_maybe(self.get_volume())
242
242
-
.push_maybe(self.get_power())
243
243
-
.spacing(6)
244
244
-
.align_y(Alignment::Center)
245
245
-
.height(Length::Fill),
246
246
-
)
247
247
-
.height(BUTTON_SIZE)
248
248
-
.padding(BUTTON_PADDING)
249
249
-
.on_press(Message::UserOpenedNotificationMenu)
250
250
-
.style(transparent)
251
251
-
.into(),
252
252
-
),
253
253
-
"date_time" => {
254
254
-
let (date, time) = self.get_time(nanel.datetime);
255
255
-
Some(
256
256
-
button(
257
257
-
column![label(time.as_str()), label(date.as_str())]
258
258
-
.clip(false)
259
259
-
.align_x(Alignment::End),
260
260
-
)
261
261
-
.padding(1) // Higher padding makes text clip right now
262
262
-
.height(BUTTON_SIZE)
263
263
-
.on_press(Message::UserOpenedCalendarMenu)
264
264
-
.style(transparent)
265
265
-
.into(),
266
266
-
)
267
267
-
}
268
268
-
"view_desktop" => Some(match self.thin.unwrap_or(false) {
269
269
-
true => button(
270
270
-
text("|")
271
271
-
.align_x(Alignment::Center)
272
272
-
.align_y(Alignment::Center),
273
273
-
)
274
274
-
.width(Length::Shrink)
275
275
-
.height(BUTTON_SIZE)
276
276
-
.padding(2) // Higher padding is too thick
277
277
-
.on_press(Message::UserClickedShowDesktop)
278
278
-
.style(transparent)
279
279
-
.into(),
280
280
-
false => button(desktop_solid())
281
281
-
.height(BUTTON_SIZE)
282
282
-
.padding(BUTTON_PADDING)
283
283
-
.on_press(Message::UserClickedShowDesktop)
284
284
-
.style(solid)
285
285
-
.into(),
286
286
-
}),
287
287
-
_ => None,
288
288
-
}
289
289
-
}
290
290
-
}
291
291
-
292
50
impl Nanel {
293
51
fn left(&self) -> Element<Message> {
294
52
let mut widgets = vec![];
295
53
if let Some(modules) = &self.config.modules.left {
296
54
for module in modules.iter() {
297
297
-
if let Some(widget) = module.get_widget(self) {
55
55
+
if let Some(widget) = self.get_widget(module) {
298
56
widgets.push(widget);
299
57
}
300
58
}
···
306
64
let mut widgets = vec![row![].width(Length::Fill).into()];
307
65
if let Some(modules) = &self.config.modules.middle {
308
66
for module in modules.iter() {
309
309
-
if let Some(widget) = module.get_widget(self) {
67
67
+
if let Some(widget) = self.get_widget(module) {
310
68
widgets.push(widget);
311
69
}
312
70
}
···
319
77
let mut widgets = vec![];
320
78
if let Some(modules) = &self.config.modules.right {
321
79
for module in modules.iter() {
322
322
-
if let Some(widget) = module.get_widget(self) {
80
80
+
if let Some(widget) = self.get_widget(module) {
323
81
widgets.push(widget);
324
82
}
325
83
}
···
330
88
fn tick_time(&self) -> Subscription<Message> {
331
89
time::every(time::Duration::from_millis(200)).map(|_x| Message::PanelUpdatedTime)
332
90
}
91
91
+
92
92
+
pub fn get_widget(&self, module: &Module) -> Option<Element<Message>>
93
93
+
where
94
94
+
Message: Clone + 'static,
95
95
+
{
96
96
+
match module.name.as_str() {
97
97
+
"start_menu" => Some(start_menu(Message::UserOpenedStartMenu)),
98
98
+
"workspaces" => Some(workspaces(Message::UserOpenedWorkspaceMenu)),
99
99
+
"directory_menu" => Some(directory_menu(Message::UserOpenedDirectoryMenu)),
100
100
+
"vertical_seperator" => Some(vertical_rule(GAP).into()),
101
101
+
"taskbar" => Some(text!("TODO: taskbar").into()),
102
102
+
"system_tray" => Some(system_tray(
103
103
+
Message::UserOpenedSystrayMenu,
104
104
+
module.hidden_menu.unwrap_or(false),
105
105
+
)),
106
106
+
"notification_tray" => Some(notification_tray(Message::UserOpenedNotificationMenu)),
107
107
+
"quick_settings" => Some(quick_settings(
108
108
+
Message::UserOpenedQuickSettingsMenu,
109
109
+
module.get_connection(),
110
110
+
module.get_volume(),
111
111
+
module.get_power(),
112
112
+
)),
113
113
+
"date_time" => Some(date_time(
114
114
+
Message::UserOpenedCalendarMenu,
115
115
+
self.datetime,
116
116
+
module.mm_dd_yyyy.unwrap_or(false),
117
117
+
module.military.unwrap_or(false),
118
118
+
module.seconds.unwrap_or(false),
119
119
+
)),
120
120
+
121
121
+
"view_desktop" => Some(view_desktop(
122
122
+
Message::UserClickedShowDesktop,
123
123
+
module.thin.unwrap_or(false),
124
124
+
)),
125
125
+
_ => None,
126
126
+
}
127
127
+
}
333
128
}
334
129
335
130
impl Application for Nanel {
···
339
134
340
135
type Theme = Theme;
341
136
342
342
-
type Flags = Config;
137
137
+
type Flags = Config<Module>;
343
138
344
139
fn new(flags: Self::Flags) -> (Self, Task<Self::Message>) {
345
140
(
···
410
205
// }
411
206
// }
412
207
413
413
-
pub fn panel_main(config: Config) -> Result<(), iced_layershell::Error> {
208
208
+
pub fn panel_main(config: Config<Module>) -> Result<(), iced_layershell::Error> {
414
209
// thread::spawn(|| {
415
210
// let conn = Connection::connect_to_env().unwrap();
416
211
// let mut event_queue: EventQueue<WlrClientState> = conn.new_event_queue();
+64
src/styles.rs
···
1
1
+
use iced::{
2
2
+
Background, Theme, border,
3
3
+
theme::palette,
4
4
+
widget::{button, container},
5
5
+
};
6
6
+
7
7
+
use crate::config::CORNER_RADIUS;
8
8
+
9
9
+
pub fn rounded_container(theme: &Theme) -> container::Style {
10
10
+
let palette = theme.extended_palette();
11
11
+
12
12
+
container::Style {
13
13
+
background: Some(palette.background.weak.color.into()),
14
14
+
border: border::rounded(CORNER_RADIUS),
15
15
+
..container::Style::default()
16
16
+
}
17
17
+
}
18
18
+
19
19
+
fn styled(pair: palette::Pair) -> button::Style {
20
20
+
button::Style {
21
21
+
background: Some(Background::Color(pair.color)),
22
22
+
text_color: pair.text,
23
23
+
border: border::rounded(CORNER_RADIUS),
24
24
+
..button::Style::default()
25
25
+
}
26
26
+
}
27
27
+
28
28
+
fn disabled(style: button::Style) -> button::Style {
29
29
+
button::Style {
30
30
+
background: style
31
31
+
.background
32
32
+
.map(|background| background.scale_alpha(0.5)),
33
33
+
text_color: style.text_color.scale_alpha(0.5),
34
34
+
..style
35
35
+
}
36
36
+
}
37
37
+
38
38
+
pub fn solid(theme: &Theme, status: button::Status) -> button::Style {
39
39
+
let palette = theme.extended_palette();
40
40
+
let base = styled(palette.primary.strong);
41
41
+
42
42
+
match status {
43
43
+
button::Status::Active | button::Status::Pressed => base,
44
44
+
button::Status::Hovered => button::Style {
45
45
+
background: Some(Background::Color(palette.primary.base.color)),
46
46
+
..base
47
47
+
},
48
48
+
button::Status::Disabled => disabled(base),
49
49
+
}
50
50
+
}
51
51
+
52
52
+
pub fn transparent(theme: &Theme, status: button::Status) -> button::Style {
53
53
+
let palette = theme.extended_palette();
54
54
+
let base = styled(palette.background.base);
55
55
+
56
56
+
match status {
57
57
+
button::Status::Active | button::Status::Pressed => base,
58
58
+
button::Status::Hovered => button::Style {
59
59
+
background: Some(Background::Color(palette.background.weak.color)),
60
60
+
..base
61
61
+
},
62
62
+
button::Status::Disabled => disabled(base),
63
63
+
}
64
64
+
}