-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
214 lines (189 loc) · 7.34 KB
/
main.py
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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
#!/usr/bin/env python
'''
formerly (from KivyPixels) kivyspritetouch.py
based on http://kivy.org/docs/examples/gen__canvas__fbo_canvas__py.html
'''
from __future__ import print_function
import sys
import platform
try:
import kivy # noqa: F401
except ImportError:
print("This program requires kivy. Try:", file=sys.stderr)
print("python -m venv .venv", file=sys.stderr)
if platform.system() == "Windows":
print(".\\.venv\\Scripts\\activate.ps1", file=sys.stderr)
else:
print("source .venv/bin/activate", file=sys.stderr)
print("pip install --upgrade pip", file=sys.stderr)
print("pip install --upgrade pip", file=sys.stderr)
print("pip install --upgrade setuptools wheel", file=sys.stderr)
print("pip install --upgrade kivy", file=sys.stderr)
sys.exit(1)
# from kivy.uix.boxlayout import BoxLayout
# from kivy.uix.colorpicker import ColorPicker
# from kivy.uix.button import Button
# from kivy.graphics.instructions import InstructionGroup
# from kivy.graphics import Color, Rectangle
# from kivy.graphics import Line
from kivymd.app import MDApp
# from kivy.core.window import Window
# from kivy.animation import Animation
# from kivy.factory import Factory
from kivymd.uix.button import MDFloatingActionButton
# from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.uix.floatlayout import MDFloatLayout
from kivy.metrics import dp
from kivy.clock import Clock
# from kivy.graphics import Ellipse
# from kivy.uix.image import Image
# from kivy.core.image import Image as CoreImage
# import os
# from kivy.graphics import Point
# import random
# TODO: implement resize
# from array import array
# from pythonpixels import PPImage
# from pythonpixels import PPColor
# class MainForm(BoxLayout):
from rotocanvas.kivypixels.pixelwidget import PixelWidget
from rotocanvas.kivypixels.colorpopup import ColorPopup
from rotocanvas import (
echo0,
)
class RotoCanvasApp(MDApp):
def build(self):
self.pixelWidget = None
self.mainWidget = MDFloatLayout(
# orientation='horizontal',
md_bg_color='black',
)
self.pixelWidget = PixelWidget()
self.mainWidget.add_widget(self.pixelWidget)
self.spacing = dp(8)
self.margin = dp(8)
# spacing = self.spacing
# margin = self.margin
m_ratio = .01 # Fixed later
'''
self.buttonsLayout = MDBoxLayout(
orientation='vertical',
size_hint=(.1, 1.0),
spacing=spacing,
padding=(margin, margin, margin, margin),
)
self.mainWidget.add_widget(self.buttonsLayout)
'''
self.paletteWidget = ColorPopup(self.choseColor,
size_hint=(.9, .8))
self.right_edge_ratio = 1.0 - m_ratio # fixed later
self.saveButton = MDFloatingActionButton(
text="Save",
icon='content-save',
on_press=self.pixelWidget.onSaveButtonClick,
pos_hint={
"right": self.right_edge_ratio,
"top": 1.0 - m_ratio
},
# ^ fixed later.
)
self.mainWidget.add_widget(self.saveButton)
self.previous_button = None
self.initialized = False
Clock.schedule_once(self.add_relative_widgets, 1)
return self.mainWidget
def add_relative_widgets(self, _):
'''Add widgets that are positioned based on ratios.
This must be scheduled since the ratio of the widget width to
the window's greatest dimension has to be determined, and those
dimensions can only be determined after the window is displayed
for at least one frame.
Args:
_ (EventArgs): (unused) automatically set by Kivy schedule
methods.
'''
self.initialized = True
self.pack_button(self.saveButton, add=False)
self.paletteButton = MDFloatingActionButton(
text="Palette",
icon='palette',
on_press=self.paletteWidget.open,
)
self.pack_button(self.paletteButton)
'''
# self.colorButton = MDFloatingActionButton(text="Color",
# id="colorButton")
# self.buttonsLayout.add_widget(self.colorButton)
# self.colorButton.bind(on_press=self.pixelWidget.onColorButtonClick)
# self.eraserButton = MDFloatingActionButton(text="Eraser",
# id="eraserButton")
# self.buttonsLayout.add_widget(self.eraserButton)
# self.eraserButton.bind(
# on_press=self.pixelWidget.onEraserButtonClick)
'''
def pack_button(self, button, add=True):
"""Pack a button with options specific to this program's layout
Args:
button (Widget): The widget to add.
add (Optional[bool]): Add to mainWidget. Defaults to True.
"""
if not self.initialized:
raise RuntimeError(
"pack_button can only work after at least 1 frame."
)
spacing = self.spacing
margin = self.margin
greater_dim = self.mainWidget.width
if self.mainWidget.height > self.mainWidget.width:
greater_dim = self.mainWidget.height
b_ratio = self.saveButton.width / greater_dim
# ^ For this to work, saveButton must be added on a frame
# *before* this method runs!
s_ratio = spacing / greater_dim
m_ratio = margin / greater_dim
r_ratio = 1.0 - m_ratio
f_ratio = 1.0 - m_ratio # first button (bottom)
echo0(f"\nbutton: {button.text}")
echo0(f"s_ratio: {s_ratio}") # ~.01
echo0(f"m_ratio: {m_ratio}") # ~.01
echo0(f"r_ratio: {r_ratio}") # ~.99
echo0(f"b_ratio: {b_ratio}") # ~.07
echo0(f"f_ratio: {f_ratio}") # ~.01
if self.previous_button is not None:
echo0(f"self.previous_button.pos: {self.previous_button.pos}")
echo0(f"self.previous_button.width: {self.previous_button.width}")
echo0(f"self.mainWidget.width: {self.mainWidget.width}")
top = f_ratio
if self.previous_button is not None:
prev_bottom = (self.previous_button.pos[1]
/ self.mainWidget.height)
echo0(f"prev_bottom: {prev_bottom}")
top = prev_bottom - m_ratio
echo0(f"top: {top}")
button.pos_hint = {
"top": top, # bottom does not work on MDFloatLayout
"right": f_ratio,
}
if add:
self.mainWidget.add_widget(button)
self.previous_button = button
def choseColor(self, color):
if color is not None:
self.pixelWidget.viewImage.setBrushColor(color)
def saveBrush(self):
if self.brushImage is not None:
self.brushImage.saveAs(
"debug save (brush).png",
texture_flipped=self.texture_flipped,
)
# normalSize = self.brushImage.get_norm_image_size()
# self.brushImage.size = (int(normalSize[0]), int(normalSize[1]))
# data = bytes(self.brushImage.data)
# # convert from bytearray to bytes
# surface = pygame.image.fromstring(data,
# self.brushImage.size,
# 'RGBA',
# True)
# pygame.image.save(surface, "debug save (brush).png")
if __name__ == "__main__":
RotoCanvasApp().run()