sync commit
This commit is contained in:
parent
b0d45a5eec
commit
235e14dcea
|
@ -3,3 +3,5 @@ use druid::Selector;
|
|||
pub const PROCESS_WORKBOOK: Selector<()> = Selector::new("process-workbook");
|
||||
pub const PROCESS_BLOCK: Selector<usize> = Selector::new("process-block");
|
||||
pub const DELETE_BLOCK: Selector<usize> = Selector::new("delete-block");
|
||||
|
||||
pub const RENAME_BLOCK: Selector<usize> = Selector::new("rename-block");
|
||||
|
|
|
@ -4,13 +4,14 @@ use druid::{
|
|||
Data, Lens,
|
||||
};
|
||||
|
||||
use crate::editor;
|
||||
use super::{EditorData, Modals};
|
||||
|
||||
#[derive(Clone, Data, Lens, Debug)]
|
||||
pub struct AppData {
|
||||
#[data(same_fn = "PartialEq::eq")]
|
||||
pub filename: Option<String>,
|
||||
pub blocks: Vector<Block>,
|
||||
pub modals: Modals,
|
||||
}
|
||||
|
||||
impl Default for AppData {
|
||||
|
@ -18,6 +19,7 @@ impl Default for AppData {
|
|||
Self {
|
||||
filename: None,
|
||||
blocks: vector![Block::new("Block #1", 0)],
|
||||
modals: Modals::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +46,7 @@ impl AppData {
|
|||
#[derive(Clone, Data, Lens, Default, PartialEq, Debug)]
|
||||
pub struct Block {
|
||||
pub name: String,
|
||||
pub editor_data: editor::EditorData,
|
||||
pub editor_data: EditorData,
|
||||
#[data(same_fn = "PartialEq::eq")]
|
||||
pub output: Output,
|
||||
pub index: usize,
|
||||
|
@ -63,7 +65,7 @@ impl Block {
|
|||
pub fn new_with_content(name: &str, index: usize, content: &str) -> Self {
|
||||
Self {
|
||||
name: name.to_string(),
|
||||
editor_data: editor::EditorData::new(content),
|
||||
editor_data: super::EditorData::new(content),
|
||||
output: Default::default(),
|
||||
index,
|
||||
}
|
|
@ -0,0 +1,203 @@
|
|||
use std::ops::Range;
|
||||
|
||||
use druid::{Data, Lens};
|
||||
use ropey::Rope;
|
||||
|
||||
#[derive(Clone, Data, PartialEq, Eq, Debug)]
|
||||
pub enum EditMode {
|
||||
Normal,
|
||||
Insert,
|
||||
}
|
||||
|
||||
#[derive(Data, Lens, Clone, PartialEq, Debug)]
|
||||
pub struct EditorData {
|
||||
#[data(same_fn = "PartialEq::eq")]
|
||||
pub content: Rope,
|
||||
pub cursor_pos: usize,
|
||||
pub mode: EditMode,
|
||||
pub cursor_opactiy: f64,
|
||||
pub cursor_fade: f64,
|
||||
pub selection_pos: usize,
|
||||
}
|
||||
|
||||
impl Default for EditorData {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
content: Rope::from_str("let x = 1;\nx+1"),
|
||||
cursor_pos: 5,
|
||||
selection_pos: 5,
|
||||
mode: EditMode::Normal,
|
||||
cursor_opactiy: 255.0,
|
||||
cursor_fade: 1.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl EditorData {
|
||||
pub fn new(content: &str) -> Self {
|
||||
println!("new block: {}", content);
|
||||
Self {
|
||||
content: Rope::from_str(content),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn move_cursor(&mut self, idx: usize) {
|
||||
if idx <= self.content.len_chars() {
|
||||
self.cursor_pos = idx;
|
||||
self.deselect();
|
||||
// dbg!(self.content.char(self.cursor_pos));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn select_range(&self) -> Range<usize> {
|
||||
if self.cursor_pos > self.selection_pos {
|
||||
self.selection_pos..self.cursor_pos
|
||||
} else {
|
||||
self.cursor_pos..self.selection_pos
|
||||
}
|
||||
}
|
||||
|
||||
pub fn push_str(&mut self, s: &str) {
|
||||
if self.selection_pos != self.cursor_pos {
|
||||
self.content.remove(self.select_range());
|
||||
self.content.insert(self.select_range().start, s);
|
||||
} else {
|
||||
self.content.insert(self.cursor_pos, s);
|
||||
}
|
||||
self.move_cursor(self.select_range().start + s.len());
|
||||
}
|
||||
|
||||
pub fn push(&mut self, c: char) {
|
||||
self.content.insert_char(self.cursor_pos, c);
|
||||
self.cursor_right();
|
||||
}
|
||||
|
||||
// pub fn cursor_to_end(&mut self) {
|
||||
// self.move_cursor(self.content.len_chars());
|
||||
// }
|
||||
|
||||
pub fn deselect(&mut self) {
|
||||
self.selection_pos = self.cursor_pos;
|
||||
}
|
||||
|
||||
pub fn delete_char_forward(&mut self) {
|
||||
if !self.select_range().is_empty() {
|
||||
let range = self.select_range();
|
||||
self.content.remove(self.select_range());
|
||||
self.move_cursor(range.start);
|
||||
return;
|
||||
}
|
||||
|
||||
if self.cursor_pos < self.content.len_chars() {
|
||||
self.content.remove((self.cursor_pos)..self.cursor_pos + 1);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn delete_char_back(&mut self) {
|
||||
// Delete selection
|
||||
if !self.select_range().is_empty() {
|
||||
let range = self.select_range();
|
||||
self.content.remove(self.select_range());
|
||||
self.move_cursor(range.start);
|
||||
return;
|
||||
}
|
||||
|
||||
// Cant delete character sif we are at the start of the buffer
|
||||
if self.cursor_pos > 0 {
|
||||
self.content.remove((self.cursor_pos - 1)..self.cursor_pos);
|
||||
self.cursor_left();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cursor_left(&mut self) {
|
||||
if self.cursor_pos > 0 {
|
||||
self.move_cursor(self.cursor_pos - 1);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cursor_up(&mut self) {
|
||||
let line_idx = self.content.char_to_line(self.cursor_pos);
|
||||
|
||||
if line_idx > 0 {
|
||||
let start_of_current_line = self.content.line_to_char(line_idx);
|
||||
let line_pos = self.cursor_pos - start_of_current_line;
|
||||
let up_line_start = self.content.line_to_char(line_idx - 1);
|
||||
let up_line = self.content.line(line_idx - 1);
|
||||
self.move_cursor(up_line_start + line_pos.min(up_line.len_chars() - 1));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cursor_down(&mut self) {
|
||||
let line_idx = self.content.char_to_line(self.cursor_pos);
|
||||
if line_idx < self.content.len_lines() - 1 {
|
||||
let start_of_current_line = self.content.line_to_char(line_idx);
|
||||
let line_pos = self.cursor_pos - start_of_current_line;
|
||||
let start_of_next_line = self.content.line_to_char(line_idx + 1);
|
||||
let next_line_len = self.content.line(line_idx + 1).len_chars();
|
||||
|
||||
self.move_cursor(start_of_next_line + line_pos.min(next_line_len));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cursor_right(&mut self) {
|
||||
if self.cursor_pos < self.content.len_chars() {
|
||||
self.move_cursor(self.cursor_pos + 1);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn select_to_end_of_line(&mut self) {
|
||||
let line_idx = self.content.char_to_line(self.cursor_pos);
|
||||
let start_of_line = self.content.line_to_char(line_idx);
|
||||
let line = self.content.line(line_idx);
|
||||
if line_idx == self.content.len_lines() - 1 {
|
||||
self.selection_pos = start_of_line + line.len_chars();
|
||||
} else {
|
||||
self.selection_pos = start_of_line + line.len_chars() - 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cursor_to_end_of_line(&mut self) {
|
||||
let line_idx = self.content.char_to_line(self.cursor_pos);
|
||||
let start_of_line = self.content.line_to_char(line_idx);
|
||||
let line = self.content.line(line_idx);
|
||||
if line_idx == self.content.len_lines() - 1 {
|
||||
self.move_cursor(start_of_line + line.len_chars());
|
||||
} else {
|
||||
self.move_cursor(start_of_line + line.len_chars() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn select_to_start_of_line(&mut self) {
|
||||
let start_of_line = self
|
||||
.content
|
||||
.line_to_char(self.content.char_to_line(self.cursor_pos));
|
||||
|
||||
self.selection_pos = start_of_line;
|
||||
}
|
||||
|
||||
pub fn cursor_to_start_of_line(&mut self) {
|
||||
let start_of_line = self
|
||||
.content
|
||||
.line_to_char(self.content.char_to_line(self.cursor_pos));
|
||||
|
||||
self.move_cursor(start_of_line);
|
||||
}
|
||||
|
||||
pub fn select_all(&mut self) {
|
||||
self.selection_pos = self.content.len_chars();
|
||||
self.cursor_pos = 0;
|
||||
}
|
||||
|
||||
pub fn select_left(&mut self) {
|
||||
if self.cursor_pos > 0 {
|
||||
self.selection_pos -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn select_right(&mut self) {
|
||||
if self.cursor_pos < self.content.len_chars() {
|
||||
self.selection_pos += 1;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
mod app_data;
|
||||
mod editor_data;
|
||||
mod modals;
|
||||
|
||||
pub use app_data::{AppData, Block};
|
||||
pub use editor_data::{EditMode, EditorData};
|
||||
pub use modals::*;
|
|
@ -0,0 +1,13 @@
|
|||
use druid::{Data, Lens};
|
||||
|
||||
#[derive(Clone, Data, Lens, Default, Debug)]
|
||||
pub struct RenameBlock {
|
||||
pub name: String,
|
||||
pub input: String,
|
||||
pub block_index: usize,
|
||||
}
|
||||
|
||||
#[derive(Clone, Data, Lens, Default, Debug)]
|
||||
pub struct Modals {
|
||||
pub rename_block: Option<RenameBlock>,
|
||||
}
|
|
@ -1,222 +1,24 @@
|
|||
use std::ops::Range;
|
||||
|
||||
use abacus_core::Output;
|
||||
use clipboard::ClipboardProvider;
|
||||
use druid::{
|
||||
piet::{CairoTextLayout, Text, TextAttribute, TextLayout, TextLayoutBuilder},
|
||||
widget::{Container, Flex, Label, Padding, Svg, SvgData},
|
||||
Color, Data, Event, FontDescriptor, FontFamily, FontWeight, Lens, LifeCycle, PaintCtx, Rect,
|
||||
RenderContext, Target, Widget, WidgetExt,
|
||||
Color, Event, FontDescriptor, FontFamily, FontWeight, LifeCycle, PaintCtx, Rect, RenderContext,
|
||||
Target, Widget, WidgetExt,
|
||||
};
|
||||
|
||||
use ropey::Rope;
|
||||
use syntect::easy::HighlightLines;
|
||||
use syntect::highlighting::{Style, ThemeSet};
|
||||
use syntect::parsing::SyntaxSet;
|
||||
|
||||
use crate::{app_header::ToolbarButtonController, Block};
|
||||
use crate::{
|
||||
app_header::ToolbarButtonController,
|
||||
data::{EditMode, EditorData},
|
||||
Block,
|
||||
};
|
||||
|
||||
const FONT_SIZE: f64 = 16.0;
|
||||
|
||||
#[derive(Clone, Data, PartialEq, Eq, Debug)]
|
||||
pub enum EditMode {
|
||||
Normal,
|
||||
Insert,
|
||||
}
|
||||
|
||||
#[derive(Data, Lens, Clone, PartialEq, Debug)]
|
||||
pub struct EditorData {
|
||||
#[data(same_fn = "PartialEq::eq")]
|
||||
pub content: Rope,
|
||||
pub cursor_pos: usize,
|
||||
pub mode: EditMode,
|
||||
pub cursor_opactiy: f64,
|
||||
pub cursor_fade: f64,
|
||||
pub selection_pos: usize,
|
||||
}
|
||||
|
||||
impl Default for EditorData {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
content: Rope::from_str("let x = 1;\nx+1"),
|
||||
cursor_pos: 5,
|
||||
selection_pos: 5,
|
||||
mode: EditMode::Normal,
|
||||
cursor_opactiy: 255.0,
|
||||
cursor_fade: 1.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl EditorData {
|
||||
pub fn new(content: &str) -> Self {
|
||||
println!("new block: {}", content);
|
||||
Self {
|
||||
content: Rope::from_str(content),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn move_cursor(&mut self, idx: usize) {
|
||||
if idx <= self.content.len_chars() {
|
||||
self.cursor_pos = idx;
|
||||
self.deselect();
|
||||
// dbg!(self.content.char(self.cursor_pos));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn select_range(&self) -> Range<usize> {
|
||||
if self.cursor_pos > self.selection_pos {
|
||||
self.selection_pos..self.cursor_pos
|
||||
} else {
|
||||
self.cursor_pos..self.selection_pos
|
||||
}
|
||||
}
|
||||
|
||||
pub fn push_str(&mut self, s: &str) {
|
||||
if self.selection_pos != self.cursor_pos {
|
||||
self.content.remove(self.select_range());
|
||||
self.content.insert(self.select_range().start, s);
|
||||
} else {
|
||||
self.content.insert(self.cursor_pos, s);
|
||||
}
|
||||
self.move_cursor(self.select_range().start + s.len());
|
||||
}
|
||||
|
||||
pub fn push(&mut self, c: char) {
|
||||
self.content.insert_char(self.cursor_pos, c);
|
||||
self.cursor_right();
|
||||
}
|
||||
|
||||
// pub fn cursor_to_end(&mut self) {
|
||||
// self.move_cursor(self.content.len_chars());
|
||||
// }
|
||||
|
||||
pub fn deselect(&mut self) {
|
||||
self.selection_pos = self.cursor_pos;
|
||||
}
|
||||
|
||||
pub fn delete_char_forward(&mut self) {
|
||||
if !self.select_range().is_empty() {
|
||||
let range = self.select_range();
|
||||
self.content.remove(self.select_range());
|
||||
self.move_cursor(range.start);
|
||||
return;
|
||||
}
|
||||
|
||||
if self.cursor_pos < self.content.len_chars() {
|
||||
self.content.remove((self.cursor_pos)..self.cursor_pos + 1);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn delete_char_back(&mut self) {
|
||||
// Delete selection
|
||||
if !self.select_range().is_empty() {
|
||||
let range = self.select_range();
|
||||
self.content.remove(self.select_range());
|
||||
self.move_cursor(range.start);
|
||||
return;
|
||||
}
|
||||
|
||||
// Cant delete character sif we are at the start of the buffer
|
||||
if self.cursor_pos > 0 {
|
||||
self.content.remove((self.cursor_pos - 1)..self.cursor_pos);
|
||||
self.cursor_left();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cursor_left(&mut self) {
|
||||
if self.cursor_pos > 0 {
|
||||
self.move_cursor(self.cursor_pos - 1);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cursor_up(&mut self) {
|
||||
let line_idx = self.content.char_to_line(self.cursor_pos);
|
||||
|
||||
if line_idx > 0 {
|
||||
let start_of_current_line = self.content.line_to_char(line_idx);
|
||||
let line_pos = self.cursor_pos - start_of_current_line;
|
||||
let up_line_start = self.content.line_to_char(line_idx - 1);
|
||||
let up_line = self.content.line(line_idx - 1);
|
||||
self.move_cursor(up_line_start + line_pos.min(up_line.len_chars() - 1));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cursor_down(&mut self) {
|
||||
let line_idx = self.content.char_to_line(self.cursor_pos);
|
||||
if line_idx < self.content.len_lines() - 1 {
|
||||
let start_of_current_line = self.content.line_to_char(line_idx);
|
||||
let line_pos = self.cursor_pos - start_of_current_line;
|
||||
let start_of_next_line = self.content.line_to_char(line_idx + 1);
|
||||
let next_line_len = self.content.line(line_idx + 1).len_chars();
|
||||
|
||||
self.move_cursor(start_of_next_line + line_pos.min(next_line_len));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cursor_right(&mut self) {
|
||||
if self.cursor_pos < self.content.len_chars() {
|
||||
self.move_cursor(self.cursor_pos + 1);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn select_to_end_of_line(&mut self) {
|
||||
let line_idx = self.content.char_to_line(self.cursor_pos);
|
||||
let start_of_line = self.content.line_to_char(line_idx);
|
||||
let line = self.content.line(line_idx);
|
||||
if line_idx == self.content.len_lines() - 1 {
|
||||
self.selection_pos = start_of_line + line.len_chars();
|
||||
} else {
|
||||
self.selection_pos = start_of_line + line.len_chars() - 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cursor_to_end_of_line(&mut self) {
|
||||
let line_idx = self.content.char_to_line(self.cursor_pos);
|
||||
let start_of_line = self.content.line_to_char(line_idx);
|
||||
let line = self.content.line(line_idx);
|
||||
if line_idx == self.content.len_lines() - 1 {
|
||||
self.move_cursor(start_of_line + line.len_chars());
|
||||
} else {
|
||||
self.move_cursor(start_of_line + line.len_chars() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn select_to_start_of_line(&mut self) {
|
||||
let start_of_line = self
|
||||
.content
|
||||
.line_to_char(self.content.char_to_line(self.cursor_pos));
|
||||
|
||||
self.selection_pos = start_of_line;
|
||||
}
|
||||
|
||||
pub fn cursor_to_start_of_line(&mut self) {
|
||||
let start_of_line = self
|
||||
.content
|
||||
.line_to_char(self.content.char_to_line(self.cursor_pos));
|
||||
|
||||
self.move_cursor(start_of_line);
|
||||
}
|
||||
|
||||
pub fn select_all(&mut self) {
|
||||
self.selection_pos = self.content.len_chars();
|
||||
self.cursor_pos = 0;
|
||||
}
|
||||
|
||||
pub fn select_left(&mut self) {
|
||||
if self.cursor_pos > 0 {
|
||||
self.selection_pos -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn select_right(&mut self) {
|
||||
if self.cursor_pos < self.content.len_chars() {
|
||||
self.selection_pos += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AbacusEditor {
|
||||
syntax_set: SyntaxSet,
|
||||
theme_set: ThemeSet,
|
||||
|
@ -224,12 +26,9 @@ pub struct AbacusEditor {
|
|||
|
||||
impl Default for AbacusEditor {
|
||||
fn default() -> Self {
|
||||
let syntax_set = SyntaxSet::load_defaults_newlines();
|
||||
let theme_set = ThemeSet::load_defaults();
|
||||
|
||||
Self {
|
||||
syntax_set,
|
||||
theme_set,
|
||||
syntax_set: SyntaxSet::load_defaults_newlines(),
|
||||
theme_set: ThemeSet::load_defaults(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -331,16 +130,6 @@ impl AbacusEditor {
|
|||
|
||||
impl Widget<EditorData> for AbacusEditor {
|
||||
fn paint(&mut self, ctx: &mut druid::PaintCtx, data: &EditorData, _env: &druid::Env) {
|
||||
println!("test");
|
||||
// let size = ctx.size();
|
||||
// let rect = size.to_rect();
|
||||
|
||||
// if ctx.is_focused() {
|
||||
// ctx.fill(rect, &Color::rgb8(30, 30, 30));
|
||||
// } else {
|
||||
// ctx.fill(rect, &Color::rgb8(20, 20, 20));
|
||||
// }
|
||||
|
||||
if data.content.len_chars() == 0 {
|
||||
return;
|
||||
}
|
||||
|
@ -628,7 +417,10 @@ pub fn editor_header() -> impl Widget<Block> {
|
|||
.with_weight(FontWeight::BOLD)
|
||||
.with_size(14.0),
|
||||
)
|
||||
.padding(5.0),
|
||||
.padding(5.0)
|
||||
.on_click(|ctx, data, _| {
|
||||
ctx.submit_command(crate::commands::RENAME_BLOCK.with(data.index));
|
||||
}),
|
||||
)
|
||||
.with_flex_spacer(1.0)
|
||||
.with_child(
|
||||
|
|
|
@ -2,33 +2,38 @@ mod app_delegate;
|
|||
mod app_header;
|
||||
mod commands;
|
||||
mod data;
|
||||
mod modal_container;
|
||||
|
||||
mod editor;
|
||||
mod output_block;
|
||||
|
||||
use data::{AppData, Block};
|
||||
use druid::widget::{Container, Flex, List, Padding, Scroll};
|
||||
use druid::{AppLauncher, PlatformError, Widget, WidgetExt, WindowDesc};
|
||||
use modal_container::ModalContainer;
|
||||
|
||||
fn build_ui() -> impl Widget<AppData> {
|
||||
Flex::column()
|
||||
.with_child(app_header::app_header_ui())
|
||||
.with_child(app_header::header_separater())
|
||||
.with_flex_child(
|
||||
Scroll::new(
|
||||
List::new(|| {
|
||||
Flex::column()
|
||||
.with_child(editor::editor_header())
|
||||
.with_child(Container::new(Padding::new(
|
||||
10.0,
|
||||
editor::AbacusEditor::default().lens(Block::editor_data),
|
||||
)))
|
||||
.with_child(output_block::output_block())
|
||||
})
|
||||
.lens(AppData::blocks),
|
||||
)
|
||||
.vertical(),
|
||||
1.0,
|
||||
)
|
||||
ModalContainer::new(
|
||||
Flex::column()
|
||||
.with_child(app_header::app_header_ui())
|
||||
.with_child(app_header::header_separater())
|
||||
.with_flex_child(
|
||||
Scroll::new(
|
||||
List::new(|| {
|
||||
Flex::column()
|
||||
.with_child(editor::editor_header())
|
||||
.with_child(Container::new(Padding::new(
|
||||
10.0,
|
||||
editor::AbacusEditor::default().lens(Block::editor_data),
|
||||
)))
|
||||
.with_child(output_block::output_block())
|
||||
})
|
||||
.lens(AppData::blocks),
|
||||
)
|
||||
.vertical(),
|
||||
1.0,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fn main() -> Result<(), PlatformError> {
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
use crate::data;
|
||||
use druid::{
|
||||
widget::{Container, Label},
|
||||
RenderContext, Widget, WidgetPod,
|
||||
};
|
||||
|
||||
pub struct ModalContainer {
|
||||
child: WidgetPod<data::AppData, Box<dyn Widget<data::AppData>>>,
|
||||
modal: Option<WidgetPod<data::AppData, Box<dyn Widget<data::AppData>>>>,
|
||||
}
|
||||
|
||||
impl ModalContainer {
|
||||
pub fn new(child: impl Widget<data::AppData> + 'static) -> Self {
|
||||
Self {
|
||||
child: WidgetPod::new(child).boxed(),
|
||||
modal: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget<data::AppData> for ModalContainer {
|
||||
fn event(
|
||||
&mut self,
|
||||
ctx: &mut druid::EventCtx,
|
||||
event: &druid::Event,
|
||||
data: &mut data::AppData,
|
||||
env: &druid::Env,
|
||||
) {
|
||||
if let druid::Event::Command(c) = event {
|
||||
if let Some(idx) = c.get(crate::commands::RENAME_BLOCK) {
|
||||
println!("rename block");
|
||||
data.modals.rename_block = Some(data::RenameBlock {
|
||||
block_index: *idx,
|
||||
name: data
|
||||
.blocks
|
||||
.get(*idx)
|
||||
.map(|i| i.name.clone())
|
||||
.unwrap_or_default(),
|
||||
input: String::new(),
|
||||
});
|
||||
self.modal = Some(WidgetPod::new(rename_block()).boxed());
|
||||
ctx.children_changed();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if self.modal.is_none() {
|
||||
self.child.event(ctx, event, data, env);
|
||||
}
|
||||
}
|
||||
|
||||
fn lifecycle(
|
||||
&mut self,
|
||||
ctx: &mut druid::LifeCycleCtx,
|
||||
event: &druid::LifeCycle,
|
||||
data: &data::AppData,
|
||||
env: &druid::Env,
|
||||
) {
|
||||
self.child.lifecycle(ctx, event, data, env);
|
||||
}
|
||||
|
||||
fn update(
|
||||
&mut self,
|
||||
ctx: &mut druid::UpdateCtx,
|
||||
_old_data: &data::AppData,
|
||||
data: &data::AppData,
|
||||
env: &druid::Env,
|
||||
) {
|
||||
self.child.update(ctx, data, env);
|
||||
}
|
||||
|
||||
fn layout(
|
||||
&mut self,
|
||||
ctx: &mut druid::LayoutCtx,
|
||||
bc: &druid::BoxConstraints,
|
||||
data: &data::AppData,
|
||||
env: &druid::Env,
|
||||
) -> druid::Size {
|
||||
self.child.layout(ctx, bc, data, env)
|
||||
}
|
||||
|
||||
fn paint(&mut self, ctx: &mut druid::PaintCtx, data: &data::AppData, env: &druid::Env) {
|
||||
println!("paint modal container");
|
||||
self.child.paint(ctx, data, env);
|
||||
let full_rect = ctx.size().to_rect();
|
||||
if let Some(m) = self.modal.as_mut() {
|
||||
println!("painting modal");
|
||||
ctx.fill(full_rect, &druid::Color::rgba8(0, 0, 0, 100));
|
||||
m.paint(ctx, data, env)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn rename_block() -> impl Widget<data::AppData> {
|
||||
Container::new(Label::new("rename block").with_text_color(druid::Color::WHITE))
|
||||
}
|
Loading…
Reference in New Issue