luna/src/ui/entry.rs
2022-02-06 20:30:45 +01:00

117 lines
3.1 KiB
Rust

use relm4::{
factory::{DynamicIndex, FactoryPrototype, FactoryVecDeque},
gtk::{self, prelude::*, Orientation, TextBuffer},
};
use crate::hl::{self, highlight_text_buffer};
use super::AppMsg;
pub enum Entry {
Error(TextBuffer),
LuaData {
src: TextBuffer,
out: String,
result: TextBuffer,
},
}
impl FactoryPrototype for Entry {
type Factory = FactoryVecDeque<Self>;
type Widgets = EntryWidgets;
type View = gtk::Box;
type Msg = AppMsg;
type Root = gtk::Box;
fn position(&self, _key: &DynamicIndex) {}
fn init_view(&self, _key: &DynamicIndex, _sender: relm4::Sender<Self::Msg>) -> Self::Widgets {
let (first_buf, second_buf) = match self {
Self::Error(e) => (e, None),
Self::LuaData { src, result, .. } => (src, Some(result)),
};
if let Some(json) = second_buf {
highlight_text_buffer(
first_buf,
unsafe { crate::tree_sitter_lua() },
hl::LUA_HL_QUERY,
);
highlight_text_buffer(
json,
unsafe { crate::tree_sitter_json() },
hl::JSON_HL_QUERY,
);
} else {
first_buf.apply_tag(
&first_buf.tag_table().lookup("error").unwrap(),
&first_buf.start_iter(),
&first_buf.end_iter(),
);
}
let main_box = gtk::Box::new(Orientation::Vertical, 5);
main_box.set_valign(gtk::Align::Start);
main_box.set_baseline_position(gtk::BaselinePosition::Top);
let first_view = gtk::TextView::builder()
.height_request(20)
.editable(false)
.monospace(true)
.buffer(first_buf)
.build();
let second_view = match self {
Self::LuaData { out, .. } if !out.is_empty() => {
let buf = gtk::TextBuffer::new(None);
buf.set_text(out);
Some(
gtk::TextView::builder()
.height_request(20)
.editable(false)
.monospace(true)
.buffer(&buf)
.build(),
)
},
_ => None,
};
let third_view = second_buf.map(|b| {
gtk::TextView::builder()
.height_request(20)
.editable(false)
.monospace(true)
.buffer(b)
.build()
});
main_box.append(&first_view);
if let Some(v) = second_view {
main_box.append(&v);
}
if let Some(v) = third_view {
main_box.append(&v);
}
main_box.set_visible(true);
EntryWidgets { main_box }
}
fn view(&self, _key: &DynamicIndex, _widgets: &Self::Widgets) {
// This widget is never updated :P
}
fn root_widget(widgets: &Self::Widgets) -> &Self::Root {
&widgets.main_box
}
}
#[derive(Debug)]
pub struct EntryWidgets {
main_box: gtk::Box,
}