clapp-pm 1.0.44__py3-none-any.whl → 1.0.45__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,688 +0,0 @@
1
- """
2
- PyCloud OS Rain Widgets
3
- Kullanıcının masaüstüne etkileşimli widget'lar eklemesini sağlayan sistem
4
- """
5
-
6
- import os
7
- import json
8
- import logging
9
- import threading
10
- from pathlib import Path
11
- from typing import Dict, List, Optional, Any, Callable
12
- from datetime import datetime, timedelta
13
- from dataclasses import dataclass, asdict
14
- from enum import Enum
15
-
16
- try:
17
- from PyQt6.QtWidgets import (QWidget, QLabel, QVBoxLayout, QHBoxLayout,
18
- QPushButton, QFrame, QScrollArea, QGridLayout,
19
- QSlider, QSpinBox, QComboBox, QTextEdit, QProgressBar)
20
- from PyQt6.QtCore import Qt, QTimer, QThread, pyqtSignal, QRect, QPoint, QSize
21
- from PyQt6.QtGui import QFont, QPixmap, QPainter, QColor, QPalette
22
- PYQT_AVAILABLE = True
23
- except ImportError:
24
- PYQT_AVAILABLE = False
25
-
26
- class WidgetType(Enum):
27
- """Widget türleri"""
28
- CLOCK = "clock"
29
- CALENDAR = "calendar"
30
- WEATHER = "weather"
31
- SYSTEM_INFO = "system_info"
32
- CPU_MONITOR = "cpu_monitor"
33
- MEMORY_MONITOR = "memory_monitor"
34
- NOTES = "notes"
35
- CALCULATOR = "calculator"
36
- RSS_READER = "rss_reader"
37
- TODO_LIST = "todo_list"
38
-
39
- class WidgetState(Enum):
40
- """Widget durumları"""
41
- ACTIVE = "active"
42
- MINIMIZED = "minimized"
43
- HIDDEN = "hidden"
44
- LOADING = "loading"
45
- ERROR = "error"
46
-
47
- @dataclass
48
- class WidgetConfig:
49
- """Widget yapılandırması"""
50
- widget_id: str
51
- widget_type: WidgetType
52
- title: str
53
- position: tuple = (100, 100)
54
- size: tuple = (200, 150)
55
- state: WidgetState = WidgetState.ACTIVE
56
- settings: Dict = None
57
- refresh_interval: int = 30 # saniye
58
- always_on_top: bool = False
59
- transparency: float = 1.0
60
- theme: str = "auto"
61
-
62
- def __post_init__(self):
63
- if self.settings is None:
64
- self.settings = {}
65
-
66
- def to_dict(self) -> Dict:
67
- """Dict'e çevir"""
68
- data = asdict(self)
69
- data['widget_type'] = self.widget_type.value
70
- data['state'] = self.state.value
71
- return data
72
-
73
- @classmethod
74
- def from_dict(cls, data: Dict) -> 'WidgetConfig':
75
- """Dict'ten oluştur"""
76
- data['widget_type'] = WidgetType(data.get('widget_type', 'clock'))
77
- data['state'] = WidgetState(data.get('state', 'active'))
78
- return cls(**data)
79
-
80
- class BaseWidget(QWidget if PYQT_AVAILABLE else object):
81
- """Temel widget sınıfı"""
82
-
83
- def __init__(self, config: WidgetConfig, widget_manager=None):
84
- if PYQT_AVAILABLE:
85
- super().__init__()
86
-
87
- self.config = config
88
- self.widget_manager = widget_manager
89
- self.logger = logging.getLogger(f"Widget-{config.widget_id}")
90
-
91
- # Widget durumu
92
- self.is_running = False
93
- self.last_update = None
94
- self.update_timer = None
95
- self.data_sources = {}
96
-
97
- # UI bileşenleri
98
- if PYQT_AVAILABLE:
99
- self.init_ui()
100
- self.setup_timer()
101
-
102
- def init_ui(self):
103
- """UI'yı başlat"""
104
- self.setWindowTitle(self.config.title)
105
- self.setGeometry(*self.config.position, *self.config.size)
106
-
107
- # Ana layout
108
- self.layout = QVBoxLayout()
109
- self.setLayout(self.layout)
110
-
111
- # Başlık çubuğu
112
- self.title_bar = self.create_title_bar()
113
- self.layout.addWidget(self.title_bar)
114
-
115
- # İçerik alanı
116
- self.content_widget = QWidget()
117
- self.content_layout = QVBoxLayout()
118
- self.content_widget.setLayout(self.content_layout)
119
- self.layout.addWidget(self.content_widget)
120
-
121
- # Widget-specific UI
122
- self.setup_content()
123
-
124
- # Stil uygula
125
- self.apply_theme()
126
-
127
- def create_title_bar(self) -> QWidget:
128
- """Başlık çubuğu oluştur"""
129
- title_bar = QFrame()
130
- title_bar.setFixedHeight(30)
131
- title_bar.setStyleSheet("background-color: #2b2b2b; border-radius: 5px;")
132
-
133
- layout = QHBoxLayout()
134
- layout.setContentsMargins(5, 0, 5, 0)
135
-
136
- # Başlık
137
- title_label = QLabel(self.config.title)
138
- title_label.setStyleSheet("color: white; font-weight: bold;")
139
- layout.addWidget(title_label)
140
-
141
- layout.addStretch()
142
-
143
- # Ayarlar butonu
144
- settings_btn = QPushButton("⚙")
145
- settings_btn.setFixedSize(20, 20)
146
- settings_btn.setStyleSheet("background-color: #404040; border: none; color: white;")
147
- settings_btn.clicked.connect(self.show_settings)
148
- layout.addWidget(settings_btn)
149
-
150
- # Kapat butonu
151
- close_btn = QPushButton("✕")
152
- close_btn.setFixedSize(20, 20)
153
- close_btn.setStyleSheet("background-color: #ff5555; border: none; color: white;")
154
- close_btn.clicked.connect(self.close_widget)
155
- layout.addWidget(close_btn)
156
-
157
- title_bar.setLayout(layout)
158
- return title_bar
159
-
160
- def setup_content(self):
161
- """Widget içeriğini ayarla (alt sınıflarda override edilir)"""
162
- label = QLabel("Temel Widget")
163
- label.setAlignment(Qt.AlignmentFlag.AlignCenter)
164
- self.content_layout.addWidget(label)
165
-
166
- def setup_timer(self):
167
- """Güncelleme timer'ını ayarla"""
168
- if self.config.refresh_interval > 0:
169
- self.update_timer = QTimer()
170
- self.update_timer.timeout.connect(self.update_data)
171
- self.update_timer.start(self.config.refresh_interval * 1000)
172
-
173
- def apply_theme(self):
174
- """Tema uygula"""
175
- # Temel stil
176
- style = """
177
- QWidget {
178
- background-color: #3c3c3c;
179
- color: white;
180
- border: 1px solid #555;
181
- border-radius: 8px;
182
- }
183
- QLabel {
184
- border: none;
185
- padding: 2px;
186
- }
187
- """
188
-
189
- if self.config.transparency < 1.0:
190
- self.setWindowOpacity(self.config.transparency)
191
-
192
- self.setStyleSheet(style)
193
-
194
- def update_data(self):
195
- """Veriyi güncelle"""
196
- try:
197
- self.last_update = datetime.now()
198
- # Alt sınıflarda implement edilir
199
- self.on_data_update()
200
- except Exception as e:
201
- self.logger.error(f"Data update error: {e}")
202
-
203
- def on_data_update(self):
204
- """Veri güncellemesi (alt sınıflarda override edilir)"""
205
- pass
206
-
207
- def show_settings(self):
208
- """Ayarları göster"""
209
- if self.widget_manager:
210
- self.widget_manager.show_widget_settings(self.config.widget_id)
211
-
212
- def close_widget(self):
213
- """Widget'ı kapat"""
214
- if self.widget_manager:
215
- self.widget_manager.remove_widget(self.config.widget_id)
216
- self.close()
217
-
218
- def get_settings_schema(self) -> Dict:
219
- """Ayar şemasını döndür"""
220
- return {
221
- "refresh_interval": {
222
- "type": "int",
223
- "label": "Yenileme Aralığı (saniye)",
224
- "default": 30,
225
- "min": 5,
226
- "max": 3600
227
- },
228
- "transparency": {
229
- "type": "float",
230
- "label": "Şeffaflık",
231
- "default": 1.0,
232
- "min": 0.1,
233
- "max": 1.0
234
- }
235
- }
236
-
237
- def apply_settings(self, settings: Dict):
238
- """Ayarları uygula"""
239
- if "refresh_interval" in settings:
240
- self.config.refresh_interval = settings["refresh_interval"]
241
- if self.update_timer:
242
- self.update_timer.setInterval(self.config.refresh_interval * 1000)
243
-
244
- if "transparency" in settings:
245
- self.config.transparency = settings["transparency"]
246
- self.setWindowOpacity(self.config.transparency)
247
-
248
- class ClockWidget(BaseWidget):
249
- """Saat widget'ı"""
250
-
251
- def setup_content(self):
252
- """Saat içeriğini ayarla"""
253
- self.time_label = QLabel()
254
- self.time_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
255
- self.time_label.setFont(QFont("Arial", 16, QFont.Weight.Bold))
256
- self.content_layout.addWidget(self.time_label)
257
-
258
- self.date_label = QLabel()
259
- self.date_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
260
- self.date_label.setFont(QFont("Arial", 10))
261
- self.content_layout.addWidget(self.date_label)
262
-
263
- def on_data_update(self):
264
- """Saat verilerini güncelle"""
265
- now = datetime.now()
266
-
267
- # Locale manager'dan format al
268
- if self.widget_manager and self.widget_manager.kernel:
269
- locale_manager = self.widget_manager.kernel.get_module("locale")
270
- if locale_manager:
271
- time_str = locale_manager.format_time(now)
272
- date_str = locale_manager.format_date(now)
273
- else:
274
- time_str = now.strftime("%H:%M")
275
- date_str = now.strftime("%d.%m.%Y")
276
- else:
277
- time_str = now.strftime("%H:%M")
278
- date_str = now.strftime("%d.%m.%Y")
279
-
280
- self.time_label.setText(time_str)
281
- self.date_label.setText(date_str)
282
-
283
- class SystemInfoWidget(BaseWidget):
284
- """Sistem bilgisi widget'ı"""
285
-
286
- def setup_content(self):
287
- """Sistem bilgisi içeriğini ayarla"""
288
- self.cpu_label = QLabel("CPU: -")
289
- self.memory_label = QLabel("RAM: -")
290
- self.uptime_label = QLabel("Uptime: -")
291
-
292
- for label in [self.cpu_label, self.memory_label, self.uptime_label]:
293
- label.setFont(QFont("Arial", 9))
294
- self.content_layout.addWidget(label)
295
-
296
- def on_data_update(self):
297
- """Sistem bilgilerini güncelle"""
298
- try:
299
- if self.widget_manager and self.widget_manager.kernel:
300
- # CPU bilgisi
301
- process_manager = self.widget_manager.kernel.get_module("process")
302
- if process_manager:
303
- cpu_percent = process_manager.get_system_cpu_usage()
304
- self.cpu_label.setText(f"CPU: {cpu_percent:.1f}%")
305
-
306
- # Bellek bilgisi
307
- memory_manager = self.widget_manager.kernel.get_module("memory")
308
- if memory_manager:
309
- memory_info = memory_manager.get_memory_info()
310
- used_mb = memory_info.get("used_mb", 0)
311
- total_mb = memory_info.get("total_mb", 0)
312
- percent = (used_mb / total_mb * 100) if total_mb > 0 else 0
313
- self.memory_label.setText(f"RAM: {percent:.1f}% ({used_mb:.0f}MB)")
314
-
315
- # Uptime
316
- uptime = self.widget_manager.kernel.get_uptime()
317
- hours = int(uptime // 3600)
318
- minutes = int((uptime % 3600) // 60)
319
- self.uptime_label.setText(f"Uptime: {hours:02d}:{minutes:02d}")
320
-
321
- except Exception as e:
322
- self.logger.error(f"System info update error: {e}")
323
-
324
- class NotesWidget(BaseWidget):
325
- """Not widget'ı"""
326
-
327
- def setup_content(self):
328
- """Not içeriğini ayarla"""
329
- self.notes_edit = QTextEdit()
330
- self.notes_edit.setPlaceholderText("Notlarınızı buraya yazın...")
331
- self.notes_edit.textChanged.connect(self.save_notes)
332
- self.content_layout.addWidget(self.notes_edit)
333
-
334
- # Kayıtlı notları yükle
335
- self.load_notes()
336
-
337
- def load_notes(self):
338
- """Notları yükle"""
339
- notes_file = Path(f"users/widgets/{self.config.widget_id}.txt")
340
- if notes_file.exists():
341
- try:
342
- with open(notes_file, 'r', encoding='utf-8') as f:
343
- content = f.read()
344
- self.notes_edit.setPlainText(content)
345
- except Exception as e:
346
- self.logger.error(f"Failed to load notes: {e}")
347
-
348
- def save_notes(self):
349
- """Notları kaydet"""
350
- notes_file = Path(f"users/widgets/{self.config.widget_id}.txt")
351
- notes_file.parent.mkdir(parents=True, exist_ok=True)
352
-
353
- try:
354
- with open(notes_file, 'w', encoding='utf-8') as f:
355
- f.write(self.notes_edit.toPlainText())
356
- except Exception as e:
357
- self.logger.error(f"Failed to save notes: {e}")
358
-
359
- class WeatherWidget(BaseWidget):
360
- """Hava durumu widget'ı"""
361
-
362
- def setup_content(self):
363
- """Hava durumu içeriğini ayarla"""
364
- self.location_label = QLabel("📍 Konum belirsiz")
365
- self.temp_label = QLabel("🌡️ --°C")
366
- self.condition_label = QLabel("☁️ Bekleniyor...")
367
-
368
- for label in [self.location_label, self.temp_label, self.condition_label]:
369
- label.setFont(QFont("Arial", 9))
370
- self.content_layout.addWidget(label)
371
-
372
- def on_data_update(self):
373
- """Hava durumu verilerini güncelle (demo)"""
374
- # Demo veri (gerçek API entegrasyonu yapılabilir)
375
- import random
376
- temp = random.randint(15, 35)
377
- conditions = ["☀️ Güneşli", "☁️ Bulutlu", "🌧️ Yağmurlu", "❄️ Karlı"]
378
- condition = random.choice(conditions)
379
-
380
- self.location_label.setText("📍 İstanbul")
381
- self.temp_label.setText(f"🌡️ {temp}°C")
382
- self.condition_label.setText(condition)
383
-
384
- class WidgetFactory:
385
- """Widget fabrikası"""
386
-
387
- @staticmethod
388
- def create_widget(config: WidgetConfig, widget_manager=None) -> Optional[BaseWidget]:
389
- """Widget oluştur"""
390
- if not PYQT_AVAILABLE:
391
- return None
392
-
393
- widget_classes = {
394
- WidgetType.CLOCK: ClockWidget,
395
- WidgetType.SYSTEM_INFO: SystemInfoWidget,
396
- WidgetType.NOTES: NotesWidget,
397
- WidgetType.WEATHER: WeatherWidget,
398
- }
399
-
400
- widget_class = widget_classes.get(config.widget_type)
401
- if widget_class:
402
- return widget_class(config, widget_manager)
403
-
404
- return None
405
-
406
- class WidgetManager:
407
- """Widget yöneticisi"""
408
-
409
- def __init__(self, kernel=None):
410
- self.kernel = kernel
411
- self.logger = logging.getLogger("WidgetManager")
412
-
413
- # Widget verileri
414
- self.widgets: Dict[str, BaseWidget] = {}
415
- self.widget_configs: Dict[str, WidgetConfig] = {}
416
-
417
- # Dosya yolları
418
- self.widgets_dir = Path("users/widgets")
419
- self.widgets_dir.mkdir(parents=True, exist_ok=True)
420
- self.config_file = self.widgets_dir / "widgets.json"
421
-
422
- # Widget ayarları
423
- self.max_widgets = 20
424
- self.default_refresh_interval = 30
425
-
426
- # Başlangıç
427
- self.load_widget_configs()
428
- self.restore_widgets()
429
-
430
- def create_widget(self, widget_type: WidgetType, title: str = None,
431
- position: tuple = None, **kwargs) -> Optional[str]:
432
- """Yeni widget oluştur"""
433
- try:
434
- if len(self.widgets) >= self.max_widgets:
435
- self.logger.warning("Maximum widget limit reached")
436
- return None
437
-
438
- # Widget ID oluştur
439
- import uuid
440
- widget_id = str(uuid.uuid4())[:8]
441
-
442
- # Varsayılan değerler
443
- if title is None:
444
- title = widget_type.value.replace("_", " ").title()
445
-
446
- if position is None:
447
- position = (100 + len(self.widgets) * 50, 100 + len(self.widgets) * 50)
448
-
449
- # Konfigürasyon oluştur
450
- config = WidgetConfig(
451
- widget_id=widget_id,
452
- widget_type=widget_type,
453
- title=title,
454
- position=position,
455
- **kwargs
456
- )
457
-
458
- # Widget oluştur
459
- widget = WidgetFactory.create_widget(config, self)
460
- if not widget:
461
- self.logger.error(f"Failed to create widget: {widget_type}")
462
- return None
463
-
464
- # Kaydet
465
- self.widgets[widget_id] = widget
466
- self.widget_configs[widget_id] = config
467
- self.save_widget_configs()
468
-
469
- # Göster
470
- widget.show()
471
- widget.update_data()
472
-
473
- self.logger.info(f"Widget created: {widget_id} ({widget_type.value})")
474
- return widget_id
475
-
476
- except Exception as e:
477
- self.logger.error(f"Failed to create widget: {e}")
478
- return None
479
-
480
- def remove_widget(self, widget_id: str) -> bool:
481
- """Widget'ı kaldır"""
482
- try:
483
- if widget_id not in self.widgets:
484
- return False
485
-
486
- # Widget'ı kapat
487
- widget = self.widgets[widget_id]
488
- if hasattr(widget, 'update_timer') and widget.update_timer:
489
- widget.update_timer.stop()
490
-
491
- widget.close()
492
-
493
- # Veriyi temizle
494
- del self.widgets[widget_id]
495
- del self.widget_configs[widget_id]
496
-
497
- # Widget dosyasını sil
498
- widget_file = self.widgets_dir / f"{widget_id}.txt"
499
- if widget_file.exists():
500
- widget_file.unlink()
501
-
502
- self.save_widget_configs()
503
-
504
- self.logger.info(f"Widget removed: {widget_id}")
505
- return True
506
-
507
- except Exception as e:
508
- self.logger.error(f"Failed to remove widget {widget_id}: {e}")
509
- return False
510
-
511
- def get_widget(self, widget_id: str) -> Optional[BaseWidget]:
512
- """Widget'ı al"""
513
- return self.widgets.get(widget_id)
514
-
515
- def list_widgets(self) -> List[Dict]:
516
- """Widget listesi"""
517
- return [config.to_dict() for config in self.widget_configs.values()]
518
-
519
- def update_widget_config(self, widget_id: str, **kwargs) -> bool:
520
- """Widget konfigürasyonunu güncelle"""
521
- try:
522
- if widget_id not in self.widget_configs:
523
- return False
524
-
525
- config = self.widget_configs[widget_id]
526
-
527
- # Güncelle
528
- for key, value in kwargs.items():
529
- if hasattr(config, key):
530
- setattr(config, key, value)
531
-
532
- # Widget'a uygula
533
- if widget_id in self.widgets:
534
- widget = self.widgets[widget_id]
535
- if hasattr(widget, 'apply_settings'):
536
- widget.apply_settings(kwargs)
537
-
538
- self.save_widget_configs()
539
- return True
540
-
541
- except Exception as e:
542
- self.logger.error(f"Failed to update widget config {widget_id}: {e}")
543
- return False
544
-
545
- def show_widget_settings(self, widget_id: str):
546
- """Widget ayarlarını göster"""
547
- # Bu bir dialog açacak (widget ayar penceresi)
548
- self.logger.info(f"Opening settings for widget: {widget_id}")
549
- # TODO: Ayar dialogu implementasyonu
550
-
551
- def save_widget_configs(self):
552
- """Widget konfigürasyonlarını kaydet"""
553
- try:
554
- configs_data = {
555
- widget_id: config.to_dict()
556
- for widget_id, config in self.widget_configs.items()
557
- }
558
-
559
- with open(self.config_file, 'w', encoding='utf-8') as f:
560
- json.dump(configs_data, f, indent=2, ensure_ascii=False)
561
-
562
- except Exception as e:
563
- self.logger.error(f"Failed to save widget configs: {e}")
564
-
565
- def load_widget_configs(self):
566
- """Widget konfigürasyonlarını yükle"""
567
- try:
568
- if not self.config_file.exists():
569
- return
570
-
571
- with open(self.config_file, 'r', encoding='utf-8') as f:
572
- configs_data = json.load(f)
573
-
574
- for widget_id, config_data in configs_data.items():
575
- try:
576
- config = WidgetConfig.from_dict(config_data)
577
- self.widget_configs[widget_id] = config
578
- except Exception as e:
579
- self.logger.error(f"Failed to load widget config {widget_id}: {e}")
580
-
581
- self.logger.info(f"Loaded {len(self.widget_configs)} widget configurations")
582
-
583
- except Exception as e:
584
- self.logger.error(f"Failed to load widget configs: {e}")
585
-
586
- def restore_widgets(self):
587
- """Widget'ları geri yükle"""
588
- try:
589
- for widget_id, config in self.widget_configs.items():
590
- if config.state == WidgetState.ACTIVE:
591
- widget = WidgetFactory.create_widget(config, self)
592
- if widget:
593
- self.widgets[widget_id] = widget
594
- widget.show()
595
- widget.update_data()
596
-
597
- self.logger.info(f"Restored {len(self.widgets)} widgets")
598
-
599
- except Exception as e:
600
- self.logger.error(f"Failed to restore widgets: {e}")
601
-
602
- def get_available_widget_types(self) -> List[Dict]:
603
- """Mevcut widget türleri"""
604
- return [
605
- {
606
- "type": WidgetType.CLOCK.value,
607
- "name": "Saat",
608
- "description": "Dijital saat ve tarih göstergesi",
609
- "icon": "🕐"
610
- },
611
- {
612
- "type": WidgetType.SYSTEM_INFO.value,
613
- "name": "Sistem Bilgisi",
614
- "description": "CPU, RAM ve uptime izleme",
615
- "icon": "💻"
616
- },
617
- {
618
- "type": WidgetType.WEATHER.value,
619
- "name": "Hava Durumu",
620
- "description": "Anlık hava durumu bilgisi",
621
- "icon": "🌤️"
622
- },
623
- {
624
- "type": WidgetType.NOTES.value,
625
- "name": "Notlar",
626
- "description": "Hızlı not alma aracı",
627
- "icon": "📝"
628
- }
629
- ]
630
-
631
- def hide_all_widgets(self):
632
- """Tüm widget'ları gizle"""
633
- for widget in self.widgets.values():
634
- widget.hide()
635
-
636
- def show_all_widgets(self):
637
- """Tüm widget'ları göster"""
638
- for widget in self.widgets.values():
639
- widget.show()
640
-
641
- def refresh_all_widgets(self):
642
- """Tüm widget'ları yenile"""
643
- for widget in self.widgets.values():
644
- widget.update_data()
645
-
646
- def shutdown(self):
647
- """Widget manager'ı kapat"""
648
- try:
649
- # Tüm widget'ları kapat
650
- for widget_id in list(self.widgets.keys()):
651
- self.remove_widget(widget_id)
652
-
653
- # Konfigürasyonları kaydet
654
- self.save_widget_configs()
655
-
656
- self.logger.info("Widget manager shutdown completed")
657
-
658
- except Exception as e:
659
- self.logger.error(f"Widget manager shutdown failed: {e}")
660
-
661
- # Kolaylık fonksiyonları
662
- _widget_manager = None
663
-
664
- def init_widget_manager(kernel=None) -> WidgetManager:
665
- """Widget manager'ı başlat"""
666
- global _widget_manager
667
- _widget_manager = WidgetManager(kernel)
668
- return _widget_manager
669
-
670
- def get_widget_manager() -> Optional[WidgetManager]:
671
- """Widget manager'ı al"""
672
- return _widget_manager
673
-
674
- def create_widget(widget_type: str, **kwargs) -> Optional[str]:
675
- """Widget oluştur (kısayol)"""
676
- if _widget_manager:
677
- try:
678
- widget_type_enum = WidgetType(widget_type)
679
- return _widget_manager.create_widget(widget_type_enum, **kwargs)
680
- except ValueError:
681
- return None
682
- return None
683
-
684
- def remove_widget(widget_id: str) -> bool:
685
- """Widget kaldır (kısayol)"""
686
- if _widget_manager:
687
- return _widget_manager.remove_widget(widget_id)
688
- return False