Browse Source

refact menu code

Bastien Sevajol 3 years ago
parent
commit
fe5f8c0be4
6 changed files with 143 additions and 117 deletions
  1. BIN
      resources/ui.png
  2. BIN
      resources/ui.xcf
  3. 22 30
      src/scene/main.rs
  4. 12 84
      src/ui/mod.rs
  5. 0 3
      src/ui/scene_item_menu.rs
  6. 109 0
      src/ui/vertical_menu.rs

BIN
resources/ui.png View File


BIN
resources/ui.xcf View File


+ 22 - 30
src/scene/main.rs View File

1
 use std::cmp;
1
 use std::cmp;
2
 use std::collections::HashMap;
2
 use std::collections::HashMap;
3
+use std::f32::consts::FRAC_PI_2;
3
 
4
 
4
 use ggez::event::MouseButton;
5
 use ggez::event::MouseButton;
5
 use ggez::graphics::{DrawMode, MeshBuilder, StrokeOptions};
6
 use ggez::graphics::{DrawMode, MeshBuilder, StrokeOptions};
23
 use crate::scene::item::{
24
 use crate::scene::item::{
24
     apply_scene_item_modifier, ItemState, SceneItem, SceneItemModifier, SceneItemType,
25
     apply_scene_item_modifier, ItemState, SceneItem, SceneItemModifier, SceneItemType,
25
 };
26
 };
26
-use crate::ui::scene_item_menu::SceneItemMenuItem;
27
-use crate::ui::{SceneItemPrepareOrder, UiItem, UiSpriteInfo, UserEvent};
27
+use crate::ui::vertical_menu::{vertical_menu_sprite_info, VerticalMenuSpriteInfo};
28
+use crate::ui::MenuItem;
29
+use crate::ui::{SceneItemPrepareOrder, UiComponent, UserEvent};
28
 use crate::{Offset, ScenePoint, WindowPoint};
30
 use crate::{Offset, ScenePoint, WindowPoint};
29
-use std::f32::consts::FRAC_PI_2;
30
 
31
 
31
 pub struct MainState {
32
 pub struct MainState {
32
     // time
33
     // time
158
     }
159
     }
159
 
160
 
160
     fn digest_click(&mut self, window_click_point: WindowPoint) {
161
     fn digest_click(&mut self, window_click_point: WindowPoint) {
161
-        let scene_position =
162
+        let scene_click_point =
162
             scene_point_from_window_point(&window_click_point, &self.display_offset);
163
             scene_point_from_window_point(&window_click_point, &self.display_offset);
163
         self.selected_scene_items.drain(..);
164
         self.selected_scene_items.drain(..);
164
-        if let Some(scene_item_usize) = self.get_first_scene_item_for_scene_point(&scene_position) {
165
+        if let Some(scene_item_usize) =
166
+            self.get_first_scene_item_for_scene_point(&scene_click_point)
167
+        {
165
             self.selected_scene_items.push(scene_item_usize);
168
             self.selected_scene_items.push(scene_item_usize);
166
         }
169
         }
167
 
170
 
170
             match scene_item_prepare_order {
173
             match scene_item_prepare_order {
171
                 SceneItemPrepareOrder::Move(scene_item_usize) => {
174
                 SceneItemPrepareOrder::Move(scene_item_usize) => {
172
                     let mut scene_item = self.get_scene_item_mut(*scene_item_usize);
175
                     let mut scene_item = self.get_scene_item_mut(*scene_item_usize);
173
-                    scene_item.next_order = Some(Order::MoveTo(scene_position));
176
+                    scene_item.next_order = Some(Order::MoveTo(scene_click_point));
174
                 }
177
                 }
175
             }
178
             }
176
 
179
 
177
             self.scene_item_prepare_order = None;
180
             self.scene_item_prepare_order = None;
178
         }
181
         }
179
 
182
 
