Mercurial > hg > tilerswift
changeset 50:fef68d9650af
refactor TilePicker and GridCanvas (now ROMCanvas) into common superclass
Also add a GridHolder class to more transparently iterate over
variably-dimensioned arrays.
author | Jordi Gutiérrez Hermoso <jordigh@octave.org> |
---|---|
date | Fri, 06 Sep 2019 08:32:35 -0400 |
parents | 5ca986354475 |
children | f2b46bee6c50 |
files | img/checkerboard.png tilerswift |
diffstat | 2 files changed, 99 insertions(+), 78 deletions(-) [+] |
line wrap: on
line diff
index 3d04e84950736555874defe921fb796f927cea12..089edf2f6fe31ae6ffc095f44736791b287e96b4 GIT binary patch literal 3126 zc%1E4TToj?7~YfHNg%W&K+BzQla!(KoRbS7qjrD<I8<uNMQC42fD>{YLek`vi!*%y z6<Ve<w0Q4>w$#?kLuXLyrK3}^wce@>tqN^@C|0HFIMXU>VVK5$6NoURSbcDGrknHc z{=5J8{kz|8lCyhko6Dji5+e{oQEa)T3R(#^IaFxxfsrBHX(_5KLTGp(a?UP=zNm3i znFaa#2F{*@p2AbU)rU}iCN`q;$i{XUBn7t8N?uV&qe;=F!_pcUN?|QUHS+PMhJ9Ug z&si&`4Kb(A`+BRC{<Kdhgi1G%Nk8s-djKK1jH_oIESrn)8en0B1QFoj9<j(55n?2U zwij#_Awp`rV6a3&8o)dYmNf4l1=9i^`<O!mUJ30nFb4csXitFgeZl;nfz1Zy!JiT@ zXBW6;O$RSHHDzq24Pl8Gx6tB24U<n(`6k3rbfKAo$DpB2W*u#&O@QegBvAq&FQcVp zd2V?~F|LS3{(|BL@Wu0LWY`w@af?(Eq9E6Sx%2)(S#aK<GXI4CGK#J!WlLcqJO@<% zOQ-}6K}O1?a*`w!3VDPwHcA;8sZ3DEtd31dOiN8kOitEh<>zQJ@-mZ?wFT?)C|a-A zr{xshV`A>k*XbFYgit6H%1C8=R8%~Zo}AA7?c#qIspNP~Vj=^HRD@VX_)nuWSf`W- zl!Z+sL}H0lM#>ctkpMUzjdw~cl8B{J34ED}T@XhSl~kQh7s+C_*vX6?u}t^=L-Nex z;gPtiv1?hnMsJTIV$It4gv9K-a<uDm^#)^ssnA?vv6hyVvlZ1fwGY(QZ{60^%sE<| z{DVGWXM0Cy*Fz6K@@Q}0?mhj3k3IgxlTSVU%z>f9&mTGZ!iz7x{K~7Z9e@3eH{Uw( z-l@~?pZVa!k3K$k{_`)s9G|#waq{ac-+cSs)Yb2Qxc>7m)4%@q`;D1dtPAU0C}DM} zK$l1&5lcv{ix72SfJ!1wr)BD*Eu?)%Oa{{}k1gJRXm~`CsjIpc*XSLKSd*on%)XAL z1(e;Mu%3UUEF|ntT^Es3Ou*rZRcIrcx!JEhC|bc*pS(KMkF+b;jg{zkQv5$t{FVJT zR(U7IznsE<L9a{W;eRkeu+|GDZkLN|6PCX*>$+F11yD8yHABeU6hH)C#Oo<|3^fd8 zrV7jyv!2qMDe9fnDc=%;%iYX7x^7K4Te5u=-z+eJ>*O8gVqWmsIB&Jx<!R-RDNlnR z^-uTa04hC%vOw+{-o=Hx5^$qmjR80&1hztTzr*3<1b`dc`RXYM=Y+zn%ih9SIA4>O z_XxbZZTU7tH=oM}ih3#KKCZ1ra3a%a>X|u+s+LCU_+}hT&$>Cdu+4#Bwc8<d*uC81 ziw(QiQVF1}5J+(DbTziw`PT5;p-Gyq27GcDJRGIR%lUj*hjE7U)B!Fv3~sRk#$dF0 zD15C+xfL>~27tR|v-n1*4FjyOS<Bcqf%7&w?QJbwsoU$a3rJ@$P4sr)tI>wr<;*XO zHWnI%O*yqd%?(4fIo*QW#R*=%DUbnV3--YI8P#$9iNMl?VFfo5Z>f#%<XVw#a{SY6 zfE7a6S|8_K_(4#4ny`<tAWuWndZ;KmPg5A^8RvU61ppm`hYE4e5DMyp;{^aJ(18KX UL=oG~MtmV*t(z^!iW_?V0LV$FmjD0&
--- a/tilerswift +++ b/tilerswift @@ -56,6 +56,10 @@ self.set_palette(self.default_palette) + def __repr__(self): + num_to_ascii = {0: " ", 1: ".", 2: "o", 3: "#"} + return "\n".join([[num_to_ascii[val] for val in row] for row in self.tile]) + def palette_to_qt(self): return [QtGui.QColor(NES_PALETTE[color_idx]).rgb() for color_idx in self.palette] @@ -66,26 +70,49 @@ self.pixmap = QtGui.QPixmap(image) -class GridCanvas(QtWidgets.QWidget): +class GridHolder(object): + def __init__(self, things, numrows, numcols, fillvalue=None): + self.numrows = numrows + self.numcols = numcols + self.fillvalue = fillvalue + if things is None: + self.things = [] + for i in range(self.numrows): + self.things.extend([fillvalue]*self.numcols) + else: + self.things = things + + def __getitem__(self, idx): + i, j = idx + return self.things[i*self.numcols + j] - def __init__(self, filename): + def __setitem__(self, idx, value): + i, j = idx + self.things[i*self.numcols + j] = value + + def __repr__(self): + return f"GridHolder(numrows={self.numrows}, numcols={self.numcols}, fillvalue={self.fillvalue})" + + def __iter__(self): + for thing in self.things: + yield thing + + def resize(self, numrows, numcols): + self.numrows = numrows + self.numcols = numcols + + +class TileGrid(QtWidgets.QWidget): + def __init__(self, numrows, numcols, scalefactor, spacing): super().__init__() - self.file_name = filename - self.tiles = read_rom(self.file_name) - - self.numcols = 16 - self.numrows = len(self.tiles)//self.numcols - - self.scalefactor = 5 - self.spacing = 2 + self.numcols = numcols + self.numrows = numrows + self.scalefactor = scalefactor + self.spacing = spacing self.setStyleSheet(CHECKERBOARD_CSS) - self.picked_tile = None - - self.resize() - def paintEvent(self, event): painter = QtGui.QPainter(self) @@ -99,22 +126,26 @@ for i in range(self.numrows): for j in range(self.numcols): - tile = self.tiles[i*self.numcols + j] - rect = QtCore.QRect( - self.spacing + j*self.tilesize, - self.spacing + i*self.tilesize, - 8*self.scalefactor, 8*self.scalefactor - ) - painter.drawPixmap(rect, tile.pixmap) + tile = self.tiles[i, j] + if tile: + rect = QtCore.QRect( + self.spacing + j*self.tilesize, + self.spacing + i*self.tilesize, + self.tilesize - self.spacing, + self.tilesize - self.spacing + ) + flipx, flipy = self.flips[i, j] + painter.drawPixmap( + rect, + tile.pixmap.transformed(QtGui.QTransform().scale(flipx, flipy)) + ) - def mousePressEvent(self, event): + def mouseClickToIJ(self, event): j, i = ( (event.x() - self.spacing)//self.tilesize, (event.y() - self.spacing)//self.tilesize, ) - tile = self.tiles[i*self.numcols + j] - - self.picked_tile = tile + return (i, j) def resize(self): self.tilesize = self.spacing + self.scalefactor*8 @@ -141,77 +172,67 @@ self.resize() -class TilePicker(QtWidgets.QWidget): - - def __init__(self, grid_canvas): - super().__init__() +class ROMCanvas(TileGrid): + def __init__(self, filename): + tiles = read_rom(filename) - self.grid_canvas = grid_canvas - self.setStyleSheet(CHECKERBOARD_CSS) - self.numrows = 20 - self.numcols = 20 + super().__init__( + numcols=16, + numrows=len(tiles)//16, + spacing=2, + scalefactor=5 + ) - self.picked_tiles = [] - self.flips = [] - for i in range(self.numrows): - self.picked_tiles.append([None]*self.numcols) - self.flips.append([(1, 1)]*self.numcols) + self.tiles = GridHolder(tiles, self.numrows, self.numcols) + self.flips = GridHolder(None, self.numrows, self.numcols, fillvalue=(1, 1)) + + self.filename = filename + self.picked_tile = None self.resize() - def resize(self): - self.tilesize = self.grid_canvas.scalefactor*8 - self.setFixedSize(QtCore.QSize( - self.tilesize*self.numcols, - self.tilesize*self.numrows - )) - self.update() + def mousePressEvent(self, event): + i, j = self.mouseClickToIJ(event) + tile = self.tiles[i, j] - def paintEvent(self, event): - painter = QtGui.QPainter(self) + self.picked_tile = tile + + +class TilePicker(TileGrid): - # I don't really know what this block of code means, but it's - # what I have to do in order to get this widget to obey CSS - # styles. - opt = QtWidgets.QStyleOption() - opt.initFrom(self) - style = self.style() - style.drawPrimitive(QtWidgets.QStyle.PE_Widget, opt, painter, self) + def __init__(self, rom_canvas): + super().__init__( + numcols=20, + numrows=20, + spacing=0, + scalefactor=5, + ) - for i in range(self.numrows): - for j in range(self.numcols): - tile = self.picked_tiles[i][j] - if tile: - rect = QtCore.QRect( - j*self.tilesize, - i*self.tilesize, - 8*self.grid_canvas.scalefactor, - 8*self.grid_canvas.scalefactor - ) - flipx, flipy = self.flips[i][j] - painter.drawPixmap( - rect, - tile.pixmap.transformed(QtGui.QTransform().scale(flipx, flipy)) - ) + self.rom_canvas = rom_canvas + self.tiles = GridHolder(None, self.numrows, self.numcols) + self.flips = GridHolder(None, self.numcols, self.numcols, fillvalue=(1, 1)) + + self.resize() def mousePressEvent(self, event): - j, i = event.x()//self.tilesize, event.y()//self.tilesize + i, j = self.mouseClickToIJ(event) + if event.button() == QtCore.Qt.LeftButton: - self.picked_tiles[i][j] = self.grid_canvas.picked_tile + self.tiles[i, j] = self.rom_canvas.picked_tile elif event.button() == QtCore.Qt.RightButton: - self.picked_tiles[i][j] = None + self.tiles[i, j] = None elif event.button() == QtCore.Qt.MidButton: - flipx, flipy = self.flips[i][j] + flipx, flipy = self.flips[i, j] if flipx == 1: if flipy == 1: - self.flips[i][j] = (1, -1) + self.flips[i, j] = (1, -1) else: - self.flips[i][j] = (-1, 1) + self.flips[i, j] = (-1, 1) else: if flipy == 1: - self.flips[i][j] = (-1, -1) + self.flips[i, j] = (-1, -1) else: - self.flips[i][j] = (1, 1) + self.flips[i, j] = (1, 1) self.update() @@ -274,7 +295,7 @@ "Open ROM", "", "NES Files (*.nes)" ) - self.grid_widget = GridCanvas(filename[0]) + self.grid_widget = ROMCanvas(filename[0]) self.tile_picker = TilePicker(self.grid_widget)