33"""
44
55from krita import Krita
6- from PyQt5 .QtCore import Qt
6+ from PyQt5 .QtCore import Qt , pyqtSignal
77from PyQt5 .QtWidgets import (
88 QVBoxLayout ,
99 QHBoxLayout ,
2828)
2929
3030
31- class CommonSettings (QFormLayout ):
32- name = QLineEdit ("spritesheet.png" )
33- directory = QLineEdit ()
34- change_dir = QPushButton (Krita .instance ().icon ("folder" ), None )
35- reset_dir = QPushButton (Krita .instance ().icon ("view-refresh" ), None )
36-
37- unique_frames = QCheckBox ("Only unique frames" )
38- write_texture_atlas = QCheckBox ("Write JSON texture atlas" )
31+ class MainSettings (QFormLayout ):
32+ change_dir_clicked = pyqtSignal ()
33+ reset_dir_clicked = pyqtSignal ()
3934
4035 def __init__ (self ):
4136 super ().__init__ ()
37+ ki = Krita .instance ()
4238
39+ self .name = QLineEdit ("spritesheet.png" )
4340 self .name .setToolTip ("Name of the exported spritesheet file" )
41+
42+ self .directory = QLineEdit ()
4443 self .directory .setToolTip ("Directory to export the spritesheet to" )
4544
46- self .change_dir .setToolTip ("Open a file picker for the export directory" )
47- self .reset_dir .setToolTip (
45+ change_dir = QPushButton (ki .icon ("folder" ), None )
46+ change_dir .setToolTip ("Open a file picker for the export directory" )
47+ change_dir .clicked .connect (self .change_dir_clicked .emit )
48+
49+ reset_dir = QPushButton (ki .icon ("view-refresh" ), None )
50+ reset_dir .setToolTip (
4851 "Reset export directory to the current document's directory"
4952 )
53+ reset_dir .clicked .connect (self .reset_dir_clicked .emit )
5054
55+ self .unique_frames = QCheckBox ("Only unique frames" )
56+ self .write_texture_atlas = QCheckBox ("Write JSON texture atlas" )
5157 self .write_texture_atlas .setToolTip (
5258 "Write a JSON texture atlas that can be used in game frameworks (e.g. Phaser 3)"
5359 )
5460
5561 dir_layout = QHBoxLayout ()
56- dir_layout .addWidget (self .directory )
57- dir_layout .addWidget (self .change_dir )
58- dir_layout .addWidget (self .reset_dir )
62+ for w in (self .directory , change_dir , reset_dir ):
63+ dir_layout .addWidget (w )
5964
6065 self .addRow ("Export name:" , self .name )
6166 self .addRow ("Export directory:" , dir_layout )
@@ -73,48 +78,47 @@ class FramesExport(QGroupBox):
7378 Controls configuration for exporting individual frames as an image sequence.
7479 """
7580
76- base_name = QLineEdit ("sprite" )
77-
78- custom_dir = QCheckBox ("Custom directory" )
79- directory = QLineEdit ()
80- change_dir = QPushButton (Krita .instance ().icon ("folder" ), None )
81- reset_dir = QPushButton (Krita .instance ().icon ("view-refresh" ), None )
82-
83- force_new = QCheckBox ("Force new folder" )
81+ change_dir_clicked = pyqtSignal ()
82+ reset_dir_clicked = pyqtSignal ()
8483
8584 def __init__ (self ):
8685 super ().__init__ ("Export image sequence" )
8786 self .setCheckable (True )
8887 self .setChecked (False )
88+ ki = Krita .instance ()
8989
90- self .toggle_custom_dir ( Qt . Unchecked )
91- self .custom_dir . stateChanged . connect ( self . toggle_custom_dir )
90+ self .base_name = QLineEdit ( "sprite" )
91+ self .custom_dir = QCheckBox ( "Custom directory" )
9292
93+ self .directory = QLineEdit ()
9394 self .directory .setToolTip ("Directory the images will be exported to" )
94- self .change_dir .setToolTip ("Open a file picker for the images directory" )
95- self .reset_dir .setToolTip ("Reset images directory based on the export path" )
9695
96+ change_dir = QPushButton (ki .icon ("folder" ), None )
97+ change_dir .setToolTip ("Open a file picker for the images directory" )
98+ change_dir .clicked .connect (self .change_dir_clicked .emit )
99+
100+ reset_dir = QPushButton (ki .icon ("view-refresh" ), None )
101+ reset_dir .setToolTip ("Reset images directory based on the export path" )
102+ reset_dir .clicked .connect (self .reset_dir_clicked .emit )
103+
104+ self .force_new = QCheckBox ("Force new folder" )
97105 self .force_new .setToolTip (
98106 "If checked, create a new frames folder if one exists.\n Otherwise, write the sprites in the existing folder (may overwrite files)"
99107 )
100108
101109 dir_layout = QHBoxLayout ()
102110 dir_layout .addWidget (self .custom_dir )
103- dir_layout .addWidget (self .directory )
104- dir_layout .addWidget (self .change_dir )
105- dir_layout .addWidget (self .reset_dir )
111+
112+ for w in (self .directory , change_dir , reset_dir ):
113+ w .setEnabled (False )
114+ self .custom_dir .toggled .connect (w .setEnabled )
115+ dir_layout .addWidget (w )
106116
107117 layout = QFormLayout (self )
108118 layout .addRow ("Base name:" , self .base_name )
109119 layout .addRow (dir_layout )
110120 layout .addRow (self .force_new )
111121
112- def toggle_custom_dir (self , state : int ):
113- enabled = state == Qt .Checked
114- self .directory .setEnabled (enabled )
115- self .change_dir .setEnabled (enabled )
116- self .reset_dir .setEnabled (enabled )
117-
118122 def apply_settings (self , exporter : Exporter ):
119123 if not self .isChecked ():
120124 exporter .export_frame_sequence = False
@@ -137,24 +141,23 @@ class SpritePlacement(QFormLayout):
137141 oriented, and how many cells to put in that direction.
138142 """
139143
140- h_dir = QRadioButton ("Horizontal" )
141- columns = QRadioButton ("Columns" )
142- size = QSpinBox (value = DEFAULT_SPACE , minimum = DEFAULT_SPACE )
143-
144144 def __init__ (self ):
145145 super ().__init__ ()
146146 self .setFieldGrowthPolicy (QFormLayout .FieldGrowthPolicy .AllNonFixedFieldsGrow )
147147 self .setHorizontalSpacing (12 )
148148
149+ self .h_dir = QRadioButton ("Horizontal" )
149150 self .h_dir .setChecked (True )
150151 self .h_dir .setToolTip ("Order sprites horizontally" )
151152
152153 v_dir = QRadioButton ("Vertical" )
153154 v_dir .setToolTip ("Order sprites vertically" )
154155
156+ self .size = QSpinBox (value = DEFAULT_SPACE , minimum = DEFAULT_SPACE )
155157 self .size .setSpecialValueText ("Auto" )
156158 self .size .setToolTip ("Number of columns or rows in the spritesheet" )
157159
160+ self .columns = QRadioButton ("Columns" )
158161 self .columns .setChecked (True )
159162 rows = QRadioButton ("Rows" )
160163
@@ -192,16 +195,15 @@ def apply_settings(self, exporter: Exporter):
192195
193196
194197class SpinBoxes (QFormLayout ):
195- start = QSpinBox (value = DEFAULT_TIME , minimum = DEFAULT_TIME , maximum = 9999 )
196- end = QSpinBox (value = DEFAULT_TIME , minimum = DEFAULT_TIME , maximum = 9999 )
197- step = QSpinBox (value = 1 , minimum = 1 )
198-
199198 def __init__ (self ):
200199 super ().__init__ ()
201200
202- self .start .setSpecialValueText ("Auto" )
203- self .end .setSpecialValueText ("Auto" )
204- self .step .setSpecialValueText ("Auto" )
201+ self .start = QSpinBox (value = DEFAULT_TIME , minimum = DEFAULT_TIME , maximum = 9999 )
202+ self .end = QSpinBox (value = DEFAULT_TIME , minimum = DEFAULT_TIME , maximum = 9999 )
203+ self .step = QSpinBox (value = 1 , minimum = 1 )
204+
205+ for spin_box in (self .start , self .end , self .step ):
206+ spin_box .setSpecialValueText ("Auto" )
205207
206208 self .start .setToolTip ("First frame time of the animation (inclusive)" )
207209 self .end .setToolTip ("Last frame time of the animation (inclusive)" )
@@ -227,56 +229,51 @@ class EdgePadding(QFormLayout):
227229 def __init__ (self ):
228230 super ().__init__ ()
229231
230- self .left = self ._make_spin_box ("left" )
231- self .top = self ._make_spin_box ("top" )
232- self .right = self ._make_spin_box ("right" )
233- self .bottom = self ._make_spin_box ("bottom" )
234-
235- self .addRow ("Padding left:" , self .left )
236- self .addRow ("Padding top:" , self .top )
237- self .addRow ("Padding right:" , self .right )
238- self .addRow ("Padding bottom:" , self .bottom )
232+ self .left = self ._add_spin_box ("left" )
233+ self .top = self ._add_spin_box ("top" )
234+ self .right = self ._add_spin_box ("right" )
235+ self .bottom = self ._add_spin_box ("bottom" )
239236
240237 def apply_settings (self , exp : Exporter ) -> None :
241238 exp .pad_left = self .left .value ()
242239 exp .pad_top = self .top .value ()
243240 exp .pad_right = self .right .value ()
244241 exp .pad_bottom = self .bottom .value ()
245242
246- @staticmethod
247- def _make_spin_box (edge : str ) -> QSpinBox :
243+ def _add_spin_box (self , edge : str ) -> QSpinBox :
248244 spin_box = QSpinBox (value = 0 , minimum = - 99 , maximum = 99 )
249245 spin_box .setSuffix ("px" )
250246 spin_box .setToolTip (
251247 f"Pad the { edge } edge of each sprite, or clip it if negative"
252248 )
249+
250+ self .addRow (f"Padding { edge } :" , spin_box )
253251 return spin_box
254252
255253
256254class Dialog (QDialog ):
257- common_settings = CommonSettings ()
258- frames = FramesExport ()
259- edges = EdgePadding ()
260-
261- # Extra settings group
262- layers_as_animation = QCheckBox ("Use layers as animation frames" )
263- placement = SpritePlacement ()
264- frame_times = SpinBoxes ()
265-
266- dialog_buttons = QDialogButtonBox (QDialogButtonBox .Ok | QDialogButtonBox .Cancel )
267-
268255 def __init__ (self ):
269256 super ().__init__ ()
270257 self .setWindowTitle (i18n ("SpritesheetExporter" ))
271258 self .setWindowModality (Qt .NonModal ) # Don't block input to other windows
272259 self .setMinimumSize (425 , 480 )
273260 self .setSizeGripEnabled (True )
274261
262+ self .main_settings = MainSettings ()
263+ self .frames = FramesExport ()
264+ self .edges = EdgePadding ()
265+
266+ # Extra settings group
267+ self .layers_as_animation = QCheckBox ("Use layers as animation frames" )
275268 self .layers_as_animation .setToolTip (
276269 "Treat each layer as a frame instead of using the animation timeline"
277270 )
271+ self .placement = SpritePlacement ()
272+ self .frame_times = SpinBoxes ()
278273
279- self .dialog_buttons .rejected .connect (self .close )
274+ dialog_buttons = QDialogButtonBox (QDialogButtonBox .Ok | QDialogButtonBox .Cancel )
275+ dialog_buttons .accepted .connect (self .accept )
276+ dialog_buttons .rejected .connect (self .reject )
280277
281278 # Setup layouts
282279 spin_boxes = QHBoxLayout ()
@@ -295,7 +292,7 @@ def __init__(self):
295292 extras .addLayout (spin_boxes )
296293
297294 root_layout = QVBoxLayout (self ) # the box holding everything
298- root_layout .addLayout (self .common_settings )
295+ root_layout .addLayout (self .main_settings )
299296 root_layout .addWidget (self .frames )
300297 root_layout .addWidget (extra_settings )
301- root_layout .addWidget (self . dialog_buttons )
298+ root_layout .addWidget (dialog_buttons )
0 commit comments