diff --git a/assets/voxygen/element/ui/map/buttons/location_marker_group_leader.png b/assets/voxygen/element/ui/map/buttons/location_marker_group_leader.png new file mode 100644 index 0000000000..def0612808 --- /dev/null +++ b/assets/voxygen/element/ui/map/buttons/location_marker_group_leader.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ba6271eb2808a6028c14cbf56ef04cf6e5c9c9450b6f1d65056d91897324639b +size 660 diff --git a/voxygen/src/hud/img_ids.rs b/voxygen/src/hud/img_ids.rs index 6193e28dc7..b702d0bf14 100644 --- a/voxygen/src/hud/img_ids.rs +++ b/voxygen/src/hud/img_ids.rs @@ -369,6 +369,7 @@ image_ids! { indicator_group_down: "voxygen.element.ui.map.buttons.group_indicator_arrow_down", location_marker: "voxygen.element.ui.map.buttons.location_marker", location_marker_group: "voxygen.element.ui.map.buttons.location_marker_group", + location_marker_group_leader: "voxygen.element.ui.map.buttons.location_marker_group_leader", map_mode_overlay: "voxygen.element.ui.map.buttons.map_modes", minimap_mode_overlay: "voxygen.element.ui.map.buttons.minimap_modes", diff --git a/voxygen/src/hud/map.rs b/voxygen/src/hud/map.rs index 27334f1874..60e1c2862f 100644 --- a/voxygen/src/hud/map.rs +++ b/voxygen/src/hud/map.rs @@ -354,73 +354,78 @@ impl<'a> Widget for Map<'a> { } } } + enum MarkerChange { + Pos(Vec2), + ClickPos, + Remove, + } - let handle_widget_mouse_events = |widget, - wpos: Option>, - ui: &mut UiCell, - events: &mut Vec, - map_widget| { - // Handle Location Marking - if let Some(click) = ui - .widget_input(widget) - .clicks() - .button(ConrodMouseButton::from(location_marker_binding)) - .next() - { - match wpos { - Some(ref wpos) => events.push(Event::SetLocationMarker(wpos.as_())), - None => { - let tmp: Vec2 = Vec2::::from(click.xy) / zoom - drag; - let wpos = tmp - .map2(TerrainChunkSize::RECT_SIZE, |e, sz| e as f32 * sz as f32) - + player_pos; - events.push(Event::SetLocationMarker(wpos.as_())); - }, - } - } - - // Handle zooming with the mousewheel - let scrolled: f64 = ui - .widget_input(widget) - .scrolls() - .map(|scroll| scroll.y) - .sum(); - if scrolled != 0.0 { - let min_zoom = map_size.x as f64 / worldsize.reduce_partial_max() as f64 / 2.0; - let new_zoom_lvl: f64 = (f64::log2(zoom) - scrolled * 0.03) - .exp2() - .clamp(min_zoom, 16.0); - events.push(Event::SettingsChange(MapZoom(new_zoom_lvl))); - let cursor_mouse_pos = ui - .widget_input(map_widget) - .mouse() - .map(|mouse| mouse.rel_xy()); - if let Some(cursor_pos) = cursor_mouse_pos { - let mouse_pos = Vec2::from_slice(&cursor_pos); - let drag_new = drag + mouse_pos * (1.0 / new_zoom_lvl - 1.0 / zoom); - if drag_new != drag { - events.push(Event::MapDrag(drag_new)); + let handle_widget_mouse_events = + |widget, marker: MarkerChange, ui: &mut UiCell, events: &mut Vec, map_widget| { + // Handle Location Marking + if let Some(click) = ui + .widget_input(widget) + .clicks() + .button(ConrodMouseButton::from(location_marker_binding)) + .next() + { + match marker { + MarkerChange::Pos(ref wpos) => { + events.push(Event::SetLocationMarker(wpos.as_())) + }, + MarkerChange::ClickPos => { + let tmp: Vec2 = Vec2::::from(click.xy) / zoom - drag; + let wpos = tmp + .map2(TerrainChunkSize::RECT_SIZE, |e, sz| e as f32 * sz as f32) + + player_pos; + events.push(Event::SetLocationMarker(wpos.as_())); + }, + MarkerChange::Remove => events.push(Event::RemoveMarker), } } - } - // Handle dragging - let dragged: Vec2 = ui - .widget_input(widget) - .drags() - .left() - .map(|drag| Vec2::::from(drag.delta_xy)) - .sum(); - // Drag represents offset of view from the player_pos in chunk coords - let drag_new = drag + dragged / zoom; - if drag_new != drag { - events.push(Event::MapDrag(drag_new)); - } - }; + // Handle zooming with the mousewheel + let scrolled: f64 = ui + .widget_input(widget) + .scrolls() + .map(|scroll| scroll.y) + .sum(); + if scrolled != 0.0 { + let min_zoom = map_size.x as f64 / worldsize.reduce_partial_max() as f64 / 2.0; + let new_zoom_lvl: f64 = (f64::log2(zoom) - scrolled * 0.03) + .exp2() + .clamp(min_zoom, 16.0); + events.push(Event::SettingsChange(MapZoom(new_zoom_lvl))); + let cursor_mouse_pos = ui + .widget_input(map_widget) + .mouse() + .map(|mouse| mouse.rel_xy()); + if let Some(cursor_pos) = cursor_mouse_pos { + let mouse_pos = Vec2::from_slice(&cursor_pos); + let drag_new = drag + mouse_pos * (1.0 / new_zoom_lvl - 1.0 / zoom); + if drag_new != drag { + events.push(Event::MapDrag(drag_new)); + } + } + } + + // Handle dragging + let dragged: Vec2 = ui + .widget_input(widget) + .drags() + .left() + .map(|drag| Vec2::::from(drag.delta_xy)) + .sum(); + // Drag represents offset of view from the player_pos in chunk coords + let drag_new = drag + dragged / zoom; + if drag_new != drag { + events.push(Event::MapDrag(drag_new)); + } + }; handle_widget_mouse_events( state.ids.map_layers[0], - None, + MarkerChange::ClickPos, ui, &mut events, state.ids.map_layers[0], @@ -946,7 +951,7 @@ impl<'a> Widget for Map<'a> { handle_widget_mouse_events( state.ids.mmap_site_icons[i], - Some(site.wpos.map(|e| e as f32)), + MarkerChange::Pos(site.wpos.map(|e| e as f32)), ui, &mut events, state.ids.map_layers[0], @@ -1035,7 +1040,7 @@ impl<'a> Widget for Map<'a> { handle_widget_mouse_events( state.ids.site_difs[i], - Some(site.wpos.map(|e| e as f32)), + MarkerChange::Pos(site.wpos.map(|e| e as f32)), ui, &mut events, state.ids.map_layers[0], @@ -1079,7 +1084,7 @@ impl<'a> Widget for Map<'a> { handle_widget_mouse_events( state.ids.mmap_poi_titles[i], - Some(poi.wpos.map(|e| e as f32)), + MarkerChange::Pos(poi.wpos.map(|e| e as f32)), ui, &mut events, state.ids.map_layers[0], @@ -1209,7 +1214,7 @@ impl<'a> Widget for Map<'a> { handle_widget_mouse_events( state.ids.member_indicators[i], - Some(member_pos.0.xy().map(|e| e as f32)), + MarkerChange::Pos(member_pos.0.xy().map(|e| e as f32)), ui, &mut events, state.ids.map_layers[0], @@ -1246,7 +1251,12 @@ impl<'a> Widget for Map<'a> { }) .unwrap_or(""); - Button::image(self.imgs.location_marker_group) + let image_id = match self.client.group_info().map(|info| info.1) { + Some(leader) if leader == uid => self.imgs.location_marker_group_leader, + _ => self.imgs.location_marker_group, + }; + + Button::image(image_id) .x_y_position_relative_to( state.ids.map_layers[0], position::Relative::Scalar(rpos.x as f64), @@ -1268,6 +1278,13 @@ impl<'a> Widget for Map<'a> { TEXT_VELORITE, ) .set(state.ids.location_marker_group[i], ui); + handle_widget_mouse_events( + state.ids.location_marker_group[i], + MarkerChange::Pos(lm), + ui, + &mut events, + state.ids.map_layers[0], + ); } } // Location marker @@ -1308,7 +1325,7 @@ impl<'a> Widget for Map<'a> { handle_widget_mouse_events( state.ids.location_marker, - Some(Vec2::new(0.0, 0.0)), + MarkerChange::Remove, ui, &mut events, state.ids.map_layers[0], @@ -1340,7 +1357,7 @@ impl<'a> Widget for Map<'a> { handle_widget_mouse_events( state.ids.indicator, - Some(player_pos.xy()), + MarkerChange::Pos(player_pos.xy()), ui, &mut events, state.ids.map_layers[0], diff --git a/voxygen/src/hud/minimap.rs b/voxygen/src/hud/minimap.rs index 011b5fc40b..0c64747b83 100644 --- a/voxygen/src/hud/minimap.rs +++ b/voxygen/src/hud/minimap.rs @@ -369,6 +369,7 @@ widget_ids! { mmap_site_icons[], member_indicators[], location_marker, + location_marker_group[], voxel_minimap, } } @@ -788,6 +789,37 @@ impl<'a> Widget for MiniMap<'a> { } } + // Group location markers + if state.ids.location_marker_group.len() < self.location_markers.group.len() { + state.update(|s| { + s.ids.location_marker_group.resize( + self.location_markers.group.len(), + &mut ui.widget_id_generator(), + ) + }) + }; + for (i, (&uid, &rpos)) in self.location_markers.group.iter().enumerate() { + let lm = rpos.as_(); + if let Some(rpos) = wpos_to_rpos(lm, true) { + let (image_id, factor) = match self.client.group_info().map(|info| info.1) { + Some(leader) if leader == uid => { + (self.imgs.location_marker_group_leader, 1.2) + }, + _ => (self.imgs.location_marker_group, 1.0), + }; + + Image::new(image_id) + .x_y_position_relative_to( + state.ids.map_layers[0], + position::Relative::Scalar(rpos.x as f64), + position::Relative::Scalar(rpos.y as f64 + 8.0 * factor), + ) + .w_h(16.0 * factor, 16.0 * factor) + .parent(ui.window) + .set(state.ids.location_marker_group[i], ui) + } + } + // Location marker if let Some(rpos) = self .location_markers