dhxpyt.layout
39class Layout(object, metaclass=LoadUICaller): 40 layout_config = None 41 def __init__(self, config: LayoutConfig = None, mainwindow=False, **kwargs): 42 self.parent = kwargs.get("parent", None) 43 """Initializes the layout instance.""" 44 mainconfig = self.layout_config or config or {} 45 mainconfig = mainconfig if type(mainconfig) is dict else mainconfig.to_dict() 46 if not mainconfig: 47 mainconfig = LayoutConfig( 48 css="dhx_layout-cell--bordered", 49 type="line", 50 rows=[ 51 CellConfig(id="mainwindow_header", width="98vw", height="auto", header=None), 52 CellConfig(id="mainwindow", width="98vw", header=None) 53 ] 54 ).to_dict() 55 56 if mainwindow: 57 self.layout = js.dhx.Layout.new("maindiv", js.JSON.parse(json.dumps(mainconfig))) 58 else: 59 self.layout = js.dhx.Layout.new(None, js.JSON.parse(json.dumps(mainconfig))) 60 61 self.initialized = False 62 63 """ Placeholder Widgets Adders """ 64 65 def load_ui(self, *args, **kwargs): 66 """Subclass this to build your UI""" 67 pass 68 69 def add_grid(self, id: str = "mainwindow", grid_config: GridConfig = None) -> Grid: 70 """Adds a Grid widget into a Layout cell.""" 71 grid_widget = Grid(config=grid_config) 72 self.attach(id, grid_widget.grid) 73 if grid_config.data: 74 grid_widget.grid.data.removeAll() 75 grid_widget.grid.data.parse(js.JSON.parse(json.dumps(grid_config.data))) 76 return grid_widget 77 78 # Define a function to wait for the element to be ready 79 def wait_for_element(self, selector, callback): 80 def check_element(): 81 if js.document.querySelector(selector): 82 callback() 83 else: 84 js.window.setTimeout(create_proxy(check_element), 100) # Check again after 100ms 85 86 check_element() 87 88 def add_kanban(self, id: str = "mainwindow", kanban_config: KanbanConfig = None, kanban_callback: callable = None) -> None: 89 self.kanban_callback = kanban_callback 90 self.kanban_config = kanban_config 91 self.kanban_div_id = "kanban_root_" + str(uuid4()).replace("-", "") #"kanban_root" 92 self.attach_html(id, f'<div id="{self.kanban_div_id}" style="width:100%;height:100%;"></div>') 93 self.wait_for_element(f"#{self.kanban_div_id}", self.create_kanban) 94 95 def create_kanban(self): 96 return_kanban = Kanban(self.kanban_config, f"#{self.kanban_div_id}") 97 current_theme = js.document.documentElement.getAttribute('data-dhx-theme') 98 if current_theme == "dark": 99 theme = "willow-dark" 100 else: 101 theme = "willow" 102 103 return_kanban.kanban.setTheme(js.JSON.parse(json.dumps({"name": theme, "fonts": True}))) 104 self.kanban_callback(return_kanban) 105 106 def add_layout(self, id: str = "mainwindow", layout_config: LayoutConfig = None) -> TLayout: 107 """ Adds a Layout into a Layout cell """ 108 layout_widget = Layout(config=layout_config) 109 self.attach(id, layout_widget.layout) 110 return layout_widget 111 112 def add_menu(self, id: str = "mainwindow_header", menu_config: MenuConfig = None) -> Menu: 113 """ Adds a Layout into a Layout cell """ 114 menu_widget = Menu(config=menu_config) 115 self.attach(id, menu_widget.menu) 116 return menu_widget 117 118 def add_toolbar(self, id: str = "mainwindow", toolbar_config: ToolbarConfig = None) -> Toolbar: 119 """Adds a Toolbar widget into a Layout cell.""" 120 toolbar_widget = Toolbar(config=toolbar_config) 121 self.attach(id, toolbar_widget.toolbar) 122 return toolbar_widget 123 124 def add_sidebar(self, id: str, sidebar_config: SidebarConfig = None) -> Sidebar: 125 """Adds a Sidebar widget into a Layout cell.""" 126 sidebar_widget = Sidebar(config=sidebar_config) 127 self.attach(id, sidebar_widget.sidebar) 128 return sidebar_widget 129 130 def add_form(self, id: str, form_config: FormConfig = None) -> Form: 131 """Adds a Form widget into a Layout cell.""" 132 form_widget = Form(config=form_config) 133 self.attach(id, form_widget.form) 134 return form_widget 135 136 def add_listbox(self, id: str, listbox_config: ListboxConfig = None) -> Any: 137 """Adds a Listbox widget into a Layout cell.""" 138 listbox_widget = Listbox(config=listbox_config) 139 self.attach(id, listbox_widget.listbox) 140 return listbox_widget 141 142 def add_calendar(self, id: str, calendar_config: CalendarConfig = None) -> Any: 143 """Adds a Calendar widget into a Layout cell.""" 144 calendar_widget = Calendar(config=calendar_config) 145 self.attach(id, calendar_widget.calendar) 146 return calendar_widget 147 148 def add_chart(self, id: str, chart_config: ChartConfig = None) -> Any: 149 """Adds a Chart widget into a Layout cell.""" 150 chart_widget = Chart(config=chart_config) 151 self.attach(id, chart_widget.chart) 152 return chart_widget 153 154 def add_pagination(self, id: str, pagination_config: PaginationConfig = None) -> Any: 155 """Adds a Pagination widget into a Layout cell.""" 156 pagination_widget = Pagination(config=pagination_config) 157 self.attach(id, pagination_widget.pagination) 158 return pagination_widget 159 160 def add_cardflow(self, id: str, cardflow_config: CardFlowConfig = None) -> Any: 161 """Adds a CardFlow widget into a Layout cell.""" 162 cardflow_widget = CardFlow(config=cardflow_config, container=self.layout.getCell(id)) 163 return cardflow_widget 164 165 def add_ribbon(self, id: str, ribbon_config: RibbonConfig = None) -> Any: 166 """Adds a Ribbon widget into a Layout cell.""" 167 ribbon_widget = Ribbon(config=ribbon_config) 168 self.attach(id, ribbon_widget.ribbon) 169 return ribbon_widget 170 171 def add_tabbar(self, id: str, tabbar_config: TabbarConfig = None) -> Any: 172 """Adds a Tabbar widget into a Layout cell.""" 173 tabbar_widget = Tabbar(config=tabbar_config) 174 self.attach(id, tabbar_widget.tabbar) 175 return tabbar_widget 176 177 def add_timepicker(self, id: str, timepicker_config: TimepickerConfig = None) -> Any: 178 """Adds a Timepicker widget into a Layout cell.""" 179 timepicker_widget = Timepicker(config=timepicker_config) 180 self.attach(id, timepicker_widget.timepicker) 181 return timepicker_widget 182 183 def add_tree(self, id: str, tree_config: TreeConfig = None) -> Any: 184 """Adds a Tree widget into a Layout cell.""" 185 tree_widget = Tree(config=tree_config) 186 self.attach(id, tree_widget.tree) 187 return tree_widget 188 189 """ Layout API Functions """ 190 191 def destructor(self) -> None: 192 """Destroys the layout instance.""" 193 self.layout.destructor() 194 195 def for_each(self, callback: Callable[[Any, int, List[Any]], Any], parent_id: str = None, level: int = None) -> None: 196 """Iterates over layout cells, applying the callback function to each.""" 197 proxy_callback = create_proxy(callback) 198 self.layout.forEach(proxy_callback, parent_id, level) 199 200 def get_cell(self, id: str) -> Any: 201 """Retrieves a specific layout cell by its ID.""" 202 return self.layout.getCell(id) 203 204 def progress_hide(self) -> None: 205 """Hides the loading progress bar in the layout.""" 206 self.layout.progressHide() 207 208 def progress_show(self) -> None: 209 """Displays the loading progress bar in the layout.""" 210 self.layout.progressShow() 211 212 def remove_cell(self, id: str) -> None: 213 """Removes a specific layout cell by ID.""" 214 self.layout.removeCell(id) 215 216 def resize(self, id: str) -> None: 217 """Manually triggers a resize on a cell.""" 218 self.layout.resize(id) 219 220 """ Layout API Events """ 221 222 def add_event_handler(self, event_name: str, handler: Callable) -> None: 223 """Helper to add event handlers dynamically.""" 224 event_proxy = create_proxy(handler) 225 self.layout.events[event_name] = event_proxy 226 227 def after_add(self, handler: Callable) -> None: 228 """Fires after a cell is added.""" 229 self.add_event_handler('afterAdd', handler) 230 231 def after_collapse(self, handler: Callable) -> None: 232 """Fires after a cell is collapsed.""" 233 self.add_event_handler('afterCollapse', handler) 234 235 def after_expand(self, handler: Callable) -> None: 236 """Fires after a cell is expanded.""" 237 self.add_event_handler('afterExpand', handler) 238 239 def after_hide(self, handler: Callable) -> None: 240 """Fires after a cell is hidden.""" 241 self.add_event_handler('afterHide', handler) 242 243 def after_remove(self, handler: Callable) -> None: 244 """Fires after a cell is removed.""" 245 self.add_event_handler('afterRemove', handler) 246 247 def after_resize_end(self, handler: Callable) -> None: 248 """Fires after a cell resize ends.""" 249 self.add_event_handler('afterResizeEnd', handler) 250 251 def after_show(self, handler: Callable) -> None: 252 """Fires after a cell is shown.""" 253 self.add_event_handler('afterShow', handler) 254 255 def before_add(self, handler: Callable) -> None: 256 """Fires before adding a cell, returns false to prevent.""" 257 self.add_event_handler('beforeAdd', handler) 258 259 def before_collapse(self, handler: Callable) -> None: 260 """Fires before collapsing a cell, returns false to prevent.""" 261 self.add_event_handler('beforeCollapse', handler) 262 263 def before_expand(self, handler: Callable) -> None: 264 """Fires before expanding a cell, returns false to prevent.""" 265 self.add_event_handler('beforeExpand', handler) 266 267 def before_hide(self, handler: Callable) -> None: 268 """Fires before hiding a cell, returns false to prevent.""" 269 self.add_event_handler('beforeHide', handler) 270 271 def before_remove(self, handler: Callable) -> None: 272 """Fires before removing a cell, returns false to prevent.""" 273 self.add_event_handler('beforeRemove', handler) 274 275 def before_resize_start(self, handler: Callable) -> None: 276 """Fires before resizing a cell, returns false to prevent.""" 277 self.add_event_handler('beforeResizeStart', handler) 278 279 def before_show(self, handler: Callable) -> None: 280 """Fires before showing a cell, returns false to prevent.""" 281 self.add_event_handler('beforeShow', handler) 282 283 """ Layout API Properties """ 284 285 @property 286 def cols(self) -> List[Dict[Any, Any]]: 287 """Gets or sets the columns of the layout.""" 288 return self.layout.cols 289 290 @cols.setter 291 def cols(self, value: List[Dict[Any, Any]]) -> None: 292 self.layout.cols = value 293 294 @property 295 def css(self) -> str: 296 """Gets or sets the CSS class for the layout.""" 297 return self.layout.css 298 299 @css.setter 300 def css(self, value: str) -> None: 301 self.layout.css = value 302 303 @property 304 def rows(self) -> List[Dict[Any, Any]]: 305 """Gets or sets the rows of the layout.""" 306 return self.layout.rows 307 308 @rows.setter 309 def rows(self, value: List[Dict[Any, Any]]) -> None: 310 self.layout.rows = value 311 312 @property 313 def type(self) -> str: 314 """Gets or sets the layout type ('line', 'wide', 'space', 'none').""" 315 return self.layout.type 316 317 @type.setter 318 def type(self, value: str) -> None: 319 self.layout.type = value 320 321 """ Cell API Functions """ 322 323 def attach(self, id: str, component: Union[str, Any], config: Dict[str, Any] = None) -> Any: 324 """Attaches a component or HTML content to a cell.""" 325 return self.layout.getCell(id).attach(component, js.JSON.parse(json.dumps(config or {}))) 326 327 def attach_html(self, id: str, html: str) -> None: 328 """Inserts HTML content into a cell.""" 329 self.layout.getCell(id).attachHTML(html) 330 331 def collapse(self, id: str) -> None: 332 """Collapses the specified cell.""" 333 self.layout.getCell(id).collapse() 334 335 def detach(self, id: str) -> None: 336 """Removes an attached component or content from a cell.""" 337 self.layout.getCell(id).detach() 338 339 def expand(self, id: str) -> None: 340 """Expands the collapsed cell.""" 341 self.layout.getCell(id).expand() 342 343 def get_parent(self, id: str) -> Any: 344 """Returns the parent cell of the current cell.""" 345 return self.layout.getCell(id).getParent() 346 347 def get_widget(self, id: str) -> Any: 348 """Returns the attached widget in the layout cell.""" 349 return self.layout.getCell(id).getWidget() 350 351 def hide(self, id: str) -> None: 352 """Hides the specified cell.""" 353 self.layout.getCell(id).hide() 354 355 def is_visible(self, id: str) -> bool: 356 """Checks if the cell is visible.""" 357 return self.layout.getCell(id).isVisible() 358 359 def paint(self) -> None: 360 """Repaints the layout.""" 361 self.layout.paint() 362 363 def toggle(self, id: str) -> None: 364 """Toggles between collapsing and expanding the cell.""" 365 self.layout.getCell(id).toggle() 366 367 """ Cell API Properties """ 368 369 @property 370 def align(self) -> str: 371 """Gets or sets the alignment of the content inside a cell.""" 372 return self.layout.align 373 374 @align.setter 375 def align(self, value: str) -> None: 376 self.layout.align = value 377 378 @property 379 def resizable(self) -> bool: 380 """Gets or sets whether the cell can be resized.""" 381 return self.layout.resizable 382 383 @resizable.setter 384 def resizable(self, value: bool) -> None: 385 self.layout.resizable = value 386 387 # Add other properties similarly...
33 def __call__(cls, *args, **kwargs): 34 """Called when you call MyNewClass() """ 35 obj = type.__call__(cls, *args, **kwargs) 36 obj.load_ui() 37 return obj
Called when you call MyNewClass()
69 def add_grid(self, id: str = "mainwindow", grid_config: GridConfig = None) -> Grid: 70 """Adds a Grid widget into a Layout cell.""" 71 grid_widget = Grid(config=grid_config) 72 self.attach(id, grid_widget.grid) 73 if grid_config.data: 74 grid_widget.grid.data.removeAll() 75 grid_widget.grid.data.parse(js.JSON.parse(json.dumps(grid_config.data))) 76 return grid_widget
Adds a Grid widget into a Layout cell.
88 def add_kanban(self, id: str = "mainwindow", kanban_config: KanbanConfig = None, kanban_callback: callable = None) -> None: 89 self.kanban_callback = kanban_callback 90 self.kanban_config = kanban_config 91 self.kanban_div_id = "kanban_root_" + str(uuid4()).replace("-", "") #"kanban_root" 92 self.attach_html(id, f'<div id="{self.kanban_div_id}" style="width:100%;height:100%;"></div>') 93 self.wait_for_element(f"#{self.kanban_div_id}", self.create_kanban)
95 def create_kanban(self): 96 return_kanban = Kanban(self.kanban_config, f"#{self.kanban_div_id}") 97 current_theme = js.document.documentElement.getAttribute('data-dhx-theme') 98 if current_theme == "dark": 99 theme = "willow-dark" 100 else: 101 theme = "willow" 102 103 return_kanban.kanban.setTheme(js.JSON.parse(json.dumps({"name": theme, "fonts": True}))) 104 self.kanban_callback(return_kanban)
106 def add_layout(self, id: str = "mainwindow", layout_config: LayoutConfig = None) -> TLayout: 107 """ Adds a Layout into a Layout cell """ 108 layout_widget = Layout(config=layout_config) 109 self.attach(id, layout_widget.layout) 110 return layout_widget
Adds a Layout into a Layout cell
118 def add_toolbar(self, id: str = "mainwindow", toolbar_config: ToolbarConfig = None) -> Toolbar: 119 """Adds a Toolbar widget into a Layout cell.""" 120 toolbar_widget = Toolbar(config=toolbar_config) 121 self.attach(id, toolbar_widget.toolbar) 122 return toolbar_widget
Adds a Toolbar widget into a Layout cell.
130 def add_form(self, id: str, form_config: FormConfig = None) -> Form: 131 """Adds a Form widget into a Layout cell.""" 132 form_widget = Form(config=form_config) 133 self.attach(id, form_widget.form) 134 return form_widget
Adds a Form widget into a Layout cell.
136 def add_listbox(self, id: str, listbox_config: ListboxConfig = None) -> Any: 137 """Adds a Listbox widget into a Layout cell.""" 138 listbox_widget = Listbox(config=listbox_config) 139 self.attach(id, listbox_widget.listbox) 140 return listbox_widget
Adds a Listbox widget into a Layout cell.
142 def add_calendar(self, id: str, calendar_config: CalendarConfig = None) -> Any: 143 """Adds a Calendar widget into a Layout cell.""" 144 calendar_widget = Calendar(config=calendar_config) 145 self.attach(id, calendar_widget.calendar) 146 return calendar_widget
Adds a Calendar widget into a Layout cell.
148 def add_chart(self, id: str, chart_config: ChartConfig = None) -> Any: 149 """Adds a Chart widget into a Layout cell.""" 150 chart_widget = Chart(config=chart_config) 151 self.attach(id, chart_widget.chart) 152 return chart_widget
Adds a Chart widget into a Layout cell.
154 def add_pagination(self, id: str, pagination_config: PaginationConfig = None) -> Any: 155 """Adds a Pagination widget into a Layout cell.""" 156 pagination_widget = Pagination(config=pagination_config) 157 self.attach(id, pagination_widget.pagination) 158 return pagination_widget
Adds a Pagination widget into a Layout cell.
160 def add_cardflow(self, id: str, cardflow_config: CardFlowConfig = None) -> Any: 161 """Adds a CardFlow widget into a Layout cell.""" 162 cardflow_widget = CardFlow(config=cardflow_config, container=self.layout.getCell(id)) 163 return cardflow_widget
Adds a CardFlow widget into a Layout cell.
165 def add_ribbon(self, id: str, ribbon_config: RibbonConfig = None) -> Any: 166 """Adds a Ribbon widget into a Layout cell.""" 167 ribbon_widget = Ribbon(config=ribbon_config) 168 self.attach(id, ribbon_widget.ribbon) 169 return ribbon_widget
Adds a Ribbon widget into a Layout cell.
171 def add_tabbar(self, id: str, tabbar_config: TabbarConfig = None) -> Any: 172 """Adds a Tabbar widget into a Layout cell.""" 173 tabbar_widget = Tabbar(config=tabbar_config) 174 self.attach(id, tabbar_widget.tabbar) 175 return tabbar_widget
Adds a Tabbar widget into a Layout cell.
177 def add_timepicker(self, id: str, timepicker_config: TimepickerConfig = None) -> Any: 178 """Adds a Timepicker widget into a Layout cell.""" 179 timepicker_widget = Timepicker(config=timepicker_config) 180 self.attach(id, timepicker_widget.timepicker) 181 return timepicker_widget
Adds a Timepicker widget into a Layout cell.
183 def add_tree(self, id: str, tree_config: TreeConfig = None) -> Any: 184 """Adds a Tree widget into a Layout cell.""" 185 tree_widget = Tree(config=tree_config) 186 self.attach(id, tree_widget.tree) 187 return tree_widget
Adds a Tree widget into a Layout cell.
191 def destructor(self) -> None: 192 """Destroys the layout instance.""" 193 self.layout.destructor()
Destroys the layout instance.
195 def for_each(self, callback: Callable[[Any, int, List[Any]], Any], parent_id: str = None, level: int = None) -> None: 196 """Iterates over layout cells, applying the callback function to each.""" 197 proxy_callback = create_proxy(callback) 198 self.layout.forEach(proxy_callback, parent_id, level)
Iterates over layout cells, applying the callback function to each.
200 def get_cell(self, id: str) -> Any: 201 """Retrieves a specific layout cell by its ID.""" 202 return self.layout.getCell(id)
Retrieves a specific layout cell by its ID.
204 def progress_hide(self) -> None: 205 """Hides the loading progress bar in the layout.""" 206 self.layout.progressHide()
Hides the loading progress bar in the layout.
208 def progress_show(self) -> None: 209 """Displays the loading progress bar in the layout.""" 210 self.layout.progressShow()
Displays the loading progress bar in the layout.
212 def remove_cell(self, id: str) -> None: 213 """Removes a specific layout cell by ID.""" 214 self.layout.removeCell(id)
Removes a specific layout cell by ID.
216 def resize(self, id: str) -> None: 217 """Manually triggers a resize on a cell.""" 218 self.layout.resize(id)
Manually triggers a resize on a cell.
222 def add_event_handler(self, event_name: str, handler: Callable) -> None: 223 """Helper to add event handlers dynamically.""" 224 event_proxy = create_proxy(handler) 225 self.layout.events[event_name] = event_proxy
Helper to add event handlers dynamically.
227 def after_add(self, handler: Callable) -> None: 228 """Fires after a cell is added.""" 229 self.add_event_handler('afterAdd', handler)
Fires after a cell is added.
231 def after_collapse(self, handler: Callable) -> None: 232 """Fires after a cell is collapsed.""" 233 self.add_event_handler('afterCollapse', handler)
Fires after a cell is collapsed.
235 def after_expand(self, handler: Callable) -> None: 236 """Fires after a cell is expanded.""" 237 self.add_event_handler('afterExpand', handler)
Fires after a cell is expanded.
239 def after_hide(self, handler: Callable) -> None: 240 """Fires after a cell is hidden.""" 241 self.add_event_handler('afterHide', handler)
Fires after a cell is hidden.
243 def after_remove(self, handler: Callable) -> None: 244 """Fires after a cell is removed.""" 245 self.add_event_handler('afterRemove', handler)
Fires after a cell is removed.
247 def after_resize_end(self, handler: Callable) -> None: 248 """Fires after a cell resize ends.""" 249 self.add_event_handler('afterResizeEnd', handler)
Fires after a cell resize ends.
251 def after_show(self, handler: Callable) -> None: 252 """Fires after a cell is shown.""" 253 self.add_event_handler('afterShow', handler)
Fires after a cell is shown.
255 def before_add(self, handler: Callable) -> None: 256 """Fires before adding a cell, returns false to prevent.""" 257 self.add_event_handler('beforeAdd', handler)
Fires before adding a cell, returns false to prevent.
259 def before_collapse(self, handler: Callable) -> None: 260 """Fires before collapsing a cell, returns false to prevent.""" 261 self.add_event_handler('beforeCollapse', handler)
Fires before collapsing a cell, returns false to prevent.
263 def before_expand(self, handler: Callable) -> None: 264 """Fires before expanding a cell, returns false to prevent.""" 265 self.add_event_handler('beforeExpand', handler)
Fires before expanding a cell, returns false to prevent.
267 def before_hide(self, handler: Callable) -> None: 268 """Fires before hiding a cell, returns false to prevent.""" 269 self.add_event_handler('beforeHide', handler)
Fires before hiding a cell, returns false to prevent.
271 def before_remove(self, handler: Callable) -> None: 272 """Fires before removing a cell, returns false to prevent.""" 273 self.add_event_handler('beforeRemove', handler)
Fires before removing a cell, returns false to prevent.
275 def before_resize_start(self, handler: Callable) -> None: 276 """Fires before resizing a cell, returns false to prevent.""" 277 self.add_event_handler('beforeResizeStart', handler)
Fires before resizing a cell, returns false to prevent.
279 def before_show(self, handler: Callable) -> None: 280 """Fires before showing a cell, returns false to prevent.""" 281 self.add_event_handler('beforeShow', handler)
Fires before showing a cell, returns false to prevent.
285 @property 286 def cols(self) -> List[Dict[Any, Any]]: 287 """Gets or sets the columns of the layout.""" 288 return self.layout.cols
Gets or sets the columns of the layout.
294 @property 295 def css(self) -> str: 296 """Gets or sets the CSS class for the layout.""" 297 return self.layout.css
Gets or sets the CSS class for the layout.
303 @property 304 def rows(self) -> List[Dict[Any, Any]]: 305 """Gets or sets the rows of the layout.""" 306 return self.layout.rows
Gets or sets the rows of the layout.
312 @property 313 def type(self) -> str: 314 """Gets or sets the layout type ('line', 'wide', 'space', 'none').""" 315 return self.layout.type
Gets or sets the layout type ('line', 'wide', 'space', 'none').
323 def attach(self, id: str, component: Union[str, Any], config: Dict[str, Any] = None) -> Any: 324 """Attaches a component or HTML content to a cell.""" 325 return self.layout.getCell(id).attach(component, js.JSON.parse(json.dumps(config or {})))
Attaches a component or HTML content to a cell.
327 def attach_html(self, id: str, html: str) -> None: 328 """Inserts HTML content into a cell.""" 329 self.layout.getCell(id).attachHTML(html)
Inserts HTML content into a cell.
331 def collapse(self, id: str) -> None: 332 """Collapses the specified cell.""" 333 self.layout.getCell(id).collapse()
Collapses the specified cell.
335 def detach(self, id: str) -> None: 336 """Removes an attached component or content from a cell.""" 337 self.layout.getCell(id).detach()
Removes an attached component or content from a cell.
339 def expand(self, id: str) -> None: 340 """Expands the collapsed cell.""" 341 self.layout.getCell(id).expand()
Expands the collapsed cell.
343 def get_parent(self, id: str) -> Any: 344 """Returns the parent cell of the current cell.""" 345 return self.layout.getCell(id).getParent()
Returns the parent cell of the current cell.
347 def get_widget(self, id: str) -> Any: 348 """Returns the attached widget in the layout cell.""" 349 return self.layout.getCell(id).getWidget()
Returns the attached widget in the layout cell.
351 def hide(self, id: str) -> None: 352 """Hides the specified cell.""" 353 self.layout.getCell(id).hide()
Hides the specified cell.
355 def is_visible(self, id: str) -> bool: 356 """Checks if the cell is visible.""" 357 return self.layout.getCell(id).isVisible()
Checks if the cell is visible.
363 def toggle(self, id: str) -> None: 364 """Toggles between collapsing and expanding the cell.""" 365 self.layout.getCell(id).toggle()
Toggles between collapsing and expanding the cell.
389class MainWindow(Layout): 390 def __init__(self) -> None: 391 """Initialize the Main Window layout.""" 392 super().__init__(mainwindow=True) 393 self.initialized = True 394 self.cookie_status = None 395 396 def set_theme(self, theme: str) -> None: 397 """Sets the layout theme.""" 398 js.dhx.setTheme(theme) 399 400 def show_cookie_banner(self): 401 # Suppose you've got a <div id="cookie-banner"> in your HTML 402 cookie_banner = js.document.getElementById("cookie-banner") 403 cookie_banner.style.display = "block" 404 405 def hide_cookie_banner(self): 406 cookie_banner = js.document.getElementById("cookie-banner") 407 cookie_banner.style.display = "none" 408 409 def accept_cookies(self, _event=None): 410 # Set a cookie in the browser to remember consent 411 js.document.cookie = "cookie_consent=accepted; path=/; max-age=31536000" 412 self.hide_cookie_banner() 413 self.cookie_status = True 414 415 def reject_cookies(self, _event=None): 416 # Possibly set a cookie or local storage to remember "rejected" 417 js.document.cookie = "cookie_consent=rejected; path=/; max-age=31536000" 418 self.hide_cookie_banner() 419 self.cookie_status = False 420 421 def check_cookie_consent(self): 422 # Check the document.cookie in JavaScript from Pyodide 423 cookies = js.document.cookie 424 if "cookie_consent=accepted" not in cookies and "cookie_consent=rejected" not in cookies: 425 self.show_cookie_banner() 426 accept_button = js.document.getElementById("accept-btn") 427 reject_button = js.document.getElementById("reject-btn") 428 429 accept_button.addEventListener("click", create_proxy(self.accept_cookies)) 430 reject_button.addEventListener("click", create_proxy(self.reject_cookies))
43class LayoutConfig: 44 """ 45 Configuration class for Layout. Contains rows and columns with nested cells. 46 """ 47 def __init__(self, 48 type: str = "line", 49 rows: List[List[CellConfig]] = None, 50 cols: List[List[CellConfig]] = None, 51 css: str = None): 52 """ 53 :param type: (Optional) Type of the layout ("line", "wide", etc.) 54 :param rows: (Optional) A list of rows, where each row is a list of CellConfig objects. 55 :param cols: (Optional) A list of columns, where each column is a list of CellConfig objects. 56 :param css: (Optional) CSS class to apply to the entire layout. 57 """ 58 self.type = type 59 self.rows = rows if rows else None 60 self.cols = cols if cols else None 61 self.css = css 62 63 def process_nested_dict(self, obj): 64 # If obj is a dictionary, process its 'rows' and 'cols' if they exist 65 if isinstance(obj, dict): 66 if 'rows' in obj: 67 obj['rows'] = [ 68 self.process_nested_dict(cell) if isinstance(cell, (dict, object)) else cell for cell in obj['rows'] 69 ] 70 if 'cols' in obj: 71 obj['cols'] = [ 72 self.process_nested_dict(cell) if isinstance(cell, (dict, object)) else cell for cell in obj['cols'] 73 ] 74 return obj 75 # If obj is an object, convert it to a dict using to_dict() 76 elif hasattr(obj, 'to_dict'): 77 return obj.to_dict() 78 # Return obj as-is if it is not a dict or does not have to_dict() 79 return obj 80 81 def to_dict(self) -> Dict[str, Any]: 82 """ 83 Converts the LayoutConfig into a dictionary format that can be 84 passed into the layout constructor. Handles nested rows and cols. 85 """ 86 # Create config_dict by excluding None values 87 config_dict = {k: v for k, v in self.__dict__.items() if v is not None} 88 89 # Convert rows and columns to dictionaries, ensuring nested dicts are handled 90 if self.rows: 91 config_dict['rows'] = [ 92 self.process_nested_dict(cell) for cell in self.rows 93 ] 94 95 if self.cols: 96 config_dict['cols'] = [ 97 self.process_nested_dict(cell) for cell in self.cols 98 ] 99 100 return config_dict
Configuration class for Layout. Contains rows and columns with nested cells.
47 def __init__(self, 48 type: str = "line", 49 rows: List[List[CellConfig]] = None, 50 cols: List[List[CellConfig]] = None, 51 css: str = None): 52 """ 53 :param type: (Optional) Type of the layout ("line", "wide", etc.) 54 :param rows: (Optional) A list of rows, where each row is a list of CellConfig objects. 55 :param cols: (Optional) A list of columns, where each column is a list of CellConfig objects. 56 :param css: (Optional) CSS class to apply to the entire layout. 57 """ 58 self.type = type 59 self.rows = rows if rows else None 60 self.cols = cols if cols else None 61 self.css = css
Parameters
- type: (Optional) Type of the layout ("line", "wide", etc.)
- rows: (Optional) A list of rows, where each row is a list of CellConfig objects.
- cols: (Optional) A list of columns, where each column is a list of CellConfig objects.
- css: (Optional) CSS class to apply to the entire layout.
63 def process_nested_dict(self, obj): 64 # If obj is a dictionary, process its 'rows' and 'cols' if they exist 65 if isinstance(obj, dict): 66 if 'rows' in obj: 67 obj['rows'] = [ 68 self.process_nested_dict(cell) if isinstance(cell, (dict, object)) else cell for cell in obj['rows'] 69 ] 70 if 'cols' in obj: 71 obj['cols'] = [ 72 self.process_nested_dict(cell) if isinstance(cell, (dict, object)) else cell for cell in obj['cols'] 73 ] 74 return obj 75 # If obj is an object, convert it to a dict using to_dict() 76 elif hasattr(obj, 'to_dict'): 77 return obj.to_dict() 78 # Return obj as-is if it is not a dict or does not have to_dict() 79 return obj
81 def to_dict(self) -> Dict[str, Any]: 82 """ 83 Converts the LayoutConfig into a dictionary format that can be 84 passed into the layout constructor. Handles nested rows and cols. 85 """ 86 # Create config_dict by excluding None values 87 config_dict = {k: v for k, v in self.__dict__.items() if v is not None} 88 89 # Convert rows and columns to dictionaries, ensuring nested dicts are handled 90 if self.rows: 91 config_dict['rows'] = [ 92 self.process_nested_dict(cell) for cell in self.rows 93 ] 94 95 if self.cols: 96 config_dict['cols'] = [ 97 self.process_nested_dict(cell) for cell in self.cols 98 ] 99 100 return config_dict
Converts the LayoutConfig into a dictionary format that can be passed into the layout constructor. Handles nested rows and cols.
5class CellConfig: 6 """ 7 Configuration class for individual cells in the Layout. 8 Defines properties like header, id, width, height, etc. 9 """ 10 def __init__(self, 11 id: str = None, 12 header: str = None, 13 width: Union[str, int] = None, 14 height: Union[str, int] = None, 15 css: str = None, 16 collapsable: bool = False, 17 hidden: bool = False): 18 """ 19 :param header: (Optional) Header text of the cell. 20 :param id: (Optional) Unique identifier for the cell. 21 :param width: (Optional) Width of the cell, can be percentage or fixed. 22 :param height: (Optional) Height of the cell, can be percentage or fixed. 23 :param css: (Optional) CSS class to apply to the cell. 24 :param collapsable: (Optional) Whether the cell can be collapsed. 25 :param hidden: (Optional) Whether the cell is hidden by default. 26 """ 27 self.header = header 28 self.id = id 29 self.width = width 30 self.height = height 31 self.css = css 32 self.collapsable = collapsable 33 self.hidden = hidden 34 35 def to_dict(self) -> Dict[str, Any]: 36 """ 37 Converts the CellConfig into a dictionary format that can be 38 passed into the layout constructor. 39 """ 40 return {k: v for k, v in self.__dict__.items() if v is not None}
Configuration class for individual cells in the Layout. Defines properties like header, id, width, height, etc.
10 def __init__(self, 11 id: str = None, 12 header: str = None, 13 width: Union[str, int] = None, 14 height: Union[str, int] = None, 15 css: str = None, 16 collapsable: bool = False, 17 hidden: bool = False): 18 """ 19 :param header: (Optional) Header text of the cell. 20 :param id: (Optional) Unique identifier for the cell. 21 :param width: (Optional) Width of the cell, can be percentage or fixed. 22 :param height: (Optional) Height of the cell, can be percentage or fixed. 23 :param css: (Optional) CSS class to apply to the cell. 24 :param collapsable: (Optional) Whether the cell can be collapsed. 25 :param hidden: (Optional) Whether the cell is hidden by default. 26 """ 27 self.header = header 28 self.id = id 29 self.width = width 30 self.height = height 31 self.css = css 32 self.collapsable = collapsable 33 self.hidden = hidden
Parameters
- header: (Optional) Header text of the cell.
- id: (Optional) Unique identifier for the cell.
- width: (Optional) Width of the cell, can be percentage or fixed.
- height: (Optional) Height of the cell, can be percentage or fixed.
- css: (Optional) CSS class to apply to the cell.
- collapsable: (Optional) Whether the cell can be collapsed.
- hidden: (Optional) Whether the cell is hidden by default.
35 def to_dict(self) -> Dict[str, Any]: 36 """ 37 Converts the CellConfig into a dictionary format that can be 38 passed into the layout constructor. 39 """ 40 return {k: v for k, v in self.__dict__.items() if v is not None}
Converts the CellConfig into a dictionary format that can be passed into the layout constructor.