vertical_menu.rs 3.5KB

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