@@ -8,6 +8,7 @@ use serde_json::json;
pub struct MouseEventHandler {
state: ValueHandle<MouseState>,
child: ElementBox,
+ click_handler: Option<Box<dyn FnMut(&mut EventContext)>>,
}
#[derive(Clone, Copy, Debug, Default)]
@@ -28,8 +29,14 @@ impl MouseEventHandler {
Self {
state: state_handle,
child,
+ click_handler: None,
}
}
+
+ pub fn on_click(mut self, handler: impl FnMut(&mut EventContext) + 'static) -> Self {
+ self.click_handler = Some(Box::new(handler));
+ self
+ }
}
impl Element for MouseEventHandler {
@@ -70,6 +77,8 @@ impl Element for MouseEventHandler {
_: &mut Self::PaintState,
ctx: &mut EventContext,
) -> bool {
+ let click_handler = self.click_handler.as_mut();
+
let handled_in_child = self.child.dispatch_event(event, ctx);
self.state.update(ctx.app, |state| match event {
@@ -92,10 +101,15 @@ impl Element for MouseEventHandler {
handled_in_child
}
}
- Event::LeftMouseUp { .. } => {
+ Event::LeftMouseUp { position, .. } => {
if !handled_in_child && state.clicked {
state.clicked = false;
ctx.notify();
+ if let Some(handler) = click_handler {
+ if bounds.contains_point(*position) {
+ handler(ctx);
+ }
+ }
true
} else {
handled_in_child
@@ -25,6 +25,12 @@ pub fn init(app: &mut MutableAppContext) {
app.add_action("pane:close_active_item", |pane: &mut Pane, _: &(), ctx| {
pane.close_active_item(ctx);
});
+ app.add_action(
+ "pane:close_item",
+ |pane: &mut Pane, item_id: &usize, ctx| {
+ pane.close_item(*item_id, ctx);
+ },
+ );
app.add_action("pane:split_up", |pane: &mut Pane, _: &(), ctx| {
pane.split(SplitDirection::Up, ctx);
});
@@ -155,15 +161,17 @@ impl Pane {
pub fn close_active_item(&mut self, ctx: &mut ViewContext<Self>) {
if !self.items.is_empty() {
- self.items.remove(self.active_item);
- if self.active_item >= self.items.len() {
- self.active_item = self.items.len().saturating_sub(1);
- }
- ctx.notify();
+ self.close_item(self.items[self.active_item].id(), ctx)
}
+ }
+
+ pub fn close_item(&mut self, item_id: usize, ctx: &mut ViewContext<Self>) {
+ self.items.retain(|item| item.id() != item_id);
+ self.active_item = cmp::min(self.active_item, self.items.len().saturating_sub(1));
if self.items.is_empty() {
ctx.emit(Event::Remove);
}
+ ctx.notify();
}
fn focus_active_item(&mut self, ctx: &mut ViewContext<Self>) {
@@ -316,6 +324,7 @@ impl Pane {
icon.boxed()
}
})
+ .on_click(move |ctx| ctx.dispatch_action("pane:close_item", item_id))
.named("close-tab-icon")
} else {
let diameter = 8.;