schema.rs 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2024 Dyne.org foundation
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU Affero General Public License as
  7. * published by the Free Software Foundation, either version 3 of the
  8. * License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU Affero General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Affero General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. use sled_overlay::sled;
  19. use crate::{
  20. error::Error,
  21. expr::{self, Compiler},
  22. gfx::{GraphicsEventPublisherPtr, Rectangle, RenderApiPtr, Vertex},
  23. mesh::{Color, MeshBuilder},
  24. prop::{
  25. Property, PropertyBool, PropertyFloat32, PropertyStr, PropertySubType, PropertyType, Role,
  26. },
  27. scene::{SceneNodePtr, Slot},
  28. text::TextShaperPtr,
  29. ui::{
  30. Button, ChatView, EditBox, Image, Layer, ShapeVertex, Text, VectorArt, VectorShape, Window,
  31. },
  32. ExecutorPtr,
  33. };
  34. use super::{
  35. node::{
  36. create_button, create_chatview, create_editbox, create_image, create_layer, create_text,
  37. create_vector_art,
  38. },
  39. populate_tree, App,
  40. };
  41. const LIGHTMODE: bool = false;
  42. #[cfg(target_os = "android")]
  43. mod ui_consts {
  44. pub const CHATDB_PATH: &str = "/data/data/darkfi.darkwallet/chatdb/";
  45. pub const KING_PATH: &str = "king.png";
  46. pub const BG_PATH: &str = "bg.png";
  47. pub const EDITCHAT_HEIGHT: f32 = 163.;
  48. pub const EDITCHAT_CURSOR_ASCENT: f32 = 50.;
  49. pub const EDITCHAT_CURSOR_DESCENT: f32 = 20.;
  50. pub const TEXTBAR_BASELINE: f32 = 93.;
  51. pub const EDITCHAT_LHS_PAD: f32 = 30.;
  52. pub const SENDLABEL_WIDTH: f32 = 200.;
  53. pub const SENDLABEL_LHS_PAD: f32 = 30.;
  54. pub const FONTSIZE: f32 = 40.;
  55. pub const TIMESTAMP_FONTSIZE: f32 = 30.;
  56. pub const TIMESTAMP_WIDTH: f32 = 135.;
  57. pub const MESSAGE_SPACING: f32 = 15.;
  58. pub const LINE_HEIGHT: f32 = 58.;
  59. pub const CHATVIEW_BASELINE: f32 = 36.;
  60. }
  61. #[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))]
  62. mod ui_consts {
  63. pub const CHATDB_PATH: &str = "chatdb";
  64. pub const KING_PATH: &str = "assets/king.png";
  65. pub const BG_PATH: &str = "assets/bg.png";
  66. pub const EDITCHAT_HEIGHT: f32 = 50.;
  67. pub const EDITCHAT_CURSOR_ASCENT: f32 = 25.;
  68. pub const EDITCHAT_CURSOR_DESCENT: f32 = 8.;
  69. pub const TEXTBAR_BASELINE: f32 = 34.;
  70. pub const EDITCHAT_LHS_PAD: f32 = 20.;
  71. pub const SENDLABEL_WIDTH: f32 = 120.;
  72. pub const SENDLABEL_LHS_PAD: f32 = 30.;
  73. pub const FONTSIZE: f32 = 20.;
  74. pub const TIMESTAMP_FONTSIZE: f32 = 12.;
  75. pub const TIMESTAMP_WIDTH: f32 = 60.;
  76. pub const MESSAGE_SPACING: f32 = 5.;
  77. pub const LINE_HEIGHT: f32 = 30.;
  78. pub const CHATVIEW_BASELINE: f32 = 20.;
  79. }
  80. use ui_consts::*;
  81. pub(super) async fn make_test(app: &App, window: SceneNodePtr) {
  82. let window_scale = PropertyFloat32::wrap(&window, Role::Internal, "scale", 0).unwrap();
  83. let mut cc = Compiler::new();
  84. // Create a layer called view
  85. let layer_node = create_layer("view");
  86. let prop = layer_node.get_property("rect").unwrap();
  87. prop.set_f32(Role::App, 0, 0.).unwrap();
  88. prop.set_f32(Role::App, 1, 0.).unwrap();
  89. prop.set_expr(Role::App, 2, expr::load_var("w")).unwrap();
  90. prop.set_expr(Role::App, 3, expr::load_var("h")).unwrap();
  91. layer_node.set_property_bool(Role::App, "is_visible", true).unwrap();
  92. let layer_node =
  93. layer_node.setup(|me| Layer::new(me, app.render_api.clone(), app.ex.clone())).await;
  94. window.link(layer_node.clone());
  95. // Create a bg mesh
  96. let node = create_vector_art("bg");
  97. let prop = node.get_property("rect").unwrap();
  98. prop.set_f32(Role::App, 0, 0.).unwrap();
  99. prop.set_f32(Role::App, 1, 0.).unwrap();
  100. prop.set_expr(Role::App, 2, expr::load_var("w")).unwrap();
  101. prop.set_expr(Role::App, 3, expr::load_var("h")).unwrap();
  102. node.set_property_u32(Role::App, "z_index", 0).unwrap();
  103. let c = if LIGHTMODE { 1. } else { 0. };
  104. let mut shape = VectorShape::new();
  105. shape.add_filled_box(
  106. expr::const_f32(0.),
  107. expr::const_f32(0.),
  108. expr::load_var("w"),
  109. expr::load_var("h"),
  110. [c, c, c, 1.],
  111. );
  112. let node =
  113. node.setup(|me| VectorArt::new(me, shape, app.render_api.clone(), app.ex.clone())).await;
  114. layer_node.clone().link(node);
  115. // Create button bg
  116. let node = create_vector_art("btnbg");
  117. let prop = node.get_property("rect").unwrap();
  118. let code = cc.compile("w - 210").unwrap();
  119. prop.set_expr(Role::App, 0, code).unwrap();
  120. prop.set_f32(Role::App, 1, 10.).unwrap();
  121. prop.set_f32(Role::App, 2, 200.).unwrap();
  122. prop.set_f32(Role::App, 3, 60.).unwrap();
  123. node.set_property_u32(Role::App, "z_index", 1).unwrap();
  124. // Setup the pimpl
  125. let verts = if LIGHTMODE {
  126. vec![
  127. ShapeVertex::from_xy(0., 0., [1., 0., 0., 1.]),
  128. ShapeVertex::from_xy(200., 0., [1., 0., 0., 1.]),
  129. ShapeVertex::from_xy(0., 60., [1., 0., 0., 1.]),
  130. ShapeVertex::from_xy(200., 60., [1., 0., 0., 1.]),
  131. ]
  132. } else {
  133. vec![
  134. ShapeVertex::from_xy(0., 0., [1., 0., 0., 1.]),
  135. ShapeVertex::from_xy(200., 0., [1., 0., 1., 1.]),
  136. ShapeVertex::from_xy(0., 60., [0., 0., 1., 1.]),
  137. ShapeVertex::from_xy(200., 60., [1., 1., 0., 1.]),
  138. ]
  139. };
  140. let indices = vec![0, 2, 1, 1, 2, 3];
  141. let shape = VectorShape { verts, indices };
  142. let node =
  143. node.setup(|me| VectorArt::new(me, shape, app.render_api.clone(), app.ex.clone())).await;
  144. layer_node.clone().link(node);
  145. // Create the button
  146. let node = create_button("btn");
  147. node.set_property_bool(Role::App, "is_active", true).unwrap();
  148. let prop = node.get_property("rect").unwrap();
  149. let code = cc.compile("w - 220").unwrap();
  150. prop.set_expr(Role::App, 0, code).unwrap();
  151. prop.set_f32(Role::App, 1, 10.).unwrap();
  152. prop.set_f32(Role::App, 2, 200.).unwrap();
  153. prop.set_f32(Role::App, 3, 60.).unwrap();
  154. //let (sender, btn_click_recvr) = async_channel::unbounded();
  155. //let slot_click = Slot { name: "button_clicked".to_string(), notify: sender };
  156. //node.register("click", slot_click).unwrap();
  157. let node = node.setup(|me| Button::new(me, app.ex.clone())).await;
  158. layer_node.clone().link(node);
  159. // Create another mesh
  160. let node = create_vector_art("box");
  161. let prop = node.get_property("rect").unwrap();
  162. prop.set_f32(Role::App, 0, 10.).unwrap();
  163. prop.set_f32(Role::App, 1, 10.).unwrap();
  164. prop.set_f32(Role::App, 2, 60.).unwrap();
  165. prop.set_f32(Role::App, 3, 60.).unwrap();
  166. node.set_property_u32(Role::App, "z_index", 1).unwrap();
  167. // Setup the pimpl
  168. let verts = if LIGHTMODE {
  169. vec![
  170. ShapeVertex::from_xy(0., 0., [1., 0., 0., 1.]),
  171. ShapeVertex::from_xy(60., 0., [1., 0., 0., 1.]),
  172. ShapeVertex::from_xy(0., 60., [0., 0., 0., 1.]),
  173. ShapeVertex::from_xy(60., 60., [1., 0., 0., 1.]),
  174. ]
  175. } else {
  176. vec![
  177. ShapeVertex::from_xy(0., 0., [1., 0., 0., 1.]),
  178. ShapeVertex::from_xy(60., 0., [1., 0., 1., 1.]),
  179. ShapeVertex::from_xy(0., 60., [0., 0., 1., 1.]),
  180. ShapeVertex::from_xy(60., 60., [1., 1., 0., 1.]),
  181. ]
  182. };
  183. let indices = vec![0, 2, 1, 1, 2, 3];
  184. let shape = VectorShape { verts, indices };
  185. let node =
  186. node.setup(|me| VectorArt::new(me, shape, app.render_api.clone(), app.ex.clone())).await;
  187. layer_node.clone().link(node);
  188. // Debugging tool
  189. let node = create_vector_art("debugtool");
  190. let prop = node.get_property("rect").unwrap();
  191. prop.set_f32(Role::App, 0, 0.).unwrap();
  192. let code = cc.compile("h/2").unwrap();
  193. prop.set_expr(Role::App, 1, code).unwrap();
  194. prop.set_expr(Role::App, 2, expr::load_var("w")).unwrap();
  195. let code = cc.compile("h/2 - 200").unwrap();
  196. prop.set_expr(Role::App, 3, code).unwrap();
  197. node.set_property_u32(Role::App, "z_index", 2).unwrap();
  198. let mut shape = VectorShape::new();
  199. shape.add_filled_box(
  200. expr::const_f32(0.),
  201. expr::const_f32(0.),
  202. expr::load_var("w"),
  203. expr::const_f32(5.),
  204. [0., 1., 0., 1.],
  205. );
  206. shape.add_filled_box(
  207. expr::const_f32(0.),
  208. cc.compile("h - 5").unwrap(),
  209. expr::load_var("w"),
  210. expr::load_var("h"),
  211. [0., 1., 0., 1.],
  212. );
  213. let node =
  214. node.setup(|me| VectorArt::new(me, shape, app.render_api.clone(), app.ex.clone())).await;
  215. layer_node.clone().link(node);
  216. // Create KING GNU!
  217. let node = create_image("king");
  218. let prop = node.get_property("rect").unwrap();
  219. prop.set_f32(Role::App, 0, 80.).unwrap();
  220. prop.set_f32(Role::App, 1, 10.).unwrap();
  221. prop.set_f32(Role::App, 2, 60.).unwrap();
  222. prop.set_f32(Role::App, 3, 60.).unwrap();
  223. node.set_property_str(Role::App, "path", KING_PATH).unwrap();
  224. node.set_property_u32(Role::App, "z_index", 1).unwrap();
  225. let node = node.setup(|me| Image::new(me, app.render_api.clone(), app.ex.clone())).await;
  226. layer_node.clone().link(node);
  227. // Create some text
  228. let node = create_text("label");
  229. let prop = node.get_property("rect").unwrap();
  230. prop.set_f32(Role::App, 0, 100.).unwrap();
  231. prop.set_f32(Role::App, 1, 100.).unwrap();
  232. prop.set_f32(Role::App, 2, 800.).unwrap();
  233. prop.set_f32(Role::App, 3, 200.).unwrap();
  234. node.set_property_f32(Role::App, "baseline", 40.).unwrap();
  235. node.set_property_f32(Role::App, "font_size", 60.).unwrap();
  236. node.set_property_str(Role::App, "text", "anon1🍆").unwrap();
  237. //node.set_property_str(Role::App, "text", "anon1").unwrap();
  238. let prop = node.get_property("text_color").unwrap();
  239. prop.set_f32(Role::App, 0, 0.).unwrap();
  240. prop.set_f32(Role::App, 1, 1.).unwrap();
  241. prop.set_f32(Role::App, 2, 0.).unwrap();
  242. prop.set_f32(Role::App, 3, 1.).unwrap();
  243. node.set_property_u32(Role::App, "z_index", 1).unwrap();
  244. let node = node
  245. .setup(|me| {
  246. Text::new(
  247. me,
  248. window_scale.clone(),
  249. app.render_api.clone(),
  250. app.text_shaper.clone(),
  251. app.ex.clone(),
  252. )
  253. })
  254. .await;
  255. layer_node.clone().link(node);
  256. // Text edit
  257. let node = create_editbox("editz");
  258. node.set_property_bool(Role::App, "is_active", true).unwrap();
  259. node.set_property_bool(Role::App, "is_focused", true).unwrap();
  260. let prop = node.get_property("rect").unwrap();
  261. prop.set_f32(Role::App, 0, 150.).unwrap();
  262. prop.set_f32(Role::App, 1, 150.).unwrap();
  263. prop.set_f32(Role::App, 2, 380.).unwrap();
  264. //let code = vec![Op::Sub((
  265. // Box::new(Op::LoadVar("h".to_string())),
  266. // Box::new(Op::ConstFloat32(60.)),
  267. //))];
  268. //prop.set_expr(Role::App, 1, code).unwrap();
  269. //let code = vec![Op::Sub((
  270. // Box::new(Op::LoadVar("w".to_string())),
  271. // Box::new(Op::ConstFloat32(120.)),
  272. //))];
  273. //prop.set_expr(Role::App, 2, code).unwrap();
  274. prop.set_f32(Role::App, 3, 60.).unwrap();
  275. node.set_property_f32(Role::App, "baseline", 40.).unwrap();
  276. node.set_property_f32(Role::App, "font_size", 20.).unwrap();
  277. node.set_property_f32(Role::App, "font_size", 40.).unwrap();
  278. node.set_property_str(Role::App, "text", "hello king!😁🍆jelly 🍆1234").unwrap();
  279. let prop = node.get_property("text_color").unwrap();
  280. if LIGHTMODE {
  281. prop.set_f32(Role::App, 0, 0.).unwrap();
  282. prop.set_f32(Role::App, 1, 0.).unwrap();
  283. prop.set_f32(Role::App, 2, 0.).unwrap();
  284. prop.set_f32(Role::App, 3, 1.).unwrap();
  285. } else {
  286. prop.set_f32(Role::App, 0, 1.).unwrap();
  287. prop.set_f32(Role::App, 1, 1.).unwrap();
  288. prop.set_f32(Role::App, 2, 1.).unwrap();
  289. prop.set_f32(Role::App, 3, 1.).unwrap();
  290. }
  291. let prop = node.get_property("cursor_color").unwrap();
  292. prop.set_f32(Role::App, 0, 1.).unwrap();
  293. prop.set_f32(Role::App, 1, 0.5).unwrap();
  294. prop.set_f32(Role::App, 2, 0.5).unwrap();
  295. prop.set_f32(Role::App, 3, 1.).unwrap();
  296. node.set_property_f32(Role::App, "cursor_ascent", 40.).unwrap();
  297. node.set_property_f32(Role::App, "cursor_descent", 40.).unwrap();
  298. let prop = node.get_property("hi_bg_color").unwrap();
  299. if LIGHTMODE {
  300. prop.set_f32(Role::App, 0, 0.5).unwrap();
  301. prop.set_f32(Role::App, 1, 0.5).unwrap();
  302. prop.set_f32(Role::App, 2, 0.5).unwrap();
  303. prop.set_f32(Role::App, 3, 1.).unwrap();
  304. } else {
  305. prop.set_f32(Role::App, 0, 1.).unwrap();
  306. prop.set_f32(Role::App, 1, 1.).unwrap();
  307. prop.set_f32(Role::App, 2, 1.).unwrap();
  308. prop.set_f32(Role::App, 3, 0.5).unwrap();
  309. }
  310. let prop = node.get_property("selected").unwrap();
  311. prop.set_null(Role::App, 0).unwrap();
  312. prop.set_null(Role::App, 1).unwrap();
  313. node.set_property_u32(Role::App, "z_index", 1).unwrap();
  314. //node.set_property_bool(Role::App, "debug", true).unwrap();
  315. //let editbox_text = PropertyStr::wrap(node, Role::App, "text", 0).unwrap();
  316. //let editbox_focus = PropertyBool::wrap(node, Role::App, "is_focused", 0).unwrap();
  317. //let darkirc_backend = app.darkirc_backend.clone();
  318. //let task = app.ex.spawn(async move {
  319. // while let Ok(_) = btn_click_recvr.recv().await {
  320. // let text = editbox_text.get();
  321. // editbox_text.prop().unset(Role::App, 0).unwrap();
  322. // // Clicking outside the editbox makes it lose focus
  323. // // So lets focus it again
  324. // editbox_focus.set(true);
  325. // debug!(target: "app", "sending text {text}");
  326. // let privmsg =
  327. // Privmsg { channel: "#random".to_string(), nick: "king".to_string(), msg: text };
  328. // darkirc_backend.send(privmsg).await;
  329. // }
  330. //});
  331. //tasks.push(task);
  332. let node = node
  333. .setup(|me| {
  334. EditBox::new(
  335. me,
  336. window_scale.clone(),
  337. app.render_api.clone(),
  338. app.text_shaper.clone(),
  339. app.ex.clone(),
  340. )
  341. })
  342. .await;
  343. layer_node.clone().link(node);
  344. // ChatView
  345. let node = create_chatview("chatty");
  346. let prop = node.get_property("rect").unwrap();
  347. prop.set_f32(Role::App, 0, 0.).unwrap();
  348. let code = cc.compile("h/2").unwrap();
  349. prop.set_expr(Role::App, 1, code).unwrap();
  350. prop.set_expr(Role::App, 2, expr::load_var("w")).unwrap();
  351. let code = cc.compile("h/2 - 200").unwrap();
  352. prop.set_expr(Role::App, 3, code).unwrap();
  353. node.set_property_f32(Role::App, "font_size", 20.).unwrap();
  354. node.set_property_f32(Role::App, "timestamp_font_size", 10.).unwrap();
  355. node.set_property_f32(Role::App, "timestamp_width", 80.).unwrap();
  356. node.set_property_f32(Role::App, "line_height", 30.).unwrap();
  357. node.set_property_f32(Role::App, "baseline", 20.).unwrap();
  358. node.set_property_u32(Role::App, "z_index", 1).unwrap();
  359. //node.set_property_bool(Role::App, "debug", true).unwrap();
  360. let prop = node.get_property("timestamp_color").unwrap();
  361. prop.set_f32(Role::App, 0, 0.5).unwrap();
  362. prop.set_f32(Role::App, 1, 0.5).unwrap();
  363. prop.set_f32(Role::App, 2, 0.5).unwrap();
  364. prop.set_f32(Role::App, 3, 0.5).unwrap();
  365. let prop = node.get_property("text_color").unwrap();
  366. if LIGHTMODE {
  367. prop.set_f32(Role::App, 0, 0.).unwrap();
  368. prop.set_f32(Role::App, 1, 0.).unwrap();
  369. prop.set_f32(Role::App, 2, 0.).unwrap();
  370. prop.set_f32(Role::App, 3, 1.).unwrap();
  371. } else {
  372. prop.set_f32(Role::App, 0, 1.).unwrap();
  373. prop.set_f32(Role::App, 1, 1.).unwrap();
  374. prop.set_f32(Role::App, 2, 1.).unwrap();
  375. prop.set_f32(Role::App, 3, 1.).unwrap();
  376. }
  377. let prop = node.get_property("nick_colors").unwrap();
  378. #[rustfmt::skip]
  379. let nick_colors = [
  380. 0.00, 0.94, 1.00, 1.,
  381. 0.36, 1.00, 0.69, 1.,
  382. 0.29, 1.00, 0.45, 1.,
  383. 0.00, 0.73, 0.38, 1.,
  384. 0.21, 0.67, 0.67, 1.,
  385. 0.56, 0.61, 1.00, 1.,
  386. 0.84, 0.48, 1.00, 1.,
  387. 1.00, 0.61, 0.94, 1.,
  388. 1.00, 0.36, 0.48, 1.,
  389. 1.00, 0.30, 0.00, 1.
  390. ];
  391. for c in nick_colors {
  392. prop.push_f32(Role::App, c).unwrap();
  393. }
  394. let prop = node.get_property("hi_bg_color").unwrap();
  395. if LIGHTMODE {
  396. prop.set_f32(Role::App, 0, 0.5).unwrap();
  397. prop.set_f32(Role::App, 1, 0.5).unwrap();
  398. prop.set_f32(Role::App, 2, 0.5).unwrap();
  399. prop.set_f32(Role::App, 3, 1.).unwrap();
  400. } else {
  401. prop.set_f32(Role::App, 0, 0.5).unwrap();
  402. prop.set_f32(Role::App, 1, 0.5).unwrap();
  403. prop.set_f32(Role::App, 2, 0.5).unwrap();
  404. prop.set_f32(Role::App, 3, 1.).unwrap();
  405. }
  406. let db = sled::open(CHATDB_PATH).expect("cannot open sleddb");
  407. let chat_tree = db.open_tree(b"chat").unwrap();
  408. if chat_tree.is_empty() {
  409. populate_tree(&chat_tree);
  410. }
  411. debug!(target: "app", "db has {} lines", chat_tree.len());
  412. let node = node
  413. .setup(|me| {
  414. ChatView::new(
  415. me,
  416. chat_tree,
  417. window_scale,
  418. app.render_api.clone(),
  419. app.text_shaper.clone(),
  420. app.ex.clone(),
  421. )
  422. })
  423. .await;
  424. layer_node.clone().link(node);
  425. }
  426. pub(super) async fn make(app: &App, window: SceneNodePtr) {
  427. let window_scale = PropertyFloat32::wrap(&window, Role::Internal, "scale", 0).unwrap();
  428. let mut cc = Compiler::new();
  429. cc.add_const_f32("EDITCHAT_HEIGHT", EDITCHAT_HEIGHT);
  430. cc.add_const_f32("SENDLABEL_WIDTH", SENDLABEL_WIDTH);
  431. cc.add_const_f32("SENDLABEL_LHS_PAD", SENDLABEL_LHS_PAD);
  432. // Main view
  433. let layer_node = create_layer("view");
  434. let prop = layer_node.get_property("rect").unwrap();
  435. prop.set_f32(Role::App, 0, 0.).unwrap();
  436. prop.set_f32(Role::App, 1, 0.).unwrap();
  437. prop.set_expr(Role::App, 2, expr::load_var("w")).unwrap();
  438. prop.set_expr(Role::App, 3, expr::load_var("h")).unwrap();
  439. layer_node.set_property_bool(Role::App, "is_visible", true).unwrap();
  440. let layer_node =
  441. layer_node.setup(|me| Layer::new(me, app.render_api.clone(), app.ex.clone())).await;
  442. window.link(layer_node.clone());
  443. // Create a bg image
  444. let node = create_image("bg_image");
  445. let prop = node.get_property("rect").unwrap();
  446. prop.set_f32(Role::App, 0, 0.).unwrap();
  447. prop.set_f32(Role::App, 1, 0.).unwrap();
  448. prop.set_expr(Role::App, 2, expr::load_var("w")).unwrap();
  449. prop.set_expr(Role::App, 3, expr::load_var("h")).unwrap();
  450. let prop = node.get_property("uv").unwrap();
  451. prop.set_f32(Role::App, 0, 0.).unwrap();
  452. prop.set_f32(Role::App, 1, 0.).unwrap();
  453. prop.set_f32(Role::App, 2, 1.).unwrap();
  454. prop.set_f32(Role::App, 3, 1.).unwrap();
  455. node.set_property_str(Role::App, "path", BG_PATH).unwrap();
  456. node.set_property_u32(Role::App, "z_index", 0).unwrap();
  457. let node = node.setup(|me| Image::new(me, app.render_api.clone(), app.ex.clone())).await;
  458. layer_node.clone().link(node);
  459. // Create a bg mesh
  460. let node = create_vector_art("bg");
  461. let prop = node.get_property("rect").unwrap();
  462. prop.set_f32(Role::App, 0, 0.).unwrap();
  463. prop.set_f32(Role::App, 1, 0.).unwrap();
  464. prop.set_expr(Role::App, 2, expr::load_var("w")).unwrap();
  465. prop.set_expr(Role::App, 3, expr::load_var("h")).unwrap();
  466. node.set_property_u32(Role::App, "z_index", 1).unwrap();
  467. let c = if LIGHTMODE { 1. } else { 0.05 };
  468. // Setup the pimpl
  469. let node_id = node.id;
  470. let mut shape = VectorShape::new();
  471. shape.add_filled_box(
  472. expr::const_f32(0.),
  473. expr::const_f32(0.),
  474. expr::load_var("w"),
  475. expr::load_var("h"),
  476. [c, c, c, 0.4],
  477. );
  478. let node =
  479. node.setup(|me| VectorArt::new(me, shape, app.render_api.clone(), app.ex.clone())).await;
  480. layer_node.clone().link(node);
  481. // Create the toolbar bg
  482. let node = create_vector_art("toolbar_bg");
  483. let prop = node.get_property("rect").unwrap();
  484. prop.set_f32(Role::App, 0, 0.).unwrap();
  485. prop.set_f32(Role::App, 1, 0.).unwrap();
  486. prop.set_expr(Role::App, 2, expr::load_var("w")).unwrap();
  487. prop.set_f32(Role::App, 3, EDITCHAT_HEIGHT).unwrap();
  488. node.set_property_u32(Role::App, "z_index", 2).unwrap();
  489. let mut shape = VectorShape::new();
  490. shape.add_filled_box(
  491. expr::const_f32(0.),
  492. expr::const_f32(0.),
  493. expr::load_var("w"),
  494. expr::load_var("h"),
  495. [0.05, 0.05, 0.05, 1.],
  496. );
  497. shape.add_filled_box(
  498. expr::const_f32(0.),
  499. cc.compile("h - 1").unwrap(),
  500. expr::load_var("w"),
  501. expr::load_var("h"),
  502. [0.4, 0.4, 0.4, 1.],
  503. );
  504. let node =
  505. node.setup(|me| VectorArt::new(me, shape, app.render_api.clone(), app.ex.clone())).await;
  506. layer_node.clone().link(node);
  507. // Create some text
  508. let node = create_text("channel_label");
  509. let prop = node.get_property("rect").unwrap();
  510. prop.set_f32(Role::App, 0, SENDLABEL_LHS_PAD).unwrap();
  511. prop.set_f32(Role::App, 1, 0.).unwrap();
  512. prop.set_expr(Role::App, 2, expr::load_var("w")).unwrap();
  513. prop.set_f32(Role::App, 3, EDITCHAT_HEIGHT).unwrap();
  514. node.set_property_u32(Role::App, "z_index", 2).unwrap();
  515. node.set_property_f32(Role::App, "baseline", TEXTBAR_BASELINE).unwrap();
  516. node.set_property_f32(Role::App, "font_size", FONTSIZE).unwrap();
  517. node.set_property_str(Role::App, "text", "random").unwrap();
  518. //node.set_property_str(Role::App, "text", "anon1").unwrap();
  519. let prop = node.get_property("text_color").unwrap();
  520. prop.set_f32(Role::App, 0, 1.).unwrap();
  521. prop.set_f32(Role::App, 1, 1.).unwrap();
  522. prop.set_f32(Role::App, 2, 1.).unwrap();
  523. prop.set_f32(Role::App, 3, 1.).unwrap();
  524. node.set_property_u32(Role::App, "z_index", 3).unwrap();
  525. let node = node
  526. .setup(|me| {
  527. Text::new(
  528. me,
  529. window_scale.clone(),
  530. app.render_api.clone(),
  531. app.text_shaper.clone(),
  532. app.ex.clone(),
  533. )
  534. })
  535. .await;
  536. layer_node.clone().link(node);
  537. // ChatView
  538. let node = create_chatview("chatty");
  539. let prop = node.get_property("rect").unwrap();
  540. prop.set_f32(Role::App, 0, 0.).unwrap();
  541. prop.set_f32(Role::App, 1, EDITCHAT_HEIGHT).unwrap();
  542. prop.set_expr(Role::App, 2, expr::load_var("w")).unwrap();
  543. let code = cc.compile("h - 2 * EDITCHAT_HEIGHT").unwrap();
  544. prop.set_expr(Role::App, 3, code).unwrap();
  545. node.set_property_f32(Role::App, "font_size", FONTSIZE).unwrap();
  546. node.set_property_f32(Role::App, "timestamp_font_size", TIMESTAMP_FONTSIZE).unwrap();
  547. node.set_property_f32(Role::App, "timestamp_width", TIMESTAMP_WIDTH).unwrap();
  548. node.set_property_f32(Role::App, "line_height", LINE_HEIGHT).unwrap();
  549. node.set_property_f32(Role::App, "message_spacing", MESSAGE_SPACING).unwrap();
  550. node.set_property_f32(Role::App, "baseline", CHATVIEW_BASELINE).unwrap();
  551. node.set_property_u32(Role::App, "z_index", 2).unwrap();
  552. //node.set_property_bool(Role::App, "debug", true).unwrap();
  553. #[cfg(target_os = "android")]
  554. node.set_property_f32(Role::App, "scroll_start_accel", 40.).unwrap();
  555. #[cfg(target_os = "linux")]
  556. node.set_property_f32(Role::App, "scroll_start_accel", 15.).unwrap();
  557. node.set_property_f32(Role::App, "scroll_resist", 0.9).unwrap();
  558. let prop = node.get_property("timestamp_color").unwrap();
  559. prop.set_f32(Role::App, 0, 0.407).unwrap();
  560. prop.set_f32(Role::App, 1, 0.604).unwrap();
  561. prop.set_f32(Role::App, 2, 0.647).unwrap();
  562. prop.set_f32(Role::App, 3, 1.).unwrap();
  563. let prop = node.get_property("text_color").unwrap();
  564. if LIGHTMODE {
  565. prop.set_f32(Role::App, 0, 0.).unwrap();
  566. prop.set_f32(Role::App, 1, 0.).unwrap();
  567. prop.set_f32(Role::App, 2, 0.).unwrap();
  568. prop.set_f32(Role::App, 3, 1.).unwrap();
  569. } else {
  570. prop.set_f32(Role::App, 0, 1.).unwrap();
  571. prop.set_f32(Role::App, 1, 1.).unwrap();
  572. prop.set_f32(Role::App, 2, 1.).unwrap();
  573. prop.set_f32(Role::App, 3, 1.).unwrap();
  574. }
  575. let prop = node.get_property("nick_colors").unwrap();
  576. #[rustfmt::skip]
  577. let nick_colors = [
  578. 0.00, 0.94, 1.00, 1.,
  579. 0.36, 1.00, 0.69, 1.,
  580. 0.29, 1.00, 0.45, 1.,
  581. 0.00, 0.73, 0.38, 1.,
  582. 0.21, 0.67, 0.67, 1.,
  583. 0.56, 0.61, 1.00, 1.,
  584. 0.84, 0.48, 1.00, 1.,
  585. 1.00, 0.61, 0.94, 1.,
  586. 1.00, 0.36, 0.48, 1.,
  587. 1.00, 0.30, 0.00, 1.
  588. ];
  589. for c in nick_colors {
  590. prop.push_f32(Role::App, c).unwrap();
  591. }
  592. let prop = node.get_property("hi_bg_color").unwrap();
  593. if LIGHTMODE {
  594. prop.set_f32(Role::App, 0, 0.5).unwrap();
  595. prop.set_f32(Role::App, 1, 0.5).unwrap();
  596. prop.set_f32(Role::App, 2, 0.5).unwrap();
  597. prop.set_f32(Role::App, 3, 1.).unwrap();
  598. } else {
  599. prop.set_f32(Role::App, 0, 0.5).unwrap();
  600. prop.set_f32(Role::App, 1, 0.5).unwrap();
  601. prop.set_f32(Role::App, 2, 0.5).unwrap();
  602. prop.set_f32(Role::App, 3, 1.).unwrap();
  603. }
  604. let db = sled::open(CHATDB_PATH).expect("cannot open sleddb");
  605. let chat_tree = db.open_tree(b"chat").unwrap();
  606. //if chat_tree.is_empty() {
  607. // populate_tree(&chat_tree);
  608. //}
  609. debug!(target: "app", "db has {} lines", chat_tree.len());
  610. let node = node
  611. .setup(|me| {
  612. ChatView::new(
  613. me,
  614. chat_tree,
  615. window_scale.clone(),
  616. app.render_api.clone(),
  617. app.text_shaper.clone(),
  618. app.ex.clone(),
  619. )
  620. })
  621. .await;
  622. layer_node.clone().link(node);
  623. // Create the editbox bg
  624. let node = create_vector_art("editbox_bg");
  625. let prop = node.get_property("rect").unwrap();
  626. prop.set_f32(Role::App, 0, 0.).unwrap();
  627. let code = cc.compile("h - EDITCHAT_HEIGHT").unwrap();
  628. prop.set_expr(Role::App, 1, code).unwrap();
  629. prop.set_expr(Role::App, 2, expr::load_var("w")).unwrap();
  630. prop.set_f32(Role::App, 3, EDITCHAT_HEIGHT).unwrap();
  631. node.set_property_u32(Role::App, "z_index", 2).unwrap();
  632. let mut shape = VectorShape::new();
  633. shape.add_filled_box(
  634. expr::const_f32(0.),
  635. expr::const_f32(0.),
  636. cc.compile("w - SENDLABEL_WIDTH").unwrap(),
  637. expr::load_var("h"),
  638. [0., 0.13, 0.08, 1.],
  639. );
  640. shape.add_filled_box(
  641. expr::const_f32(0.),
  642. expr::const_f32(0.),
  643. expr::load_var("w"),
  644. expr::const_f32(1.),
  645. [0.41, 0.6, 0.65, 1.],
  646. );
  647. shape.add_filled_box(
  648. cc.compile("w - SENDLABEL_WIDTH").unwrap(),
  649. expr::const_f32(0.),
  650. cc.compile("w - SENDLABEL_WIDTH - 1").unwrap(),
  651. expr::load_var("h"),
  652. [0.41, 0.6, 0.65, 1.],
  653. );
  654. shape.add_filled_box(
  655. cc.compile("w - SENDLABEL_WIDTH + 1").unwrap(),
  656. expr::const_f32(0.),
  657. expr::load_var("w"),
  658. expr::load_var("h"),
  659. [0.04, 0.04, 0.04, 1.],
  660. );
  661. let node =
  662. node.setup(|me| VectorArt::new(me, shape, app.render_api.clone(), app.ex.clone())).await;
  663. layer_node.clone().link(node);
  664. // Create some text
  665. let node = create_text("send_label");
  666. let prop = node.get_property("rect").unwrap();
  667. let code = cc.compile("w - (SENDLABEL_WIDTH - SENDLABEL_LHS_PAD)").unwrap();
  668. prop.set_expr(Role::App, 0, code).unwrap();
  669. let code = cc.compile("h - EDITCHAT_HEIGHT").unwrap();
  670. prop.set_expr(Role::App, 1, code).unwrap();
  671. prop.set_f32(Role::App, 2, SENDLABEL_WIDTH).unwrap();
  672. prop.set_f32(Role::App, 3, EDITCHAT_HEIGHT).unwrap();
  673. node.set_property_f32(Role::App, "baseline", TEXTBAR_BASELINE).unwrap();
  674. node.set_property_f32(Role::App, "font_size", FONTSIZE).unwrap();
  675. node.set_property_str(Role::App, "text", "send").unwrap();
  676. //node.set_property_str(Role::App, "text", "anon1").unwrap();
  677. let prop = node.get_property("text_color").unwrap();
  678. prop.set_f32(Role::App, 0, 0.).unwrap();
  679. prop.set_f32(Role::App, 1, 1.).unwrap();
  680. prop.set_f32(Role::App, 2, 0.94).unwrap();
  681. prop.set_f32(Role::App, 3, 1.).unwrap();
  682. node.set_property_u32(Role::App, "z_index", 3).unwrap();
  683. let node = node
  684. .setup(|me| {
  685. Text::new(
  686. me,
  687. window_scale.clone(),
  688. app.render_api.clone(),
  689. app.text_shaper.clone(),
  690. app.ex.clone(),
  691. )
  692. })
  693. .await;
  694. layer_node.clone().link(node);
  695. // Text edit
  696. let node = create_editbox("editz");
  697. node.set_property_bool(Role::App, "is_active", true).unwrap();
  698. node.set_property_bool(Role::App, "is_focused", true).unwrap();
  699. let prop = node.get_property("rect").unwrap();
  700. prop.set_f32(Role::App, 0, EDITCHAT_LHS_PAD).unwrap();
  701. let code = cc.compile("h - EDITCHAT_HEIGHT").unwrap();
  702. prop.set_expr(Role::App, 1, code).unwrap();
  703. let code = cc.compile("w - (SENDLABEL_WIDTH + SENDLABEL_LHS_PAD)").unwrap();
  704. prop.set_expr(Role::App, 2, code).unwrap();
  705. prop.set_f32(Role::App, 3, EDITCHAT_HEIGHT).unwrap();
  706. node.set_property_f32(Role::App, "baseline", TEXTBAR_BASELINE).unwrap();
  707. node.set_property_f32(Role::App, "font_size", FONTSIZE).unwrap();
  708. //node.set_property_str(Role::App, "text", "hello king!😁🍆jelly 🍆1234").unwrap();
  709. let prop = node.get_property("text_color").unwrap();
  710. if LIGHTMODE {
  711. prop.set_f32(Role::App, 0, 0.).unwrap();
  712. prop.set_f32(Role::App, 1, 0.).unwrap();
  713. prop.set_f32(Role::App, 2, 0.).unwrap();
  714. prop.set_f32(Role::App, 3, 1.).unwrap();
  715. } else {
  716. prop.set_f32(Role::App, 0, 1.).unwrap();
  717. prop.set_f32(Role::App, 1, 1.).unwrap();
  718. prop.set_f32(Role::App, 2, 1.).unwrap();
  719. prop.set_f32(Role::App, 3, 1.).unwrap();
  720. }
  721. let prop = node.get_property("cursor_color").unwrap();
  722. prop.set_f32(Role::App, 0, 0.816).unwrap();
  723. prop.set_f32(Role::App, 1, 0.627).unwrap();
  724. prop.set_f32(Role::App, 2, 1.).unwrap();
  725. prop.set_f32(Role::App, 3, 1.).unwrap();
  726. node.set_property_f32(Role::App, "cursor_ascent", EDITCHAT_CURSOR_ASCENT).unwrap();
  727. node.set_property_f32(Role::App, "cursor_descent", EDITCHAT_CURSOR_DESCENT).unwrap();
  728. let prop = node.get_property("hi_bg_color").unwrap();
  729. if LIGHTMODE {
  730. prop.set_f32(Role::App, 0, 0.5).unwrap();
  731. prop.set_f32(Role::App, 1, 0.5).unwrap();
  732. prop.set_f32(Role::App, 2, 0.5).unwrap();
  733. prop.set_f32(Role::App, 3, 1.).unwrap();
  734. } else {
  735. prop.set_f32(Role::App, 0, 1.).unwrap();
  736. prop.set_f32(Role::App, 1, 1.).unwrap();
  737. prop.set_f32(Role::App, 2, 1.).unwrap();
  738. prop.set_f32(Role::App, 3, 0.5).unwrap();
  739. }
  740. let prop = node.get_property("selected").unwrap();
  741. prop.set_null(Role::App, 0).unwrap();
  742. prop.set_null(Role::App, 1).unwrap();
  743. node.set_property_u32(Role::App, "z_index", 3).unwrap();
  744. //node.set_property_bool(Role::App, "debug", true).unwrap();
  745. //let editbox_text = PropertyStr::wrap(node, Role::App, "text", 0).unwrap();
  746. //let editbox_focus = PropertyBool::wrap(node, Role::App, "is_focused", 0).unwrap();
  747. //let darkirc_backend = app.darkirc_backend.clone();
  748. //let task = app.ex.spawn(async move {
  749. // while let Ok(_) = btn_click_recvr.recv().await {
  750. // let text = editbox_text.get();
  751. // editbox_text.prop().unset(Role::App, 0).unwrap();
  752. // // Clicking outside the editbox makes it lose focus
  753. // // So lets focus it again
  754. // editbox_focus.set(true);
  755. // debug!(target: "app", "sending text {text}");
  756. // let privmsg =
  757. // Privmsg { channel: "#random".to_string(), nick: "king".to_string(), msg: text };
  758. // darkirc_backend.send(privmsg).await;
  759. // }
  760. //});
  761. //tasks.push(task);
  762. let node = node
  763. .setup(|me| {
  764. EditBox::new(
  765. me,
  766. window_scale.clone(),
  767. app.render_api.clone(),
  768. app.text_shaper.clone(),
  769. app.ex.clone(),
  770. )
  771. })
  772. .await;
  773. layer_node.clone().link(node);
  774. // Create the send button
  775. let node = create_button("send_btn");
  776. node.set_property_bool(Role::App, "is_active", true).unwrap();
  777. let prop = node.get_property("rect").unwrap();
  778. let code = cc.compile("w - SENDLABEL_WIDTH").unwrap();
  779. prop.set_expr(Role::App, 0, code).unwrap();
  780. let code = cc.compile("h - EDITCHAT_HEIGHT").unwrap();
  781. prop.set_expr(Role::App, 1, code).unwrap();
  782. prop.set_f32(Role::App, 2, SENDLABEL_WIDTH).unwrap();
  783. prop.set_f32(Role::App, 3, EDITCHAT_HEIGHT).unwrap();
  784. let node = node.setup(|me| Button::new(me, app.ex.clone())).await;
  785. layer_node.clone().link(node);
  786. // Create a popup layer to show upgrade msg
  787. let node = create_layer("upgrade_popup");
  788. let prop = node.get_property("rect").unwrap();
  789. prop.set_f32(Role::App, 0, 0.).unwrap();
  790. prop.set_f32(Role::App, 1, 0.).unwrap();
  791. prop.set_expr(Role::App, 2, expr::load_var("w")).unwrap();
  792. let code = cc.compile("h / 2").unwrap();
  793. prop.set_expr(Role::App, 3, code).unwrap();
  794. node.set_property_bool(Role::App, "is_visible", false).unwrap();
  795. node.set_property_u32(Role::App, "z_index", 10).unwrap();
  796. let popup_layer_node =
  797. node.setup(|me| Layer::new(me, app.render_api.clone(), app.ex.clone())).await;
  798. layer_node.clone().link(popup_layer_node.clone());
  799. // Background for popup
  800. let node = create_vector_art("upgradebg");
  801. let prop = node.get_property("rect").unwrap();
  802. prop.set_f32(Role::App, 0, 0.).unwrap();
  803. prop.set_f32(Role::App, 1, 0.).unwrap();
  804. prop.set_expr(Role::App, 2, expr::load_var("w")).unwrap();
  805. prop.set_expr(Role::App, 3, expr::load_var("h")).unwrap();
  806. node.set_property_u32(Role::App, "z_index", 0).unwrap();
  807. // Setup the pimpl
  808. let verts = vec![
  809. ShapeVertex::from_xy(0., 0., [1., 0., 0., 1.]),
  810. ShapeVertex::new(expr::load_var("w"), expr::const_f32(0.), [1., 0., 1., 1.]),
  811. ShapeVertex::new(expr::const_f32(0.), expr::load_var("h"), [0., 0., 1., 1.]),
  812. ShapeVertex::new(expr::load_var("w"), expr::load_var("h"), [1., 1., 0., 1.]),
  813. ];
  814. let indices = vec![0, 2, 1, 1, 2, 3];
  815. let shape = VectorShape { verts, indices };
  816. let node =
  817. node.setup(|me| VectorArt::new(me, shape, app.render_api.clone(), app.ex.clone())).await;
  818. popup_layer_node.clone().link(node);
  819. // Create some text
  820. let node = create_text("send_label");
  821. let prop = node.get_property("rect").unwrap();
  822. prop.set_f32(Role::App, 0, 10.).unwrap();
  823. prop.set_f32(Role::App, 1, 10.).unwrap();
  824. prop.set_expr(Role::App, 2, expr::load_var("w")).unwrap();
  825. prop.set_expr(Role::App, 3, expr::load_var("h")).unwrap();
  826. node.set_property_f32(Role::App, "baseline", TEXTBAR_BASELINE).unwrap();
  827. node.set_property_f32(Role::App, "font_size", 2. * FONTSIZE).unwrap();
  828. node.set_property_str(Role::App, "text", "YO THERE'S A NEW VERSION!!! UPGRADE TIEM!!!")
  829. .unwrap();
  830. //node.set_property_str(Role::App, "text", "anon1").unwrap();
  831. let prop = node.get_property("text_color").unwrap();
  832. prop.set_f32(Role::App, 0, 0.).unwrap();
  833. prop.set_f32(Role::App, 1, 1.).unwrap();
  834. prop.set_f32(Role::App, 2, 0.94).unwrap();
  835. prop.set_f32(Role::App, 3, 1.).unwrap();
  836. node.set_property_u32(Role::App, "z_index", 1).unwrap();
  837. let node = node
  838. .setup(|me| {
  839. Text::new(
  840. me,
  841. window_scale.clone(),
  842. app.render_api.clone(),
  843. app.text_shaper.clone(),
  844. app.ex.clone(),
  845. )
  846. })
  847. .await;
  848. popup_layer_node.clone().link(node);
  849. }