schema.rs 33 KB

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