commit
2603c63925
|
@ -13,3 +13,4 @@ env/*
|
|||
ffmpeg
|
||||
*.bak
|
||||
*~
|
||||
*.goutput*
|
|
@ -0,0 +1,119 @@
|
|||
<?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>586</width>
|
||||
<height>197</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,348 @@
|
|||
from PyQt5 import QtGui, QtCore, QtWidgets
|
||||
from PIL import Image, ImageDraw, ImageEnhance, ImageChops, ImageFilter
|
||||
import os
|
||||
import math
|
||||
|
||||
from component import Component
|
||||
from toolkit.frame import BlankFrame, scale
|
||||
|
||||
|
||||
class Component(Component):
|
||||
name = 'Conway\'s Game of Life'
|
||||
version = '1.0.0a'
|
||||
|
||||
def widget(self, *args):
|
||||
super().widget(*args)
|
||||
self.scale = 32
|
||||
self.updateGridSize()
|
||||
self.startingGrid = {}
|
||||
self.page.pushButton_pickImage.clicked.connect(self.pickImage)
|
||||
self.trackWidgets({
|
||||
'tickRate': self.page.spinBox_tickRate,
|
||||
'scale': self.page.spinBox_scale,
|
||||
'color': self.page.lineEdit_color,
|
||||
'shapeType': self.page.comboBox_shapeType,
|
||||
'shadow': self.page.checkBox_shadow,
|
||||
'customImg': self.page.checkBox_customImg,
|
||||
'image': self.page.lineEdit_image,
|
||||
}, colorWidgets={
|
||||
'color': self.page.pushButton_color,
|
||||
})
|
||||
self.page.spinBox_scale.setValue(self.scale)
|
||||
self.page.spinBox_scale.valueChanged.connect(self.updateGridSize)
|
||||
|
||||
def pickImage(self):
|
||||
imgDir = self.settings.value("componentDir", os.path.expanduser("~"))
|
||||
filename, _ = QtWidgets.QFileDialog.getOpenFileName(
|
||||
self.page, "Choose Image", imgDir,
|
||||
"Image Files (%s)" % " ".join(self.core.imageFormats))
|
||||
if filename:
|
||||
self.settings.setValue("componentDir", os.path.dirname(filename))
|
||||
self.page.lineEdit_image.setText(filename)
|
||||
self.update()
|
||||
|
||||
def update(self):
|
||||
self.updateGridSize()
|
||||
if self.page.checkBox_customImg.isChecked():
|
||||
self.page.label_color.setVisible(False)
|
||||
self.page.lineEdit_color.setVisible(False)
|
||||
self.page.pushButton_color.setVisible(False)
|
||||
self.page.label_shape.setVisible(False)
|
||||
self.page.comboBox_shapeType.setVisible(False)
|
||||
self.page.label_image.setVisible(True)
|
||||
self.page.lineEdit_image.setVisible(True)
|
||||
self.page.pushButton_pickImage.setVisible(True)
|
||||
else:
|
||||
self.page.label_color.setVisible(True)
|
||||
self.page.lineEdit_color.setVisible(True)
|
||||
self.page.pushButton_color.setVisible(True)
|
||||
self.page.label_shape.setVisible(True)
|
||||
self.page.comboBox_shapeType.setVisible(True)
|
||||
self.page.label_image.setVisible(False)
|
||||
self.page.lineEdit_image.setVisible(False)
|
||||
self.page.pushButton_pickImage.setVisible(False)
|
||||
super().update()
|
||||
|
||||
def previewClickEvent(self, pos, size, button):
|
||||
pos = (
|
||||
math.ceil((pos[0] / size[0]) * self.gridWidth) - 1,
|
||||
math.ceil((pos[1] / size[1]) * self.gridHeight) - 1
|
||||
)
|
||||
if button == 1:
|
||||
self.startingGrid[pos] = True
|
||||
elif button == 2 and pos in self.startingGrid:
|
||||
self.startingGrid.pop(pos)
|
||||
|
||||
def updateGridSize(self):
|
||||
w, h = self.core.resolutions[-1].split('x')
|
||||
self.gridWidth = int(int(w) / self.scale)
|
||||
self.gridHeight = int(int(h) / self.scale)
|
||||
self.pxWidth = math.ceil(self.width / self.gridWidth)
|
||||
self.pxHeight = math.ceil(self.height / self.gridHeight)
|
||||
|
||||
def previewRender(self):
|
||||
return self.drawGrid(self.startingGrid)
|
||||
|
||||
def preFrameRender(self, *args, **kwargs):
|
||||
super().preFrameRender(*args, **kwargs)
|
||||
self.progressBarSetText.emit("Computing evolution...")
|
||||
self.tickGrids = {0: self.startingGrid}
|
||||
tick = 0
|
||||
for frameNo in range(
|
||||
self.tickRate, len(self.completeAudioArray), self.sampleSize
|
||||
):
|
||||
if self.parent.canceled:
|
||||
break
|
||||
if frameNo % self.tickRate == 0:
|
||||
tick += 1
|
||||
self.tickGrids[tick] = self.gridForTick(tick)
|
||||
|
||||
# update progress bar
|
||||
progress = int(100*(frameNo/len(self.completeAudioArray)))
|
||||
if progress >= 100:
|
||||
progress = 100
|
||||
pStr = "Computing evolution: "+str(progress)+'%'
|
||||
self.progressBarSetText.emit(pStr)
|
||||
self.progressBarUpdate.emit(int(progress))
|
||||
|
||||
def properties(self):
|
||||
if self.customImg and (
|
||||
not self.image or not os.path.exists(self.image)
|
||||
):
|
||||
return ['error']
|
||||
return []
|
||||
|
||||
def error(self):
|
||||
return "No image selected to represent life."
|
||||
|
||||
def frameRender(self, frameNo):
|
||||
tick = math.floor(frameNo / self.tickRate)
|
||||
grid = self.tickGrids[tick]
|
||||
return self.drawGrid(grid)
|
||||
|
||||
def drawGrid(self, grid):
|
||||
frame = BlankFrame(self.width, self.height)
|
||||
|
||||
def drawCustomImg():
|
||||
try:
|
||||
img = Image.open(self.image)
|
||||
except Exception:
|
||||
return
|
||||
img = img.resize((self.pxWidth, self.pxHeight), Image.ANTIALIAS)
|
||||
frame.paste(img, box=(drawPtX, drawPtY))
|
||||
|
||||
def drawShape():
|
||||
drawer = ImageDraw.Draw(frame)
|
||||
rect = (
|
||||
(drawPtX, drawPtY),
|
||||
(drawPtX + self.pxWidth, drawPtY + self.pxHeight)
|
||||
)
|
||||
shape = self.page.comboBox_shapeType.currentText().lower()
|
||||
|
||||
# Rectangle
|
||||
if shape == 'rectangle':
|
||||
drawer.rectangle(rect, fill=self.color)
|
||||
|
||||
# Elliptical
|
||||
elif shape == 'elliptical':
|
||||
drawer.ellipse(rect, fill=self.color)
|
||||
|
||||
tenthX, tenthY = scale(10, self.pxWidth, self.pxHeight, int)
|
||||
smallerShape = (
|
||||
(drawPtX + tenthX + int(tenthX / 4),
|
||||
drawPtY + tenthY + int(tenthY / 2)),
|
||||
(drawPtX + self.pxWidth - tenthX - int(tenthX / 4),
|
||||
drawPtY + self.pxHeight - (tenthY + int(tenthY / 2)))
|
||||
)
|
||||
outlineShape = (
|
||||
(drawPtX + int(tenthX / 4),
|
||||
drawPtY + int(tenthY / 2)),
|
||||
(drawPtX + self.pxWidth - int(tenthX / 4),
|
||||
drawPtY + self.pxHeight - int(tenthY / 2))
|
||||
)
|
||||
# Circle
|
||||
if shape == 'circle':
|
||||
drawer.ellipse(outlineShape, fill=self.color)
|
||||
drawer.ellipse(smallerShape, fill=(0,0,0,0))
|
||||
|
||||
# Lilypad
|
||||
elif shape == 'lilypad':
|
||||
drawer.pieslice(smallerShape, 290, 250, fill=self.color)
|
||||
|
||||
# Pac-Man
|
||||
elif shape == 'pac-man':
|
||||
drawer.pieslice(outlineShape, 35, 320, fill=self.color)
|
||||
|
||||
hX, hY = scale(50, self.pxWidth, self.pxHeight, int) # halfline
|
||||
tX, tY = scale(33, self.pxWidth, self.pxHeight, int) # thirdline
|
||||
qX, qY = scale(20, self.pxWidth, self.pxHeight, int) # quarterline
|
||||
|
||||
# Path
|
||||
if shape == 'path':
|
||||
drawer.ellipse(rect, fill=self.color)
|
||||
rects = {
|
||||
direction: False
|
||||
for direction in (
|
||||
'up', 'down', 'left', 'right',
|
||||
)
|
||||
}
|
||||
for cell in nearbyCoords(x, y):
|
||||
if grid.get(cell) is None:
|
||||
continue
|
||||
if cell[0] == x:
|
||||
if cell[1] < y:
|
||||
rects['up'] = True
|
||||
if cell[1] > y:
|
||||
rects['down'] = True
|
||||
if cell[1] == y:
|
||||
if cell[0] < x:
|
||||
rects['left'] = True
|
||||
if cell[0] > x:
|
||||
rects['right'] = True
|
||||
|
||||
for direction, rect in rects.items():
|
||||
if rect:
|
||||
if direction == 'up':
|
||||
sect = (
|
||||
(drawPtX, drawPtY),
|
||||
(drawPtX + self.pxWidth, drawPtY + hY)
|
||||
)
|
||||
elif direction == 'down':
|
||||
sect = (
|
||||
(drawPtX, drawPtY + hY),
|
||||
(drawPtX + self.pxWidth,
|
||||
drawPtY + self.pxHeight)
|
||||
)
|
||||
elif direction == 'left':
|
||||
sect = (
|
||||
(drawPtX, drawPtY),
|
||||
(drawPtX + hX,
|
||||
drawPtY + self.pxHeight)
|
||||
)
|
||||
elif direction == 'right':
|
||||
sect = (
|
||||
(drawPtX + hX, drawPtY),
|
||||
(drawPtX + self.pxWidth,
|
||||
drawPtY + self.pxHeight)
|
||||
)
|
||||
drawer.rectangle(sect, fill=self.color)
|
||||
|
||||
# Duck
|
||||
elif shape == 'duck':
|
||||
duckHead = (
|
||||
(drawPtX + qX, drawPtY + qY),
|
||||
(drawPtX + int(qX * 3), drawPtY + int(tY * 2))
|
||||
)
|
||||
duckBeak = (
|
||||
(drawPtX + hX, drawPtY + qY),
|
||||
(drawPtX + self.pxWidth + qX,
|
||||
drawPtY + int(qY * 3))
|
||||
)
|
||||
duckWing = (
|
||||
(drawPtX, drawPtY + hY),
|
||||
rect[1]
|
||||
)
|
||||
duckBody = (
|
||||
(drawPtX + int(qX / 4), drawPtY + int(qY * 3)),
|
||||
(drawPtX + int(tX * 2), drawPtY + self.pxHeight)
|
||||
)
|
||||
drawer.ellipse(duckBody, fill=self.color)
|
||||
drawer.ellipse(duckHead, fill=self.color)
|
||||
drawer.pieslice(duckWing, 130, 200, fill=self.color)
|
||||
drawer.pieslice(duckBeak, 145, 200, fill=self.color)
|
||||
|
||||
# Peace
|
||||
elif shape == 'peace':
|
||||
line = (
|
||||
(drawPtX + hX - int(tenthX / 2), drawPtY + int(tenthY / 2)),
|
||||
(drawPtX + hX + int(tenthX / 2),
|
||||
drawPtY + self.pxHeight - int(tenthY / 2))
|
||||
)
|
||||
drawer.ellipse(outlineShape, fill=self.color)
|
||||
drawer.ellipse(smallerShape, fill=(0,0,0,0))
|
||||
drawer.rectangle(line, fill=self.color)
|
||||
slantLine = lambda difference: (
|
||||
((drawPtX + difference),
|
||||
(drawPtY + self.pxHeight - qY)),
|
||||
((drawPtX + hX),
|
||||
(drawPtY + hY)),
|
||||
)
|
||||
drawer.line(
|
||||
slantLine(qX),
|
||||
fill=self.color,
|
||||
width=tenthX
|
||||
)
|
||||
drawer.line(
|
||||
slantLine(self.pxWidth - qX),
|
||||
fill=self.color,
|
||||
width=tenthX
|
||||
)
|
||||
|
||||
for x, y in grid:
|
||||
drawPtX = x * self.pxWidth
|
||||
if drawPtX > self.width:
|
||||
continue
|
||||
drawPtY = y * self.pxHeight
|
||||
if drawPtY > self.height:
|
||||
continue
|
||||
|
||||
if self.customImg:
|
||||
drawCustomImg()
|
||||
else:
|
||||
drawShape()
|
||||
|
||||
if self.shadow:
|
||||
shadImg = ImageEnhance.Contrast(frame).enhance(0.0)
|
||||
shadImg = shadImg.filter(ImageFilter.GaussianBlur(5.00))
|
||||
shadImg = ImageChops.offset(shadImg, -2, 2)
|
||||
shadImg.paste(frame, box=(0, 0), mask=frame)
|
||||
frame = shadImg
|
||||
return frame
|
||||
|
||||
def gridForTick(self, tick):
|
||||
'''Given a tick number over 0, returns a new grid dict of tuples'''
|
||||
lastGrid = self.tickGrids[tick - 1]
|
||||
|
||||
def neighbours(x, y):
|
||||
return [
|
||||
cell for cell in nearbyCoords(x, y)
|
||||
if lastGrid.get(cell) is not None
|
||||
]
|
||||
|
||||
newGrid = {}
|
||||
for x, y in lastGrid:
|
||||
surrounding = len(neighbours(x, y))
|
||||
if surrounding == 2 or surrounding == 3:
|
||||
newGrid[(x, y)] = True
|
||||
potentialNewCells = set([
|
||||
coordTup for origin in lastGrid
|
||||
for coordTup in list(nearbyCoords(*origin))
|
||||
])
|
||||
for x, y in potentialNewCells:
|
||||
if (x, y) in newGrid:
|
||||
continue
|
||||
surrounding = len(neighbours(x, y))
|
||||
if surrounding == 3:
|
||||
newGrid[(x, y)] = True
|
||||
|
||||
return newGrid
|
||||
|
||||
def savePreset(self):
|
||||
pr = super().savePreset()
|
||||
pr['GRID'] = self.startingGrid
|
||||
return pr
|
||||
|
||||
def loadPreset(self, pr, *args):
|
||||
super().loadPreset(pr, *args)
|
||||
self.startingGrid = pr['GRID']
|
||||
|
||||
|
||||
def nearbyCoords(x, y):
|
||||
yield x + 1, y + 1
|
||||
yield x + 1, y - 1
|
||||
yield x - 1, y + 1
|
||||
yield x - 1, y - 1
|
||||
yield x, y + 1
|
||||
yield x, y - 1
|
||||
yield x + 1, y
|
||||
yield x - 1, y
|
|
@ -0,0 +1,358 @@
|
|||
<?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>586</width>
|
||||
<height>197</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Simulation Speed</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="spinBox_tickRate">
|
||||
<property name="suffix">
|
||||
<string> frames per tick</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>30</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>5</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEdit_color">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>0,0,0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Grid Scale</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="spinBox_scale">
|
||||
<property name="minimum">
|
||||
<number>24</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>128</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>32</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBox_customImg">
|
||||
<property name="text">
|
||||
<string>Custom Image</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_image">
|
||||
<property name="text">
|
||||
<string>Image</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEdit_image"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_pickImage">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_color">
|
||||
<property name="text">
|
||||
<string>Color</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEdit_color_3">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>0,0,0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_color">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="default">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_shape">
|
||||
<property name="text">
|
||||
<string>Shape</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboBox_shapeType">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Path</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Rectangle</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Elliptical</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Circle</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Lilypad</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Pac-Man</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Duck</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Peace</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_8">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBox_shadow">
|
||||
<property name="text">
|
||||
<string>Shadow</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_9">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTextBrowser" name="textBrowser">
|
||||
<property name="html">
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Click the preview window to place a cell. Right-click to remove.</span></p>
|
||||
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">- A cell with less than 2 neighbours will die from underpopulation</p>
|
||||
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">- A cell with more than 3 neighbours will die from overpopulation.</p>
|
||||
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">- An empty space surrounded by 3 live cells will cause reproduction.</p></body></html></string>
|
||||
</property>
|
||||
<property name="tabStopWidth">
|
||||
<number>80</number>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::NoTextInteraction</set>
|
||||
</property>
|
||||
<property name="openLinks">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -50,6 +50,22 @@ class PreviewWindow(QtWidgets.QLabel):
|
|||
self.pixmap = QtGui.QPixmap(img)
|
||||
self.repaint()
|
||||
|
||||
def mousePressEvent(self, event):
|
||||
if self.parent.encoding:
|
||||
return
|
||||
|
||||
i = self.parent.window.listWidget_componentList.currentRow()
|
||||
if i >= 0:
|
||||
component = self.parent.core.selectedComponents[i]
|
||||
if not hasattr(component, 'previewClickEvent'):
|
||||
return
|
||||
pos = (event.x(), event.y())
|
||||
size = (self.width(), self.height())
|
||||
component.previewClickEvent(
|
||||
pos, size, event.button()
|
||||
)
|
||||
self.parent.core.updateComponent(i)
|
||||
|
||||
@QtCore.pyqtSlot(str)
|
||||
def threadError(self, msg):
|
||||
self.parent.showMessage(
|
||||
|
|
Reference in New Issue