180
-        // FIXME BS NOW: interpreter sur quel element du menu on a click ...
181
         if let Some((scene_item_usize, scene_menu_point)) = self.scene_item_menu {
183
         if let Some((scene_item_usize, scene_menu_point)) = self.scene_item_menu {
182
-            let window_menu_point =
183
-                window_point_from_scene_point(&scene_menu_point, &self.display_offset);
184
-            let menu_sprite_info = UiSpriteInfo::from_type(UiItem::SceneItemMenu);
185
-            let scene_item = self.get_scene_item(scene_item_usize);
186
-            if window_click_point.x >= window_menu_point.x
187
-                && window_click_point.x <= window_menu_point.x + menu_sprite_info.width
188
-                && window_click_point.y >= window_menu_point.y
189
-                && window_click_point.y <= window_menu_point.y + menu_sprite_info.height
184
+            let menu_sprite_info = vertical_menu_sprite_info(UiComponent::SceneItemMenu);
185
+            if let Some(menu_item) =
186
+                menu_sprite_info.item_clicked(&scene_menu_point, &scene_click_point)
190
             {
187
             {
191
-                if let Some(menu_item) = menu_sprite_info.which_item_clicked(
192
-                    window_menu_point,
193
-                    window_click_point,
194
-                    scene_item,
195
-                ) {
196
-                    match menu_item {
197
-                        SceneItemMenuItem::Move => {
198
-                            self.scene_item_prepare_order =
199
-                                Some(SceneItemPrepareOrder::Move(scene_item_usize));
200
-                            self.scene_item_menu = None;
201
-                        }
188
+                match menu_item {
189
+                    MenuItem::Move => {
190
+                        self.scene_item_prepare_order =
191
+                            Some(SceneItemPrepareOrder::Move(scene_item_usize));
192
+                        self.scene_item_menu = None;
202
                     }
193
                     }
194
+                    MenuItem::MoveFast => {}
195
+                    MenuItem::Hide => {}
203
                 }
196
                 }
204
-            } else {
205
-                self.scene_item_menu = None;
206
-            }
197
+            };
198
+            self.scene_item_menu = None;
207
         };
199
         };
208
     }
200
     }
209
 
201
 
329
 
321
 
