From 4a3446ebc48953ec0b025c4be38e6e83535922f5 Mon Sep 17 00:00:00 2001 From: Thxios Date: Fri, 6 Mar 2020 18:49:43 +0900 Subject: [PATCH] . Signed-off-by: Thxios --- src/Brush.py | 14 +++++++++++--- src/Layer.py | 15 +++++++++------ src/Section.py | 16 ++++++++++++++-- src/Sprite.py | 47 ++++++++++++++++++++++++++++++++++++++--------- 4 files changed, 72 insertions(+), 20 deletions(-) diff --git a/src/Brush.py b/src/Brush.py index c59b16d..3721f65 100644 --- a/src/Brush.py +++ b/src/Brush.py @@ -3,6 +3,13 @@ class Brush: + _layer = None + + def SetCurrentLayer(self, layer: Layer): + self._layer = layer + + +class _Brush: currentColor = (0, 0, 0, 0) _layer = None @@ -24,7 +31,7 @@ def SetCurrentColor(self, color): self.currentColor = color -class PencilBrush(Brush): +class PencilBrush(_Brush): def OnMouseDown(self, clickedPixel): self._layer.SetPixel(*clickedPixel, self.currentColor) @@ -32,16 +39,17 @@ def OnMouseDrag(self, clickedPixel): self._layer.SetPixel(*clickedPixel, self.currentColor) -class PickerBrush(Brush): +class PickerBrush(_Brush): def OnMouseDown(self, clickedPixel): self.currentColor = self._layer.GetPixel(*clickedPixel) return self.currentColor -class FloodBrush(Brush): +class FloodBrush(_Brush): def OnMouseDown(self, clickedPixel): pass +Brush = Brush() PencilBrush = PencilBrush() FloodBrush = FloodBrush() diff --git a/src/Layer.py b/src/Layer.py index 0eb2ff9..6ac0d13 100644 --- a/src/Layer.py +++ b/src/Layer.py @@ -23,7 +23,7 @@ def Clear(self): def SetPixel(self, x, y, color): self._pixel[x][y] = utility.RGBA2INT(color) - def GetPixel(self, x, y): + def GetPixel(self, x, y) -> (int, int, int, int): return utility.INT2RGBA(self._pixel[x][y]) def Paste(self, x, y, layer): @@ -35,7 +35,7 @@ def Paste(self, x, y, layer): self._pixel[xs:xe, ys:ye] = layer._pixel[crop_xs:crop_xe, crop_ys:crop_ye] - def Crop(self, xRange, yRange): + def CropLayer(self, xRange, yRange): _xs, _xe = xRange _ys, _ye = yRange _xs, _xe = max(_xs, 0), min(_xe, self.w) @@ -45,10 +45,10 @@ def Crop(self, xRange, yRange): _layer._pixel = self._pixel[_xs:_xe, _ys:_ye] return _layer - def GetSurface(self): + def GetSurface(self) -> pg.Surface: return self._surface - def GetArray(self): + def GetArray(self) -> np.ndarray: return self._pixel @staticmethod @@ -72,6 +72,9 @@ def FromSurface(surface: pg.Surface): @staticmethod def Empty(wid, hei): - _layer = Layer(wid, hei) - return _layer + return Layer(wid, hei) + + @staticmethod + def Solid(wid, hei, color): + return Layer(wid, hei, color) diff --git a/src/Section.py b/src/Section.py index e49f74d..84cdeda 100644 --- a/src/Section.py +++ b/src/Section.py @@ -1,6 +1,7 @@ import pygame as pg -from src.Layer import Layer +from src.Sprite import Sprite from src.Brush import PencilBrush +from math import ceil, floor class Section: @@ -30,6 +31,7 @@ def SetBackgroundColor(self, color): def OnClicked(self, button, x, y): if not self.rect.collidepoint(x, y): return + raise NotImplementedError('For test') def Changed(self): self._hasChange = True @@ -41,7 +43,7 @@ def Draw(self, screen): pg.draw.rect(screen, self._outlineColor, self.rect, 3) self._hasChange = False - def LocalPosition(self, position): + def LocalPosition(self, position) -> (int, int): _x, _y = position return _x - self.x, _y - self.y @@ -58,6 +60,8 @@ class CanvasSection(Section): bgImage = pg.image.load('data/TransparentBG.png') bgColor = (60, 63, 65) + sprite = Sprite.Empty(32, 32) + def SetupCanvas(self, w, h): self.canvasWidth = w self.canvasHeight = h @@ -82,9 +86,17 @@ def Magnify(self, mag, pivot): self.canvas.h = self.canvasHeight * self.magnification self.Changed() + def DisplayArea(self): + _xs, _xe = max(0, self.canvas.x), min(self.w, self.canvas.x + self.canvas.w) + _ys, _ye = max(0, self.canvas.y), min(self.h, self.canvas.y + self.canvas.h) + def Update(self): self.surface.fill(self.bgColor) self.surface.blit(self.bgImage, (self.canvas.x, self.canvas.y), self.canvas) + self.surface.blit( + pg.transform.scale(self.sprite.GetSurface(), (self.canvas.w, self.canvas.h)), + self.canvas.topleft + ) def OnClicked(self, button, x, y): if self.canvas.collidepoint(x, y): diff --git a/src/Sprite.py b/src/Sprite.py index 71092d5..913e75d 100644 --- a/src/Sprite.py +++ b/src/Sprite.py @@ -1,8 +1,9 @@ import pygame as pg from src.Layer import Layer +from src.Brush import Brush -class Frame: +class _Frame: _layer = [] _layerCount = 0 @@ -23,17 +24,23 @@ def DeleteLayer(self, idx): else: raise ValueError("DeleteLayer - trial to delete last layer") - def GetLayer(self, idx): + def GetLayer(self, idx) -> Layer: if idx < 0 or idx >= self._layerCount: raise IndexError("GetLayer - number of layers doesn't match") return self._layer[idx] - def LayerCount(self): + def GetSurface(self) -> pg.Surface: + _surface = pg.Surface((self.w, self.h), pg.SRCALPHA, 32) + for _layer in self._layer: + pg.surfarray.blit_array(_surface, _layer.GetArray()) + return _surface + + def LayerCount(self) -> int: return self._layerCount @staticmethod def Empty(wid, hei): - _frame = Frame(wid, hei) + _frame = _Frame(wid, hei) _frame.AddLayer(Layer.Empty(wid, hei)) return _frame @@ -48,23 +55,45 @@ def __init__(self, wid, hei): self.w = wid self.h = hei - def AddFrame(self, frame: Frame): + def AddFrame(self, frame: _Frame): self._frame.append(frame) self._frameCount += 1 + if self._frameCount == 1: + self.SetFrame(0) + + def GetSurface(self) -> pg.Surface: + return self.CurrentFrame().GetSurface() - def CurrentFrame(self): + def CurrentFrame(self) -> _Frame: return self._frame[self._currentFrame] - def CurrentLayer(self): + def CurrentLayer(self) -> Layer: return self._frame[self._currentFrame].GetLayer(self._currentLayer) - def FrameCount(self): + def FrameCount(self) -> int: return self._frameCount + def LayerCount(self) -> int: + return self.CurrentFrame().LayerCount() + + def SetFrame(self, idx): + if idx < 0 or idx > self._frameCount: + raise IndexError("SetFrame - invalid index") + self._currentFrame = idx + if self.LayerCount() > self._currentLayer: + self._currentLayer = self.LayerCount() - 1 + Brush.SetCurrentLayer(self.CurrentLayer()) + + def SetLayer(self, idx): + if idx < 0 or idx > self.LayerCount(): + raise IndexError("SetLayer - invalid index") + self._currentLayer = idx + Brush.SetCurrentLayer(self.CurrentLayer()) + @staticmethod def Empty(wid, hei, frameCount=1): _sprite = Sprite(wid, hei) for _ in range(frameCount): - _sprite.AddFrame(Frame.Empty(wid, hei)) + _sprite.AddFrame(_Frame.Empty(wid, hei)) return _sprite