diff --git a/src/main/python/plotlyst/core/domain.py b/src/main/python/plotlyst/core/domain.py
index 064fe6fe9..7f37d785c 100644
--- a/src/main/python/plotlyst/core/domain.py
+++ b/src/main/python/plotlyst/core/domain.py
@@ -972,6 +972,7 @@ class WorldBuildingEntityType(Enum):
SETTING = 2
GROUP = 3
ITEM = 4
+ CONTAINER = 5
@dataclass
@@ -1477,7 +1478,7 @@ class ImportOrigin:
class NovelDescriptor:
title: str
id: uuid.UUID = field(default_factory=uuid.uuid4)
- lang_settings: LanguageSettings = LanguageSettings()
+ lang_settings: LanguageSettings = field(default_factory=LanguageSettings)
import_origin: Optional[ImportOrigin] = None
subtitle: str = field(default='', metadata=config(exclude=exclude_if_empty))
icon: str = field(default='', metadata=config(exclude=exclude_if_empty))
@@ -1782,8 +1783,8 @@ class Novel(NovelDescriptor):
premise: str = ''
synopsis: Optional['Document'] = None
prefs: NovelPreferences = field(default_factory=NovelPreferences)
- world: WorldBuilding = WorldBuilding()
- board: Board = Board()
+ world: WorldBuilding = field(default_factory=WorldBuilding)
+ board: Board = field(default_factory=Board)
def pov_characters(self) -> List[Character]:
pov_ids = set()
diff --git a/src/main/python/plotlyst/test/view/test_scenes.py b/src/main/python/plotlyst/test/view/test_scenes.py
index f9a4ec2c5..e2ef7d6b5 100644
--- a/src/main/python/plotlyst/test/view/test_scenes.py
+++ b/src/main/python/plotlyst/test/view/test_scenes.py
@@ -2,7 +2,7 @@
from PyQt6.QtCharts import QPieSeries
from PyQt6.QtCore import Qt, QModelIndex
-from PyQt6.QtGui import QBrush, QColor, QAction
+from PyQt6.QtGui import QAction
from PyQt6.QtWidgets import QMessageBox, QSpinBox
from src.main.python.plotlyst.core.client import client
@@ -194,7 +194,7 @@ def _edit_day(editor: QSpinBox):
def test_character_distribution_display(qtbot, filled_window: MainWindow):
def assert_painted(index: QModelIndex):
- assert index.data(role=Qt.ItemDataRole.BackgroundRole) == QBrush(QColor('darkblue'))
+ assert index.data(role=Qt.ItemDataRole.BackgroundRole) is not None
def assert_not_painted(index: QModelIndex):
assert index.data(role=Qt.ItemDataRole.BackgroundRole) is None
diff --git a/src/main/python/plotlyst/view/icons.py b/src/main/python/plotlyst/view/icons.py
index f172b7b84..22876f81c 100644
--- a/src/main/python/plotlyst/view/icons.py
+++ b/src/main/python/plotlyst/view/icons.py
@@ -612,6 +612,10 @@ def big_five_icon(color_on: str = '#7209b7') -> QIcon:
def expand_icon() -> QIcon:
return IconRegistry.from_name('fa5s.expand-alt', vflip=True)
+ @staticmethod
+ def group_icon() -> QIcon:
+ return IconRegistry.from_name('mdi.account-group')
+
@staticmethod
def docx_icon() -> QIcon:
return IconRegistry.from_name('mdi.file-word-outline')
diff --git a/src/main/python/plotlyst/view/main_window.py b/src/main/python/plotlyst/view/main_window.py
index 764a100d8..d326e31b3 100644
--- a/src/main/python/plotlyst/view/main_window.py
+++ b/src/main/python/plotlyst/view/main_window.py
@@ -131,7 +131,6 @@ def __init__(self, *args, **kwargs):
self.btnScenes.setIcon(IconRegistry.scene_icon(NAV_BAR_BUTTON_DEFAULT_COLOR, NAV_BAR_BUTTON_CHECKED_COLOR))
self.btnWorld.setIcon(
IconRegistry.world_building_icon(NAV_BAR_BUTTON_DEFAULT_COLOR, NAV_BAR_BUTTON_CHECKED_COLOR))
- self.btnWorld.setHidden(True)
self.btnNotes.setIcon(
IconRegistry.document_edition_icon(NAV_BAR_BUTTON_DEFAULT_COLOR, NAV_BAR_BUTTON_CHECKED_COLOR))
self.btnManuscript.setIcon(
diff --git a/src/main/python/plotlyst/view/manuscript_view.py b/src/main/python/plotlyst/view/manuscript_view.py
index e5c793ec3..242703108 100644
--- a/src/main/python/plotlyst/view/manuscript_view.py
+++ b/src/main/python/plotlyst/view/manuscript_view.py
@@ -58,7 +58,7 @@ def __init__(self, novel: Novel):
super().__init__(novel, [NovelUpdatedEvent, SceneChangedEvent, ChapterChangedEvent, SceneDeletedEvent])
self.ui = Ui_ManuscriptView()
self.ui.setupUi(self.widget)
- self.ui.splitter.setSizes([100, 500])
+ self.ui.splitter.setSizes([150, 500])
self.ui.splitterEditor.setSizes([400, 150])
self.ui.stackedWidget.setCurrentWidget(self.ui.pageOverview)
diff --git a/src/main/python/plotlyst/view/style/base.py b/src/main/python/plotlyst/view/style/base.py
index e6d1a7f5a..485559fbb 100644
--- a/src/main/python/plotlyst/view/style/base.py
+++ b/src/main/python/plotlyst/view/style/base.py
@@ -29,6 +29,7 @@
style = '''
* {
icon-size: 20px;
+ color: #040406;
}
QToolTip {
diff --git a/src/main/python/plotlyst/view/style/tab.py b/src/main/python/plotlyst/view/style/tab.py
index f32686249..221866bcc 100644
--- a/src/main/python/plotlyst/view/style/tab.py
+++ b/src/main/python/plotlyst/view/style/tab.py
@@ -19,29 +19,34 @@
"""
style = '''
-QTabWidget::pane {
- border: 1px solid black;
- background: #f8f9fa;
+
+QTabWidget::pane[borderless=true] {
+ border-top: 1px solid lightgrey;
}
-QTabWidget::tab-bar:top {
+QTabWidget::tab-bar:top[centered=false] {
top: 1px;
}
-QTabWidget::tab-bar:bottom {
+QTabWidget::tab-bar:bottom[centered=false] {
bottom: 1px;
}
-QTabWidget::tab-bar:left {
+QTabWidget::tab-bar:left[centered=false] {
right: 1px;
}
-QTabWidget::tab-bar:right {
+QTabWidget::tab-bar:right[centered=false] {
left: 1px;
}
+QTabWidget::tab-bar[centered=true] {
+ alignment: center;
+}
+
QTabBar::tab {
- border: 1px solid black;
+ border: 1px solid lightgrey;
+ border-radius: 3px;
}
QTabBar::tab:selected {
@@ -53,13 +58,17 @@
}
QTabBar::tab:!selected:hover {
- background: #999;
+ background: #B5B5B5;
}
QTabBar::tab:top:!selected {
margin-top: 3px;
}
+QTabBar::tab:top:!selected:hover {
+ margin-top: 1px;
+}
+
QTabBar::tab:bottom:!selected {
margin-bottom: 3px;
}
diff --git a/src/main/python/plotlyst/view/widget/input.py b/src/main/python/plotlyst/view/widget/input.py
index 8f989b25a..320301612 100644
--- a/src/main/python/plotlyst/view/widget/input.py
+++ b/src/main/python/plotlyst/view/widget/input.py
@@ -56,6 +56,7 @@ def __init__(self, parent=None, height: int = 25):
super(AutoAdjustableTextEdit, self).__init__(parent)
self.textChanged.connect(self._resizeToContent)
self._minHeight = height
+ self._resizedOnShow: bool = False
self.setAcceptRichText(False)
self.setFixedHeight(self._minHeight)
self.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
@@ -66,13 +67,40 @@ def setText(self, text: str) -> None:
@overrides
def showEvent(self, a0: QtGui.QShowEvent) -> None:
- self._resizeToContent()
+ if not self._resizedOnShow:
+ self._resizeToContent()
+ self._resizedOnShow = True
def _resizeToContent(self):
size = self.document().size()
self.setFixedHeight(max(self._minHeight, size.height()))
+class AutoAdjustableLineEdit(QLineEdit):
+ def __init__(self, parent=None, defaultWidth: int = 200):
+ super(AutoAdjustableLineEdit, self).__init__(parent)
+ self._padding = 10
+ self._defaultWidth = defaultWidth + self._padding
+ self._resizedOnShow: bool = False
+ self.setFixedWidth(self._defaultWidth)
+ self.textChanged.connect(self._resizeToContent)
+
+ @overrides
+ def showEvent(self, a0: QtGui.QShowEvent) -> None:
+ if not self._resizedOnShow:
+ self._resizeToContent()
+ self._resizedOnShow = True
+
+ def _resizeToContent(self):
+ text = self.text().strip()
+ if text:
+ text_width = self.fontMetrics().boundingRect(text).width()
+ width = max(text_width + self._padding, self._defaultWidth)
+ self.setFixedWidth(width)
+ else:
+ self.setFixedWidth(self._defaultWidth)
+
+
class TextBlockData(QTextBlockUserData):
def __init__(self):
super(TextBlockData, self).__init__()
diff --git a/src/main/python/plotlyst/view/widget/world/__init__.py b/src/main/python/plotlyst/view/widget/world/__init__.py
new file mode 100644
index 000000000..82d1fae9f
--- /dev/null
+++ b/src/main/python/plotlyst/view/widget/world/__init__.py
@@ -0,0 +1 @@
+from .editor import WorldBuildingTreeView
diff --git a/src/main/python/plotlyst/view/widget/world/editor.py b/src/main/python/plotlyst/view/widget/world/editor.py
new file mode 100644
index 000000000..22cb32b81
--- /dev/null
+++ b/src/main/python/plotlyst/view/widget/world/editor.py
@@ -0,0 +1,182 @@
+"""
+Plotlyst
+Copyright (C) 2021-2023 Zsolt Kovari
+
+This file is part of Plotlyst.
+
+Plotlyst is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Plotlyst is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+"""
+from functools import partial
+from typing import Optional, Dict, Set
+
+from PyQt6.QtCore import pyqtSignal
+from qthandy import vspacer, clear_layout
+from qtmenu import MenuWidget, ActionTooltipDisplayMode
+
+from src.main.python.plotlyst.common import recursive
+from src.main.python.plotlyst.core.domain import Novel, WorldBuildingEntity, WorldBuildingEntityType
+from src.main.python.plotlyst.view.common import action
+from src.main.python.plotlyst.view.icons import IconRegistry
+from src.main.python.plotlyst.view.widget.tree import TreeView, ContainerNode, TreeSettings
+
+
+class EntityAdditionMenu(MenuWidget):
+ entityTriggered = pyqtSignal(WorldBuildingEntity)
+
+ def __init__(self, parent=None):
+ super(EntityAdditionMenu, self).__init__(parent)
+ self.setTooltipDisplayMode(ActionTooltipDisplayMode.DISPLAY_UNDER)
+
+ self.addAction(action('Location', IconRegistry.location_icon(),
+ slot=lambda: self._triggered(WorldBuildingEntityType.SETTING),
+ tooltip='Physical location in the world'))
+ self.addAction(action('Entity', IconRegistry.world_building_icon(),
+ slot=lambda: self._triggered(WorldBuildingEntityType.ABSTRACT),
+ tooltip='Abstract entity in the world, e.g., magic'))
+ self.addAction(action('Social group', IconRegistry.group_icon(),
+ slot=lambda: self._triggered(WorldBuildingEntityType.GROUP),
+ tooltip='Social group in the world, e.g., a guild or an organization'))
+ self.addSeparator()
+ self.addAction(action('Item', IconRegistry.from_name('mdi.ring', '#b6a6ca'),
+ slot=lambda: self._triggered(WorldBuildingEntityType.ITEM),
+ tooltip='Relevant item in the world, e.g., an artifact'))
+ self.addSeparator()
+ self.addAction(action('Container',
+ slot=lambda: self._triggered(WorldBuildingEntityType.CONTAINER),
+ tooltip='General container to group worldbuilding entities together'))
+
+ def _triggered(self, wdType: WorldBuildingEntityType):
+ if wdType == WorldBuildingEntityType.SETTING:
+ name = 'New location'
+ icon_name = 'fa5s.map-pin'
+ elif wdType == WorldBuildingEntityType.GROUP:
+ name = 'New group'
+ icon_name = 'mdi.account-group'
+ elif wdType == WorldBuildingEntityType.ITEM:
+ name = 'New item'
+ elif wdType == WorldBuildingEntityType.CONTAINER:
+ name = 'Container'
+ else:
+ name = 'New entity'
+ icon_name = ''
+
+ entity = WorldBuildingEntity(name, icon=icon_name, type=wdType)
+
+ self.entityTriggered.emit(entity)
+
+
+class EntityNode(ContainerNode):
+ addEntity = pyqtSignal(WorldBuildingEntity)
+
+ def __init__(self, entity: WorldBuildingEntity, parent=None, settings: Optional[TreeSettings] = None):
+ super(EntityNode, self).__init__(entity.name, parent=parent, settings=settings)
+ self._entity = entity
+ self.setPlusButtonEnabled(True)
+ self._additionMenu = EntityAdditionMenu(self._btnAdd)
+ self._additionMenu.entityTriggered.connect(self.addEntity.emit)
+ self.setPlusMenu(self._additionMenu)
+ self.refresh()
+
+ def entity(self) -> WorldBuildingEntity:
+ return self._entity
+
+ def refresh(self):
+ self._lblTitle.setText(self._entity.name)
+
+ if self._entity.icon:
+ self._icon.setIcon(IconRegistry.from_name(self._entity.icon, self._entity.icon_color))
+ self._icon.setVisible(True)
+ else:
+ self._icon.setHidden(True)
+
+
+class RootNode(EntityNode):
+
+ def __init__(self, entity: WorldBuildingEntity, parent=None, settings: Optional[TreeSettings] = None):
+ super(RootNode, self).__init__(entity, parent=parent, settings=settings)
+ self.setMenuEnabled(False)
+ self.setPlusButtonEnabled(False)
+
+
+class WorldBuildingTreeView(TreeView):
+ entitySelected = pyqtSignal(WorldBuildingEntity)
+
+ def __init__(self, parent=None, settings: Optional[TreeSettings] = None):
+ super(WorldBuildingTreeView, self).__init__(parent)
+ self._novel: Optional[Novel] = None
+ self._settings: Optional[TreeSettings] = settings
+ self._root: Optional[RootNode] = None
+ self._entities: Dict[WorldBuildingEntity, EntityNode] = {}
+ self._selectedEntities: Set[WorldBuildingEntity] = set()
+ self._centralWidget.setProperty('bg', True)
+
+ def selectRoot(self):
+ self._root.select()
+ self._entitySelectionChanged(self._root, self._root.isSelected())
+
+ def setSettings(self, settings: TreeSettings):
+ self._settings = settings
+
+ def setNovel(self, novel: Novel):
+ self._novel = novel
+ self._root = RootNode(self._novel.world.root_entity, settings=self._settings)
+ self._root.selectionChanged.connect(partial(self._entitySelectionChanged, self._root))
+ self.refresh()
+
+ def addEntity(self, entity: WorldBuildingEntity):
+ wdg = self.__initEntityWidget(entity)
+ self._root.addChild(wdg)
+
+ def refresh(self):
+ def addChildWdg(parent: WorldBuildingEntity, child: WorldBuildingEntity):
+ childWdg = self.__initEntityWidget(child)
+ self._entities[parent].addChild(childWdg)
+
+ self.clearSelection()
+ self._entities.clear()
+ clear_layout(self._centralWidget)
+
+ self._entities[self._novel.world.root_entity] = self._root
+ self._centralWidget.layout().addWidget(self._root)
+ for entity in self._novel.world.root_entity.children:
+ wdg = self.__initEntityWidget(entity)
+ self._root.addChild(wdg)
+ recursive(entity, lambda parent: parent.children, addChildWdg)
+ self._centralWidget.layout().addWidget(vspacer())
+
+ def clearSelection(self):
+ for entity in self._selectedEntities:
+ self._entities[entity].deselect()
+ self._selectedEntities.clear()
+
+ def _entitySelectionChanged(self, node: EntityNode, selected: bool):
+ if selected:
+ self.clearSelection()
+ self._selectedEntities.add(node.entity())
+ self.entitySelected.emit(node.entity())
+ elif node.entity() in self._selectedEntities:
+ self._selectedEntities.remove(node.entity())
+
+ def _addEntity(self, parent: EntityNode, entity: WorldBuildingEntity):
+ wdg = self.__initEntityWidget(entity)
+ parent.addChild(wdg)
+ parent.entity().children.append(entity)
+
+ def __initEntityWidget(self, entity: WorldBuildingEntity) -> EntityNode:
+ node = EntityNode(entity, settings=self._settings)
+ node.selectionChanged.connect(partial(self._entitySelectionChanged, node))
+ node.addEntity.connect(partial(self._addEntity, node))
+
+ self._entities[entity] = node
+ return node
diff --git a/src/main/python/plotlyst/view/world_building_view.py b/src/main/python/plotlyst/view/world_building_view.py
index 583dc7cc0..7f4309596 100644
--- a/src/main/python/plotlyst/view/world_building_view.py
+++ b/src/main/python/plotlyst/view/world_building_view.py
@@ -17,17 +17,20 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see .
"""
-from PyQt6.QtCore import Qt
-from PyQt6.QtGui import QPalette
from overrides import overrides
+from qthandy import incr_font, transparent
from src.main.python.plotlyst.core.domain import Novel, WorldBuildingEntity
from src.main.python.plotlyst.core.template import default_location_profiles
from src.main.python.plotlyst.view._view import AbstractNovelView
+from src.main.python.plotlyst.view.common import link_buttons_to_pages, ButtonPressResizeEventFilter
from src.main.python.plotlyst.view.generated.world_building_view_ui import Ui_WorldBuildingView
from src.main.python.plotlyst.view.icons import IconRegistry
-from src.main.python.plotlyst.view.widget.world_building import WorldBuildingEditor, WorldBuildingItem, \
- WorldBuildingProfileTemplateView
+from src.main.python.plotlyst.view.widget.input import AutoAdjustableLineEdit
+from src.main.python.plotlyst.view.widget.tree import TreeSettings
+from src.main.python.plotlyst.view.widget.utility import IconSelectorButton
+from src.main.python.plotlyst.view.widget.world.editor import EntityAdditionMenu
+from src.main.python.plotlyst.view.widget.world_building import WorldBuildingProfileTemplateView
class WorldBuildingView(AbstractNovelView):
@@ -37,33 +40,37 @@ def __init__(self, novel: Novel):
self.ui = Ui_WorldBuildingView()
self.ui.setupUi(self.widget)
- self.widget.setPalette(QPalette(Qt.GlobalColor.white))
- self.ui.btnEditorToggle.setIcon(IconRegistry.document_edition_icon())
+ self.ui.btnNew.setIcon(IconRegistry.plus_icon(color='white'))
+ self.ui.btnNew.installEventFilter(ButtonPressResizeEventFilter(self.ui.btnNew))
+ self._additionMenu = EntityAdditionMenu(self.ui.btnNew)
+ self._additionMenu.entityTriggered.connect(self.ui.treeWorld.addEntity)
- self._editor = WorldBuildingEditor(self.novel.world.root_entity)
- self.ui.wdgEditorParent.layout().addWidget(self._editor)
- self.ui.wdgSidebar.setVisible(self.ui.btnEditorToggle.isChecked())
self._settingTemplate = WorldBuildingProfileTemplateView(self.novel, default_location_profiles()[0])
- self.ui.wdgSidebar.layout().addWidget(self._settingTemplate)
- self.ui.wdgSidebar.setDisabled(True)
- self.ui.splitter.setSizes([500, 150])
+ self.ui.splitter.setSizes([150, 500])
+ self._lineName = AutoAdjustableLineEdit()
+ self._lineName.setPlaceholderText('Name')
+ transparent(self._lineName)
+ incr_font(self._lineName, 15)
+ self._btnIcon = IconSelectorButton()
+ self.ui.wdgName.layout().addWidget(self._btnIcon)
+ self.ui.wdgName.layout().addWidget(self._lineName)
- self._editor.scene().modelChanged.connect(lambda: self.repo.update_novel(self.novel))
- self._editor.scene().selectionChanged.connect(self._selectionChanged)
+ self.ui.treeWorld.setSettings(TreeSettings(font_incr=2))
+ self.ui.treeWorld.setNovel(self.novel)
+ self.ui.treeWorld.entitySelected.connect(self._selection_changed)
+ self.ui.treeWorld.selectRoot()
- self.ui.btnEditorToggle.setChecked(False)
+ link_buttons_to_pages(self.ui.stackedWidget, [(self.ui.btnWorldView, self.ui.pageEditor),
+ (self.ui.btnHistoryView, self.ui.pageHistory)])
+ self.ui.btnWorldView.setChecked(True)
@overrides
def refresh(self):
pass
- def _selectionChanged(self):
- self._settingTemplate.clearValues()
-
- items = self._editor.scene().selectedItems()
- if len(items) == 1 and isinstance(items[0], WorldBuildingItem):
- self.ui.wdgSidebar.setEnabled(True)
- entity: WorldBuildingEntity = items[0].entity()
- self._settingTemplate.setLocation(entity)
+ def _selection_changed(self, entity: WorldBuildingEntity):
+ self._lineName.setText(entity.name)
+ if entity.icon:
+ self._btnIcon.selectIcon(entity.icon, entity.icon_color)
else:
- self.ui.wdgSidebar.setDisabled(True)
+ self._btnIcon.reset()
diff --git a/ui/main_window.ui b/ui/main_window.ui
index 4948c131d..5a93cc062 100644
--- a/ui/main_window.ui
+++ b/ui/main_window.ui
@@ -230,7 +230,7 @@
-
- false
+ true
@@ -248,7 +248,7 @@
PointingHandCursor
- World building (Not implemented yet)
+ World building
@@ -268,6 +268,9 @@
true
+
+ buttonGroup
+
-
diff --git a/ui/scenes_view.ui b/ui/scenes_view.ui
index 90d06c353..83aea30f2 100644
--- a/ui/scenes_view.ui
+++ b/ui/scenes_view.ui
@@ -1158,8 +1158,8 @@
0
0
- 98
- 28
+ 84
+ 16
@@ -1313,7 +1313,7 @@
-
+
diff --git a/ui/world_building_view.ui b/ui/world_building_view.ui
index 7784dd1e8..343bf6c4f 100644
--- a/ui/world_building_view.ui
+++ b/ui/world_building_view.ui
@@ -6,19 +6,22 @@
0
0
- 400
- 300
+ 1082
+ 655
Form
+
+ true
+
3
- 2
+ 0
2
@@ -29,92 +32,412 @@
2
-
-
-
-
- PointingHandCursor
-
-
-
-
-
- true
-
-
- true
-
-
- true
+
-
+
+
+
+ 0
+ 0
+
-
-
+
+
+
+ 0
+
+
+ 20
+
+
+ 0
+
+
+ 2
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ PointingHandCursor
+
+
+
+
+
+ 1
+
+
+ true
+
+
+ false
+
+
+ true
+
+
+ buttonGroup
+
+
+
+ -
+
+
+ PointingHandCursor
+
+
+
+
+
+ 3
+
+
+ true
+
+
+ false
+
+
+ true
+
+
+ buttonGroup
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+ -
+
Qt::Horizontal
-
- false
+
+
+ -
+
+
+ 15
-
-
-
- 0
+
+ 5
+
+
-
+
+
+
+ 130
+ 16777215
+
-
- 0
+
+ PointingHandCursor
-
- 0
+
+ Add new scene
-
- 0
+
+
-
- 0
+
+ Ctrl+N
-
-
-
+
+ true
+
+
+ true
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ PointingHandCursor
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Sunken
+
+
+ Qt::Horizontal
+
+
+ false
+
+
3
- 0
+ 2
- 0
+ 2
- 0
+ 2
- 0
+ 2
+
-
+
+
+
+ 0
+ 0
+
+
+
+ true
+
+
+
+
+
+ 0
+
+
+
+ true
+
+
+
+ 3
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+
+ 8
+
+
+ 5
+
+
+ 8
+
+
+ 40
+
+
-
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Expanding
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 500
+ 16777215
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Expanding
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+ 0
+
+
+ true
+
+
+ true
+
+
+
+ true
+
+
+ Attributes
+
+
+
+
+ true
+
+
+ Topics
+
+
+
+
+ true
+
+
+ History
+
+
+
+
+ true
+
+
+ Notes
+
+
+
+
+
+
+
+
+
+ 3
+
+
+ 2
+
+
+ 2
+
+
+ 2
+
+
+ 2
+
+ -
+
+
+ TextLabel
+
+
+
+
+
+
+
+
+ WorldBuildingTreeView
+ QTreeView
+ src.main.python.plotlyst.view.widget.world
+
+
-
-
- btnEditorToggle
- toggled(bool)
- wdgSidebar
- setVisible(bool)
-
-
- 382
- 10
-
-
- 355
- 37
-
-
-
-
+
+
+
+