factory.py 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742
  1. # Copyright 2021-2024 Avaiga Private Limited
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
  4. # the License. You may obtain a copy of the License at
  5. #
  6. # http://www.apache.org/licenses/LICENSE-2.0
  7. #
  8. # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
  9. # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
  10. # specific language governing permissions and limitations under the License.
  11. import re
  12. import typing as t
  13. from datetime import datetime
  14. from ..types import PropertyType
  15. from .builder import _Builder
  16. if t.TYPE_CHECKING:
  17. from ..extension.library import ElementLibrary
  18. from ..gui import Gui
  19. class _Factory:
  20. DEFAULT_CONTROL = "text"
  21. _START_SUFFIX = ".start"
  22. _END_SUFFIX = ".end"
  23. __TAIPY_NAME_SPACE = "taipy."
  24. __CONTROL_DEFAULT_PROP_NAME = {
  25. "alert": "message",
  26. "button": "label",
  27. "chat": "messages",
  28. "chart": "data",
  29. "content": "value",
  30. "date": "date",
  31. "date_range": "dates",
  32. "dialog": "open",
  33. "expandable": "title",
  34. "file_download": "content",
  35. "file_selector": "content",
  36. "image": "content",
  37. "indicator": "display",
  38. "input": "value",
  39. "layout": "columns",
  40. "login": "title",
  41. "menu": "lov",
  42. "metric": "value",
  43. "navbar": "value",
  44. "number": "value",
  45. "pane": "open",
  46. "part": "class_name",
  47. "progress": "value",
  48. "selector": "value",
  49. "slider": "value",
  50. "status": "value",
  51. "table": "data",
  52. "text": "value",
  53. "time": "time",
  54. "toggle": "value",
  55. "tree": "value",
  56. }
  57. _TEXT_ATTRIBUTES = ["format", "id", "hover_text", "raw"]
  58. __TEXT_ANCHORS = ["bottom", "top", "left", "right"]
  59. __TEXT_ANCHOR_NONE = "none"
  60. __LIBRARIES: t.Dict[str, t.List["ElementLibrary"]] = {}
  61. __CONTROL_BUILDERS = {
  62. "alert":
  63. lambda gui, control_type, attrs: _Builder(
  64. gui=gui,
  65. control_type=control_type,
  66. element_name="Alert",
  67. attributes=attrs,
  68. )
  69. .set_value_and_default(var_type=PropertyType.dynamic_string)
  70. .set_attributes(
  71. [
  72. ("severity", PropertyType.dynamic_string),
  73. ("variant", PropertyType.dynamic_string),
  74. ("render", PropertyType.dynamic_boolean, True),
  75. ]
  76. ),
  77. "button": lambda gui, control_type, attrs: _Builder(
  78. gui=gui,
  79. control_type=control_type,
  80. element_name="Button",
  81. attributes=attrs,
  82. )
  83. .set_value_and_default(with_update=False)
  84. .set_attributes(
  85. [
  86. ("on_action", PropertyType.function),
  87. ("active", PropertyType.dynamic_boolean, True),
  88. ("hover_text", PropertyType.dynamic_string),
  89. ("width", PropertyType.string_or_number),
  90. ]
  91. ),
  92. "chat": lambda gui, control_type, attrs: _Builder(
  93. gui=gui, control_type=control_type, element_name="Chat", attributes=attrs, default_value=None
  94. )
  95. .set_value_and_default(with_update=True, with_default=False, var_type=PropertyType.data)
  96. .set_attributes(
  97. [
  98. ("on_action", PropertyType.function),
  99. ("active", PropertyType.dynamic_boolean, True),
  100. ("hover_text", PropertyType.dynamic_string),
  101. ("with_input", PropertyType.dynamic_boolean, True),
  102. ("users", PropertyType.lov),
  103. ("sender_id",),
  104. ("height",),
  105. ("page_size", PropertyType.number, 50),
  106. ("max_file_size", PropertyType.number, 1 * 1024 * 1024),
  107. ("show_sender", PropertyType.boolean, False),
  108. ("mode",),
  109. ]
  110. ),
  111. "chart": lambda gui, control_type, attrs: _Builder(
  112. gui=gui, control_type=control_type, element_name="Chart", attributes=attrs, default_value=None
  113. )
  114. .set_value_and_default(with_default=False, var_type=PropertyType.data)
  115. .set_attributes(
  116. [
  117. ("title",),
  118. ("width", PropertyType.string_or_number),
  119. ("height", PropertyType.string_or_number),
  120. ("layout", PropertyType.dynamic_dict),
  121. ("plot_config", PropertyType.dict),
  122. ("on_range_change", PropertyType.function),
  123. ("active", PropertyType.dynamic_boolean, True),
  124. ("render", PropertyType.dynamic_boolean, True),
  125. ("hover_text", PropertyType.dynamic_string),
  126. ("on_change", PropertyType.function),
  127. ("template", PropertyType.dict),
  128. ("template[dark]", PropertyType.dict, gui._get_config("chart_dark_template", None)),
  129. ("template[light]", PropertyType.dict),
  130. ("figure", PropertyType.to_json),
  131. ("on_click", PropertyType.function),
  132. ]
  133. )
  134. ._get_chart_config("scatter", "lines+markers")
  135. ._set_propagate(),
  136. "content": lambda gui, control_type, attrs: _Builder(
  137. gui=gui, control_type=control_type, element_name="PageContent", attributes=attrs
  138. ),
  139. "date": lambda gui, control_type, attrs: _Builder(
  140. gui=gui,
  141. control_type=control_type,
  142. element_name="DateSelector",
  143. attributes=attrs,
  144. default_value=datetime.fromtimestamp(0),
  145. )
  146. .set_value_and_default(var_type=PropertyType.date)
  147. .set_attributes(
  148. [
  149. ("with_time", PropertyType.boolean),
  150. ("active", PropertyType.dynamic_boolean, True),
  151. ("analogic", PropertyType.boolean),
  152. ("min", PropertyType.dynamic_date),
  153. ("max", PropertyType.dynamic_date),
  154. ("editable", PropertyType.dynamic_boolean, True),
  155. ("hover_text", PropertyType.dynamic_string),
  156. ("label",),
  157. ("on_change", PropertyType.function),
  158. ("format",),
  159. ("width", PropertyType.string_or_number),
  160. ]
  161. )
  162. ._set_propagate(),
  163. "date_range": lambda gui, control_type, attrs: _Builder(
  164. gui=gui,
  165. control_type=control_type,
  166. element_name="DateRange",
  167. attributes=attrs,
  168. )
  169. .set_value_and_default(var_type=PropertyType.date_range)
  170. .set_attributes(
  171. [
  172. ("with_time", PropertyType.boolean),
  173. ("active", PropertyType.dynamic_boolean, True),
  174. ("analogic", PropertyType.boolean),
  175. ("editable", PropertyType.dynamic_boolean, True),
  176. ("hover_text", PropertyType.dynamic_string),
  177. ("label_start",),
  178. ("label_end",),
  179. ("on_change", PropertyType.function),
  180. ("format",),
  181. ("width", PropertyType.string_or_number),
  182. ]
  183. )
  184. ._set_propagate(),
  185. "dialog": lambda gui, control_type, attrs: _Builder(
  186. gui=gui,
  187. control_type=control_type,
  188. element_name="Dialog",
  189. attributes=attrs,
  190. )
  191. .set_value_and_default(var_type=PropertyType.dynamic_boolean)
  192. ._set_partial() # partial should be set before page
  193. .set_attributes(
  194. [
  195. ("page",),
  196. ("title",),
  197. ("on_action", PropertyType.function),
  198. ("close_label", PropertyType.string),
  199. ("labels", PropertyType.string_list),
  200. ("active", PropertyType.dynamic_boolean, True),
  201. ("width", PropertyType.string_or_number),
  202. ("height", PropertyType.string_or_number),
  203. ("hover_text", PropertyType.dynamic_string),
  204. ]
  205. )
  206. ._set_propagate(),
  207. "expandable": lambda gui, control_type, attrs: _Builder(
  208. gui=gui, control_type=control_type, element_name="Expandable", attributes=attrs, default_value=None
  209. )
  210. .set_value_and_default()
  211. ._set_partial() # partial should be set before page
  212. .set_attributes(
  213. [
  214. ("page",),
  215. ("expanded", PropertyType.dynamic_boolean, True, True, False),
  216. ("hover_text", PropertyType.dynamic_string),
  217. ("on_change", PropertyType.function),
  218. ]
  219. ),
  220. "file_download": lambda gui, control_type, attrs: _Builder(
  221. gui=gui,
  222. control_type=control_type,
  223. element_name="FileDownload",
  224. attributes=attrs,
  225. )
  226. .set_value_and_default(var_name="label", with_update=False)
  227. ._set_content("content", image=False)
  228. .set_attributes(
  229. [
  230. ("on_action", PropertyType.function),
  231. ("active", PropertyType.dynamic_boolean, True),
  232. ("render", PropertyType.dynamic_boolean, True),
  233. ("auto", PropertyType.boolean, False),
  234. ("bypass_preview", PropertyType.boolean, True),
  235. ("name",),
  236. ("hover_text", PropertyType.dynamic_string),
  237. ("width", PropertyType.string_or_number),
  238. ]
  239. ),
  240. "file_selector": lambda gui, control_type, attrs: _Builder(
  241. gui=gui,
  242. control_type=control_type,
  243. element_name="FileSelector",
  244. attributes=attrs,
  245. )
  246. .set_value_and_default(var_name="label", with_update=False)
  247. ._set_file_content()
  248. .set_attributes(
  249. [
  250. ("on_action", PropertyType.function),
  251. ("active", PropertyType.dynamic_boolean, True),
  252. ("multiple", PropertyType.boolean, False),
  253. ("extensions",),
  254. ("drop_message",),
  255. ("hover_text", PropertyType.dynamic_string),
  256. ("notify", PropertyType.boolean, True),
  257. ("width", PropertyType.string_or_number),
  258. ]
  259. ),
  260. "image": lambda gui, control_type, attrs: _Builder(
  261. gui=gui,
  262. control_type=control_type,
  263. element_name="Image",
  264. attributes=attrs,
  265. )
  266. .set_value_and_default(var_name="label", with_update=False)
  267. ._set_content("content")
  268. .set_attributes(
  269. [
  270. ("on_action", PropertyType.function),
  271. ("active", PropertyType.dynamic_boolean, True),
  272. ("width",),
  273. ("height",),
  274. ("hover_text", PropertyType.dynamic_string),
  275. ]
  276. ),
  277. "indicator": lambda gui, control_type, attrs: _Builder(
  278. gui=gui,
  279. control_type=control_type,
  280. element_name="Indicator",
  281. attributes=attrs,
  282. )
  283. .set_value_and_default(with_update=False, native_type=True)
  284. .set_attributes(
  285. [
  286. ("min", PropertyType.number),
  287. ("max", PropertyType.number),
  288. ("value", PropertyType.dynamic_number),
  289. ("format",),
  290. ("orientation",),
  291. ("width",),
  292. ("height",),
  293. ]
  294. ),
  295. "input": lambda gui, control_type, attrs: _Builder(
  296. gui=gui,
  297. control_type=control_type,
  298. element_name="Input",
  299. attributes=attrs,
  300. )
  301. ._set_input_type("text", True)
  302. .set_value_and_default()
  303. ._set_propagate()
  304. .set_attributes(
  305. [
  306. ("active", PropertyType.dynamic_boolean, True),
  307. ("hover_text", PropertyType.dynamic_string),
  308. ("on_change", PropertyType.function),
  309. ("on_action", PropertyType.function),
  310. ("action_keys",),
  311. ("label",),
  312. ("change_delay", PropertyType.number, gui._get_config("change_delay", None)),
  313. ("multiline", PropertyType.boolean, False),
  314. ("lines_shown", PropertyType.number, 5),
  315. ("width", PropertyType.string_or_number),
  316. ]
  317. ),
  318. "layout": lambda gui, control_type, attrs: _Builder(
  319. gui=gui, control_type=control_type, element_name="Layout", attributes=attrs, default_value=None
  320. )
  321. .set_value_and_default(with_default=False)
  322. .set_attributes(
  323. [
  324. ("columns[mobile]",),
  325. ("gap",),
  326. ]
  327. ),
  328. "login": lambda gui, control_type, attrs: _Builder(
  329. gui=gui, control_type=control_type, element_name="Login", attributes=attrs, default_value=None
  330. )
  331. .set_value_and_default(default_val="Log-in")
  332. .set_attributes(
  333. [
  334. ("message", PropertyType.dynamic_string),
  335. ("on_action", PropertyType.function, "on_login"),
  336. ]
  337. ),
  338. "menu": lambda gui, control_type, attrs: _Builder(
  339. gui=gui,
  340. control_type=control_type,
  341. element_name="MenuCtl",
  342. attributes=attrs,
  343. )
  344. .set_attributes(
  345. [
  346. ("active", PropertyType.dynamic_boolean, True),
  347. ("label",),
  348. ("width",),
  349. ("width[mobile]",),
  350. ("on_action", PropertyType.function),
  351. ("inactive_ids", PropertyType.dynamic_list),
  352. ("hover_text", PropertyType.dynamic_string),
  353. ("lov", PropertyType.lov),
  354. ]
  355. )
  356. ._set_propagate(),
  357. "metric": lambda gui, control_type, attrs: _Builder(
  358. gui=gui,
  359. control_type=control_type,
  360. element_name="Metric",
  361. attributes=attrs,
  362. )
  363. .set_value_and_default(var_type=PropertyType.dynamic_number, native_type=True)
  364. .set_attributes(
  365. [
  366. ("title",),
  367. ("active", PropertyType.dynamic_boolean, True),
  368. ("layout", PropertyType.dynamic_dict),
  369. ("type", PropertyType.string, "circular"),
  370. ("min", PropertyType.number, 0),
  371. ("max", PropertyType.number, 100),
  372. ("delta", PropertyType.dynamic_number),
  373. ("delta_color", PropertyType.string),
  374. ("negative_delta_color", PropertyType.string),
  375. ("threshold", PropertyType.dynamic_number),
  376. ("width", PropertyType.string_or_number),
  377. ("height", PropertyType.string_or_number),
  378. ("show_value", PropertyType.boolean, True),
  379. ("format", PropertyType.string),
  380. ("delta_format", PropertyType.string),
  381. ("bar_color", PropertyType.string),
  382. ("color_map", PropertyType.dict),
  383. ("hover_text", PropertyType.dynamic_string),
  384. ("template", PropertyType.dict),
  385. ("template[dark]", PropertyType.dict),
  386. ("template[light]", PropertyType.dict),
  387. ]
  388. ),
  389. "navbar": lambda gui, control_type, attrs: _Builder(
  390. gui=gui, control_type=control_type, element_name="NavBar", attributes=attrs, default_value=None
  391. ).set_attributes(
  392. [
  393. ("active", PropertyType.dynamic_boolean, True),
  394. ("hover_text", PropertyType.dynamic_string),
  395. ("lov", PropertyType.single_lov),
  396. ]
  397. ),
  398. "number": lambda gui, control_type, attrs: _Builder(
  399. gui=gui,
  400. control_type=control_type,
  401. element_name="Input",
  402. attributes=attrs,
  403. default_value=0,
  404. )
  405. ._set_input_type("number")
  406. .set_value_and_default(var_type=PropertyType.dynamic_number)
  407. ._set_propagate()
  408. .set_attributes(
  409. [
  410. ("active", PropertyType.dynamic_boolean, True),
  411. ("step", PropertyType.dynamic_number, 1),
  412. ("step_multiplier", PropertyType.dynamic_number, 10),
  413. ("min", PropertyType.dynamic_number),
  414. ("max", PropertyType.dynamic_number),
  415. ("hover_text", PropertyType.dynamic_string),
  416. ("on_change", PropertyType.function),
  417. ("on_action", PropertyType.function),
  418. ("label",),
  419. ("change_delay", PropertyType.number, gui._get_config("change_delay", None)),
  420. ("width", PropertyType.string_or_number),
  421. ]
  422. ),
  423. "pane": lambda gui, control_type, attrs: _Builder(
  424. gui=gui, control_type=control_type, element_name="Pane", attributes=attrs, default_value=None
  425. )
  426. .set_value_and_default(var_type=PropertyType.dynamic_boolean)
  427. ._set_partial() # partial should be set before page
  428. .set_attributes(
  429. [
  430. ("page",),
  431. ("anchor", PropertyType.string, "left"),
  432. ("on_close", PropertyType.function),
  433. ("persistent", PropertyType.boolean, False),
  434. ("active", PropertyType.dynamic_boolean, True),
  435. ("width", PropertyType.string_or_number, "30vw"),
  436. ("height", PropertyType.string_or_number, "30vh"),
  437. ("hover_text", PropertyType.dynamic_string),
  438. ("on_change", PropertyType.function),
  439. ("show_button", PropertyType.boolean, False),
  440. ]
  441. )
  442. ._set_propagate(),
  443. "part": lambda gui, control_type, attrs: _Builder(
  444. gui=gui, control_type=control_type, element_name="Part", attributes=attrs, default_value=None
  445. )
  446. ._set_partial() # partial should be set before page
  447. .set_attributes(
  448. [
  449. ("page", PropertyType.dynamic_string),
  450. ("render", PropertyType.dynamic_boolean, True),
  451. ("height", PropertyType.dynamic_string),
  452. ("content", PropertyType.toHtmlContent),
  453. ("width", PropertyType.string_or_number),
  454. ]
  455. ),
  456. "progress": lambda gui, control_type, attrs: _Builder(
  457. gui=gui,
  458. control_type=control_type,
  459. element_name="Progress",
  460. attributes=attrs,
  461. )
  462. .set_value_and_default(var_type=PropertyType.dynamic_number, native_type=True)
  463. .set_attributes(
  464. [
  465. ("linear", PropertyType.boolean, False),
  466. ("show_value", PropertyType.boolean, False),
  467. ("title", PropertyType.dynamic_string),
  468. ("title_anchor", PropertyType.string, "bottom"),
  469. ("render", PropertyType.dynamic_boolean, True),
  470. ("width", PropertyType.string_or_number),
  471. ]
  472. ),
  473. "selector": lambda gui, control_type, attrs: _Builder(
  474. gui=gui, control_type=control_type, element_name="Selector", attributes=attrs, default_value=None
  475. )
  476. .set_value_and_default(with_default=False, var_type=PropertyType.lov_value)
  477. .set_attributes(
  478. [
  479. ("active", PropertyType.dynamic_boolean, True),
  480. ("dropdown", PropertyType.boolean, False),
  481. ("filter", PropertyType.boolean),
  482. ("height", PropertyType.string_or_number),
  483. ("hover_text", PropertyType.dynamic_string),
  484. ("value_by_id", PropertyType.boolean),
  485. ("multiple", PropertyType.boolean),
  486. ("width", PropertyType.string_or_number),
  487. ("on_change", PropertyType.function),
  488. ("label",),
  489. ("mode",),
  490. ("lov", PropertyType.lov),
  491. ]
  492. )
  493. ._set_propagate(),
  494. "slider": lambda gui, control_type, attrs: _Builder(
  495. gui=gui,
  496. control_type=control_type,
  497. element_name="Slider",
  498. attributes=attrs,
  499. default_value=0,
  500. )
  501. .set_value_and_default(native_type=True, var_type=PropertyType.slider_value)
  502. .set_attributes(
  503. [
  504. ("active", PropertyType.dynamic_boolean, True),
  505. ("height",),
  506. ("hover_text", PropertyType.dynamic_string),
  507. ("value_by_id", PropertyType.boolean),
  508. ("max", PropertyType.number, 100),
  509. ("min", PropertyType.number, 0),
  510. ("step", PropertyType.number, 1),
  511. ("orientation",),
  512. ("width", PropertyType.string, "300px"),
  513. ("on_change", PropertyType.function),
  514. ("continuous", PropertyType.boolean, None),
  515. ("lov", PropertyType.lov),
  516. ("change_delay", PropertyType.number, gui._get_config("change_delay", None)),
  517. ]
  518. )
  519. ._set_labels()
  520. ._set_string_with_check("text_anchor", _Factory.__TEXT_ANCHORS + [_Factory.__TEXT_ANCHOR_NONE], "bottom")
  521. ._set_propagate(),
  522. "status": lambda gui, control_type, attrs: _Builder(
  523. gui=gui,
  524. control_type=control_type,
  525. element_name="Status",
  526. attributes=attrs,
  527. )
  528. .set_value_and_default(with_update=False)
  529. .set_attributes(
  530. [
  531. ("without_close", PropertyType.boolean, False),
  532. ("hover_text", PropertyType.dynamic_string),
  533. ]
  534. ),
  535. "table": lambda gui, control_type, attrs: _Builder(
  536. gui=gui,
  537. control_type=control_type,
  538. element_name="Table",
  539. attributes=attrs,
  540. )
  541. .set_value_and_default(with_default=False, var_type=PropertyType.data)
  542. ._get_dataframe_attributes()
  543. ._get_list_attribute("selected", PropertyType.number)
  544. .set_attributes(
  545. [
  546. ("page_size", PropertyType.number, "100"),
  547. ("allow_all_rows", PropertyType.boolean),
  548. ("show_all", PropertyType.boolean),
  549. ("auto_loading", PropertyType.boolean),
  550. ("width", PropertyType.string_or_number, "100%"),
  551. ("height", PropertyType.string_or_number, "80vh"),
  552. ("active", PropertyType.dynamic_boolean, True),
  553. ("editable", PropertyType.dynamic_boolean, False),
  554. ("on_edit", PropertyType.function, gui._get_call_method_name("table_on_edit")),
  555. ("on_delete", PropertyType.function, gui._get_call_method_name("table_on_delete")),
  556. ("on_add", PropertyType.function, gui._get_call_method_name("table_on_add")),
  557. ("on_action", PropertyType.function),
  558. ("nan_value",),
  559. ("filter", PropertyType.boolean),
  560. ("hover_text", PropertyType.dynamic_string),
  561. ("size",),
  562. ("downloadable", PropertyType.boolean),
  563. ("use_checkbox", PropertyType.boolean),
  564. ]
  565. )
  566. ._set_propagate()
  567. ._set_table_pagesize_options(),
  568. "text": lambda gui, control_type, attrs: _Builder(
  569. gui=gui,
  570. control_type=control_type,
  571. element_name="Field",
  572. attributes=attrs,
  573. )
  574. .set_value_and_default(with_update=False)
  575. ._set_dataType()
  576. .set_attributes(
  577. [
  578. ("format",),
  579. ("hover_text", PropertyType.dynamic_string),
  580. ("raw", PropertyType.boolean, False),
  581. ("mode",),
  582. ("width", PropertyType.string_or_number),
  583. ]
  584. ),
  585. "time": lambda gui, control_type, attrs: _Builder(
  586. gui=gui,
  587. control_type=control_type,
  588. element_name="TimeSelector",
  589. attributes=attrs,
  590. default_value=datetime.today().time(),
  591. )
  592. .set_value_and_default(var_type=PropertyType.time)
  593. .set_attributes(
  594. [
  595. ("active", PropertyType.dynamic_boolean, True),
  596. ("analogic", PropertyType.boolean),
  597. ("editable", PropertyType.dynamic_boolean, True),
  598. ("hover_text", PropertyType.dynamic_string),
  599. ("label",),
  600. ("format",),
  601. ("width", PropertyType.string_or_number),
  602. ]
  603. )
  604. ._set_propagate(),
  605. "toggle": lambda gui, control_type, attrs: _Builder(
  606. gui=gui, control_type=control_type, element_name="Toggle", attributes=attrs, default_value=None
  607. )
  608. .set_value_and_default(with_default=False, var_type=PropertyType.toggle_value)
  609. .set_attributes(
  610. [
  611. ("active", PropertyType.dynamic_boolean, True),
  612. ("hover_text", PropertyType.dynamic_string),
  613. ("label",),
  614. ("value_by_id", PropertyType.boolean),
  615. ("unselected_value", PropertyType.string, ""),
  616. ("allow_unselect", PropertyType.boolean),
  617. ("on_change", PropertyType.function),
  618. ("mode",),
  619. ("lov", PropertyType.single_lov),
  620. ("width", PropertyType.string_or_number),
  621. ]
  622. )
  623. ._set_kind()
  624. ._set_propagate(),
  625. "tree": lambda gui, control_type, attrs: _Builder(
  626. gui=gui,
  627. control_type=control_type,
  628. element_name="TreeView",
  629. attributes=attrs,
  630. )
  631. .set_value_and_default(with_default=False, var_type=PropertyType.lov_value)
  632. .set_attributes(
  633. [
  634. ("active", PropertyType.dynamic_boolean, True),
  635. ("expanded", PropertyType.boolean_or_list, True),
  636. ("filter", PropertyType.boolean),
  637. ("hover_text", PropertyType.dynamic_string),
  638. ("height", PropertyType.string_or_number),
  639. ("value_by_id", PropertyType.boolean),
  640. ("multiple", PropertyType.boolean),
  641. ("width", PropertyType.string_or_number),
  642. ("on_change", PropertyType.function),
  643. ("select_leafs_only", PropertyType.boolean),
  644. ("row_height", PropertyType.string),
  645. ("lov", PropertyType.lov),
  646. ]
  647. )
  648. ._set_propagate(),
  649. }
  650. # TODO: process \" in property value
  651. _PROPERTY_RE = re.compile(r"\s+([a-zA-Z][\.a-zA-Z_$0-9]*(?:\[(?:.*?)\])?)=\"((?:(?:(?<=\\)\")|[^\"])*)\"")
  652. __COUNTER = 0
  653. @staticmethod
  654. def set_library(library: "ElementLibrary"):
  655. from ..extension.library import Element, ElementLibrary
  656. if isinstance(library, ElementLibrary) and isinstance(library.get_name(), str) and library.get_elements():
  657. elements = library.get_elements()
  658. for name, element in elements.items():
  659. if isinstance(element, Element):
  660. element.check(name)
  661. fact_lib = _Factory.__LIBRARIES.get(library.get_name())
  662. if fact_lib is None:
  663. _Factory.__LIBRARIES.update({library.get_name(): [library]})
  664. else:
  665. fact_lib.append(library)
  666. @staticmethod
  667. def get_default_property_name(control_name: str) -> t.Optional[str]:
  668. name = (
  669. control_name[: -len(_Factory._START_SUFFIX)]
  670. if control_name.endswith(_Factory._START_SUFFIX)
  671. else control_name[: -len(_Factory._END_SUFFIX)]
  672. if control_name.endswith(_Factory._END_SUFFIX)
  673. else control_name
  674. )
  675. name = name[len(_Factory.__TAIPY_NAME_SPACE) :] if name.startswith(_Factory.__TAIPY_NAME_SPACE) else name
  676. prop = _Factory.__CONTROL_DEFAULT_PROP_NAME.get(name)
  677. if prop is None:
  678. _, _, element = _Factory.__get_library_element(name)
  679. if element:
  680. prop = element.default_attribute
  681. return prop
  682. @staticmethod
  683. def __get_library_element(name: str):
  684. parts = name.split(".")
  685. if len(parts) > 1:
  686. element_name = ".".join(parts[1:])
  687. for lib in _Factory.__LIBRARIES.get(parts[0], []):
  688. elts = lib.get_elements()
  689. if isinstance(elts, dict):
  690. if element := elts.get(element_name):
  691. return lib, element_name, element
  692. else:
  693. element_name = name
  694. for libs in list(_Factory.__LIBRARIES.values()):
  695. for lib in libs:
  696. elts = lib.get_elements()
  697. if isinstance(elts, dict):
  698. if element := elts.get(element_name):
  699. return lib, element_name, element
  700. return None, None, None
  701. @staticmethod
  702. def call_builder(
  703. gui: "Gui", name: str, all_properties: t.Optional[t.Dict[str, t.Any]] = None, is_html: t.Optional[bool] = False
  704. ) -> t.Optional[t.Union[t.Any, t.Tuple[str, str]]]:
  705. name = name[len(_Factory.__TAIPY_NAME_SPACE) :] if name.startswith(_Factory.__TAIPY_NAME_SPACE) else name
  706. builder = _Factory.__CONTROL_BUILDERS.get(name)
  707. built = None
  708. _Factory.__COUNTER += 1
  709. with gui._get_authorization():
  710. if builder is None:
  711. lib, element_name, element = _Factory.__get_library_element(name)
  712. if lib:
  713. from ..extension.library import Element
  714. if isinstance(element, Element):
  715. return element._call_builder(
  716. element_name, gui, all_properties, lib, is_html, counter=_Factory.__COUNTER
  717. )
  718. else:
  719. built = builder(gui, name, all_properties)
  720. if isinstance(built, _Builder):
  721. return built._build_to_string() if is_html else built.get_element()
  722. return None