Skip to content

Commit 99306cb

Browse files
committed
initial commit
1 parent 2871309 commit 99306cb

File tree

3 files changed

+129
-10
lines changed

3 files changed

+129
-10
lines changed

src/mounter/gvfs.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ fn network_scan(uri: &str, sizes: IconSizes) -> Result<Vec<tab::Item>, String> {
133133
pos_opt: Cell::new(None),
134134
rect_opt: Cell::new(None),
135135
selected: false,
136+
highlighted: false,
136137
overlaps_drag_rect: false,
137138
});
138139
}

src/mouse_area.rs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ pub struct MouseArea<'a, Message> {
4747
on_forward_press: Option<Box<dyn Fn(Option<Point>) -> Message + 'a>>,
4848
on_forward_release: Option<Box<dyn Fn(Option<Point>) -> Message + 'a>>,
4949
on_scroll: Option<Box<dyn Fn(mouse::ScrollDelta, Modifiers) -> Option<Message> + 'a>>,
50+
on_enter: Option<Box<dyn Fn() -> Message + 'a>>,
51+
on_exit: Option<Box<dyn Fn() -> Message + 'a>>,
5052
show_drag_rect: bool,
5153
}
5254

@@ -169,6 +171,20 @@ impl<'a, Message> MouseArea<'a, Message> {
169171
self
170172
}
171173