330
     fn generate_scene_item_menu_sprites(&mut self) -> GameResult {
322
     fn generate_scene_item_menu_sprites(&mut self) -> GameResult {
331
         if let Some((_, scene_point)) = self.scene_item_menu {
323
         if let Some((_, scene_point)) = self.scene_item_menu {
332
-            for draw_param in UiSpriteInfo::from_type(UiItem::SceneItemMenu)
324
+            for draw_param in vertical_menu_sprite_info(UiComponent::SceneItemMenu)
333
                 .as_draw_params(&scene_point, &self.current_cursor_position)
325
                 .as_draw_params(&scene_point, &self.current_cursor_position)
334
             {
326
             {
335
                 self.ui_batch.add(draw_param);
327
                 self.ui_batch.add(draw_param);

+ 12 - 84
src/ui/mod.rs View File

2
 
2
 
3
 use crate::config::{UI_SPRITE_SHEET_HEIGHT, UI_SPRITE_SHEET_WIDTH};
3
 use crate::config::{UI_SPRITE_SHEET_HEIGHT, UI_SPRITE_SHEET_WIDTH};
4
 use crate::scene::item::SceneItem;
4
 use crate::scene::item::SceneItem;
5
-use crate::ui::scene_item_menu::SceneItemMenuItem;
6
 use crate::{Offset, ScenePoint, WindowPoint};
5
 use crate::{Offset, ScenePoint, WindowPoint};
7
 
6
 
8
-pub mod scene_item_menu;
7
+pub mod vertical_menu;
9
 
8
 
10
 const SCENE_ITEM_MENU_WIDTH: f32 = 71.0;
9
 const SCENE_ITEM_MENU_WIDTH: f32 = 71.0;
11
 const SCENE_ITEM_MENU_HEIGHT: f32 = 68.0;
10
 const SCENE_ITEM_MENU_HEIGHT: f32 = 68.0;
12
 const SCENE_ITEM_MENU_ITEM_HEIGHT: f32 = 15.0;
11
 const SCENE_ITEM_MENU_ITEM_HEIGHT: f32 = 15.0;
13
 
12
 
14
-pub enum UiItem {
13
+pub enum UiComponent {
15
     SceneItemMenu,
14
     SceneItemMenu,
16
 }
15
 }
17
-// FIXME BS NOW: Transformer ça en VerticalMenu, où l'on donne les carac des item aussi
18
-// --> ce sera capable de manière generique d'eclairer le bon item et dire quel item affiché
19
-pub struct UiSpriteInfo {
20
-    pub relative_start_x: f32,
21
-    pub relative_start_y: f32,
22
-    pub relative_width: f32,
23
-    pub relative_height: f32,
24
-    pub width: f32,
25
-    pub height: f32,
26
-}
27
-
28
-impl UiSpriteInfo {
29
-    pub fn from_type(type_: UiItem) -> Self {
30
-        match type_ {
31
-            UiItem::SceneItemMenu => Self {
32
-                relative_start_x: 0.0,
33
-                relative_start_y: 0.0,
34
-                relative_width: SCENE_ITEM_MENU_WIDTH / UI_SPRITE_SHEET_WIDTH,
35
-                relative_height: SCENE_ITEM_MENU_HEIGHT / UI_SPRITE_SHEET_HEIGHT,
36
-                width: SCENE_ITEM_MENU_WIDTH,
37
-                height: SCENE_ITEM_MENU_HEIGHT,
38
-            },
39
-        }
40
-    }
41
-
42
-    pub fn as_draw_params(
43
-        &self,
44
-        scene_point: &ScenePoint,
45
-        scene_current_cursor_point: &ScenePoint,
46
-    ) -> Vec<graphics::DrawParam> {
47
-        // FIXME BS NOW: this is a generic struct ! not SceneItemMenu struct
48
-        let mut draw_params = vec![graphics::DrawParam::new()
49
-            .src(graphics::Rect::new(
50
-                self.relative_start_x,
51
-                self.relative_start_y,
52
-                self.relative_width,
53
-                self.relative_height,
54
-            ))
55
-            .dest(*scene_point)];
56
-
57
-        let relative_cursor_position: Offset = Offset::new(
58
-            scene_current_cursor_point.x - scene_point.x,
59
-            scene_current_cursor_point.y - scene_point.y,
60
-        );
61
-
62
-        // Cursor inside menu
63
-        if relative_cursor_position.x >= 0.0
64
-            && relative_cursor_position.x <= SCENE_ITEM_MENU_WIDTH
65
-            && relative_cursor_position.y >= 0.0
66
-            && relative_cursor_position.y <= SCENE_ITEM_MENU_HEIGHT
67
-        {
68
-            let hover_item_i = (relative_cursor_position.y / SCENE_ITEM_MENU_ITEM_HEIGHT) as i32;
69
-            let source = graphics::Rect::new(
70
-                self.relative_width,
71
-                (SCENE_ITEM_MENU_ITEM_HEIGHT / UI_SPRITE_SHEET_HEIGHT) * hover_item_i as f32,
72
-                self.relative_width,
73
-                SCENE_ITEM_MENU_ITEM_HEIGHT / UI_SPRITE_SHEET_HEIGHT,
74
-            );
75
-            let destination = ScenePoint::new(
76
-                scene_point.x,
77
-                scene_point.y + (SCENE_ITEM_MENU_ITEM_HEIGHT * hover_item_i as f32),
78
-            );
79
-            draw_params.push(graphics::DrawParam::new().src(source).dest(destination));
80
-        }
81
-
82
-        draw_params
83
-    }
84
-
85
-    // FIXME BS NOW: this is a generic struct ! not SceneItemMenu struct
86
-    pub fn which_item_clicked(
87
-        &self,
88
-        _window_menu_point: WindowPoint,
89
-        _window_click_point: WindowPoint,
90
-        _scene_item: &SceneItem,
91
-    ) -> Option<SceneItemMenuItem> {
92
-        Some(SceneItemMenuItem::Move)
93
-    }
94
-}
95
 
16
 
96
 #[derive(Debug)]
17
 #[derive(Debug)]
97
 pub enum UserEvent {
18
 pub enum UserEvent {
98
-    Click(WindowPoint),                      // Window coordinates
99
-    RightClick(WindowPoint),                 // Window coordinates
100
-    AreaSelection(WindowPoint, WindowPoint), // Window coordinates
19
+    Click(WindowPoint),
20
+    RightClick(WindowPoint),
21
+    AreaSelection(WindowPoint, WindowPoint),
101
 }
22
 }
102
 
23
 
103
 pub enum SceneItemPrepareOrder {
24
 pub enum SceneItemPrepareOrder {
104
     Move(usize), // scene_item usize
25
     Move(usize), // scene_item usize
105
 }
26
 }
27
+
28
+#[derive(Clone)]
29
+pub enum MenuItem {
30
+    Move,
31
+    MoveFast,
32
+    Hide,
33
+}

+ 0 - 3
src/ui/scene_item_menu.rs View File

1
-pub enum SceneItemMenuItem {
2
-    Move,
3
-}

+ 109 - 0
src/ui/vertical_menu.rs View File

1
+use ggez::graphics;
2
+
3
+use crate::config::{UI_SPRITE_SHEET_HEIGHT, UI_SPRITE_SHEET_WIDTH};
4
+use crate::ui::{
5
+    MenuItem, UiComponent, SCENE_ITEM_MENU_HEIGHT, SCENE_ITEM_MENU_ITEM_HEIGHT,
6
+    SCENE_ITEM_MENU_WIDTH,
7
+};
8
+use crate::{Offset, ScenePoint};
9
+
10
+pub fn vertical_menu_sprite_info(type_: UiComponent) -> VerticalMenuSpriteInfo {
11
+    match type_ {
12
+        UiComponent::SceneItemMenu => VerticalMenuSpriteInfo {
13
+            relative_start_x: 0.0,
14
+            relative_start_y: 0.0,
15
+            relative_width: SCENE_ITEM_MENU_WIDTH / UI_SPRITE_SHEET_WIDTH,
16
+            relative_height: SCENE_ITEM_MENU_HEIGHT / UI_SPRITE_SHEET_HEIGHT,
17
+            width: SCENE_ITEM_MENU_WIDTH,
18
+            height: SCENE_ITEM_MENU_HEIGHT,
19
+            item_height: SCENE_ITEM_MENU_ITEM_HEIGHT,
20
+            relative_item_height: SCENE_ITEM_MENU_ITEM_HEIGHT / UI_SPRITE_SHEET_HEIGHT,
21
+            item_matches: vec![MenuItem::Move, MenuItem::MoveFast, MenuItem::Hide],
22
+        },
23
+    }
24
+}
25
+
26
+pub struct VerticalMenuSpriteInfo {
27
+    pub relative_start_x: f32,
28
+    pub relative_start_y: f32,
29
+    pub relative_width: f32,
30
+    pub relative_height: f32,
31
+    pub width: f32,
32
+    pub height: f32,
33
+    pub item_height: f32,
34
+    pub relative_item_height: f32,
35
+    pub item_matches: Vec<MenuItem>,
36
+}
37
+
38
+impl VerticalMenuSpriteInfo {
39
+    fn item_position(
40
+        &self,
41
+        menu_scene_point: &ScenePoint,
42
+        current_cursor_scene_point: &ScenePoint,
43
+    ) -> Option<usize> {
44
+        let relative_cursor_position: Offset = Offset::new(
45
+            current_cursor_scene_point.x - menu_scene_point.x,
46
+            current_cursor_scene_point.y - menu_scene_point.y,
47
+        );
48
+
49
+        // Cursor inside menu
50
+        if relative_cursor_position.x >= 0.0
51
+            && relative_cursor_position.x <= SCENE_ITEM_MENU_WIDTH
52
+            && relative_cursor_position.y >= 0.0
53
+            && relative_cursor_position.y <= SCENE_ITEM_MENU_HEIGHT
54
+        {
55
+            return Some((relative_cursor_position.y / SCENE_ITEM_MENU_ITEM_HEIGHT) as usize);
56
+        }
57
+
58
+        None
59
+    }
60
+
61
+    pub fn as_draw_params(
62
+        &self,
63
+        menu_scene_point: &ScenePoint,
64
+        scene_current_cursor_point: &ScenePoint,
65
+    ) -> Vec<graphics::DrawParam> {
66
+        let mut draw_params = vec![graphics::DrawParam::new()
67
+            .src(graphics::Rect::new(
68
+                self.relative_start_x,
69
+                self.relative_start_y,
70
+                self.relative_width,
71
+                self.relative_height,
72
+            ))
73
+            .dest(*menu_scene_point)];
74
+
75
+        if let Some(item_position) =
76
+            self.item_position(menu_scene_point, scene_current_cursor_point)
77
+        {
78
+            let source = graphics::Rect::new(
79
+                self.relative_width,
80
+                self.relative_item_height * item_position as f32,
81
+                self.relative_width,
82
+                self.relative_item_height,
83
+            );
84
+            let destination = ScenePoint::new(
85
+                menu_scene_point.x,
86
+                menu_scene_point.y + (self.item_height * item_position as f32),
87
+            );
88
+            draw_params.push(graphics::DrawParam::new().src(source).dest(destination));
89
+        }
90
+
91
+        draw_params
92
+    }
93
+
94
+    pub fn item_clicked(
95
+        &self,
96
+        menu_scene_point: &ScenePoint,
97
+        scene_current_cursor_point: &ScenePoint,
98
+    ) -> Option<MenuItem> {
99
+        if let Some(item_position) =
100
+            self.item_position(menu_scene_point, scene_current_cursor_point)
101
+        {
102
+            if let Some(menu_item) = self.item_matches.get(item_position) {
103
+                return Some(menu_item.clone());
104
+            }
105
+        };
106
+
107
+        None
108
+    }
109
+}