factory.py 27 KB

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