174+
/// The message to emit when a mouse enters the area.
175+
#[must_use]
176+
pub fn on_enter(mut self, message: impl Fn() -> Message + 'a) -> Self {
177+
self.on_enter = Some(Box::new(message));
178+
self
179+
}
180+
181+
/// The message to emit when a mouse exits the area.
182+
#[must_use]
183+
pub fn on_exit(mut self, message: impl Fn() -> Message + 'a) -> Self {
184+
self.on_exit = Some(Box::new(message));
185+
self
186+
}
187+
172188
#[must_use]
173189
pub fn show_drag_rect(mut self, show_drag_rect: bool) -> Self {
174190
self.show_drag_rect = show_drag_rect;
@@ -186,7 +202,7 @@ impl<'a, Message> MouseArea<'a, Message> {
186202
/// Local state of the [`MouseArea`].
187203
#[derive(Default)]
188204
struct State {
189-
// TODO: Support on_mouse_enter and on_mouse_exit
205+
last_position: Option<Point>,
190206
drag_initiated: Option<Point>,
191207
modifiers: Modifiers,
192208
prev_click: Option<(mouse::Click, Instant)>,
@@ -260,6 +276,8 @@ impl<'a, Message> MouseArea<'a, Message> {
260276
on_back_release: None,
261277
on_forward_press: None,
262278
on_forward_release: None,
279+
on_enter: None,
280+
on_exit: None,
263281
on_scroll: None,
264282
show_drag_rect: false,
265283
}
@@ -474,6 +492,24 @@ fn update<Message: Clone>(
474492
}
475493
}
476494

495+
if let Event::Mouse(mouse::Event::CursorMoved { position }) = event {
496+
let position_in = cursor.position_in(layout_bounds);
497+
match (position_in, state.last_position) {
498+
(None, Some(last)) => {
499+
if let Some(message) = widget.on_exit.as_ref() {
500+
shell.publish(message())
501+
}
502+
}
503+
(Some(new), None) => {
504+
if let Some(message) = widget.on_enter.as_ref() {
505+
shell.publish(message())
506+
}
507+
}
508+
_ => {}
509+
}
510+
state.last_position = position_in;
511+
}
512+
477513
if state.drag_initiated.is_none() && !cursor.is_over(layout_bounds) {
478514
return event::Status::Ignored;
479515
}

src/tab.rs

Lines changed: 91 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ static SPECIAL_DIRS: Lazy<HashMap<PathBuf, &'static str>> = Lazy::new(|| {
118118
fn button_appearance(
119119
theme: &theme::Theme,
120120
selected: bool,
121+
highlighted: bool,
121122
focused: bool,
122123
accent: bool,
123124
condensed_radius: bool,
@@ -133,6 +134,14 @@ fn button_appearance(
133134
} else {
134135
appearance.background = Some(Color::from(cosmic.bg_component_color()).into());
135136
}
137+
} else if highlighted {
138+
if accent {
139+
appearance.background = Some(Color::from(cosmic.bg_component_color()).into());
140+
appearance.icon_color = Some(Color::from(cosmic.on_bg_component_color()));
141+
appearance.text_color = Some(Color::from(cosmic.on_bg_component_color()));
142+
} else {
143+
appearance.background = Some(Color::from(cosmic.bg_component_color()).into());
144+
}
136145
} else if desktop {
137146
appearance.background = Some(Color::from(cosmic.bg_color()).into());
138147
appearance.icon_color = Some(Color::from(cosmic.on_bg_color()));
@@ -154,23 +163,56 @@ fn button_appearance(
154163

155164
fn button_style(
156165
selected: bool,
166+
highlighted: bool,
157167
accent: bool,
158168
condensed_radius: bool,
159169
desktop: bool,
160170
) -> theme::Button {
161171
//TODO: move to libcosmic?
162172
theme::Button::Custom {
163173
active: Box::new(move |focused, theme| {
164-
button_appearance(theme, selected, focused, accent, condensed_radius, desktop)
174+
button_appearance(
175+
theme,
176+
selected,
177+
highlighted,
178+
focused,
179+
accent,
180+
condensed_radius,
181+
desktop,
182+
)
165183
}),
166184
disabled: Box::new(move |theme| {
167-
button_appearance(theme, selected, false, accent, condensed_radius, desktop)
185+
button_appearance(
186+
theme,
187+
selected,
188+
highlighted,
189+
false,
190+
accent,
191+
condensed_radius,
192+
desktop,
193+
)
168194
}),
169195
hovered: Box::new(move |focused, theme| {
170-
button_appearance(theme, selected, focused, accent, condensed_radius, desktop)
196+
button_appearance(
197+
theme,
198+
selected,
199+
highlighted,
200+
focused,
201+
accent,
202+
condensed_radius,
203+
desktop,
204+
)
171205
}),
172206
pressed: Box::new(move |focused, theme| {
173-
button_appearance(theme, selected, focused, accent, condensed_radius, desktop)
207+
button_appearance(
208+
theme,
209+
selected,
210+
highlighted,
211+
focused,
212+
accent,
213+
condensed_radius,
214+
desktop,
215+
)
174216
}),
175217
}
176218
}
@@ -444,6 +486,7 @@ pub fn item_from_entry(
444486
pos_opt: Cell::new(None),
445487
rect_opt: Cell::new(None),
446488
selected: false,
489+
highlighted: false,
447490
overlaps_drag_rect: false,
448491
}
449492
}
@@ -672,6 +715,7 @@ pub fn scan_trash(sizes: IconSizes) -> Vec<Item> {
672715
pos_opt: Cell::new(None),
673716
rect_opt: Cell::new(None),
674717
selected: false,
718+
highlighted: false,
675719
overlaps_drag_rect: false,
676720
});
677721
}
@@ -854,6 +898,7 @@ pub fn scan_desktop(
854898
pos_opt: Cell::new(None),
855899
rect_opt: Cell::new(None),
856900
selected: false,
901+
highlighted: false,
857902
overlaps_drag_rect: false,
858903
})
859904
}
@@ -1022,6 +1067,8 @@ pub enum Message {
10221067
WindowToggleMaximize,
10231068
ZoomIn,
10241069
ZoomOut,
1070+
HighlightDeactivate(usize),
1071+
HighlightActivate(usize),
10251072
}
10261073

10271074
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
@@ -1247,6 +1294,7 @@ pub struct Item {
12471294
pub pos_opt: Cell<Option<(usize, usize)>>,
12481295
pub rect_opt: Cell<Option<Rectangle>>,
12491296
pub selected: bool,
1297+
pub highlighted: bool,
12501298
pub overlaps_drag_rect: bool,
12511299
}
12521300

