Multiple select block picker is now double column (needs checkboxes, better highlighting for left column)

This commit is contained in:
David Vierra 2015-02-24 21:41:43 -10:00
parent ce2e67ffb2
commit 08290cefa7
3 changed files with 359 additions and 76 deletions

View File

@ -73,8 +73,7 @@ class ReplaceDialog(QtGui.QDialog):
frame.setLayout(layout)
return frame
leftButton = BlockTypeButton(flat=True)
leftButton.multipleSelect = True
leftButton = BlockTypeButton(flat=True, multipleSelect=True)
leftButton.editorSession = self.editorSession
leftButton.blocks = oldBlocks
leftFramedButton = frameButton(leftButton)
@ -97,7 +96,6 @@ class ReplaceDialog(QtGui.QDialog):
def removeRow(self, row):
self.tableWidget.removeRow(row)
del self.replacements[row]
def getReplacements(self):
def _get():
@ -115,6 +113,6 @@ def replaceCommand(editorSession):
replacements = dialog.getReplacements()
command = SimpleRevisionCommand(editorSession, "Replace")
with command.begin():
task = editorSession.currentDimension.fillBlocksIter(editorSession.currentSelection, replacements)
task = editorSession.currentDimension.fillBlocksIter(editorSession.currentSelection, replacements, updateLights=False)
showProgress("Replacing...", task)
editorSession.pushCommand(command)

View File

