sync commit

This commit is contained in:
Joe Bellus 2022-10-16 03:55:40 -04:00
parent f590338805
commit 49d7e561db
8 changed files with 380 additions and 144 deletions

View File

@ -29,6 +29,7 @@ impl<'a> Engine<'a> {
let frame = rhai::Dynamic::cast::<dataframe::DataFrame>(res);
Output::DataFrame(frame)
}
Ok(res) if res.is::<()>() => Output::None,
Ok(res) if res.is::<dataframe::Series>() => {
let series = rhai::Dynamic::cast::<dataframe::Series>(res);
Output::Series(series)

View File

@ -4,6 +4,7 @@ mod save_file;
pub use engine::Engine;
pub use engine::Output;
pub use polars::prelude::AnyValue;
pub use save_file::{SaveBlock, SaveFile};
use rhai::EvalAltResult;

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 576 512"
version="1.1"
id="svg4"
sodipodi:docname="abacus.svg"
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs8" />
<sodipodi:namedview
id="namedview6"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="2.0058594"
inkscape:cx="288.15579"
inkscape:cy="255.75073"
inkscape:window-width="1942"
inkscape:window-height="1980"
inkscape:window-x="6470"
inkscape:window-y="80"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<!--! Font Awesome Pro 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. -->
<path
d="M512 32H64c-35.35 0-64 28.65-64 64v320c0 35.35 28.65 64 64 64h448c35.35 0 64-28.65 64-64v-320C576 60.65 547.3 32 512 32zM512 64c17.64 0 32 14.36 32 32v96h-96l0-31.1L464 160C472.8 160 480 152.8 480 144s-7.156-15.1-16-15.1L448 128V64H512zM416 64v64l-16 .0002c-8.844 0-16 7.156-16 15.1S391.2 160 400 160l15.1 .0004L416 192h-128l0-31.1L304 160C312.8 160 320 152.8 320 144s-7.156-15.1-16-15.1L288 128V64H416zM256 64v64L240 128C231.2 128 224 135.2 224 144S231.2 160 240 160l15.1 .0004L256 192H160l0-31.1L176 160C184.8 160 192 152.8 192 144S184.8 128 176 128L160 128V64H256zM32 96c0-17.64 14.36-32 32-32h64v64L112 128C103.2 128 96 135.2 96 144S103.2 160 112 160l15.1 .0004L128 192H32V96zM64 448c-17.64 0-32-14.36-32-32V224h96v64L112 288C103.2 288 96 295.2 96 304S103.2 320 112 320l15.1 .0004v32L112 352C103.2 352 96 359.2 96 368s7.156 16 16 16L128 384v64H64zM160 448v-64l16 .0002c8.844 0 16-7.156 16-16S184.8 352 176 352l-15.1 .0004v-32L176 320C184.8 320 192 312.8 192 304S184.8 288 176 288L160 288V224h96v64L240 288C231.2 288 224 295.2 224 304S231.2 320 240 320l15.1 .0004v32L240 352C231.2 352 224 359.2 224 368s7.156 16 16 16L256 384v64H160zM288 448v-64l16 .0002c8.844 0 16-7.156 16-16S312.8 352 304 352l-15.1 .0004v-32L304 320c8.844 0 16-7.156 16-16s-7.156-15.1-16-15.1L288 288V224h128l0 128L400 352c-8.844 0-16 7.156-16 16s7.156 16 16 16L416 384v64H288zM544 416c0 17.64-14.36 32-32 32h-64v-64l16 .0002c8.844 0 16-7.156 16-16S472.8 352 464 352l-15.1 .0004L448 224h96V416z"
id="path2"
style="fill:#ffffff" />
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -22,9 +22,19 @@ pub fn app_header_ui() -> impl Widget<AppData> {
.parse::<SvgData>()
.unwrap_or_default();
let abacus_svg = include_str!("../assets/abacus.svg")
.parse::<SvgData>()
.unwrap_or_default();
Container::new(
Flex::row()
.must_fill_main_axis(true)
.with_spacer(10.0)
.with_child(
Container::new(Padding::new(5.0, Svg::new(abacus_svg).fix_width(20.0)))
.controller(ToolbarButtonController::new(Color::rgb8(50, 50, 50)))
.on_click(|_ctx, _, _| {}),
)
.with_spacer(20.0)
.with_child(
Container::new(Padding::new(10.0, Svg::new(open_svg).fix_width(10.0)))

View File

@ -17,15 +17,15 @@ pub struct EditorData {
pub mode: EditMode,
pub cursor_opactiy: f64,
pub cursor_fade: f64,
pub selection_pos: usize,
pub selection_pos: Option<usize>,
}
impl Default for EditorData {
fn default() -> Self {
Self {
content: Rope::from_str("1234567890\n\n\n123\n\n1234\n1234"),
content: Rope::from_str(""),
cursor_pos: 0,
selection_pos: 0,
selection_pos: None,
mode: EditMode::Normal,
cursor_opactiy: 255.0,
cursor_fade: 1.0,
@ -42,25 +42,23 @@ impl EditorData {
}
pub fn move_cursor(&mut self, idx: usize) {
let has_selection = self.cursor_pos != self.selection_pos;
self.cursor_pos = idx;
if !has_selection {
self.deselect();
}
}
pub fn select_range(&self) -> Range<usize> {
if self.cursor_pos > self.selection_pos {
self.selection_pos..self.cursor_pos
if let Some(selection_pos) = self.selection_pos {
if self.cursor_pos > selection_pos {
selection_pos..self.cursor_pos
} else {
self.cursor_pos..selection_pos
}
} else {
self.cursor_pos..self.selection_pos
self.cursor_pos..self.cursor_pos
}
}
pub fn push_str(&mut self, s: &str) {
if self.selection_pos != self.cursor_pos {
if self.selection_pos.is_some() {
self.content.remove(self.select_range());
self.content.insert(self.select_range().start, s);
} else {
@ -79,7 +77,64 @@ impl EditorData {
// }
pub fn deselect(&mut self) {
self.selection_pos = self.cursor_pos;
self.selection_pos = None;
}
pub fn delete_current_line(&mut self) {
if self.current_line_index() < self.content.len_lines() {
self.content.remove(
self.current_line_start()
..(self.current_line_start()
+ self
.current_line()
.len_chars()
.min(self.content.len_chars())),
);
} else {
self.cursor_up();
self.content.remove(
self.current_line_start()..(self.cursor_pos + self.current_line().len_chars()),
);
}
if self.cursor_pos > self.content.len_chars() && self.content.len_chars() > 0 {
self.cursor_pos = self.content.len_chars() - 1;
} else if self.cursor_pos > self.content.len_chars() {
self.cursor_pos = 0;
}
self.deselect();
}
pub fn word_scan_forward(&mut self) {
while self.cursor_pos < self.content.len_chars() {
self.cursor_pos += 1;
if !self
.current_char()
.map(|c| c.is_alphanumeric())
.unwrap_or(false)
{
break;
}
self.deselect();
}
}
pub fn word_scan_backward(&mut self) {
if self.cursor_pos > 0 {
self.cursor_pos -= 1;
}
while self.cursor_pos > 0 {
if !self
.content
.get_char(self.cursor_pos - 1)
.map(|c| c.is_alphanumeric())
.unwrap_or(false)
{
break;
} else {
self.cursor_pos -= 1;
}
self.deselect();
}
}
pub fn delete_char_forward(&mut self) {
@ -87,6 +142,7 @@ impl EditorData {
let range = self.select_range();
self.content.remove(self.select_range());
self.move_cursor(range.start);
self.deselect();
return;
}
@ -101,6 +157,7 @@ impl EditorData {
let range = self.select_range();
self.content.remove(self.select_range());
self.move_cursor(range.start);
self.deselect();
return;
}
@ -111,6 +168,13 @@ impl EditorData {
}
}
pub fn delete_to_eol(&mut self) {
self.content.remove(
self.cursor_pos
..(self.current_line_start() + self.current_line().to_string().len() - 1),
)
}
pub fn cursor_left(&mut self) {
match self.mode {
EditMode::Insert => {
@ -130,11 +194,9 @@ impl EditorData {
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));
self.move_cursor(up_line_start + self.current_column().min(up_line.len_chars() - 1));
}
}
@ -153,12 +215,10 @@ impl EditorData {
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();
let start_of_next_line = self.content.line_to_char(self.current_line_index() + 1);
let next_line_len = self.content.line(line_idx + 1).len_chars().max(1) - 1;
let new_pos = start_of_next_line + line_pos.min(next_line_len);
let new_pos = start_of_next_line + self.current_column().min(next_line_len);
self.move_cursor(new_pos);
}
@ -179,39 +239,14 @@ impl EditorData {
}
pub fn cursor_right(&mut self) {
let has_selection = self.cursor_pos != self.selection_pos;
match self.mode {
EditMode::Insert => {
if self.cursor_pos < self.content.len_chars() {
self.move_cursor(self.cursor_pos + 1);
}
}
EditMode::Normal => {
if self.current_line_index() == self.content.len_lines() - 1 {
if self.cursor_pos < self.content.len_chars() - 1 {
self.move_cursor(self.cursor_pos + 1);
}
} else if self.current_column() < (self.current_line().len_chars().max(2) - 2) {
self.move_cursor(self.cursor_pos + 1);
}
}
}
if !has_selection {
self.deselect();
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;
}
self.selection_pos = Some(self.cursor_pos);
self.cursor_to_end_of_line();
}
pub fn cursor_to_end_of_line(&mut self) {
@ -226,11 +261,8 @@ impl EditorData {
}
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;
self.selection_pos = Some(self.cursor_pos);
self.cursor_to_start_of_line();
}
pub fn cursor_to_start_of_line(&mut self) {
@ -241,9 +273,17 @@ impl EditorData {
self.move_cursor(start_of_line);
}
pub fn normal_mode(&mut self) {
self.mode = EditMode::Normal;
if self.cursor_pos == self.content.len_chars() && self.content.len_chars() != 0 {
self.cursor_pos -= 1;
}
self.deselect();
}
pub fn select_all(&mut self) {
self.selection_pos = self.content.len_chars();
self.cursor_pos = 0;
self.selection_pos = Some(0);
self.cursor_pos = self.content.len_chars();
}
pub fn select_left(&mut self) {
@ -300,7 +340,6 @@ mod tests {
};
data.push_str("0123456789\n\n1234");
data.cursor_pos = 12;
data.selection_pos = 12;
data.cursor_left();
assert_eq!(data.cursor_pos, 11);
data.cursor_left();
@ -315,7 +354,6 @@ mod tests {
};
data.push_str("0123456789\n\n\n1234");
data.cursor_pos = 14;
data.selection_pos = 14;
data.cursor_left();
assert_eq!(data.cursor_pos, 12);
data.cursor_left();
@ -332,7 +370,6 @@ mod tests {
};
data.push_str("0123456789\n1234");
data.cursor_pos = 12;
data.selection_pos = 12;
assert_eq!(data.current_char().unwrap(), '1');
data.cursor_left();
assert_eq!(data.cursor_pos, 10);

View File

@ -19,9 +19,88 @@ use crate::{
const FONT_SIZE: f64 = 16.0;
mod keymap {
pub const LINE_ABOVE: &str = "O";
pub const LINE_BELOW: &str = "o";
pub const DELETE_LINE: &str = "dd";
pub const EDIT_EOL: &str = "A";
pub const EDIT: &str = "i";
pub const EDIT_BOL: &str = "I";
pub const CURSOR_LEFT: &str = "h";
pub const CURSOR_RIGHT: &str = "l";
pub const CURSOR_UP: &str = "k";
pub const CURSOR_DOWN: &str = "j";
pub const DELETE_CHAR: &str = "x";
pub const DELETE_TO_EOL: &str = "D";
pub const WORD_FORWARD: &str = "w";
pub const WORD_BACK: &str = "b";
pub const SELECT_MODE: &str = "v";
#[derive(Debug, Default)]
pub struct KeyList {
input_value: String,
commands: Vec<&'static str>,
}
impl KeyList {
pub fn new() -> Self {
Self {
input_value: String::new(),
commands: vec![
LINE_ABOVE,
LINE_BELOW,
DELETE_LINE,
EDIT_EOL,
EDIT,
EDIT_BOL,
CURSOR_LEFT,
CURSOR_RIGHT,
CURSOR_UP,
CURSOR_DOWN,
DELETE_CHAR,
DELETE_TO_EOL,
WORD_FORWARD,
WORD_BACK,
SELECT_MODE,
],
}
}
pub fn push(&mut self, s: &str) {
self.input_value.push_str(s);
if !self.valid() {
self.clear();
}
}
fn valid(&self) -> bool {
self.commands
.iter()
.any(|i| i.starts_with(&self.input_value))
}
pub fn clear(&mut self) {
self.input_value.clear();
}
pub fn get(&mut self) -> Option<&str> {
let v = self
.commands
.iter()
.find(|i| **i == self.input_value)
.cloned();
if v.is_some() {
self.clear();
}
v
}
}
}
pub struct AbacusEditor {
syntax_set: SyntaxSet,
theme_set: ThemeSet,
key_list: keymap::KeyList,
}
impl Default for AbacusEditor {
@ -29,6 +108,7 @@ impl Default for AbacusEditor {
Self {
syntax_set: SyntaxSet::load_defaults_newlines(),
theme_set: ThemeSet::load_defaults(),
key_list: keymap::KeyList::new(),
}
}
}
@ -68,13 +148,22 @@ impl AbacusEditor {
}
if data.mode == EditMode::Normal {
let range = if data.current_line() == "\n" {
(data.cursor_pos.max(1) - 1)..data.cursor_pos
let char_rect = if data.content.len_chars() == 0 {
let rects = layout.rects_for_range(0..1);
rects.first().cloned()
} else if data.current_char() == Some('\n')
|| data.cursor_pos == data.content.len_chars()
{
let range = (data.cursor_pos.max(1) - 1)..data.cursor_pos;
layout.rects_for_range(range).last().cloned().map(|rect| {
Rect::new(rect.max_x(), rect.min_y(), rect.max_x() + 10., rect.max_y())
})
} else {
data.cursor_pos..(data.cursor_pos + 1)
let range = data.cursor_pos..(data.cursor_pos + 1);
layout.rects_for_range(range).last().cloned()
};
if let Some(char_rect) = layout.rects_for_range(range).last() {
if let Some(char_rect) = char_rect {
if char_rect.width() == 0. {
let rect = Rect::new(
char_rect.min_x(),
@ -106,7 +195,11 @@ impl AbacusEditor {
let mut layout = ctx
.text()
.new_text_layout(data.content.to_string())
.new_text_layout(if data.content.len_chars() == 0 {
String::from(" ")
} else {
data.content.to_string()
})
.font(FontFamily::MONOSPACE, FONT_SIZE);
let mut pos = 0;
@ -134,22 +227,31 @@ impl AbacusEditor {
impl Widget<EditorData> for AbacusEditor {
fn paint(&mut self, ctx: &mut druid::PaintCtx, data: &EditorData, _env: &druid::Env) {
if data.content.len_chars() == 0 {
return;
}
let layout = self.build_highlighted_layout(ctx, data);
if ctx.has_focus() {
self.paint_cursor(ctx, data, &layout);
}
if data.selection_pos != data.cursor_pos {
if data.selection_pos.is_some() {
let rects = layout.rects_for_range(data.select_range());
for rect in rects.iter() {
ctx.fill(rect, &Color::rgb8(90, 90, 90));
if rect.width() == 0.0 {
ctx.fill(
Rect::new(
rect.min_x(),
rect.min_y(),
rect.max_x() + 10.0,
rect.max_y(),
),
&Color::rgb8(90, 90, 90),
);
} else {
ctx.fill(rect, &Color::rgb8(90, 90, 90));
}
}
}
if ctx.has_focus() {
self.paint_cursor(ctx, data, &layout);
}
ctx.draw_text(&layout, (0.0, 0.0));
}
@ -171,7 +273,7 @@ impl Widget<EditorData> for AbacusEditor {
}
}
"c" => {
if data.cursor_pos != data.selection_pos {
if data.selection_pos.is_some() {
let mut cb: clipboard::ClipboardContext =
clipboard::ClipboardProvider::new().unwrap();
if let Some(slice) = data.content.get_slice(data.select_range())
@ -195,42 +297,67 @@ impl Widget<EditorData> for AbacusEditor {
ctx.request_paint();
}
druid::keyboard_types::Key::Character(ch) if data.mode == EditMode::Normal => {
match ch.as_ref() {
"i" => {
data.mode = EditMode::Insert;
self.key_list.push(ch);
match self.key_list.get() {
Some(keymap::DELETE_LINE) => {
data.delete_current_line();
data.deselect();
}
"O" => {
Some(keymap::DELETE_CHAR) => {
data.delete_char_forward();
data.deselect();
}
Some(keymap::EDIT) => {
data.mode = EditMode::Insert;
data.deselect();
}
Some(keymap::LINE_ABOVE) => {
data.mode = EditMode::Insert;
data.cursor_to_start_of_line();
data.content.insert(data.cursor_pos, "\n");
data.deselect();
}
"A" => {
Some(keymap::LINE_BELOW) => {
data.mode = EditMode::Insert;
data.cursor_to_end_of_line();
data.push_str("\n");
data.deselect();
}
"I" => {
Some(keymap::EDIT_EOL) => {
data.mode = EditMode::Insert;
data.cursor_to_end_of_line();
data.deselect();
}
Some(keymap::EDIT_BOL) => {
data.cursor_to_start_of_line();
data.mode = EditMode::Insert;
data.deselect();
}
"a" => {
if e.mods.ctrl() {
data.select_all();
}
}
"h" => {
Some(keymap::CURSOR_LEFT) => {
data.cursor_left();
}
"j" => {
Some(keymap::CURSOR_DOWN) => {
data.cursor_down();
}
"k" => {
Some(keymap::CURSOR_UP) => {
data.cursor_up();
}
"l" => {
Some(keymap::CURSOR_RIGHT) => {
data.cursor_right();
}
"x" => {
data.delete_char_forward();
Some(keymap::DELETE_TO_EOL) => {
data.delete_to_eol();
data.deselect();
}
Some(keymap::WORD_FORWARD) => {
data.word_scan_forward();
}
Some(keymap::WORD_BACK) => {
data.word_scan_backward();
}
Some(keymap::SELECT_MODE) => {
data.selection_pos = Some(data.cursor_pos);
}
_ => {}
}
@ -238,21 +365,28 @@ impl Widget<EditorData> for AbacusEditor {
druid::keyboard_types::Key::Enter if e.mods.ctrl() => {
ctx.submit_command(crate::commands::PROCESS_WORKBOOK.to(Target::Global));
}
druid::keyboard_types::Key::Enter => {
druid::keyboard_types::Key::Enter if data.mode == EditMode::Insert => {
data.push('\n');
ctx.request_layout();
ctx.request_paint();
data.deselect();
}
druid::keyboard_types::Key::Enter if data.mode == EditMode::Normal => {
data.cursor_down();
data.deselect();
}
druid::keyboard_types::Key::Backspace => {
data.delete_char_back();
ctx.request_layout();
data.deselect();
}
druid::keyboard_types::Key::Delete => {
data.delete_char_forward();
ctx.request_layout();
data.deselect();
}
druid::keyboard_types::Key::Escape => {
data.mode = EditMode::Normal;
data.normal_mode();
data.deselect();
}
druid::keyboard_types::Key::ArrowLeft if e.mods.shift() => {
@ -266,22 +400,27 @@ impl Widget<EditorData> for AbacusEditor {
}
druid::keyboard_types::Key::ArrowRight if !e.mods.shift() => {
data.cursor_right();
data.deselect();
}
druid::keyboard_types::Key::ArrowUp if !e.mods.shift() => {
data.cursor_up();
data.deselect();
}
druid::keyboard_types::Key::ArrowDown if !e.mods.shift() => {
data.cursor_down();
data.deselect();
}
druid::keyboard_types::Key::ArrowUp if e.mods.shift() => {
data.select_up();
data.deselect();
}
druid::keyboard_types::Key::ArrowDown if e.mods.shift() => {
data.select_down();
}
druid::keyboard_types::Key::Tab => {
data.push_str(" ");
data.deselect();
}
druid::keyboard_types::Key::End if e.mods.shift() => {
data.select_to_end_of_line();
@ -330,31 +469,18 @@ impl Widget<EditorData> for AbacusEditor {
.unwrap();
let pos = layout.hit_test_point(e.pos);
if e.buttons.has_left() {
let new_pos = (pos.idx + 1).min(data.content.len_chars());
if new_pos != data.selection_pos {
if new_pos > data.cursor_pos {
data.selection_pos = pos.idx.min(data.content.len_chars());
} else {
data.selection_pos = pos.idx.max(1) - 1;
}
ctx.request_paint();
if data.selection_pos.is_none() {
data.selection_pos = Some(data.cursor_pos);
}
let new_pos = (pos.idx + 1).min(data.content.len_chars());
if new_pos > data.cursor_pos {
data.cursor_pos = pos.idx.min(data.content.len_chars());
} else {
data.cursor_pos = pos.idx.max(1) - 1;
}
ctx.request_paint();
}
}
// Event::AnimFrame(e) => {
// data.cursor_opactiy += ((*e as f64) * 0.00000065) * data.cursor_fade;
// if data.cursor_opactiy >= 255.0 {
// data.cursor_opactiy = 255.0;
// data.cursor_fade *= -1.0;
// } else if data.cursor_opactiy <= 0.0 {
// data.cursor_opactiy = 0.1;
// data.cursor_fade *= -1.0;
// }
// if ctx.has_focus() {
// ctx.request_paint();
// ctx.request_anim_frame();
// }
// }
_ => {}
}
}
@ -437,6 +563,23 @@ pub fn editor_header() -> impl Widget<Block> {
ctx.submit_command(crate::commands::RENAME_BLOCK.with(data.index));
}),
)
.with_flex_spacer(1.0)
.with_child(
Label::dynamic(|data: &Block, _| {
match data.editor_data.mode {
EditMode::Insert => "EDIT",
EditMode::Normal => "",
}
.to_string()
})
.with_font(
FontDescriptor::new(FontFamily::SANS_SERIF)
.with_size(14.0)
.with_weight(FontWeight::BOLD),
)
.padding(5.0),
)
.with_spacer(10.0)
.with_child(
Label::dynamic(|data: &Block, _| {
format!(
@ -448,7 +591,7 @@ pub fn editor_header() -> impl Widget<Block> {
.with_font(FontDescriptor::new(FontFamily::SANS_SERIF).with_size(14.0))
.padding(5.0),
)
.with_flex_spacer(1.0)
.with_spacer(20.0)
.with_child(
Container::new(Padding::new(10.0, Svg::new(run_svg).fix_width(10.0)))
.controller(ToolbarButtonController::new(Color::rgb8(50, 50, 50)))

View File

@ -38,7 +38,7 @@ fn build_ui() -> impl Widget<AppData> {
fn main() -> Result<(), PlatformError> {
AppLauncher::with_window(
WindowDesc::new(build_ui())
.resizable(true)
.resizable(false)
.window_size((600.0, 800.0)),
)
.delegate(app_delegate::Delegate)

View File

@ -12,18 +12,26 @@ pub fn output_block() -> impl Widget<Block> {
ViewSwitcher::new(
|data: &Block, _env| data.clone(),
|selector: &Block, _data, _env| match &selector.output {
Output::Scalar(v) => Box::new(Padding::new(
25.0,
Label::new(v.to_string())
.with_font(
FontDescriptor::new(FontFamily::MONOSPACE).with_weight(FontWeight::BOLD),
)
.with_text_size(OUTPUT_FONT_SIZE)
.padding(10.0)
.background(Color::rgb8(30, 30, 30))
.rounded(4.0)
.expand_width(),
)),
Output::Scalar(v) => {
let str = match v {
_ if v.is::<String>() => v.clone().cast::<String>(),
_ if v.is::<&str>() => v.clone().cast::<&str>().to_string(),
v => v.to_string(),
};
Box::new(Padding::new(
25.0,
Label::new(str)
.with_font(
FontDescriptor::new(FontFamily::MONOSPACE)
.with_weight(FontWeight::BOLD),
)
.with_text_size(OUTPUT_FONT_SIZE)
.padding(10.0)
.background(Color::rgb8(30, 30, 30))
.rounded(4.0)
.expand_width(),
))
}
Output::Error(e) => Box::new(Padding::new(
25.0,
Label::new(e.to_string())
@ -81,7 +89,7 @@ pub fn output_block() -> impl Widget<Block> {
for v in series.iter() {
col.add_child(
Label::new(v.to_string())
Label::new(format_dataframe_value(v))
.with_font(
FontDescriptor::new(FontFamily::MONOSPACE)
.with_weight(FontWeight::MEDIUM),
@ -108,17 +116,15 @@ pub fn output_block() -> impl Widget<Block> {
.expand_width(),
))
}
_ => Box::new(Padding::new(
0.0,
Label::new("")
.with_font(
FontDescriptor::new(FontFamily::MONOSPACE).with_weight(FontWeight::BOLD),
)
.with_text_size(0.0)
.padding(0.0)
.background(Color::TRANSPARENT)
.expand_width(),
)),
Output::None => Box::new(Container::new(Label::new(""))),
},
)
}
fn format_dataframe_value(value: abacus_core::AnyValue) -> String {
match value {
abacus_core::AnyValue::Utf8(v) => v.to_string(),
abacus_core::AnyValue::Utf8Owned(v) => v,
_ => value.to_string(),
}
}