Implemented infrastructure for tools to show modal dialogs. - icy_draw - icy_draw is the successor to mystic draw. fork / mirror
HTML git clone https://git.drkhsh.at/icy_draw.git
DIR Log
DIR Files
DIR Refs
DIR README
DIR LICENSE
---
DIR commit 12c2e402fb179e793a7ef318d70eb90a03a9a2a5
DIR parent f23f4c1556c2ac7c2095a6b74debf94be5e14d71
HTML Author: Mike Krüger <mkrueger@posteo.de>
Date: Thu, 27 Jul 2023 07:40:50 +0200
Implemented infrastructure for tools to show modal dialogs.
Diffstat:
M i18n/en/icy_draw.ftl | 6 ++++--
M src/model/tool/brush_imp.rs | 124 ++++++++++++++++---------------
M src/model/tool/click_imp.rs | 5 +++--
M src/model/tool/draw_ellipse_filled… | 12 +++++++-----
M src/model/tool/draw_ellipse_imp.rs | 12 +++++++-----
M src/model/tool/draw_rectangle_fill… | 12 +++++++-----
M src/model/tool/draw_rectangle_imp.… | 12 +++++++-----
M src/model/tool/erase_imp.rs | 5 +++--
M src/model/tool/fill_imp.rs | 12 +++++++-----
M src/model/tool/flip_imp.rs | 5 +++--
M src/model/tool/font_imp.rs | 13 +++++++------
M src/model/tool/line_imp.rs | 12 +++++++-----
M src/model/tool/mod.rs | 13 ++++++++++++-
M src/model/tool/move_layer_imp.rs | 5 +++--
M src/model/tool/pencil_imp.rs | 14 ++++++++------
M src/model/tool/pipette_imp.rs | 5 +++--
M src/ui/ansi_editor/mod.rs | 2 +-
M src/ui/char_table.rs | 2 +-
M src/ui/main_window.rs | 23 +++++++++++++----------
M src/ui/mod.rs | 3 +++
A src/ui/select_character_dialog.rs | 64 +++++++++++++++++++++++++++++++
21 files changed, 234 insertions(+), 127 deletions(-)
---
DIR diff --git a/i18n/en/icy_draw.ftl b/i18n/en/icy_draw.ftl
@@ -80,4 +80,6 @@ export-save-sauce-label=Save sauce info
export-compression-level-label=Compression level
export-compression-level-off=Off
export-compression-level-medium=Medium
-export-compression-level-high=High
-\ No newline at end of file
+export-compression-level-high=High
+
+select-character-title=Select Character
+\ No newline at end of file
DIR diff --git a/src/model/tool/brush_imp.rs b/src/model/tool/brush_imp.rs
@@ -5,11 +5,11 @@ use eframe::{
use egui_extras::RetainedImage;
use i18n_embed_fl::fl;
use icy_engine::AttributedChar;
-use std::sync::{Arc, Mutex};
+use std::{sync::{Arc, Mutex}, rc::Rc, cell::RefCell};
-use crate::ansi_editor::BufferView;
+use crate::{ansi_editor::BufferView, SelectCharacterDialog};
-use super::{Editor, Position, Tool};
+use super::{Editor, Position, Tool, ToolUiResult};
#[derive(PartialEq, Eq)]
pub enum BrushType {
@@ -22,7 +22,7 @@ pub struct BrushTool {
pub use_fore: bool,
pub use_back: bool,
pub size: i32,
- pub char_code: char,
+ pub char_code: Rc<RefCell<char>>,
pub font_page: usize,
pub brush_type: BrushType,
@@ -66,7 +66,7 @@ impl BrushTool {
let attribute = editor.caret.get_attribute();
editor.set_char(
center + Position::new(x, y),
- Some(AttributedChar::new(self.char_code, attribute)),
+ Some(AttributedChar::new(*self.char_code.borrow(), attribute)),
);
}
BrushType::Color => {
@@ -106,7 +106,8 @@ impl Tool for BrushTool {
_ctx: &egui::Context,
ui: &mut egui::Ui,
buffer_opt: Option<std::sync::Arc<std::sync::Mutex<crate::ui::ansi_editor::BufferView>>>,
- ) {
+ ) -> ToolUiResult {
+ let mut result = ToolUiResult::new();
ui.vertical_centered(|ui| {
ui.horizontal(|ui| {
if ui
@@ -144,7 +145,7 @@ impl Tool for BrushTool {
);
if let Some(b) = &buffer_opt {
- ui.add(draw_glyph(b.clone(), self.char_code, self.font_page));
+ draw_glyph(ui, b.clone(), &mut result,self.char_code.clone(), self.font_page);
}
});
ui.radio_value(
@@ -152,6 +153,7 @@ impl Tool for BrushTool {
BrushType::Color,
fl!(crate::LANGUAGE_LOADER, "tool-colorize"),
);
+ result
}
fn handle_click(
@@ -179,62 +181,64 @@ impl Tool for BrushTool {
}
}
-pub fn draw_glyph(buf: Arc<Mutex<BufferView>>, ch: char, font_page: usize) -> impl egui::Widget {
- move |ui: &mut egui::Ui| {
- let font = &buf.lock().unwrap().editor.buf.font_table[font_page];
- let scale = 1.5;
- let (id, stroke_rect) = ui.allocate_space(Vec2::new(
- scale * font.size.width as f32,
- scale * font.size.height as f32,
- ));
- let mut response = ui.interact(stroke_rect, id, Sense::click());
-
- let col = if response.hovered() {
- Color32::WHITE
- } else {
- Color32::GRAY
- };
-
- let painter = ui.painter_at(stroke_rect);
- painter.rect_filled(stroke_rect, Rounding::none(), Color32::BLACK);
- let s = font.size;
- if let Some(glyph) = font.get_glyph(ch) {
- for y in 0..s.height {
- for x in 0..s.width {
- if glyph.data[y as usize] & (128 >> x) != 0 {
- painter.rect_filled(
- Rect::from_min_size(
- Pos2::new(
- stroke_rect.left() + x as f32 * scale,
- stroke_rect.top() + y as f32 * scale,
- ),
- Vec2::new(scale, scale),
+pub fn draw_glyph(ui: &mut egui::Ui, buf: Arc<Mutex<BufferView>>, ui_result: &mut ToolUiResult, ch: Rc<RefCell<char>>, font_page: usize) {
+ let font = &buf.lock().unwrap().editor.buf.font_table[font_page];
+ let scale = 1.5;
+ let (id, stroke_rect) = ui.allocate_space(Vec2::new(
+ scale * font.size.width as f32,
+ scale * font.size.height as f32,
+ ));
+ let mut response = ui.interact(stroke_rect, id, Sense::click());
+
+ let col = if response.hovered() {
+ Color32::WHITE
+ } else {
+ Color32::GRAY
+ };
+
+ if response.clicked() {
+ ui_result.modal_dialog = Some(Box::new(SelectCharacterDialog::new(ch.clone())));
+ }
+
+ let painter = ui.painter_at(stroke_rect);
+ painter.rect_filled(stroke_rect, Rounding::none(), Color32::BLACK);
+ let s = font.size;
+ let ch = *ch.borrow();
+ if let Some(glyph) = font.get_glyph(ch) {
+ for y in 0..s.height {
+ for x in 0..s.width {
+ if glyph.data[y as usize] & (128 >> x) != 0 {
+ painter.rect_filled(
+ Rect::from_min_size(
+ Pos2::new(
+ stroke_rect.left() + x as f32 * scale,
+ stroke_rect.top() + y as f32 * scale,
),
- Rounding::none(),
- col,
- );
- }
+ Vec2::new(scale, scale),
+ ),
+ Rounding::none(),
+ col,
+ );
}
}
- response = response.on_hover_ui(|ui| {
- ui.horizontal(|ui| {
- ui.label(RichText::new("Char").small());
- ui.label(
- RichText::new(format!("{0}/0x{0:02X}", ch as u32))
- .small()
- .color(Color32::WHITE),
- );
- });
- ui.horizontal(|ui| {
- ui.label(RichText::new("Font").small());
- ui.label(
- RichText::new(font.name.to_string())
- .small()
- .color(Color32::WHITE),
- );
- });
- });
}
- response
+ response = response.on_hover_ui(|ui| {
+ ui.horizontal(|ui| {
+ ui.label(RichText::new("Char").small());
+ ui.label(
+ RichText::new(format!("{0}/0x{0:02X}", ch as u32))
+ .small()
+ .color(Color32::WHITE),
+ );
+ });
+ ui.horizontal(|ui| {
+ ui.label(RichText::new("Font").small());
+ ui.label(
+ RichText::new(font.name.to_string())
+ .small()
+ .color(Color32::WHITE),
+ );
+ });
+ });
}
}
DIR diff --git a/src/model/tool/click_imp.rs b/src/model/tool/click_imp.rs
@@ -9,7 +9,7 @@ use crate::{
model::{Selection, Shape},
};
-use super::{Event, Position, Tool};
+use super::{Event, Position, Tool, ToolUiResult};
pub struct ClickTool {}
@@ -23,7 +23,8 @@ impl Tool for ClickTool {
_ctx: &egui::Context,
_ui: &mut egui::Ui,
_buffer_opt: Option<std::sync::Arc<std::sync::Mutex<crate::ui::ansi_editor::BufferView>>>,
- ) {
+ ) -> ToolUiResult {
+ ToolUiResult::new()
}
fn handle_click(
DIR diff --git a/src/model/tool/draw_ellipse_filled_imp.rs b/src/model/tool/draw_ellipse_filled_imp.rs
@@ -7,7 +7,7 @@ use icy_engine::{Rectangle, TextAttribute};
use crate::ansi_editor::BufferView;
use super::{
- brush_imp::draw_glyph, plot_point, DrawMode, Event, Plottable, Position, ScanLines, Tool,
+ brush_imp::draw_glyph, plot_point, DrawMode, Event, Plottable, Position, ScanLines, Tool, ToolUiResult,
};
pub struct DrawEllipseFilledTool {
@@ -16,7 +16,7 @@ pub struct DrawEllipseFilledTool {
pub use_fore: bool,
pub use_back: bool,
pub attr: TextAttribute,
- pub char_code: char,
+ pub char_code: std::rc::Rc<std::cell::RefCell<char>>,
pub font_page: usize,
}
@@ -31,7 +31,7 @@ impl Plottable for DrawEllipseFilledTool {
self.use_back
}
fn get_char_code(&self) -> char {
- self.char_code
+ *self.char_code.borrow()
}
}
@@ -52,7 +52,8 @@ impl Tool for DrawEllipseFilledTool {
_ctx: &egui::Context,
ui: &mut egui::Ui,
buffer_opt: Option<std::sync::Arc<std::sync::Mutex<crate::ui::ansi_editor::BufferView>>>,
- ) {
+ ) -> ToolUiResult {
+ let mut result = ToolUiResult::new();
ui.vertical_centered(|ui| {
ui.horizontal(|ui| {
if ui
@@ -83,7 +84,7 @@ impl Tool for DrawEllipseFilledTool {
);
if let Some(b) = &buffer_opt {
- ui.add(draw_glyph(b.clone(), self.char_code, self.font_page));
+ draw_glyph(ui, b.clone(), &mut result,self.char_code.clone(), self.font_page);
}
});
ui.radio_value(
@@ -96,6 +97,7 @@ impl Tool for DrawEllipseFilledTool {
DrawMode::Colorize,
fl!(crate::LANGUAGE_LOADER, "tool-colorize"),
);
+ result
}
fn handle_drag(
DIR diff --git a/src/model/tool/draw_ellipse_imp.rs b/src/model/tool/draw_ellipse_imp.rs
@@ -8,7 +8,7 @@ use crate::ansi_editor::BufferView;
use super::{
brush_imp::draw_glyph, line_imp::set_half_block, DrawMode, Event, Plottable, Position,
- ScanLines, Tool,
+ ScanLines, Tool, ToolUiResult,
};
pub struct DrawEllipseTool {
@@ -17,7 +17,7 @@ pub struct DrawEllipseTool {
pub use_fore: bool,
pub use_back: bool,
pub attr: TextAttribute,
- pub char_code: char,
+ pub char_code: std::rc::Rc<std::cell::RefCell<char>>,
pub font_page: usize,
}
@@ -32,7 +32,7 @@ impl Plottable for DrawEllipseTool {
self.use_back
}
fn get_char_code(&self) -> char {
- self.char_code
+ *self.char_code.borrow()
}
}
@@ -53,7 +53,8 @@ impl Tool for DrawEllipseTool {
_ctx: &egui::Context,
ui: &mut egui::Ui,
buffer_opt: Option<std::sync::Arc<std::sync::Mutex<crate::ui::ansi_editor::BufferView>>>,
- ) {
+ ) -> ToolUiResult {
+ let mut result = ToolUiResult::new();
ui.vertical_centered(|ui| {
ui.horizontal(|ui| {
if ui
@@ -84,7 +85,7 @@ impl Tool for DrawEllipseTool {
);
if let Some(b) = &buffer_opt {
- ui.add(draw_glyph(b.clone(), self.char_code, self.font_page));
+ draw_glyph(ui, b.clone(), &mut result,self.char_code.clone(), self.font_page);
}
});
ui.radio_value(
@@ -97,6 +98,7 @@ impl Tool for DrawEllipseTool {
DrawMode::Colorize,
fl!(crate::LANGUAGE_LOADER, "tool-colorize"),
);
+ result
}
fn handle_drag(
DIR diff --git a/src/model/tool/draw_rectangle_filled_imp.rs b/src/model/tool/draw_rectangle_filled_imp.rs
@@ -4,7 +4,7 @@ use icy_engine::{Position, Rectangle, TextAttribute};
use crate::ansi_editor::BufferView;
-use super::{brush_imp::draw_glyph, plot_point, DrawMode, Event, Plottable, ScanLines, Tool};
+use super::{brush_imp::draw_glyph, plot_point, DrawMode, Event, Plottable, ScanLines, Tool, ToolUiResult};
use std::sync::{Arc, Mutex};
pub struct DrawRectangleFilledTool {
@@ -13,7 +13,7 @@ pub struct DrawRectangleFilledTool {
pub use_fore: bool,
pub use_back: bool,
pub attr: TextAttribute,
- pub char_code: char,
+ pub char_code: std::rc::Rc<std::cell::RefCell<char>>,
pub font_page: usize,
}
@@ -29,7 +29,7 @@ impl Plottable for DrawRectangleFilledTool {
self.use_back
}
fn get_char_code(&self) -> char {
- self.char_code
+ *self.char_code.borrow()
}
}
@@ -50,7 +50,8 @@ impl Tool for DrawRectangleFilledTool {
_ctx: &egui::Context,
ui: &mut egui::Ui,
buffer_opt: Option<std::sync::Arc<std::sync::Mutex<crate::ui::ansi_editor::BufferView>>>,
- ) {
+ ) -> ToolUiResult {
+ let mut result = ToolUiResult::new();
ui.vertical_centered(|ui| {
ui.horizontal(|ui| {
if ui
@@ -81,7 +82,7 @@ impl Tool for DrawRectangleFilledTool {
);
if let Some(b) = &buffer_opt {
- ui.add(draw_glyph(b.clone(), self.char_code, self.font_page));
+ draw_glyph(ui, b.clone(), &mut result,self.char_code.clone(), self.font_page);
}
});
ui.radio_value(
@@ -94,6 +95,7 @@ impl Tool for DrawRectangleFilledTool {
DrawMode::Colorize,
fl!(crate::LANGUAGE_LOADER, "tool-colorize"),
);
+ result
}
fn handle_drag(
DIR diff --git a/src/model/tool/draw_rectangle_imp.rs b/src/model/tool/draw_rectangle_imp.rs
@@ -6,7 +6,7 @@ use crate::ansi_editor::BufferView;
use super::{
brush_imp::draw_glyph, line_imp::set_half_block, DrawMode, Event, Plottable, Position,
- ScanLines, Tool,
+ ScanLines, Tool, ToolUiResult,
};
use std::sync::{Arc, Mutex};
@@ -16,7 +16,7 @@ pub struct DrawRectangleTool {
pub use_fore: bool,
pub use_back: bool,
pub attr: TextAttribute,
- pub char_code: char,
+ pub char_code: std::rc::Rc<std::cell::RefCell<char>>,
pub font_page: usize,
}
@@ -32,7 +32,7 @@ impl Plottable for DrawRectangleTool {
self.use_back
}
fn get_char_code(&self) -> char {
- self.char_code
+ *self.char_code.borrow()
}
}
@@ -52,7 +52,8 @@ impl Tool for DrawRectangleTool {
_ctx: &egui::Context,
ui: &mut egui::Ui,
buffer_opt: Option<std::sync::Arc<std::sync::Mutex<crate::ui::ansi_editor::BufferView>>>,
- ) {
+ ) -> ToolUiResult {
+ let mut result = ToolUiResult::new();
ui.vertical_centered(|ui| {
ui.horizontal(|ui| {
if ui
@@ -83,7 +84,7 @@ impl Tool for DrawRectangleTool {
);
if let Some(b) = &buffer_opt {
- ui.add(draw_glyph(b.clone(), self.char_code, self.font_page));
+ draw_glyph(ui, b.clone(), &mut result,self.char_code.clone(), self.font_page);
}
});
ui.radio_value(
@@ -96,6 +97,7 @@ impl Tool for DrawRectangleTool {
DrawMode::Colorize,
fl!(crate::LANGUAGE_LOADER, "tool-colorize"),
);
+ result
}
fn handle_drag(
DIR diff --git a/src/model/tool/erase_imp.rs b/src/model/tool/erase_imp.rs
@@ -6,7 +6,7 @@ use icy_engine::{AttributedChar, TextAttribute};
use crate::ansi_editor::BufferView;
-use super::{Editor, Position, Tool};
+use super::{Editor, Position, Tool, ToolUiResult};
#[derive(PartialEq, Eq)]
pub enum EraseType {
@@ -87,7 +87,7 @@ impl Tool for EraseTool {
_ctx: &egui::Context,
ui: &mut egui::Ui,
_buffer_opt: Option<std::sync::Arc<std::sync::Mutex<crate::ui::ansi_editor::BufferView>>>,
- ) {
+ ) -> ToolUiResult {
ui.horizontal(|ui| {
ui.label(fl!(crate::LANGUAGE_LOADER, "tool-size-label"));
ui.add(
@@ -106,6 +106,7 @@ impl Tool for EraseTool {
EraseType::Shade,
fl!(crate::LANGUAGE_LOADER, "tool-shade"),
);
+ ToolUiResult::new()
}
fn handle_click(
DIR diff --git a/src/model/tool/fill_imp.rs b/src/model/tool/fill_imp.rs
@@ -9,7 +9,7 @@ use icy_engine::{AttributedChar, TextAttribute};
use crate::ansi_editor::BufferView;
-use super::{brush_imp::draw_glyph, Editor, Event, Position, Tool};
+use super::{brush_imp::draw_glyph, Editor, Event, Position, Tool, ToolUiResult};
#[derive(PartialEq, Eq)]
pub enum FillType {
@@ -22,7 +22,7 @@ pub struct FillTool {
pub use_back: bool,
pub attr: TextAttribute,
- pub char_code: char,
+ pub char_code: std::rc::Rc<std::cell::RefCell<char>>,
pub font_page: usize,
pub fill_type: FillType,
}
@@ -157,7 +157,8 @@ impl Tool for FillTool {
_ctx: &egui::Context,
ui: &mut egui::Ui,
buffer_opt: Option<std::sync::Arc<std::sync::Mutex<crate::ui::ansi_editor::BufferView>>>,
- ) {
+ ) -> ToolUiResult {
+ let mut result = ToolUiResult::new();
ui.vertical_centered(|ui| {
ui.horizontal(|ui| {
if ui
@@ -183,7 +184,7 @@ impl Tool for FillTool {
);
if let Some(b) = &buffer_opt {
- ui.add(draw_glyph(b.clone(), self.char_code, self.font_page));
+ draw_glyph(ui, b.clone(), &mut result,self.char_code.clone(), self.font_page);
}
});
ui.radio_value(
@@ -191,6 +192,7 @@ impl Tool for FillTool {
FillType::Colorize,
fl!(crate::LANGUAGE_LOADER, "tool-colorize"),
);
+ result
}
fn handle_click(
@@ -215,7 +217,7 @@ impl Tool for FillTool {
attr,
pos,
ch,
- AttributedChar::new(self.char_code, attr),
+ AttributedChar::new(*self.char_code.borrow(), attr),
);
editor.end_atomic_undo();
}
DIR diff --git a/src/model/tool/flip_imp.rs b/src/model/tool/flip_imp.rs
@@ -4,7 +4,7 @@ use eframe::egui;
use crate::ansi_editor::BufferView;
-use super::{Event, Position, Tool};
+use super::{Event, Position, Tool, ToolUiResult};
pub struct FlipTool {}
impl Tool for FlipTool {
@@ -22,7 +22,8 @@ impl Tool for FlipTool {
_ctx: &egui::Context,
_ui: &mut egui::Ui,
_buffer_opt: Option<std::sync::Arc<std::sync::Mutex<crate::ui::ansi_editor::BufferView>>>,
- ) {
+ ) -> ToolUiResult {
+ ToolUiResult::new()
}
fn handle_click(
DIR diff --git a/src/model/tool/font_imp.rs b/src/model/tool/font_imp.rs
@@ -5,7 +5,7 @@ use std::{
use crate::ansi_editor::BufferView;
-use super::{Event, MKey, MModifiers, Position, Tool};
+use super::{Event, MKey, MModifiers, Position, Tool, ToolUiResult};
use directories::ProjectDirs;
use eframe::{
egui::{self, ComboBox},
@@ -23,9 +23,9 @@ pub struct FontTool {
}
impl FontTool {
- pub fn get_selected_font(&self) -> Option<&TheDrawFont> {
+ /*pub fn get_selected_font(&self) -> Option<&TheDrawFont> {
self.fonts.get(self.selected_font as usize)
- }
+ }*/
fn is_hidden(entry: &DirEntry) -> bool {
entry
@@ -86,10 +86,10 @@ impl Tool for FontTool {
fn show_ui(
&mut self,
- ctx: &egui::Context,
+ _ctx: &egui::Context,
ui: &mut egui::Ui,
- buffer_opt: Option<std::sync::Arc<std::sync::Mutex<crate::ui::ansi_editor::BufferView>>>,
- ) {
+ _buffer_opt: Option<std::sync::Arc<std::sync::Mutex<crate::ui::ansi_editor::BufferView>>>,
+ ) -> ToolUiResult {
ui.vertical_centered(|ui| {
let mut selected_text = "<none>".to_string();
@@ -113,6 +113,7 @@ impl Tool for FontTool {
}
});
});
+ ToolUiResult::new()
}
fn handle_click(
DIR diff --git a/src/model/tool/line_imp.rs b/src/model/tool/line_imp.rs
@@ -7,7 +7,7 @@ use icy_engine::{AttributedChar, Rectangle, TextAttribute};
use crate::{ansi_editor::BufferView, model::ScanLines};
use super::{
- brush_imp::draw_glyph, plot_point, DrawMode, Editor, Event, Plottable, Position, Tool,
+ brush_imp::draw_glyph, plot_point, DrawMode, Editor, Event, Plottable, Position, Tool, ToolUiResult,
};
pub struct LineTool {
@@ -16,7 +16,7 @@ pub struct LineTool {
pub use_fore: bool,
pub use_back: bool,
pub attr: TextAttribute,
- pub char_code: char,
+ pub char_code: std::rc::Rc<std::cell::RefCell<char>>,
pub font_page: usize,
pub old_pos: Position,
@@ -34,7 +34,7 @@ impl Plottable for LineTool {
self.use_back
}
fn get_char_code(&self) -> char {
- self.char_code
+ *self.char_code.borrow()
}
}
@@ -196,7 +196,8 @@ impl Tool for LineTool {
_ctx: &egui::Context,
ui: &mut egui::Ui,
buffer_opt: Option<std::sync::Arc<std::sync::Mutex<crate::ui::ansi_editor::BufferView>>>,
- ) {
+ ) -> ToolUiResult {
+ let mut result = ToolUiResult::new();
ui.vertical_centered(|ui| {
ui.horizontal(|ui| {
if ui
@@ -227,7 +228,7 @@ impl Tool for LineTool {
);
if let Some(b) = &buffer_opt {
- ui.add(draw_glyph(b.clone(), self.char_code, self.font_page));
+ draw_glyph(ui, b.clone(), &mut result,self.char_code.clone(), self.font_page);
}
});
ui.radio_value(
@@ -240,6 +241,7 @@ impl Tool for LineTool {
DrawMode::Colorize,
fl!(crate::LANGUAGE_LOADER, "tool-colorize"),
);
+ result
}
/*
fn handle_key(
DIR diff --git a/src/model/tool/mod.rs b/src/model/tool/mod.rs
@@ -78,6 +78,17 @@ impl MModifiers {
matches!(self, MModifiers::Control)
}
}
+pub struct ToolUiResult {
+ pub modal_dialog: Option<Box<dyn crate::ModalDialog>>
+}
+
+impl ToolUiResult {
+ pub fn new() -> Self {
+ Self {
+ modal_dialog: None
+ }
+ }
+}
pub trait Tool {
fn get_icon_name(&self) -> &'static RetainedImage;
@@ -95,7 +106,7 @@ pub trait Tool {
ctx: &egui::Context,
ui: &mut egui::Ui,
buffer_opt: Option<std::sync::Arc<std::sync::Mutex<crate::ui::ansi_editor::BufferView>>>,
- );
+ ) -> ToolUiResult;
fn handle_key(
&mut self,
DIR diff --git a/src/model/tool/move_layer_imp.rs b/src/model/tool/move_layer_imp.rs
@@ -1,4 +1,4 @@
-use super::{Event, Position, Tool};
+use super::{Event, Position, Tool, ToolUiResult};
use crate::ansi_editor::BufferView;
use eframe::egui;
use std::sync::{Arc, Mutex};
@@ -21,7 +21,8 @@ impl Tool for MoveLayer {
_ctx: &egui::Context,
_ui: &mut egui::Ui,
_buffer_opt: Option<std::sync::Arc<std::sync::Mutex<crate::ui::ansi_editor::BufferView>>>,
- ) {
+ ) -> ToolUiResult {
+ ToolUiResult::new()
}
fn handle_drag_begin(
DIR diff --git a/src/model/tool/pencil_imp.rs b/src/model/tool/pencil_imp.rs
@@ -9,7 +9,7 @@ use std::sync::{Arc, Mutex};
use crate::{ansi_editor::BufferView, model::ScanLines};
-use super::{line_imp::set_half_block, Position, Tool};
+use super::{line_imp::set_half_block, Position, Tool, ToolUiResult, brush_imp::draw_glyph};
#[derive(PartialEq, Eq)]
pub enum PencilType {
@@ -22,7 +22,7 @@ pub enum PencilType {
pub struct PencilTool {
pub use_fore: bool,
pub use_back: bool,
- pub char_code: char,
+ pub char_code: std::rc::Rc<std::cell::RefCell<char>>,
pub font_page: usize,
pub last_pos: Position,
@@ -77,7 +77,7 @@ impl PencilTool {
PencilType::Solid => {
let editor = &mut buffer_view.lock().unwrap().editor;
let attribute = editor.caret.get_attribute();
- editor.set_char(center, Some(AttributedChar::new(self.char_code, attribute)));
+ editor.set_char(center, Some(AttributedChar::new(*self.char_code.borrow(), attribute)));
}
PencilType::Color => {
let editor = &mut buffer_view.lock().unwrap().editor;
@@ -109,7 +109,8 @@ impl Tool for PencilTool {
_ctx: &egui::Context,
ui: &mut egui::Ui,
buffer_opt: Option<std::sync::Arc<std::sync::Mutex<crate::ui::ansi_editor::BufferView>>>,
- ) {
+ ) -> ToolUiResult {
+ let mut result = ToolUiResult::new();
ui.vertical_centered(|ui| {
ui.horizontal(|ui| {
if ui
@@ -144,7 +145,7 @@ impl Tool for PencilTool {
);
if let Some(b) = &buffer_opt {
- ui.add(draw_glyph(b.clone(), self.char_code, self.font_page));
+ draw_glyph(ui, b.clone(), &mut result,self.char_code.clone(), self.font_page);
}
});
ui.radio_value(
@@ -152,6 +153,7 @@ impl Tool for PencilTool {
PencilType::Color,
fl!(crate::LANGUAGE_LOADER, "tool-colorize"),
);
+ result
}
fn handle_click(
@@ -180,7 +182,7 @@ impl Tool for PencilTool {
}
}
-pub fn draw_glyph(buf: Arc<Mutex<BufferView>>, ch: char, font_page: usize) -> impl egui::Widget {
+pub fn draw_glyph_plain(buf: Arc<Mutex<BufferView>>, ch: char, font_page: usize) -> impl egui::Widget {
move |ui: &mut egui::Ui| {
let font = &buf.lock().unwrap().editor.buf.font_table[font_page];
let scale = 1.5;
DIR diff --git a/src/model/tool/pipette_imp.rs b/src/model/tool/pipette_imp.rs
@@ -4,7 +4,7 @@ use eframe::egui;
use crate::ansi_editor::BufferView;
-use super::{Event, Position, Tool};
+use super::{Event, Position, Tool, ToolUiResult};
pub struct PipetteTool {}
impl Tool for PipetteTool {
@@ -22,7 +22,8 @@ impl Tool for PipetteTool {
_ctx: &egui::Context,
_ui: &mut egui::Ui,
_buffer_opt: Option<std::sync::Arc<std::sync::Mutex<crate::ui::ansi_editor::BufferView>>>,
- ) {
+ ) -> ToolUiResult {
+ ToolUiResult::new()
}
fn handle_click(
DIR diff --git a/src/ui/ansi_editor/mod.rs b/src/ui/ansi_editor/mod.rs
@@ -430,7 +430,7 @@ impl Document for AnsiEditor {
.get_outline_char_code(i as i32)
.unwrap();
let cur_page = self.buffer_view.lock().unwrap().editor.cur_font_page;
- ui.add(draw_glyph(
+ ui.add(crate::model::pencil_imp::draw_glyph_plain(
self.buffer_view.clone(),
unsafe { char::from_u32_unchecked(ch as u32) },
cur_page,
DIR diff --git a/src/ui/char_table.rs b/src/ui/char_table.rs
@@ -18,7 +18,7 @@ pub fn show_char_table(buffer_opt: Option<Arc<Mutex<BufferView>>>) -> impl egui:
ui.horizontal_wrapped(|ui| {
for i in 0..font_length {
let ch = unsafe { char::from_u32_unchecked(i as u32) };
- if ui.add(draw_glyph(buffer.clone(), ch, font_page)).clicked() {
+ if ui.add(crate::model::pencil_imp::draw_glyph_plain(buffer.clone(), ch, font_page)).clicked() {
if let Ok(b) = &mut buffer.lock() {
let mut p = AsciiParser::new();
let editor = &mut b.editor;
DIR diff --git a/src/ui/main_window.rs b/src/ui/main_window.rs
@@ -2,7 +2,7 @@ use std::{
fs,
path::{Path, PathBuf},
sync::Arc,
- time::Duration,
+ time::Duration, cell::RefCell, rc::Rc,
};
use crate::{model::Tool, Document, EditSauceDialog, FontEditor, NewFileDialog, ModalDialog};
@@ -44,7 +44,7 @@ impl MainWindow {
use_back: true,
use_fore: true,
brush_type: crate::model::pencil_imp::PencilType::Shade,
- char_code: '\u{00B0}',
+ char_code: Rc::new(RefCell::new('\u{00B0}')),
font_page: 0,
last_pos: Position::default(),
}));
@@ -53,7 +53,7 @@ impl MainWindow {
use_back: true,
use_fore: true,
brush_type: crate::model::brush_imp::BrushType::Shade,
- char_code: '\u{00B0}',
+ char_code: Rc::new(RefCell::new('\u{00B0}')),
font_page: 0,
}));
tools.push(Box::new(crate::model::erase_imp::EraseTool {
@@ -66,7 +66,7 @@ impl MainWindow {
use_fore: true,
use_back: true,
attr: icy_engine::TextAttribute::default(),
- char_code: '\u{00B0}',
+ char_code: Rc::new(RefCell::new('\u{00B0}')),
font_page: 0,
old_pos: icy_engine::Position { x: 0, y: 0 },
}));
@@ -76,7 +76,7 @@ impl MainWindow {
use_fore: true,
use_back: true,
attr: icy_engine::TextAttribute::default(),
- char_code: '\u{00B0}',
+ char_code: Rc::new(RefCell::new('\u{00B0}')),
font_page: 0,
},
));
@@ -87,7 +87,7 @@ impl MainWindow {
use_fore: true,
use_back: true,
attr: icy_engine::TextAttribute::default(),
- char_code: '\u{00B0}',
+ char_code: Rc::new(RefCell::new('\u{00B0}')),
font_page: 0,
},
));
@@ -96,7 +96,7 @@ impl MainWindow {
use_fore: true,
use_back: true,
attr: icy_engine::TextAttribute::default(),
- char_code: '\u{00B0}',
+ char_code: Rc::new(RefCell::new('\u{00B0}')),
font_page: 0,
}));
@@ -106,7 +106,7 @@ impl MainWindow {
use_fore: true,
use_back: true,
attr: icy_engine::TextAttribute::default(),
- char_code: '\u{00B0}',
+ char_code: Rc::new(RefCell::new('\u{00B0}')),
font_page: 0,
},
));
@@ -114,7 +114,7 @@ impl MainWindow {
tools.push(Box::new(crate::model::fill_imp::FillTool {
use_fore: true,
use_back: true,
- char_code: '\u{00B0}',
+ char_code: Rc::new(RefCell::new('\u{00B0}')),
font_page: 0,
fill_type: crate::model::fill_imp::FillType::Character,
attr: icy_engine::TextAttribute::default(),
@@ -588,7 +588,10 @@ impl eframe::App for MainWindow {
crate::add_tool_switcher(ctx, ui, self);
if let Some(tool) = self.tab_viewer.tools.get_mut(self.tab_viewer.selected_tool) {
- tool.show_ui(ctx, ui, buffer_opt.clone());
+ let tool_result = tool.show_ui(ctx, ui, buffer_opt.clone());
+ if tool_result.modal_dialog.is_some() {
+ self.modal_dialog = tool_result.modal_dialog;
+ }
}
});
SidePanel::right("right_panel").show(ctx, |ui| {
DIR diff --git a/src/ui/mod.rs b/src/ui/mod.rs
@@ -36,6 +36,9 @@ mod export_file_dialog;
mod layer_view;
pub use layer_view::*;
+mod select_character_dialog;
+pub use select_character_dialog::*;
+
pub type TerminalResult<T> = Result<T, Box<dyn Error>>;
pub trait ModalDialog {
DIR diff --git a/src/ui/select_character_dialog.rs b/src/ui/select_character_dialog.rs
@@ -0,0 +1,63 @@
+use std::{rc::Rc, cell::RefCell};
+
+use eframe::egui::{self};
+use egui_modal::Modal;
+use i18n_embed_fl::fl;
+
+use crate::{TerminalResult, ModalDialog};
+
+pub struct SelectCharacterDialog {
+ pub should_commit: bool,
+ ch: Rc<RefCell<char>>,
+ selected_ch: char
+}
+
+impl SelectCharacterDialog {
+ pub fn new(ch: Rc<RefCell<char>>) -> Self {
+ let selected_ch = *ch.borrow();
+ SelectCharacterDialog {
+ should_commit: false,
+ ch,
+ selected_ch
+ }
+ }
+}
+
+impl ModalDialog for SelectCharacterDialog {
+ fn show(&mut self, ctx: &egui::Context) -> bool {
+ let mut result = false;
+ let modal = Modal::new(ctx, "my_modal");
+
+ modal.show(|ui| {
+ modal.title(ui, fl!(crate::LANGUAGE_LOADER, "select-character-title"));
+
+ modal.frame(ui, |ui| {
+ });
+
+ modal.buttons(ui, |ui| {
+ if ui
+ .button(fl!(crate::LANGUAGE_LOADER, "new-file-ok"))
+ .clicked()
+ {
+ self.should_commit = true;
+ result = true;
+ }
+ if ui
+ .button(fl!(crate::LANGUAGE_LOADER, "new-file-cancel"))
+ .clicked()
+ {
+ result = true;
+ }
+ });
+ });
+ modal.open();
+ result
+ }
+
+ fn should_commit(&self) -> bool { self.should_commit }
+
+ fn commit(&self, editor: &mut crate::model::Editor) -> TerminalResult<bool> {
+ self.ch.swap(&RefCell::new(self.selected_ch));
+ Ok(true)
+ }
+}
+\ No newline at end of file