add tooltips
This commit is contained in:
parent
fea00da8a3
commit
4d05d5a3ee
4 changed files with 235 additions and 70 deletions
|
@ -14,7 +14,6 @@ logic mostly like https://git.crispypin.cc/CrispyPin/marble
|
|||
- make direct power (comparator -> machine) work, (needs storing power direction in machine tiles)
|
||||
- cut selections, copy to system clipboard
|
||||
- timestamps in solutions and blueprints
|
||||
- tooltips
|
||||
- lock tile types for early levels to make it less overwhelming
|
||||
- display tool variant more clearly (it's not obvious there are more states)
|
||||
- option to use 8-bit marbles?
|
||||
|
|
126
src/editor.rs
126
src/editor.rs
|
@ -21,7 +21,7 @@ use crate::{
|
|||
solution::{Score, Solution},
|
||||
text_input, texture_option_button,
|
||||
theme::*,
|
||||
userdata_dir, Scroll, Textures, TILE_TEXTURE_SIZE,
|
||||
userdata_dir, Scroll, Textures, Tooltip, TILE_TEXTURE_SIZE,
|
||||
};
|
||||
|
||||
const HEADER_HEIGHT: i32 = 40;
|
||||
|
@ -64,6 +64,7 @@ pub struct Editor {
|
|||
total_steps: usize,
|
||||
popup: EndPopup,
|
||||
score: Option<Score>,
|
||||
tooltip: Tooltip,
|
||||
|
||||
blueprints: Vec<Blueprint>,
|
||||
selected_blueprint: usize,
|
||||
|
@ -176,6 +177,7 @@ impl Editor {
|
|||
draw_overlay: true,
|
||||
undo_history: Vec::new(),
|
||||
undo_index: 0,
|
||||
tooltip: Tooltip::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -567,6 +569,8 @@ impl Editor {
|
|||
}
|
||||
}
|
||||
|
||||
self.tooltip.init_frame(d);
|
||||
|
||||
self.draw_board(d, textures);
|
||||
self.board_overlay(d, textures);
|
||||
self.draw_bottom_bar(d, textures);
|
||||
|
@ -593,6 +597,7 @@ impl Editor {
|
|||
.enumerate()
|
||||
{
|
||||
let i = i + self.blueprint_scroll;
|
||||
self.tooltip.add(5, y, 32, 32, "Delete");
|
||||
if simple_button(d, 5, y, 32, 32) {
|
||||
b.remove_file();
|
||||
self.blueprints.remove(i);
|
||||
|
@ -612,6 +617,7 @@ impl Editor {
|
|||
if is_selected {
|
||||
self.blueprint_name_selected = text_selected;
|
||||
}
|
||||
self.tooltip.add(42 + 205, y, 32, 32, "Select");
|
||||
simple_option_button(d, 42 + 205, y, 32, 32, i, &mut self.selected_blueprint);
|
||||
|
||||
d.draw_texture_ex(
|
||||
|
@ -625,6 +631,8 @@ impl Editor {
|
|||
}
|
||||
}
|
||||
|
||||
self.tooltip.draw(d);
|
||||
|
||||
if matches!(self.popup, EndPopup::Success | EndPopup::Failure) {
|
||||
let x = d.get_screen_width() / 2 - POPUP_WIDTH / 2;
|
||||
let y = d.get_screen_height() / 2 - POPUP_HEIGHT / 2;
|
||||
|
@ -694,6 +702,7 @@ impl Editor {
|
|||
}
|
||||
|
||||
if self.sim_state == SimState::Editing {
|
||||
self.tooltip.add(150, 4, 32, 32, "Undo");
|
||||
if simple_button(d, 150, 4, 32, 32) {
|
||||
self.undo()
|
||||
}
|
||||
|
@ -704,6 +713,7 @@ impl Editor {
|
|||
};
|
||||
draw_scaled_texture(d, textures.get(undo_icon), 150, 4, 2.);
|
||||
|
||||
self.tooltip.add(186, 4, 32, 32, "Redo");
|
||||
if simple_button(d, 186, 4, 32, 32) {
|
||||
self.redo()
|
||||
}
|
||||
|
@ -715,48 +725,48 @@ impl Editor {
|
|||
draw_scaled_texture(d, textures.get(redo_icon), 186, 4, 2.);
|
||||
}
|
||||
simple_toggle_button(d, &mut self.draw_overlay, 223, 4, 32, 32, 4);
|
||||
self.tooltip.add(223, 4, 32, 32, "Toggle overlay");
|
||||
|
||||
match self.sim_state {
|
||||
SimState::Editing => {
|
||||
if simple_button(d, 260, 4, 32, 32) {
|
||||
self.init_sim();
|
||||
self.sim_state = SimState::Running;
|
||||
}
|
||||
draw_scaled_texture(d, textures.get("play"), 260, 4, 2.);
|
||||
}
|
||||
SimState::Running => {
|
||||
if self.sim_state == SimState::Running {
|
||||
self.tooltip.add(260, 4, 32, 32, "Pause");
|
||||
if simple_button(d, 260, 4, 32, 32) {
|
||||
self.sim_state = SimState::Stepping;
|
||||
}
|
||||
draw_scaled_texture(d, textures.get("pause"), 260, 4, 2.);
|
||||
if simple_button(d, 296, 4, 32, 32) {
|
||||
self.sim_state = SimState::Editing;
|
||||
self.popup = EndPopup::None;
|
||||
}
|
||||
draw_scaled_texture(d, textures.get("stop"), 296, 4, 2.);
|
||||
}
|
||||
SimState::Stepping => {
|
||||
} else {
|
||||
self.tooltip.add(260, 4, 32, 32, "Start");
|
||||
if simple_button(d, 260, 4, 32, 32) {
|
||||
if self.sim_state == SimState::Editing {
|
||||
self.init_sim()
|
||||
}
|
||||
self.sim_state = SimState::Running;
|
||||
}
|
||||
draw_scaled_texture(d, textures.get("play"), 260, 4, 2.);
|
||||
}
|
||||
|
||||
if self.sim_state != SimState::Editing {
|
||||
self.tooltip.add(296, 4, 32, 32, "Stop");
|
||||
if simple_button(d, 296, 4, 32, 32) {
|
||||
self.sim_state = SimState::Editing;
|
||||
self.popup = EndPopup::None;
|
||||
}
|
||||
draw_scaled_texture(d, textures.get("stop"), 296, 4, 2.);
|
||||
}
|
||||
}
|
||||
|
||||
self.tooltip.add(332, 4, 32, 32, "Step");
|
||||
if simple_button(d, 332, 4, 32, 32) {
|
||||
self.step_pressed();
|
||||
}
|
||||
draw_scaled_texture(d, textures.get("step"), 332, 4, 2.);
|
||||
|
||||
self.tooltip.add(368, 4, 48, 32, "Speed");
|
||||
draw_usize(d, textures, 1 << self.sim_speed, 368, 4, SPEED_DIGITS, 1);
|
||||
slider(d, &mut self.sim_speed, 0, MAX_SPEED_POWER, 368, 24, 48, 12);
|
||||
|
||||
self.tooltip.add(420, 4, 180, 32, "Steps");
|
||||
draw_usize(d, textures, self.machine.step_count(), 420, 4, 9, 2);
|
||||
if self.stage > Some(0) {
|
||||
self.tooltip.add(420, 44, 180, 32, "Total steps");
|
||||
let total_steps = self.total_steps + self.machine.step_count();
|
||||
draw_usize(d, textures, total_steps, 420, 44, 9, 2);
|
||||
}
|
||||
|
@ -875,7 +885,8 @@ impl Editor {
|
|||
}
|
||||
|
||||
let mouse_pos = d.get_mouse_position();
|
||||
let mut tool_button = |(row, col): (i32, i32), texture: &str, tool_option: Tool| {
|
||||
let mut tool_button =
|
||||
|(row, col): (i32, i32), texture: &str, tooltip: &'static str, tool_option: Tool| {
|
||||
let border = 4.;
|
||||
let gap = 2.;
|
||||
let tex_size = 32.;
|
||||
|
@ -895,30 +906,67 @@ impl Editor {
|
|||
border,
|
||||
);
|
||||
let bounds = Rectangle::new(pos.x, pos.y, button_size, button_size);
|
||||
self.tooltip.add_rec(bounds, tooltip);
|
||||
if bounds.check_collision_point_rec(mouse_pos) {
|
||||
get_scroll(d)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
};
|
||||
tool_button((0, -2), "eraser", Tool::Erase);
|
||||
tool_button((1, -2), "selection", Tool::SelectArea(Selection::default()));
|
||||
tool_button((0, -2), "eraser", "Eraser", Tool::Erase);
|
||||
tool_button(
|
||||
(1, -2),
|
||||
"selection",
|
||||
"Select",
|
||||
Tool::SelectArea(Selection::default()),
|
||||
);
|
||||
|
||||
tool_button((0, -1), "blueprint", Tool::Blueprint);
|
||||
tool_button((1, -1), "transparent", Tool::None);
|
||||
tool_button((0, -1), "blueprint", "Blueprints", Tool::Blueprint);
|
||||
tool_button((1, -1), "transparent", "None", Tool::None);
|
||||
|
||||
if !hide_tile_tools {
|
||||
tool_button((0, 0), "block", Tool::SetTile(Tile::from_char('#')));
|
||||
tool_button((0, 1), "silo_off", Tool::SetTile(Tile::from_char('B')));
|
||||
tool_button((0, 2), "button_off", Tool::SetTile(Tile::from_char('*')));
|
||||
tool_button((0, 3), "io_tile_off", Tool::SetTile(Tile::from_char('I')));
|
||||
tool_button((0, 4), "flipper_off", Tool::SetTile(Tile::from_char('F')));
|
||||
tool_button((0, 5), "digit_tool", Tool::Digits(None));
|
||||
tool_button(
|
||||
(0, 0),
|
||||
"block",
|
||||
"Block",
|
||||
Tool::SetTile(Tile::from_char('#')),
|
||||
);
|
||||
tool_button(
|
||||
(0, 1),
|
||||
"silo_off",
|
||||
"Silo",
|
||||
Tool::SetTile(Tile::from_char('B')),
|
||||
);
|
||||
tool_button(
|
||||
(0, 2),
|
||||
"button_off",
|
||||
"Button",
|
||||
Tool::SetTile(Tile::from_char('*')),
|
||||
);
|
||||
tool_button(
|
||||
(0, 3),
|
||||
"io_tile_off",
|
||||
"Input/Output silo",
|
||||
Tool::SetTile(Tile::from_char('I')),
|
||||
);
|
||||
tool_button(
|
||||
(0, 4),
|
||||
"flipper_off",
|
||||
"Flipper",
|
||||
Tool::SetTile(Tile::from_char('F')),
|
||||
);
|
||||
tool_button((0, 5), "digit_tool", "Digit", Tool::Digits(None));
|
||||
|
||||
tool_button((1, 0), "marble", Tool::SetTile(Tile::from_char('o')));
|
||||
tool_button(
|
||||
(1, 0),
|
||||
"marble",
|
||||
"Marble",
|
||||
Tool::SetTile(Tile::from_char('o')),
|
||||
);
|
||||
match tool_button(
|
||||
(1, 1),
|
||||
Tile::Wire(self.tool_wire, false).texture(),
|
||||
self.tool_wire.texture_name_off(),
|
||||
self.tool_wire.human_name(),
|
||||
Tool::Wire,
|
||||
) {
|
||||
Some(Scroll::Down) => self.tool_wire.next(),
|
||||
|
@ -926,14 +974,20 @@ impl Editor {
|
|||
None => (),
|
||||
}
|
||||
|
||||
match tool_button((1, 2), Tile::Arrow(self.tool_arrow).texture(), Tool::Arrow) {
|
||||
match tool_button(
|
||||
(1, 2),
|
||||
self.tool_arrow.arrow_tile_texture_name(),
|
||||
self.tool_arrow.arrow_tile_human_name(),
|
||||
Tool::Arrow,
|
||||
) {
|
||||
Some(Scroll::Down) => self.tool_arrow = self.tool_arrow.right(),
|
||||
Some(Scroll::Up) => self.tool_arrow = self.tool_arrow.left(),
|
||||
None => (),
|
||||
}
|
||||
if tool_button(
|
||||
(1, 3),
|
||||
Tile::Mirror(self.tool_mirror).texture(),
|
||||
self.tool_mirror.texture_name(),
|
||||
self.tool_mirror.human_name(),
|
||||
Tool::Mirror,
|
||||
)
|
||||
.is_some()
|
||||
|
@ -942,7 +996,8 @@ impl Editor {
|
|||
}
|
||||
match tool_button(
|
||||
(1, 4),
|
||||
Tile::Powerable(PTile::Math(self.tool_math), false).texture(),
|
||||
self.tool_math.texture_name_off(),
|
||||
self.tool_math.human_name(),
|
||||
Tool::Math,
|
||||
) {
|
||||
Some(Scroll::Down) => self.tool_math.next(),
|
||||
|
@ -951,7 +1006,8 @@ impl Editor {
|
|||
}
|
||||
match tool_button(
|
||||
(1, 5),
|
||||
Tile::Powerable(PTile::Comparator(self.tool_comparator), false).texture(),
|
||||
self.tool_comparator.texture_name_off(),
|
||||
self.tool_comparator.human_name(),
|
||||
Tool::Comparator,
|
||||
) {
|
||||
Some(Scroll::Down) => self.tool_comparator.next(),
|
||||
|
|
|
@ -270,6 +270,15 @@ impl Direction {
|
|||
}
|
||||
}
|
||||
|
||||
pub const fn arrow_tile_human_name(self) -> &'static str {
|
||||
match self {
|
||||
Direction::Up => "Up Arrow",
|
||||
Direction::Down => "Down Arrow",
|
||||
Direction::Left => "Left Arrow",
|
||||
Direction::Right => "Right Arrow",
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn arrow_texture_name(self) -> &'static str {
|
||||
match self {
|
||||
Direction::Up => "direction_up",
|
||||
|
@ -320,6 +329,7 @@ impl WireType {
|
|||
WireType::Cross => "wire_cross_on",
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn texture_name_off(self) -> &'static str {
|
||||
match self {
|
||||
WireType::Vertical => "wire_vertical_off",
|
||||
|
@ -327,6 +337,14 @@ impl WireType {
|
|||
WireType::Cross => "wire_cross_off",
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn human_name(self) -> &'static str {
|
||||
match self {
|
||||
WireType::Vertical => "Vertical Wire",
|
||||
WireType::Horizontal => "Horizontal Wire",
|
||||
WireType::Cross => "Wire Cross",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MirrorType {
|
||||
|
@ -360,9 +378,26 @@ impl MirrorType {
|
|||
MirrorType::Back => "mirror_back",
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn human_name(self) -> &'static str {
|
||||
match self {
|
||||
MirrorType::Forward => "Mirror A",
|
||||
MirrorType::Back => "Mirror B",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MathOp {
|
||||
pub const fn human_name(self) -> &'static str {
|
||||
match self {
|
||||
MathOp::Add => "Math: Add",
|
||||
MathOp::Sub => "Math: Subtract",
|
||||
MathOp::Mul => "Math: Multiply",
|
||||
MathOp::Div => "Math: Divide",
|
||||
MathOp::Rem => "Math: Remainder",
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn texture_name_on(self) -> &'static str {
|
||||
match self {
|
||||
MathOp::Add => "add_on",
|
||||
|
@ -372,6 +407,7 @@ impl MathOp {
|
|||
MathOp::Rem => "rem_on",
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn texture_name_off(self) -> &'static str {
|
||||
match self {
|
||||
MathOp::Add => "add_off",
|
||||
|
@ -404,6 +440,15 @@ impl MathOp {
|
|||
}
|
||||
|
||||
impl Comparison {
|
||||
pub const fn human_name(self) -> &'static str {
|
||||
match self {
|
||||
Comparison::LessThan => "Comparator: Less than",
|
||||
Comparison::GreaterThan => "Comparator: Greater than",
|
||||
Comparison::Equal => "Comparator: Equal",
|
||||
Comparison::NotEqual => "Comparator: Not Equal",
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn texture_name_on(self) -> &'static str {
|
||||
match self {
|
||||
Comparison::LessThan => "lt_on",
|
||||
|
@ -412,6 +457,7 @@ impl Comparison {
|
|||
Comparison::NotEqual => "neq_on",
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn texture_name_off(self) -> &'static str {
|
||||
match self {
|
||||
Comparison::LessThan => "lt_off",
|
||||
|
|
64
src/util.rs
64
src/util.rs
|
@ -44,6 +44,70 @@ pub fn simple_button(d: &mut RaylibDrawHandle, x: i32, y: i32, width: i32, heigh
|
|||
pressed
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Tooltip {
|
||||
text: Option<&'static str>,
|
||||
mouse_x: i32,
|
||||
mouse_y: i32,
|
||||
screen_width: i32,
|
||||
screen_height: i32,
|
||||
}
|
||||
|
||||
impl Tooltip {
|
||||
pub fn init_frame(&mut self, d: &mut RaylibDrawHandle) {
|
||||
let p = d.get_mouse_position();
|
||||
*self = Self {
|
||||
text: None,
|
||||
mouse_x: p.x as i32,
|
||||
mouse_y: p.y as i32,
|
||||
screen_width: d.get_screen_width(),
|
||||
screen_height: d.get_screen_height(),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn add(&mut self, x: i32, y: i32, width: i32, height: i32, text: &'static str) {
|
||||
if self.mouse_x >= x
|
||||
&& self.mouse_y >= y
|
||||
&& self.mouse_x <= (x + width)
|
||||
&& self.mouse_y <= (y + height)
|
||||
{
|
||||
self.text = Some(text);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_rec(&mut self, bounds: Rectangle, text: &'static str) {
|
||||
self.add(
|
||||
bounds.x as i32,
|
||||
bounds.y as i32,
|
||||
bounds.width as i32,
|
||||
bounds.height as i32,
|
||||
text,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn draw(&self, d: &mut RaylibDrawHandle) {
|
||||
if let Some(text) = self.text {
|
||||
let font_size = 20;
|
||||
let margin = 4;
|
||||
let text_width = d.measure_text(text, font_size);
|
||||
let x = self
|
||||
.mouse_x
|
||||
.min(self.screen_width - text_width - margin * 2);
|
||||
let y = self
|
||||
.mouse_y
|
||||
.min(self.screen_height - font_size - margin * 2);
|
||||
d.draw_rectangle(
|
||||
x,
|
||||
y,
|
||||
text_width + margin * 2,
|
||||
font_size + margin * 2,
|
||||
BG_LIGHT,
|
||||
);
|
||||
d.draw_text(text, x + margin, y + margin, font_size, Color::WHITE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn simple_toggle_button(
|
||||
d: &mut RaylibDrawHandle,
|
||||
state: &mut bool,
|
||||
|
|
Loading…
Reference in a new issue