def __init__( self, path, columns = defaultFileSystemColumns, allowMultipleSelection = False, displayMode = DisplayMode.List, **kw ) : GafferUI.Widget.__init__( self, _TreeView(), **kw ) self._qtWidget().setAlternatingRowColors( True ) self._qtWidget().setUniformRowHeights( True ) self._qtWidget().setEditTriggers( QtWidgets.QTreeView.NoEditTriggers ) self._qtWidget().activated.connect( Gaffer.WeakMethod( self.__activated ) ) if Qt.__binding__ in ( "PySide2", "PyQt5" ) : self._qtWidget().header().setSectionsMovable( False ) else : self._qtWidget().header().setMovable( False ) self._qtWidget().header().setSortIndicator( 0, QtCore.Qt.AscendingOrder ) self._qtWidget().setSortingEnabled( True ) self._qtWidget().expansionChanged.connect( Gaffer.WeakMethod( self.__expansionChanged ) ) # install an empty model, so we an construct our selection model # around it. we'll update the model contents shortly in setPath(). _GafferUI._pathListingWidgetUpdateModel( GafferUI._qtAddress( self._qtWidget() ), None ) _GafferUI._pathListingWidgetSetColumns( GafferUI._qtAddress( self._qtWidget() ), columns ) self.__selectionModel = QtCore.QItemSelectionModel( self._qtWidget().model() ) self._qtWidget().setSelectionModel( self.__selectionModel ) self.__selectionChangedSlot = Gaffer.WeakMethod( self.__selectionChanged ) self._qtWidget().selectionModel().selectionChanged.connect( self.__selectionChangedSlot ) if allowMultipleSelection : self._qtWidget().setSelectionMode( QtWidgets.QAbstractItemView.ExtendedSelection ) self.__pathSelectedSignal = GafferUI.WidgetSignal() self.__selectionChangedSignal = GafferUI.WidgetSignal() self.__displayModeChangedSignal = GafferUI.WidgetSignal() self.__expansionChangedSignal = GafferUI.WidgetSignal() # members for implementing drag and drop self.__emittingButtonPress = False self.__borrowedButtonPress = None self.__buttonPressConnection = self.buttonPressSignal().connect( Gaffer.WeakMethod( self.__buttonPress ) ) self.__buttonReleaseConnection = self.buttonReleaseSignal().connect( Gaffer.WeakMethod( self.__buttonRelease ) ) self.__mouseMoveConnection = self.mouseMoveSignal().connect( Gaffer.WeakMethod( self.__mouseMove ) ) self.__dragBeginConnection = self.dragBeginSignal().connect( Gaffer.WeakMethod( self.__dragBegin ) ) self.__dragEndConnection = self.dragEndSignal().connect( Gaffer.WeakMethod( self.__dragEnd ) ) self.__dragPointer = "paths" self.__path = None self.setDisplayMode( displayMode ) self.setPath( path )
def __init__(self, plug): self.__grid = GafferUI.GridContainer(spacing=4) GafferUI.PlugValueWidget.__init__(self, self.__grid, plug) model = _PlugTableModel(plug, self.getContext(), self._qtWidget()) selectionModel = QtCore.QItemSelectionModel(model, self._qtWidget()) with self.__grid: self.__sectionChooser = _SectionChooser(plug, parenting={ "index": (1, 0), }) self.__sectionChooser.currentSectionChangedSignal().connect( Gaffer.WeakMethod(self.__currentSectionChanged), scoped=False) with GafferUI.ListContainer( parenting={ "index": (0, 1), "alignment": (GafferUI.HorizontalAlignment.Left, GafferUI.VerticalAlignment.Bottom), }): self.__defaultLabel = GafferUI.Label("Default") self.__defaultLabel._qtWidget().setIndent(6) GafferUI.Spacer(imath.V2i(1, 8)) self.__defaultTable = _PlugTableView(selectionModel, _PlugTableView.Mode.Defaults, parenting={ "index": (1, 1), }) with GafferUI.ListContainer(parenting={ "index": (2, 1), "alignment": (GafferUI.HorizontalAlignment.Left, GafferUI.VerticalAlignment.Top) }, ): GafferUI.Spacer(imath.V2i(1, 4), maximumSize=imath.V2i(1, 4)) addColumnButton = GafferUI.MenuButton( image="plus.png", hasFrame=False, toolTip="Click to add column, or drop plug to connect", menu=GafferUI.Menu( Gaffer.WeakMethod(self.__addColumnMenuDefinition))) addColumnButton.dragEnterSignal().connect(Gaffer.WeakMethod( self.__addColumnButtonDragEnter), scoped=False) addColumnButton.dragLeaveSignal().connect(Gaffer.WeakMethod( self.__addColumnButtonDragLeave), scoped=False) addColumnButton.dropSignal().connect(Gaffer.WeakMethod( self.__addColumnButtonDrop), scoped=False) self.__rowNamesTable = _PlugTableView(selectionModel, _PlugTableView.Mode.RowNames, parenting={ "index": (0, 2), }) self.__cellsTable = _PlugTableView(selectionModel, _PlugTableView.Mode.Cells, parenting={ "index": (1, 2), }) _LinkedScrollBar(GafferUI.ListContainer.Orientation.Vertical, [self.__cellsTable, self.__rowNamesTable], parenting={ "index": (2, 2), "alignment": (GafferUI.HorizontalAlignment.Left, GafferUI.VerticalAlignment.None_) }) _LinkedScrollBar(GafferUI.ListContainer.Orientation.Horizontal, [self.__cellsTable, self.__defaultTable], parenting={ "index": (1, 3), }) addRowButton = GafferUI.Button( image="plus.png", hasFrame=False, toolTip="Click to add row, or drop new row names", parenting={"index": (0, 4)}) addRowButton.clickedSignal().connect(Gaffer.WeakMethod( self.__addRowButtonClicked), scoped=False) addRowButton.dragEnterSignal().connect(Gaffer.WeakMethod( self.__addRowButtonDragEnter), scoped=False) addRowButton.dragLeaveSignal().connect(Gaffer.WeakMethod( self.__addRowButtonDragLeave), scoped=False) addRowButton.dropSignal().connect(Gaffer.WeakMethod( self.__addRowButtonDrop), scoped=False) if isinstance(plug.node(), Gaffer.Reference): # Currently we only allow new rows to be added to references # that had no rows when they were exported. We don't want to # get into merge hell trying to combine user-added and referenced # rows, particularly as we are planning to add row-reordering # features in future. for row in plug.children()[1:]: if not plug.node().isChildEdit(row): addRowButton.setVisible(False) break # Because dragging plugs to the add button involves making # an output connection from the spreadsheet, it doesn't make # sense to allow it on promoted plugs. if not isinstance(plug.node(), Gaffer.Spreadsheet): addColumnButton.setVisible(False) self.__statusLabel = GafferUI.Label( "", parenting={ "index": (slice(1, 3), 4), "alignment": (GafferUI.HorizontalAlignment.Left, GafferUI.VerticalAlignment.Top) }) # The status label occupies the same column as `cellsTable`, and has a dynamic width based on the length # of the status text. Ignore the width in X so that the column width is dictated solely by `cellsTable`, # otherwise large status labels can force cells off the screen. self.__statusLabel._qtWidget().setSizePolicy( QtWidgets.QSizePolicy.Ignored, QtWidgets.QSizePolicy.Fixed) for widget in [addRowButton, addColumnButton]: widget.enterSignal().connect(Gaffer.WeakMethod( self.__enterToolTippedWidget), scoped=False) widget.leaveSignal().connect(Gaffer.WeakMethod( self.__leaveToolTippedWidget), scoped=False) for widget in [self.__defaultTable, self.__cellsTable]: widget.mouseMoveSignal().connect(Gaffer.WeakMethod( self.__cellsMouseMove), scoped=False) widget.leaveSignal().connect(Gaffer.WeakMethod(self.__cellsLeave), scoped=False) Gaffer.Metadata.plugValueChangedSignal(plug.node()).connect( Gaffer.WeakMethod(self.__plugMetadataChanged), scoped=False) self.__updateVisibleSections() self.__updateDefaultRowVisibility()
def __init__(self, plug): self.__grid = GafferUI.GridContainer(spacing=4) GafferUI.PlugValueWidget.__init__(self, self.__grid, plug) model = _PlugTableModel(plug, self.getContext(), self._qtWidget()) selectionModel = QtCore.QItemSelectionModel(model, self._qtWidget()) with self.__grid: self.__sectionChooser = _SectionChooser(plug, parenting={ "index": (1, 0), }) self.__sectionChooser.currentSectionChangedSignal().connect( Gaffer.WeakMethod(self.__currentSectionChanged), scoped=False) with GafferUI.ListContainer( parenting={ "index": (0, 1), "alignment": (GafferUI.HorizontalAlignment.Left, GafferUI.VerticalAlignment.Bottom), }): self.__defaultLabel = GafferUI.Label("Default") self.__defaultLabel._qtWidget().setIndent(6) GafferUI.Spacer(imath.V2i(1, 8)) self.__defaultTable = _PlugTableView(selectionModel, _PlugTableView.Mode.Defaults, parenting={ "index": (1, 1), }) self.__rowNamesTable = _PlugTableView(selectionModel, _PlugTableView.Mode.RowNames, parenting={ "index": (0, 2), }) self.__updateRowNamesWidth() self.__cellsTable = _PlugTableView(selectionModel, _PlugTableView.Mode.Cells, parenting={ "index": (1, 2), }) _LinkedScrollBar(GafferUI.ListContainer.Orientation.Vertical, [self.__cellsTable, self.__rowNamesTable], parenting={ "index": (2, 2), }) _LinkedScrollBar(GafferUI.ListContainer.Orientation.Horizontal, [self.__cellsTable, self.__defaultTable], parenting={ "index": (1, 3), }) addRowButton = GafferUI.Button( image="plus.png", hasFrame=False, toolTip="Click to add row, or drop new row names", parenting={"index": (0, 4)}) addRowButton.clickedSignal().connect(Gaffer.WeakMethod( self.__addRowButtonClicked), scoped=False) addRowButton.dragEnterSignal().connect(Gaffer.WeakMethod( self.__addRowButtonDragEnter), scoped=False) addRowButton.dragLeaveSignal().connect(Gaffer.WeakMethod( self.__addRowButtonDragLeave), scoped=False) addRowButton.dropSignal().connect(Gaffer.WeakMethod( self.__addRowButtonDrop), scoped=False) addRowButton.setVisible(_Algo.dimensionsEditable(plug)) self.__statusLabel = GafferUI.Label( "", parenting={ "index": (slice(1, 3), 4), "alignment": (GafferUI.HorizontalAlignment.Left, GafferUI.VerticalAlignment.Top) }) # The status label occupies the same column as `cellsTable`, and has a dynamic width based on the length # of the status text. Ignore the width in X so that the column width is dictated solely by `cellsTable`, # otherwise large status labels can force cells off the screen. self.__statusLabel._qtWidget().setSizePolicy( QtWidgets.QSizePolicy.Ignored, QtWidgets.QSizePolicy.Fixed) for widget in [addRowButton]: widget.enterSignal().connect(Gaffer.WeakMethod( self.__enterToolTippedWidget), scoped=False) widget.leaveSignal().connect(Gaffer.WeakMethod( self.__leaveToolTippedWidget), scoped=False) for widget in [self.__defaultTable, self.__cellsTable]: widget.mouseMoveSignal().connect(Gaffer.WeakMethod( self.__cellsMouseMove), scoped=False) widget.leaveSignal().connect(Gaffer.WeakMethod(self.__cellsLeave), scoped=False) Gaffer.Metadata.plugValueChangedSignal().connect(Gaffer.WeakMethod( self.__plugMetadataChanged), scoped=False) self.__updateVisibleSections() self.__updateDefaultRowVisibility()