@@ -2592,6 +2640,16 @@ impl Tab {
25922640
}
25932641
}
25942642
}
2643+
Message::HighlightDeactivate(i) => {
2644+
if let Some(item) = self.items_opt.as_mut().and_then(|f| f.get_mut(i)) {
2645+
item.highlighted = false;
2646+
}
2647+
}
2648+
Message::HighlightActivate(i) => {
2649+
if let Some(item) = self.items_opt.as_mut().and_then(|f| f.get_mut(i)) {
2650+
item.highlighted = true;
2651+
}
2652+
}
25952653

25962654
Message::Scroll(viewport) => {
25972655
self.scroll_opt = Some(viewport.absolute_offset());
@@ -3554,14 +3612,21 @@ impl Tab {
35543612
.size(icon_sizes.grid()),
35553613
)
35563614
.padding(space_xxxs)
3557-
.class(button_style(item.selected, false, false, false))
3615+
.class(button_style(
3616+
item.selected,
3617+
item.highlighted,
3618+
false,
3619+
false,
3620+
false,
3621+
))
35583622
.into(),
35593623
widget::tooltip(
35603624
widget::button::custom(widget::text::body(&item.display_name))
35613625
.id(item.button_id.clone())
35623626
.padding([0, space_xxxs])
35633627
.class(button_style(
35643628
item.selected,
3629+
item.highlighted,
35653630
true,
35663631
true,
35673632
matches!(self.mode, Mode::Desktop),
@@ -3606,7 +3671,9 @@ impl Tab {
36063671
.on_press(move |_| Message::Click(Some(i)))
36073672
.on_double_click(move |_| Message::DoubleClick(Some(i)))
36083673
.on_release(move |_| Message::ClickRelease(Some(i)))
3609-
.on_middle_press(move |_| Message::MiddleClick(i));
3674+
.on_middle_press(move |_| Message::MiddleClick(i))
3675+
.on_enter(move || Message::HighlightActivate(i))
3676+
.on_exit(move || Message::HighlightDeactivate(i));
36103677

36113678
//TODO: error if the row or col is already set?
36123679
while grid_elements.len() <= row {
@@ -3703,6 +3770,7 @@ impl Tab {
37033770
.padding(space_xxxs)
37043771
.class(button_style(
37053772
item.selected,
3773+
item.highlighted,
37063774
false,
37073775
false,
37083776
false,
@@ -3711,7 +3779,13 @@ impl Tab {
37113779
.id(item.button_id.clone())
37123780
.on_press(Message::Click(Some(*i)))
37133781
.padding([0, space_xxxs])
3714-
.class(button_style(item.selected, true, true, false)),
3782+
.class(button_style(
3783+
item.selected,
3784+
item.highlighted,
3785+
true,
3786+
true,
3787+
false,
3788+
)),
37153789
];
37163790

37173791
let mut column = widget::column::with_capacity(buttons.len())
@@ -3922,12 +3996,20 @@ impl Tab {
39223996
.width(Length::Fill)
39233997
.id(item.button_id.clone())
39243998
.padding([0, space_xxs])
3925-
.class(button_style(item.selected, true, false, false)),
3999+
.class(button_style(
4000+
item.selected,
4001+
item.highlighted,
4002+
true,
4003+
false,
4004+
false,
4005+
)),
39264006
)
39274007
.on_press(move |_| Message::Click(Some(i)))
39284008
.on_double_click(move |_| Message::DoubleClick(Some(i)))
39294009
.on_release(move |_| Message::ClickRelease(Some(i)))
3930-
.on_middle_press(move |_| Message::MiddleClick(i));
4010+
.on_middle_press(move |_| Message::MiddleClick(i))
4011+
.on_enter(move || Message::HighlightActivate(i))
4012+
.on_exit(move || Message::HighlightDeactivate(i));
39314013

39324014
if self.context_menu.is_some() {
39334015
mouse_area

0 commit comments

Comments
 (0)