From 0d25fd0eabc1c75d6ebf7d52afa71765dd7500d8 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Wed, 8 May 2019 10:27:32 -0700 Subject: [PATCH] Generalize "switch" to "segmented control" in the UI --- demo/common/src/ui.rs | 4 +- ui/src/lib.rs | 89 +++++++++++++++++++++++++++---------------- 2 files changed, 58 insertions(+), 35 deletions(-) diff --git a/demo/common/src/ui.rs b/demo/common/src/ui.rs index 7e77f32d..50f3bb75 100644 --- a/demo/common/src/ui.rs +++ b/demo/common/src/ui.rs @@ -212,7 +212,7 @@ where *action = UIAction::ModelChanged; } - let mode_switch_width = debug_ui_presenter.ui_presenter.measure_switch(3); + let mode_switch_width = debug_ui_presenter.ui_presenter.measure_segmented_control(3); let mode_switch_size = Point2DI32::new(mode_switch_width, BUTTON_HEIGHT); debug_ui_presenter.ui_presenter.draw_tooltip( device, @@ -577,7 +577,7 @@ where .ui_presenter .draw_text(device, text, Point2DI32::new(text_x, text_y), false); - let switch_width = debug_ui_presenter.ui_presenter.measure_switch(2); + let switch_width = debug_ui_presenter.ui_presenter.measure_segmented_control(2); let switch_x = PADDING + EFFECTS_PANEL_WIDTH - (switch_width + PADDING); let switch_y = window_y + PADDING + (BUTTON_HEIGHT + PADDING) * index; let switch_position = Point2DI32::new(switch_x, switch_y); diff --git a/ui/src/lib.rs b/ui/src/lib.rs index 044e3c8c..6d740eed 100644 --- a/ui/src/lib.rs +++ b/ui/src/lib.rs @@ -43,7 +43,7 @@ const DEBUG_SOLID_VERTEX_SIZE: usize = 4; const ICON_SIZE: i32 = 48; -const SWITCH_SEGMENT_SIZE: i32 = 96; +const SEGMENT_SIZE: i32 = 96; pub static TEXT_COLOR: ColorU = ColorU { r: 255, g: 255, b: 255, a: 255 }; pub static WINDOW_COLOR: ColorU = ColorU { r: 0, g: 0, b: 0, a: 255 - 90 }; @@ -250,8 +250,8 @@ impl UIPresenter where D: Device { } #[inline] - pub fn measure_switch(&self, segment_count: u8) -> i32 { - SWITCH_SEGMENT_SIZE * segment_count as i32 + (segment_count - 1) as i32 + pub fn measure_segmented_control(&self, segment_count: u8) -> i32 { + SEGMENT_SIZE * segment_count as i32 + (segment_count - 1) as i32 } pub fn draw_solid_rounded_rect(&self, device: &D, rect: RectI32, color: ColorU) { @@ -428,17 +428,22 @@ impl UIPresenter where D: Device { segment_labels: &[&str], mut value: u8) -> u8 { - value = self.draw_switch(device, origin, value, segment_labels.len() as u8); + if let Some(new_value) = self.draw_segmented_control(device, + origin, + Some(value), + segment_labels.len() as u8) { + value = new_value; + } origin = origin + Point2DI32::new(0, BUTTON_TEXT_OFFSET); for (segment_index, segment_label) in segment_labels.iter().enumerate() { let label_width = self.measure_text(segment_label); - let offset = SWITCH_SEGMENT_SIZE / 2 - label_width / 2; + let offset = SEGMENT_SIZE / 2 - label_width / 2; self.draw_text(device, segment_label, origin + Point2DI32::new(offset, 0), segment_index as u8 == value); - origin += Point2DI32::new(SWITCH_SEGMENT_SIZE + 1, 0); + origin += Point2DI32::new(SEGMENT_SIZE + 1, 0); } value @@ -452,11 +457,15 @@ impl UIPresenter where D: Device { on_texture: &D::Texture, mut value: bool) -> bool { - value = self.draw_switch(device, origin, value as u8, 2) != 0; + if let Some(new_value) = self.draw_segmented_control(device, + origin, + Some(value as u8), + 2) { + value = new_value != 0; + } - let off_offset = SWITCH_SEGMENT_SIZE / 2 - device.texture_size(off_texture).x() / 2; - let on_offset = SWITCH_SEGMENT_SIZE + SWITCH_SEGMENT_SIZE / 2 - - device.texture_size(on_texture).x() / 2; + let off_offset = SEGMENT_SIZE / 2 - device.texture_size(off_texture).x() / 2; + let on_offset = SEGMENT_SIZE + SEGMENT_SIZE / 2 - device.texture_size(on_texture).x() / 2; let off_color = if !value { WINDOW_COLOR } else { TEXT_COLOR }; let on_color = if value { WINDOW_COLOR } else { TEXT_COLOR }; @@ -473,38 +482,52 @@ impl UIPresenter where D: Device { value } - fn draw_switch(&mut self, device: &D, origin: Point2DI32, mut value: u8, segment_count: u8) - -> u8 { - let widget_width = self.measure_switch(segment_count); + fn draw_segmented_control(&mut self, + device: &D, + origin: Point2DI32, + mut value: Option, + segment_count: u8) + -> Option { + let widget_width = self.measure_segmented_control(segment_count); let widget_rect = RectI32::new(origin, Point2DI32::new(widget_width, BUTTON_HEIGHT)); + + let mut clicked_segment = None; if let Some(position) = self.event_queue.handle_mouse_down_in_rect(widget_rect) { - let segment = (position.x() / (SWITCH_SEGMENT_SIZE + 1)) as u8; - value = segment.min(segment_count - 1); + let segment = ((position.x() / (SEGMENT_SIZE + 1)) as u8).min(segment_count - 1); + if let Some(ref mut value) = value { + *value = segment; + } + clicked_segment = Some(segment); } self.draw_solid_rounded_rect(device, widget_rect, WINDOW_COLOR); self.draw_rounded_rect_outline(device, widget_rect, OUTLINE_COLOR); - let highlight_size = Point2DI32::new(SWITCH_SEGMENT_SIZE, BUTTON_HEIGHT); - let x_offset = value as i32 * SWITCH_SEGMENT_SIZE + (value as i32 - 1); - self.draw_solid_rounded_rect(device, - RectI32::new(origin + Point2DI32::new(x_offset, 0), - highlight_size), - TEXT_COLOR); - - let mut segment_origin = origin + Point2DI32::new(SWITCH_SEGMENT_SIZE + 1, 0); - for next_segment_index in 1..segment_count { - let prev_segment_index = next_segment_index - 1; - if value != prev_segment_index && value != next_segment_index { - self.draw_line(device, - segment_origin, - segment_origin + Point2DI32::new(0, BUTTON_HEIGHT), - TEXT_COLOR); - } - segment_origin = segment_origin + Point2DI32::new(SWITCH_SEGMENT_SIZE + 1, 0); + if let Some(value) = value { + let highlight_size = Point2DI32::new(SEGMENT_SIZE, BUTTON_HEIGHT); + let x_offset = value as i32 * SEGMENT_SIZE + (value as i32 - 1); + self.draw_solid_rounded_rect(device, + RectI32::new(origin + Point2DI32::new(x_offset, 0), + highlight_size), + TEXT_COLOR); } - value + let mut segment_origin = origin + Point2DI32::new(SEGMENT_SIZE + 1, 0); + for next_segment_index in 1..segment_count { + let prev_segment_index = next_segment_index - 1; + match value { + Some(value) if value == prev_segment_index || value == next_segment_index => {} + _ => { + self.draw_line(device, + segment_origin, + segment_origin + Point2DI32::new(0, BUTTON_HEIGHT), + TEXT_COLOR); + } + } + segment_origin = segment_origin + Point2DI32::new(SEGMENT_SIZE + 1, 0); + } + + clicked_segment } pub fn draw_tooltip(&self, device: &D, string: &str, rect: RectI32) {