Multiple select block picker is now double column (needs checkboxes, better highlighting for left column)
This commit is contained in:
parent
ce2e67ffb2
commit
08290cefa7
@ -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)
|
||||
|
254
src/mcedit2/ui/block_picker_multiple.ui
Normal file
254
src/mcedit2/ui/block_picker_multiple.ui
Normal 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>
|
@ -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
|
||||
|
Reference in New Issue
Block a user