@@ -16,6 +16,7 @@ egui = { workspace = true }
|
||||
notedeck_columns = { workspace = true }
|
||||
notedeck_ui = { workspace = true }
|
||||
notedeck_dave = { workspace = true }
|
||||
notedeck_notebook = { workspace = true }
|
||||
notedeck = { workspace = true }
|
||||
nostrdb = { workspace = true }
|
||||
puffin = { workspace = true, optional = true }
|
||||
|
||||
@@ -5,6 +5,7 @@ use egui_winit::winit::platform::android::activity::AndroidApp;
|
||||
use notedeck::enostr::Error;
|
||||
use notedeck_columns::Damus;
|
||||
use notedeck_dave::Dave;
|
||||
use notedeck_notebook::Notebook;
|
||||
|
||||
use crate::{app::NotedeckApp, chrome::Chrome, setup::setup_chrome};
|
||||
use notedeck::Notedeck;
|
||||
@@ -80,6 +81,7 @@ pub async fn android_main(app: AndroidApp) {
|
||||
let context = &mut notedeck.app_context();
|
||||
let dave = Dave::new(cc.wgpu_render_state.as_ref());
|
||||
let columns = Damus::new(context, &app_args);
|
||||
let notebook = Notebook::new();
|
||||
let mut chrome = Chrome::new();
|
||||
|
||||
// ensure we recognized all the arguments
|
||||
@@ -93,8 +95,9 @@ pub async fn android_main(app: AndroidApp) {
|
||||
return Err(Error::Empty.into());
|
||||
}
|
||||
|
||||
chrome.add_app(NotedeckApp::Columns(columns));
|
||||
chrome.add_app(NotedeckApp::Dave(dave));
|
||||
chrome.add_app(NotedeckApp::Columns(Box::new(columns)));
|
||||
chrome.add_app(NotedeckApp::Dave(Box::new(dave)));
|
||||
chrome.add_app(NotedeckApp::Notebook(Box::new(notebook)));
|
||||
|
||||
// test dav
|
||||
chrome.set_active(0);
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
use notedeck::{AppAction, AppContext};
|
||||
use notedeck_columns::Damus;
|
||||
use notedeck_dave::Dave;
|
||||
use notedeck_notebook::Notebook;
|
||||
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
pub enum NotedeckApp {
|
||||
Dave(Dave),
|
||||
Columns(Damus),
|
||||
Dave(Box<Dave>),
|
||||
Columns(Box<Damus>),
|
||||
Notebook(Box<Notebook>),
|
||||
Other(Box<dyn notedeck::App>),
|
||||
}
|
||||
|
||||
@@ -14,6 +16,7 @@ impl notedeck::App for NotedeckApp {
|
||||
match self {
|
||||
NotedeckApp::Dave(dave) => dave.update(ctx, ui),
|
||||
NotedeckApp::Columns(columns) => columns.update(ctx, ui),
|
||||
NotedeckApp::Notebook(notebook) => notebook.update(ctx, ui),
|
||||
NotedeckApp::Other(other) => other.update(ctx, ui),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ use notedeck_columns::{
|
||||
column::SelectionResult, timeline::kind::ListKind, timeline::TimelineKind, Damus,
|
||||
};
|
||||
use notedeck_dave::{Dave, DaveAvatar};
|
||||
use notedeck_notebook::Notebook;
|
||||
use notedeck_ui::{app_images, AnimationHelper, ProfilePic};
|
||||
|
||||
static ICON_WIDTH: f32 = 40.0;
|
||||
@@ -199,6 +200,16 @@ impl Chrome {
|
||||
None
|
||||
}
|
||||
|
||||
fn get_notebook(&mut self) -> Option<&mut Notebook> {
|
||||
for app in &mut self.apps {
|
||||
if let NotedeckApp::Notebook(notebook) = app {
|
||||
return Some(notebook);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn switch_to_dave(&mut self) {
|
||||
for (i, app) in self.apps.iter().enumerate() {
|
||||
if let NotedeckApp::Dave(_) = app {
|
||||
@@ -207,6 +218,14 @@ impl Chrome {
|
||||
}
|
||||
}
|
||||
|
||||
fn switch_to_notebook(&mut self) {
|
||||
for (i, app) in self.apps.iter().enumerate() {
|
||||
if let NotedeckApp::Notebook(_) = app {
|
||||
self.active = i as i32;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn switch_to_columns(&mut self) {
|
||||
for (i, app) in self.apps.iter().enumerate() {
|
||||
if let NotedeckApp::Columns(_) = app {
|
||||
@@ -428,13 +447,11 @@ impl Chrome {
|
||||
ui.add(milestone_name(i18n));
|
||||
ui.add_space(16.0);
|
||||
//let dark_mode = ui.ctx().style().visuals.dark_mode;
|
||||
if columns_button(ui)
|
||||
.on_hover_cursor(egui::CursorIcon::PointingHand)
|
||||
.clicked()
|
||||
{
|
||||
if columns_button(ui)
|
||||
.on_hover_cursor(egui::CursorIcon::PointingHand)
|
||||
.clicked()
|
||||
{
|
||||
self.active = 0;
|
||||
}
|
||||
self.active = 0;
|
||||
}
|
||||
ui.add_space(32.0);
|
||||
|
||||
@@ -446,6 +463,16 @@ impl Chrome {
|
||||
self.switch_to_dave();
|
||||
}
|
||||
}
|
||||
//ui.add_space(32.0);
|
||||
|
||||
if let Some(_notebook) = self.get_notebook() {
|
||||
if notebook_button(ui)
|
||||
.on_hover_cursor(egui::CursorIcon::PointingHand)
|
||||
.clicked()
|
||||
{
|
||||
self.switch_to_notebook();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -583,6 +610,16 @@ fn accounts_button(ui: &mut egui::Ui) -> egui::Response {
|
||||
)
|
||||
}
|
||||
|
||||
fn notebook_button(ui: &mut egui::Ui) -> egui::Response {
|
||||
expanding_button(
|
||||
"columns-button",
|
||||
40.0,
|
||||
app_images::new_message_image(),
|
||||
app_images::new_message_image(),
|
||||
ui,
|
||||
)
|
||||
}
|
||||
|
||||
fn dave_sidebar_rect(ui: &mut egui::Ui) -> Rect {
|
||||
let size = vec2(60.0, 60.0);
|
||||
let available = ui.available_rect_before_wrap();
|
||||
|
||||
@@ -17,6 +17,7 @@ use notedeck_chrome::{
|
||||
};
|
||||
use notedeck_columns::Damus;
|
||||
use notedeck_dave::Dave;
|
||||
use notedeck_notebook::Notebook;
|
||||
use tracing::error;
|
||||
use tracing_appender::non_blocking::WorkerGuard;
|
||||
use tracing_subscriber::EnvFilter;
|
||||
@@ -97,6 +98,7 @@ async fn main() {
|
||||
let mut chrome = Chrome::new();
|
||||
let columns = Damus::new(&mut notedeck.app_context(), &args);
|
||||
let dave = Dave::new(cc.wgpu_render_state.as_ref());
|
||||
let notebook = Notebook::default();
|
||||
|
||||
setup_chrome(
|
||||
ctx,
|
||||
@@ -117,8 +119,9 @@ async fn main() {
|
||||
return Err(Error::Empty.into());
|
||||
}
|
||||
|
||||
chrome.add_app(NotedeckApp::Columns(columns));
|
||||
chrome.add_app(NotedeckApp::Dave(dave));
|
||||
chrome.add_app(NotedeckApp::Columns(Box::new(columns)));
|
||||
chrome.add_app(NotedeckApp::Dave(Box::new(dave)));
|
||||
chrome.add_app(NotedeckApp::Notebook(Box::new(notebook)));
|
||||
|
||||
chrome.set_active(0);
|
||||
|
||||
|
||||
9
crates/notedeck_notebook/Cargo.toml
Normal file
9
crates/notedeck_notebook/Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "notedeck_notebook"
|
||||
edition = "2024"
|
||||
version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
jsoncanvas = { git = "https://github.com/jb55/jsoncanvas", rev = "ae60f96e4d022cf037e086b793cacc3225bc14e5" }
|
||||
notedeck = { workspace = true }
|
||||
egui = { workspace = true }
|
||||
232
crates/notedeck_notebook/demo.canvas
Normal file
232
crates/notedeck_notebook/demo.canvas
Normal file
File diff suppressed because one or more lines are too long
107
crates/notedeck_notebook/src/lib.rs
Normal file
107
crates/notedeck_notebook/src/lib.rs
Normal file
@@ -0,0 +1,107 @@
|
||||
use egui::{Align, Label, Pos2, Rect, TextWrapMode};
|
||||
use jsoncanvas::{FileNode, GroupNode, JsonCanvas, LinkNode, Node, TextNode, node::*};
|
||||
use notedeck::{AppAction, AppContext};
|
||||
|
||||
pub struct Notebook {
|
||||
canvas: JsonCanvas,
|
||||
scene_rect: Rect,
|
||||
loaded: bool,
|
||||
}
|
||||
|
||||
impl Default for Notebook {
|
||||
fn default() -> Self {
|
||||
Notebook {
|
||||
canvas: demo_canvas(),
|
||||
scene_rect: Rect::from_min_max(Pos2::ZERO, Pos2::ZERO),
|
||||
loaded: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl notedeck::App for Notebook {
|
||||
fn update(&mut self, _ctx: &mut AppContext<'_>, ui: &mut egui::Ui) -> Option<AppAction> {
|
||||
//let app_action: Option<AppAction> = None;
|
||||
|
||||
if !self.loaded {
|
||||
self.scene_rect = ui.available_rect_before_wrap();
|
||||
self.loaded = true;
|
||||
}
|
||||
|
||||
egui::Scene::new().show(ui, &mut self.scene_rect, |ui| {
|
||||
for (_node_id, node) in self.canvas.get_nodes().iter() {
|
||||
let _resp = node_ui(ui, node);
|
||||
}
|
||||
});
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn node_ui(ui: &mut egui::Ui, node: &Node) -> egui::Response {
|
||||
match node {
|
||||
Node::Text(text_node) => text_node_ui(ui, text_node),
|
||||
Node::File(file_node) => file_node_ui(ui, file_node),
|
||||
Node::Link(link_node) => link_node_ui(ui, link_node),
|
||||
Node::Group(group_node) => group_node_ui(ui, group_node),
|
||||
}
|
||||
}
|
||||
|
||||
fn text_node_ui(ui: &mut egui::Ui, node: &TextNode) -> egui::Response {
|
||||
node_box_ui(ui, node.node(), |ui| {
|
||||
ui.with_layout(egui::Layout::left_to_right(Align::Min), |ui| {
|
||||
ui.add(Label::new(node.text()).wrap_mode(TextWrapMode::Wrap))
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
fn file_node_ui(ui: &mut egui::Ui, node: &FileNode) -> egui::Response {
|
||||
node_box_ui(ui, node.node(), |ui| {
|
||||
ui.label("file node");
|
||||
})
|
||||
}
|
||||
|
||||
fn link_node_ui(ui: &mut egui::Ui, node: &LinkNode) -> egui::Response {
|
||||
node_box_ui(ui, node.node(), |ui| {
|
||||
ui.label("link node");
|
||||
})
|
||||
}
|
||||
|
||||
fn group_node_ui(ui: &mut egui::Ui, node: &GroupNode) -> egui::Response {
|
||||
node_box_ui(ui, node.node(), |ui| {
|
||||
ui.label("group node");
|
||||
})
|
||||
}
|
||||
|
||||
fn node_box_ui(
|
||||
ui: &mut egui::Ui,
|
||||
node: &GenericNode,
|
||||
contents: impl FnOnce(&mut egui::Ui),
|
||||
) -> egui::Response {
|
||||
let x = node.x as f32;
|
||||
let y = node.y as f32;
|
||||
let width = node.width as f32;
|
||||
let height = node.height as f32;
|
||||
|
||||
let min = Pos2::new(x, y);
|
||||
let max = Pos2::new(x + width, y + height);
|
||||
|
||||
ui.put(Rect::from_min_max(min, max), |ui: &mut egui::Ui| {
|
||||
egui::Frame::default()
|
||||
.fill(ui.visuals().noninteractive().weak_bg_fill)
|
||||
.inner_margin(egui::Margin::same(4))
|
||||
.corner_radius(egui::CornerRadius::same(10))
|
||||
.stroke(egui::Stroke::new(
|
||||
1.0,
|
||||
ui.visuals().noninteractive().bg_stroke.color,
|
||||
))
|
||||
.show(ui, contents)
|
||||
.response
|
||||
})
|
||||
}
|
||||
|
||||
fn demo_canvas() -> JsonCanvas {
|
||||
let demo_json: String = include_str!("../demo.canvas").to_string();
|
||||
|
||||
let canvas: JsonCanvas = demo_json.parse().unwrap_or_else(|_| JsonCanvas::default());
|
||||
canvas
|
||||
}
|
||||
Reference in New Issue
Block a user