@ -0,0 +1,254 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>642</width>
<height>739</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>600</height>
</size>
</property>
<property name="windowTitle">
<string>Choose Blocks</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Search:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="searchField">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="1,1">
<item>
<widget class="BlockTypeListWidget" name="listWidget">
<property name="palette">
<palette>
<active>
<colorrole role="Highlight">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>211</red>
<green>219</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="HighlightedText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="Highlight">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>211</red>
<green>219</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="HighlightedText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="Highlight">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>51</red>
<green>153</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="HighlightedText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOn</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::MultiSelection</enum>
</property>
<property name="resizeMode">
<enum>QListView::Adjust</enum>
</property>
<property name="viewMode">
<enum>QListView::ListMode</enum>
</property>
</widget>
</item>
<item>
<widget class="BlockTypeListWidget" name="selectedBlockList"/>
</item>
</layout>
</item>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="3" column="1">
<widget class="QLabel" name="brightnessLabel">
<property name="text">
<string>Brightness: x</string>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QLabel" name="rendertypeLabel">
<property name="text">
<string>RenderType</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="3" rowspan="2">
<widget class="QPushButton" name="cancelButton">
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
<item row="1" column="1" rowspan="2">
<widget class="QLabel" name="opacityLabel">
<property name="text">
<string>Opacity: x</string>
</property>
</widget>
</item>
<item row="0" column="3" rowspan="2">
<widget class="QPushButton" name="selectButton">
<property name="text">
<string>OK</string>
</property>
</widget>
</item>
<item row="1" column="2" rowspan="2">
<widget class="QLabel" name="internalNameLabel">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>minecraft:xxxxx</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="nameLabel">
<property name="text">
<string>BlockName</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="idLabel">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>(xx:xx)</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="0" rowspan="4">
<widget class="QLabel" name="blockThumb">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>48</width>
<height>48</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>BlockTypeListWidget</class>
<extends>QListWidget</extends>
<header>blocktypelistwidget.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>searchField</tabstop>
<tabstop>listWidget</tabstop>
<tabstop>selectButton</tabstop>
<tabstop>cancelButton</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@ -216,7 +216,8 @@ class BlockTypeListWidget(QtGui.QListWidget):
def __init__(self, *args, **kwargs):
super(BlockTypeListWidget, self).__init__(*args, **kwargs)
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
self.specifiedItem = None
self.specifiedItems = []
self.multipleSelect = False
_textureAtlas = None
@ -248,8 +249,8 @@ class BlockTypeListWidget(QtGui.QListWidget):
def setSearchString(self, val):
self._searchValue = val
for item in self.findItems("", Qt.MatchContains):
item.setHidden(val.lower() not in item.block.displayName.lower())
ID = None
meta = None
try:
if ":" in val:
ID, meta = val.split(":")
@ -259,23 +260,40 @@ class BlockTypeListWidget(QtGui.QListWidget):
ID = int(ID)
meta = int(meta)
if self.specifiedItem:
self.removeItemWidget(self.specifiedItem)
self.takeItem(self.row(self.specifiedItem))
self.specifiedItem = QtGui.QListWidgetItem()
block = self.blocktypes[ID, meta]
itemWidget = BlockTypesItemWidget([block], self.textureAtlas)
self.specifiedItem.setSizeHint(itemWidget.sizeHint())
self.specifiedItem.block = block
self.specifiedItem.widget = itemWidget
self.addItem(self.specifiedItem)
self.setItemWidget(self.specifiedItem, itemWidget)
except ValueError:
pass
else:
for item in [i for i in self.specifiedItems if not i.isSelected()]:
self.removeItemWidget(item)
self.takeItem(self.row(item))
self.specifiedItems.remove(item)
block = self.blocktypes[ID, meta]
if block not in self.blocktypes:
item, itemWidget = self.createItem(block)
self.addItem(item)
self.setItemWidget(item, itemWidget)
self.specifiedItems.append(item)
for item in self.findItems("", Qt.MatchContains):
matched = val.lower() in item.block.displayName.lower()
matched |= val in item.block.internalName + item.block.blockState
if ID is not None:
matched |= (item.block.ID == ID and item.block.meta == meta)
item.setHidden(not matched)
def createItem(self, block):
item = QtGui.QListWidgetItem()
itemWidget = BlockTypesItemWidget([block], self.textureAtlas)
item.setSizeHint(itemWidget.sizeHint())
item.block = block
item.widget = itemWidget
if self.multipleSelect:
item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable)
return item, itemWidget
def updateList(self):
if self.textureAtlas is None:
@ -283,70 +301,76 @@ class BlockTypeListWidget(QtGui.QListWidget):
if self.blocktypes is None:
return
log.info("Updating blocktype list widget (multiple=%s) for %s", self.multipleSelect, self.blocktypes)
self.clear()
self.specifiedItem = None
self.specifiedItems = []
for block in self.blocktypes:
if self._searchValue:
for s in block.displayName, block.internalName:
if self._searchValue not in s:
continue
item = QtGui.QListWidgetItem()
itemWidget = BlockTypesItemWidget([block], self.textureAtlas)
item.setSizeHint(itemWidget.sizeHint())
item.block = block
item.widget = itemWidget
item, itemWidget = self.createItem(block)
self.addItem(item)
self.setItemWidget(item, itemWidget)
self.setMinimumWidth(self.sizeHintForColumn(0)+self.autoScrollMargin())
if self._searchValue:
self.setSearchString(self._searchValue)
class BlockTypePicker(QtGui.QDialog):
def __init__(self, *args, **kwargs):
self.multipleSelect = kwargs.pop('multipleSelect', False)
super(BlockTypePicker, self).__init__(*args, **kwargs)
self._editorSession = None
load_ui("block_picker.ui", baseinstance=self)
if self.multipleSelect:
load_ui("block_picker_multiple.ui", baseinstance=self)
else:
load_ui("block_picker.ui", baseinstance=self)
self.selectButton.clicked.connect(self.accept)
self.cancelButton.clicked.connect(self.reject)
self.searchField.editTextChanged.connect(self.setSearchString)
assert isinstance(self.listWidget, QtGui.QListWidget)
self.listWidget.itemSelectionChanged.connect(self.selectionDidChange)
self.listWidget.doubleClicked.connect(self.accept)
if not self.multipleSelect:
self.listWidget.doubleClicked.connect(self.accept)
else:
self.listWidget.multipleSelect = True
self.setSizeGripEnabled(True)
def exec_(self):
self.searchField.setFocus()
return super(BlockTypePicker, self).exec_()
def selectionDidChange(self):
if not self.multipleSelect:
if len(self.selectedBlocks):
block = self.selectedBlocks[0]
self.nameLabel.setText("%s" % block.displayName)
self.internalNameLabel.setText("(%d:%d) %s" % (block.ID, block.meta, block.internalName))
self.brightnessLabel.setText("Brightness: %d" % block.brightness)
self.opacityLabel.setText("Opacity: %d" % block.opacity)
self.rendertypeLabel.setText("Render: %d" % block.renderType)
pixmap = BlockTypePixmap(block, self.editorSession.textureAtlas)
self.blockThumb.setPixmap(pixmap)
else:
self.nameLabel.setText("")
self.idLabel.setText("")
self.internalNameLabel.setText("")
self.brightnessLabel.setText("")
self.opacityLabel.setText("")
self.rendertypeLabel.setText("")
@property
def multipleSelect(self):
return self.listWidget.selectionMode() == self.listWidget.MultiSelection
@multipleSelect.setter
def multipleSelect(self, value):
if value:
self.listWidget.setSelectionMode(self.listWidget.MultiSelection)
if len(self.selectedBlocks) == 0:
self.nameLabel.setText("[No selection]")
self.idLabel.setText("")
self.internalNameLabel.setText("")
self.brightnessLabel.setText("")
self.opacityLabel.setText("")
self.rendertypeLabel.setText("")
elif len(self.selectedBlocks) == 1:
block = self.selectedBlocks[0]
self.nameLabel.setText("%s" % block.displayName)
self.internalNameLabel.setText("(%d:%d) %s" % (block.ID, block.meta, block.internalName))
self.brightnessLabel.setText("Brightness: %d" % block.brightness)
self.opacityLabel.setText("Opacity: %d" % block.opacity)
self.rendertypeLabel.setText("Render: %d" % block.renderType)
pixmap = BlockTypePixmap(block, self.editorSession.textureAtlas)
self.blockThumb.setPixmap(pixmap)
else:
self.listWidget.setSelectionMode(self.listWidget.SingleSelection)
self.nameLabel.setText("[Multiple selection]")
self.idLabel.setText("")
self.internalNameLabel.setText("")
self.brightnessLabel.setText("")
self.opacityLabel.setText("")
self.rendertypeLabel.setText("")
if self.multipleSelect:
self.selectedBlockList.blocktypes = self.selectedBlocks
@property
def editorSession(self):
@ -362,6 +386,9 @@ class BlockTypePicker(QtGui.QDialog):
if self.editorSession:
self.listWidget.textureAtlas = self.editorSession.textureAtlas
self.listWidget.blocktypes = self.editorSession.worldEditor.blocktypes
if self.multipleSelect:
self.selectedBlockList.textureAtlas = self.editorSession.textureAtlas
self.searchField.clearEditText()
@property
@ -372,10 +399,11 @@ class BlockTypePicker(QtGui.QDialog):
def selectedBlocks(self, val):
self.listWidget.clearSelection()
found = False
for item in self.listWidget.findItems("", Qt.MatchContains):
for i in range(self.listWidget.count()):
item = self.listWidget.item(i)
if item.block in val:
if self.multipleSelect:
self.listWidget.setCurrentItem(item, QtGui.QItemSelectionModel.Current)
self.listWidget.setCurrentItem(item, QtGui.QItemSelectionModel.Toggle)
else:
self.listWidget.setCurrentItem(item)
found = True
@ -385,35 +413,38 @@ class BlockTypePicker(QtGui.QDialog):
def setSearchString(self, val):
self.listWidget.setSearchString(val)
_sharedPicker = None
def getBlockTypePicker():
global _sharedPicker
if _sharedPicker is None:
_sharedPicker = BlockTypePicker()
return _sharedPicker
_sharedPicker = None
_sharedMultiPicker = None
def getBlockTypePicker(multipleSelect):
global _sharedPicker, _sharedMultiPicker
if multipleSelect:
if _sharedMultiPicker is None:
_sharedMultiPicker = BlockTypePicker(multipleSelect=True)
return _sharedMultiPicker
else:
if _sharedPicker is None:
_sharedPicker = BlockTypePicker()
return _sharedPicker
@registerCustomWidget
class BlockTypeButton(QtGui.QPushButton):
def __init__(self, *args, **kwargs):
self.multipleSelect = kwargs.pop('multipleSelect', False)
super(BlockTypeButton, self).__init__(*args, **kwargs)
self._blocks = []
self.clicked.connect(self.showPicker)
self.picker = getBlockTypePicker()
self.picker = getBlockTypePicker(self.multipleSelect)
self.setLayout(QtGui.QStackedLayout())
self._viewWidget = None
self.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed)
blocksChanged = QtCore.Signal(list)
@property
def multipleSelect(self):
return self.picker.multipleSelect
@multipleSelect.setter
def multipleSelect(self, value):
self.picker.multipleSelect = value
_editor = None
@property