-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPreviewCanvas.lua
More file actions
167 lines (135 loc) · 5.96 KB
/
PreviewCanvas.lua
File metadata and controls
167 lines (135 loc) · 5.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
local ratio
local AdjustScale = function(scale)
if scale < 0 then return 1 / (math.abs(scale) + 1) end
return scale
end
local DrawCanvasGrid = function(sprite, image)
local docPref = app.preferences.document(sprite)
local color1 = docPref.bg.color1
local color2 = docPref.bg.color2
local size = docPref.bg.size
image:clear(color2)
local startRowGap = false
local isGap = false
for x = 0, math.ceil(image.width / size.width) do
isGap = startRowGap
for y = 0, math.ceil(image.height / size.height) do
if not isGap then
local bounds = Rectangle(x * size.width, y * size.height,
size.width, size.height)
image:clear(bounds, color1)
end
isGap = not isGap
end
startRowGap = not startRowGap
end
end
local DrawImageOnCanvas = function(sprite, image)
local result = Image(sprite.width, sprite.height, sprite.colorMode)
DrawCanvasGrid(sprite, result)
result:drawImage(image)
return result
end
local PreviewCanvas = function(dialog, width, height, sprite, image)
local border = 3
local padding = 8
local maxCanvasSize = Rectangle(0, 0, 200, 200)
local isMouseDown = false
local lastMouse = nil
local imagePositionDelta = Point(0, 0)
local scale = 1
image = DrawImageOnCanvas(sprite, image)
local RepaintImage = function(newImage, newPosition)
image = DrawImageOnCanvas(sprite, newImage, newPosition or position)
dialog:repaint()
end
dialog --
:label{text='Preview'}
:canvas{
width = math.min(width,maxCanvasSize.width),
height = math.min(height,maxCanvasSize.height),
onpaint = function(ev)
local gc = ev.context
-- Draw the editor background with a border first
gc:drawThemeRect("sunken_focused",
Rectangle(0, 0, gc.width, gc.height))
local innerCanvasBounds = Rectangle(border, border,
gc.width - border * 2,
gc.height - border * 2)
-- Clip to the area withing the drawn editor border
-- All drawing operations after taht will only draw within the clipping region
-- This assure that no shape will be drawn over the borders
gc:beginPath()
gc:rect(innerCanvasBounds)
gc:clip()
local adjustedScale = AdjustScale(scale)
ratio=math.min(
gc.width / image.width,
gc.height / image.height)
local destinationBounds = Rectangle(
imagePositionDelta.x +
((gc.width - image.width*ratio) / 2),
imagePositionDelta.y +
((gc.height - image.height*ratio) / 2),
image.width * adjustedScale*ratio,
image.height * adjustedScale*ratio)
-- Fill the canvas with the editor face color
gc.color = app.theme.color.editor_face
gc:fillRect(Rectangle(0, 0, gc.width, gc.height))
-- Draw the black border around the canvas
gc.color = app.theme.color.editor_sprite_border
gc:strokeRect(Rectangle(destinationBounds.x - 1,
destinationBounds.y - 1,
destinationBounds.width + 2,
destinationBounds.height + 2))
-- Draw the shadow under the canvas
gc.color = app.theme.color.editor_sprite_bottom_border
gc:fillRect(Rectangle(destinationBounds.x - 1,
destinationBounds.y + destinationBounds.height +
1, destinationBounds.width + 2, 1))
-- Draw the canvas
gc:drawImage(image, image.bounds, destinationBounds)
end,
onmousemove = function(ev)
if isMouseDown and lastMouse then
imagePositionDelta.x = imagePositionDelta.x -
(lastMouse.x - ev.x)
imagePositionDelta.y = imagePositionDelta.y -
(lastMouse.y - ev.y)
lastMouse = Point(ev.x, ev.y)
dialog:repaint()
end
end,
onmousedown = function(ev)
isMouseDown = ev.button == MouseButton.LEFT
if isMouseDown then lastMouse = Point(ev.x, ev.y) end
end,
onmouseup = function(ev)
isMouseDown = not (ev.button == MouseButton.LEFT)
end,
onwheel = function(ev)
local newScale = scale - ev.deltaY
if newScale == 0 then
if scale == 1 then
newScale = -1
else
newScale = 1
end
end
local oldAdjustedScale = AdjustScale(scale)
local newAdjustedScale = AdjustScale(newScale)
local oldWidth = image.width * oldAdjustedScale * ratio
local newWidth = image.width * newAdjustedScale * ratio
local oldHeight = image.height * oldAdjustedScale * ratio
local newHeight = image.height * newAdjustedScale * ratio
imagePositionDelta.x =
imagePositionDelta.x - (newWidth - oldWidth) / 2
imagePositionDelta.y = imagePositionDelta.y -
(newHeight - oldHeight) / 2
scale = newScale
dialog:repaint()
end
} --
return RepaintImage
end
return PreviewCanvas