factory.py 30 KB

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