summaryrefslogtreecommitdiff
path: root/src/main/python/utils/toolbar.py
diff options
context:
space:
mode:
authorpravindalve2020-05-18 11:35:46 +0530
committerGitHub2020-05-18 11:35:46 +0530
commit151ffe398218f8d46b07f9ea12b4af897b4ed81b (patch)
tree49c2e4d019dba9c398628f1107baff8d4623a5fe /src/main/python/utils/toolbar.py
parent0c693cdeb2cce18a61cc93a6c042eaa2d4b15752 (diff)
parent051af95251fd0f87457322d9bd80ca99309c6c56 (diff)
downloadChemical-PFD-151ffe398218f8d46b07f9ea12b4af897b4ed81b.tar.gz
Chemical-PFD-151ffe398218f8d46b07f9ea12b4af897b4ed81b.tar.bz2
Chemical-PFD-151ffe398218f8d46b07f9ea12b4af897b4ed81b.zip
Merge pull request #1 from Blakeinstein/master
Workspace init, and resizeable canvas, in accordance to the various paper sizes and PPI's.
Diffstat (limited to 'src/main/python/utils/toolbar.py')
-rw-r--r--src/main/python/utils/toolbar.py138
1 files changed, 138 insertions, 0 deletions
diff --git a/src/main/python/utils/toolbar.py b/src/main/python/utils/toolbar.py
new file mode 100644
index 0000000..ec3b6a8
--- /dev/null
+++ b/src/main/python/utils/toolbar.py
@@ -0,0 +1,138 @@
+from fbs_runtime.application_context.PyQt5 import ApplicationContext
+from PyQt5.QtCore import QSize, Qt, pyqtSignal, QMimeData
+from PyQt5.QtGui import QIcon, QDrag
+from PyQt5.QtWidgets import (QBoxLayout, QDockWidget, QGridLayout, QLineEdit,
+ QScrollArea, QToolButton, QWidget, QApplication)
+from re import search, IGNORECASE
+
+from .data import toolbarItems
+from .funcs import grouper
+from .layout import flowLayout
+
+resourceManager = ApplicationContext() #Used to load images, mainly toolbar icons
+
+class toolbar(QDockWidget):
+ """
+ Defines the right side toolbar, using QDockWidget.
+ """
+ toolbuttonClicked = pyqtSignal(dict) #signal for any object button pressed
+
+ def __init__(self, parent = None):
+ super(toolbar, self).__init__(parent)
+ self.toolbarButtonDict = dict() #initializes empty dict to store toolbar buttons
+ self.toolbarItems(toolbarItems.keys()) #creates all necessary buttons
+
+ self.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable)
+ #mainly used to disable closeability of QDockWidget
+
+ #declare main widget and layout
+ self.widget = QWidget(self)
+ self.layout = QBoxLayout(QBoxLayout.TopToBottom, self.widget)
+ self.setAllowedAreas(Qt.AllDockWidgetAreas)
+
+ self.searchBox = QLineEdit(self.widget) #search box to search through componenets
+
+ #connect signal to filter slot, add searchbar to toolbar
+ self.searchBox.textChanged.connect(self.searchQuery)
+ self.layout.addWidget(self.searchBox, alignment=Qt.AlignHCenter)
+
+ #create a scrollable area to house all buttons
+ self.diagArea = QScrollArea(self)
+ self.layout.addWidget(self.diagArea)
+ self.diagAreaWidget = QWidget(self.diagArea) #inner widget for scroll area
+ #custom layout for inner widget
+ self.diagAreaLayout = flowLayout(self.diagAreaWidget)
+
+ # self.diagArea.setWidget() #set inner widget to scroll area
+ self.setWidget(self.widget) #set main widget to dockwidget
+
+ def clearLayout(self):
+ # used to clear all items from toolbar, by parenting it to the toolbar instead
+ # this works because changing parents moves widgets to be the child of the new
+ # parent, setting it to none, would have qt delete them to free memory
+ for i in reversed(range(self.diagAreaLayout.count())):
+ # since changing parent would effect indexing, its important to go in reverse
+ self.diagAreaLayout.itemAt(i).widget().setParent(self)
+
+ def populateToolbar(self, list):
+ #called everytime the button box needs to be updated(incase of a filter)
+ self.clearLayout() #clears layout
+ for item in list:
+ self.diagAreaLayout.addWidget(self.toolbarButtonDict[item])
+
+ def searchQuery(self):
+ # shorten toolbaritems list with search items
+ # self.populateToolbar() # populate with toolbar items
+ text = self.searchBox.text() #get text
+ if text == '':
+ self.populateToolbar(self.toolbarItemList) # restore everything on empty string
+ else:
+ # use regex to search filter through button list and add the remainder to toolbar
+ self.populateToolbar(filter(lambda x: search(text, x, IGNORECASE), self.toolbarItemList))
+
+ def resize(self):
+ # called when main window resizes, overloading resizeEvent caused issues.
+ parent = self.parentWidget() #used to get parent dimensions
+ self.layout.setDirection(QBoxLayout.TopToBottom) # here so that a horizontal toolbar can be implemented later
+ self.setFixedWidth(.12*parent.width()) #12% of parent width
+ self.setFixedHeight(self.height()) #span available height
+ width = .12*parent.width() #12% of parent width
+ self.diagAreaWidget.setFixedWidth(width) #set inner widget width
+ # the following line, sets the required height for the current width, so that blank space doesnt occur
+ self.diagAreaWidget.setFixedHeight(self.diagAreaLayout.heightForWidth(width))
+
+ def toolbarItems(self, items):
+ #helper functions to create required buttons
+ for item in items:
+ obj = toolbarItems[item]
+ button = toolbarButton(self, obj)
+ button.clicked.connect(lambda : self.toolbuttonClicked.emit(obj))
+ self.toolbarButtonDict[item] = button
+
+ @property
+ def toolbarItemList(self):
+ #generator to iterate over all buttons
+ for i in self.toolbarButtonDict.keys():
+ yield i
+
+class toolbarButton(QToolButton):
+ """
+ Custom buttons for components that implements drag and drop functionality
+ item -> dict from toolbarItems dict, had 4 properties, name, object, icon and default arguments.
+ """
+ def __init__(self, parent = None, item = None):
+ super(toolbarButton, self).__init__(parent)
+ #uses fbs resource manager to get icons
+ self.setIcon(QIcon(resourceManager.get_resource(f'toolbar/{item["icon"]}')))
+ self.setIconSize(QSize(40, 40)) #unecessary but left for future references
+ self.dragStartPosition = None #intialize value for drag event
+ self.itemObject = item['object'] #refer current item object, to handle drag mime
+ self.setText(item["name"]) #button text
+ self.setToolTip(item["name"]) #button tooltip
+
+ def mousePressEvent(self, event):
+ #check if button was pressed or there was a drag intent
+ super(toolbarButton, self).mousePressEvent(event)
+ if event.button() == Qt.LeftButton:
+ self.dragStartPosition = event.pos() #set dragstart position
+
+ def mouseMoveEvent(self, event):
+ #handles drag
+ if not (event.buttons() and Qt.LeftButton):
+ return #ignore if left click is not held
+ if (event.pos() - self.dragStartPosition).manhattanLength() < QApplication.startDragDistance():
+ return #check if mouse was dragged enough, manhattan length is a rough and quick method in qt
+
+ drag = QDrag(self) #create drag object
+ mimeData = QMimeData() #create drag mime
+ mimeData.setText(self.itemObject) # set mime value for view to accept
+ drag.setMimeData(mimeData) # attach mime to drag
+ drag.exec(Qt.CopyAction) #execute drag
+
+ def sizeHint(self):
+ #defines button size
+ return self.minimumSizeHint()
+
+ def minimumSizeHint(self):
+ #defines button size
+ return QSize(30, 30) \ No newline at end of file