setiastrosuitepro 1.6.4__py3-none-any.whl → 1.7.1.post2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of setiastrosuitepro might be problematic. Click here for more details.
- setiastro/images/TextureClarity.svg +56 -0
- setiastro/images/abeicon.svg +16 -0
- setiastro/images/acv_icon.png +0 -0
- setiastro/images/colorwheel.svg +97 -0
- setiastro/images/cosmic.svg +40 -0
- setiastro/images/cosmicsat.svg +24 -0
- setiastro/images/first_quarter.png +0 -0
- setiastro/images/full_moon.png +0 -0
- setiastro/images/graxpert.svg +19 -0
- setiastro/images/last_quarter.png +0 -0
- setiastro/images/linearfit.svg +32 -0
- setiastro/images/narrowbandnormalization.png +0 -0
- setiastro/images/new_moon.png +0 -0
- setiastro/images/pixelmath.svg +42 -0
- setiastro/images/planetarystacker.png +0 -0
- setiastro/images/waning_crescent_1.png +0 -0
- setiastro/images/waning_crescent_2.png +0 -0
- setiastro/images/waning_crescent_3.png +0 -0
- setiastro/images/waning_crescent_4.png +0 -0
- setiastro/images/waning_crescent_5.png +0 -0
- setiastro/images/waning_gibbous_1.png +0 -0
- setiastro/images/waning_gibbous_2.png +0 -0
- setiastro/images/waning_gibbous_3.png +0 -0
- setiastro/images/waning_gibbous_4.png +0 -0
- setiastro/images/waning_gibbous_5.png +0 -0
- setiastro/images/waxing_crescent_1.png +0 -0
- setiastro/images/waxing_crescent_2.png +0 -0
- setiastro/images/waxing_crescent_3.png +0 -0
- setiastro/images/waxing_crescent_4.png +0 -0
- setiastro/images/waxing_crescent_5.png +0 -0
- setiastro/images/waxing_gibbous_1.png +0 -0
- setiastro/images/waxing_gibbous_2.png +0 -0
- setiastro/images/waxing_gibbous_3.png +0 -0
- setiastro/images/waxing_gibbous_4.png +0 -0
- setiastro/images/waxing_gibbous_5.png +0 -0
- setiastro/qml/ResourceMonitor.qml +84 -82
- setiastro/saspro/__main__.py +20 -1
- setiastro/saspro/_generated/build_info.py +2 -2
- setiastro/saspro/abe.py +37 -4
- setiastro/saspro/aberration_ai.py +364 -33
- setiastro/saspro/aberration_ai_preset.py +29 -3
- setiastro/saspro/acv_exporter.py +379 -0
- setiastro/saspro/add_stars.py +33 -6
- setiastro/saspro/astrospike_python.py +45 -3
- setiastro/saspro/backgroundneutral.py +108 -40
- setiastro/saspro/blemish_blaster.py +4 -1
- setiastro/saspro/blink_comparator_pro.py +150 -55
- setiastro/saspro/clahe.py +4 -1
- setiastro/saspro/continuum_subtract.py +4 -1
- setiastro/saspro/convo.py +13 -7
- setiastro/saspro/cosmicclarity.py +129 -18
- setiastro/saspro/crop_dialog_pro.py +123 -7
- setiastro/saspro/curve_editor_pro.py +181 -64
- setiastro/saspro/curves_preset.py +249 -47
- setiastro/saspro/doc_manager.py +245 -15
- setiastro/saspro/exoplanet_detector.py +120 -28
- setiastro/saspro/frequency_separation.py +1158 -204
- setiastro/saspro/ghs_dialog_pro.py +81 -16
- setiastro/saspro/graxpert.py +1 -0
- setiastro/saspro/gui/main_window.py +706 -264
- setiastro/saspro/gui/mixins/dock_mixin.py +245 -24
- setiastro/saspro/gui/mixins/file_mixin.py +35 -16
- setiastro/saspro/gui/mixins/menu_mixin.py +35 -1
- setiastro/saspro/gui/mixins/theme_mixin.py +160 -14
- setiastro/saspro/gui/mixins/toolbar_mixin.py +499 -24
- setiastro/saspro/gui/mixins/update_mixin.py +138 -36
- setiastro/saspro/gui/mixins/view_mixin.py +42 -0
- setiastro/saspro/halobgon.py +4 -0
- setiastro/saspro/histogram.py +184 -8
- setiastro/saspro/image_combine.py +4 -0
- setiastro/saspro/image_peeker_pro.py +4 -0
- setiastro/saspro/imageops/narrowband_normalization.py +816 -0
- setiastro/saspro/imageops/serloader.py +1345 -0
- setiastro/saspro/imageops/starbasedwhitebalance.py +23 -52
- setiastro/saspro/imageops/stretch.py +582 -62
- setiastro/saspro/isophote.py +4 -0
- setiastro/saspro/layers.py +13 -9
- setiastro/saspro/layers_dock.py +183 -3
- setiastro/saspro/legacy/image_manager.py +154 -20
- setiastro/saspro/legacy/numba_utils.py +68 -48
- setiastro/saspro/legacy/xisf.py +240 -98
- setiastro/saspro/live_stacking.py +203 -82
- setiastro/saspro/luminancerecombine.py +228 -27
- setiastro/saspro/mask_creation.py +174 -15
- setiastro/saspro/mfdeconv.py +113 -35
- setiastro/saspro/mfdeconvcudnn.py +119 -70
- setiastro/saspro/mfdeconvsport.py +112 -35
- setiastro/saspro/morphology.py +4 -0
- setiastro/saspro/multiscale_decomp.py +81 -29
- setiastro/saspro/narrowband_normalization.py +1618 -0
- setiastro/saspro/numba_utils.py +72 -57
- setiastro/saspro/ops/commands.py +18 -18
- setiastro/saspro/ops/script_editor.py +10 -2
- setiastro/saspro/ops/scripts.py +122 -0
- setiastro/saspro/perfect_palette_picker.py +37 -3
- setiastro/saspro/plate_solver.py +84 -49
- setiastro/saspro/psf_viewer.py +119 -37
- setiastro/saspro/remove_green.py +1 -1
- setiastro/saspro/resources.py +73 -0
- setiastro/saspro/rgbalign.py +460 -12
- setiastro/saspro/selective_color.py +4 -1
- setiastro/saspro/ser_stack_config.py +82 -0
- setiastro/saspro/ser_stacker.py +2321 -0
- setiastro/saspro/ser_stacker_dialog.py +1838 -0
- setiastro/saspro/ser_tracking.py +206 -0
- setiastro/saspro/serviewer.py +1625 -0
- setiastro/saspro/sfcc.py +662 -216
- setiastro/saspro/shortcuts.py +171 -33
- setiastro/saspro/signature_insert.py +692 -33
- setiastro/saspro/stacking_suite.py +1347 -485
- setiastro/saspro/star_alignment.py +247 -123
- setiastro/saspro/star_spikes.py +4 -0
- setiastro/saspro/star_stretch.py +38 -3
- setiastro/saspro/stat_stretch.py +892 -129
- setiastro/saspro/subwindow.py +787 -363
- setiastro/saspro/supernovaasteroidhunter.py +1 -1
- setiastro/saspro/texture_clarity.py +593 -0
- setiastro/saspro/wavescale_hdr.py +4 -1
- setiastro/saspro/wavescalede.py +4 -1
- setiastro/saspro/whitebalance.py +84 -12
- setiastro/saspro/widgets/common_utilities.py +28 -21
- setiastro/saspro/widgets/resource_monitor.py +209 -111
- setiastro/saspro/widgets/spinboxes.py +10 -13
- setiastro/saspro/wimi.py +27 -656
- setiastro/saspro/wims.py +13 -3
- setiastro/saspro/xisf.py +101 -11
- {setiastrosuitepro-1.6.4.dist-info → setiastrosuitepro-1.7.1.post2.dist-info}/METADATA +4 -2
- {setiastrosuitepro-1.6.4.dist-info → setiastrosuitepro-1.7.1.post2.dist-info}/RECORD +132 -87
- {setiastrosuitepro-1.6.4.dist-info → setiastrosuitepro-1.7.1.post2.dist-info}/WHEEL +0 -0
- {setiastrosuitepro-1.6.4.dist-info → setiastrosuitepro-1.7.1.post2.dist-info}/entry_points.txt +0 -0
- {setiastrosuitepro-1.6.4.dist-info → setiastrosuitepro-1.7.1.post2.dist-info}/licenses/LICENSE +0 -0
- {setiastrosuitepro-1.6.4.dist-info → setiastrosuitepro-1.7.1.post2.dist-info}/licenses/license.txt +0 -0
|
@@ -9,12 +9,30 @@ from __future__ import annotations
|
|
|
9
9
|
from typing import TYPE_CHECKING
|
|
10
10
|
|
|
11
11
|
from PyQt6.QtCore import Qt, QTimer
|
|
12
|
-
from PyQt6.QtGui import QBrush, QColor, QFont, QPalette
|
|
13
|
-
from PyQt6.QtWidgets import QApplication
|
|
12
|
+
from PyQt6.QtGui import QBrush, QColor, QFont, QPalette, QPainter, QPixmap, QIcon
|
|
13
|
+
from PyQt6.QtWidgets import QApplication, QLabel, QWidget
|
|
14
14
|
|
|
15
15
|
if TYPE_CHECKING:
|
|
16
16
|
pass
|
|
17
17
|
|
|
18
|
+
def _force_mdi_subwindow_flags(sw):
|
|
19
|
+
f = sw.windowFlags()
|
|
20
|
+
|
|
21
|
+
# Clear only the *window type* bits (NOT random low bits)
|
|
22
|
+
f &= ~Qt.WindowType.WindowType_Mask
|
|
23
|
+
|
|
24
|
+
# Force true MDI child type
|
|
25
|
+
f |= Qt.WindowType.SubWindow
|
|
26
|
+
|
|
27
|
+
# Add desired buttons/hints
|
|
28
|
+
f |= (Qt.WindowType.CustomizeWindowHint |
|
|
29
|
+
Qt.WindowType.WindowTitleHint |
|
|
30
|
+
Qt.WindowType.WindowSystemMenuHint |
|
|
31
|
+
Qt.WindowType.WindowMinimizeButtonHint |
|
|
32
|
+
Qt.WindowType.WindowMaximizeButtonHint |
|
|
33
|
+
Qt.WindowType.WindowCloseButtonHint)
|
|
34
|
+
|
|
35
|
+
sw.setWindowFlags(f)
|
|
18
36
|
|
|
19
37
|
class ThemeMixin:
|
|
20
38
|
"""
|
|
@@ -88,7 +106,7 @@ class ThemeMixin:
|
|
|
88
106
|
app.setPalette(self._gray_palette())
|
|
89
107
|
app.setStyleSheet(
|
|
90
108
|
"QToolTip { color: #f0f0f0; background-color: #3a3a3a; border: 1px solid #5a5a5a; }"
|
|
91
|
-
)
|
|
109
|
+
)
|
|
92
110
|
elif mode == "light":
|
|
93
111
|
app.setPalette(self._light_palette())
|
|
94
112
|
app.setStyleSheet(
|
|
@@ -119,6 +137,11 @@ class ThemeMixin:
|
|
|
119
137
|
self._repolish_top_levels()
|
|
120
138
|
self._apply_workspace_theme()
|
|
121
139
|
self._style_mdi_titlebars()
|
|
140
|
+
|
|
141
|
+
try:
|
|
142
|
+
self._retint_zoom_icons()
|
|
143
|
+
except Exception:
|
|
144
|
+
pass
|
|
122
145
|
self._menu_view_panels = None
|
|
123
146
|
|
|
124
147
|
try:
|
|
@@ -139,26 +162,149 @@ class ThemeMixin:
|
|
|
139
162
|
w.setUpdatesEnabled(True)
|
|
140
163
|
|
|
141
164
|
def _style_mdi_titlebars(self):
|
|
142
|
-
"""Apply theme-specific styles to MDI subwindow titlebars."""
|
|
143
165
|
mode = self._theme_mode()
|
|
166
|
+
|
|
144
167
|
if mode == "dark":
|
|
145
|
-
base = "#1b1b1b"
|
|
146
|
-
active = "#242424"
|
|
168
|
+
base = "#1b1b1b"
|
|
169
|
+
active = "#242424"
|
|
147
170
|
fg = "#dcdcdc"
|
|
148
171
|
elif mode in ("gray", "custom"):
|
|
149
172
|
base = "#3a3a3a"
|
|
150
173
|
active = "#454545"
|
|
151
174
|
fg = "#f0f0f0"
|
|
152
175
|
else:
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
176
|
+
base = "#eaeaea"
|
|
177
|
+
active = "#ffffff"
|
|
178
|
+
fg = "#141414"
|
|
156
179
|
|
|
180
|
+
# style *our* titlebar only
|
|
157
181
|
self.mdi.setStyleSheet(f"""
|
|
158
|
-
|
|
159
|
-
|
|
182
|
+
QWidget#sas_mdi_titlebar {{
|
|
183
|
+
background: {base};
|
|
184
|
+
}}
|
|
185
|
+
QWidget#sas_mdi_titlebar[active="true"] {{
|
|
186
|
+
background: {active};
|
|
187
|
+
}}
|
|
188
|
+
QLabel#sas_mdi_title_label {{
|
|
189
|
+
color: {fg};
|
|
190
|
+
background: transparent;
|
|
191
|
+
}}
|
|
192
|
+
QWidget#sas_mdi_titlebar QToolButton {{
|
|
193
|
+
color: {fg};
|
|
194
|
+
background: transparent;
|
|
195
|
+
}}
|
|
196
|
+
QWidget#sas_mdi_titlebar QToolButton:hover {{
|
|
197
|
+
background: rgba(255,255,255,0.10);
|
|
198
|
+
}}
|
|
160
199
|
""")
|
|
161
200
|
|
|
201
|
+
|
|
202
|
+
def _fix_mdi_titlebar_emboss(self, fg_hex: str):
|
|
203
|
+
"""
|
|
204
|
+
Fusion/Windows style can draw embossed title text (two-pass).
|
|
205
|
+
In dark themes that can become white-on-white -> 'double text'.
|
|
206
|
+
Force the shadow/emboss colors on the *titlebar widget only*.
|
|
207
|
+
"""
|
|
208
|
+
try:
|
|
209
|
+
fg = QColor(fg_hex)
|
|
210
|
+
except Exception:
|
|
211
|
+
fg = QColor(240, 240, 240)
|
|
212
|
+
|
|
213
|
+
for sw in self.mdi.subWindowList():
|
|
214
|
+
try:
|
|
215
|
+
tb = sw.findChild(QWidget, "qt_mdi_titlebar")
|
|
216
|
+
if tb is None:
|
|
217
|
+
continue
|
|
218
|
+
|
|
219
|
+
pal = tb.palette()
|
|
220
|
+
|
|
221
|
+
# Main text
|
|
222
|
+
pal.setColor(QPalette.ColorRole.WindowText, fg)
|
|
223
|
+
pal.setColor(QPalette.ColorRole.Text, fg)
|
|
224
|
+
pal.setColor(QPalette.ColorRole.ButtonText, fg)
|
|
225
|
+
|
|
226
|
+
# Critical: make the embossed/shadow pass dark
|
|
227
|
+
dark = QColor(0, 0, 0)
|
|
228
|
+
pal.setColor(QPalette.ColorRole.Light, dark)
|
|
229
|
+
pal.setColor(QPalette.ColorRole.Midlight, dark)
|
|
230
|
+
pal.setColor(QPalette.ColorRole.Dark, dark)
|
|
231
|
+
pal.setColor(QPalette.ColorRole.Shadow, dark)
|
|
232
|
+
|
|
233
|
+
tb.setPalette(pal)
|
|
234
|
+
|
|
235
|
+
# Also push to the label if present (some styles read it from label)
|
|
236
|
+
lbl = tb.findChild(QLabel)
|
|
237
|
+
if lbl is not None:
|
|
238
|
+
lbl.setPalette(pal)
|
|
239
|
+
except Exception:
|
|
240
|
+
pass
|
|
241
|
+
|
|
242
|
+
def _tint_icon(self, icon: QIcon, color: QColor) -> QIcon:
|
|
243
|
+
"""
|
|
244
|
+
Take an existing icon (often fromTheme) and force a single-color glyph.
|
|
245
|
+
Sets Normal and Active to the same tinted pixmaps to prevent hover flipping.
|
|
246
|
+
"""
|
|
247
|
+
if icon.isNull():
|
|
248
|
+
return icon
|
|
249
|
+
|
|
250
|
+
out = QIcon()
|
|
251
|
+
sizes = [16, 20, 24, 32, 48, 64]
|
|
252
|
+
|
|
253
|
+
for sz in sizes:
|
|
254
|
+
pm = icon.pixmap(sz, sz, QIcon.Mode.Normal, QIcon.State.Off)
|
|
255
|
+
if pm.isNull():
|
|
256
|
+
continue
|
|
257
|
+
|
|
258
|
+
tinted = QPixmap(pm.size())
|
|
259
|
+
tinted.fill(Qt.GlobalColor.transparent)
|
|
260
|
+
|
|
261
|
+
p = QPainter(tinted)
|
|
262
|
+
p.setRenderHint(QPainter.RenderHint.Antialiasing, True)
|
|
263
|
+
p.setRenderHint(QPainter.RenderHint.SmoothPixmapTransform, True)
|
|
264
|
+
|
|
265
|
+
# Use the original alpha as a mask, fill with our color
|
|
266
|
+
p.drawPixmap(0, 0, pm)
|
|
267
|
+
p.setCompositionMode(QPainter.CompositionMode.CompositionMode_SourceIn)
|
|
268
|
+
p.fillRect(tinted.rect(), color)
|
|
269
|
+
p.end()
|
|
270
|
+
|
|
271
|
+
# Normal + Active -> same pixmap (prevents hover flip)
|
|
272
|
+
out.addPixmap(tinted, QIcon.Mode.Normal, QIcon.State.Off)
|
|
273
|
+
out.addPixmap(tinted, QIcon.Mode.Active, QIcon.State.Off)
|
|
274
|
+
|
|
275
|
+
# Disabled: slightly dimmer (optional)
|
|
276
|
+
dis = QColor(color)
|
|
277
|
+
dis.setAlphaF(0.45)
|
|
278
|
+
dispm = QPixmap(tinted.size())
|
|
279
|
+
dispm.fill(Qt.GlobalColor.transparent)
|
|
280
|
+
p2 = QPainter(dispm)
|
|
281
|
+
p2.drawPixmap(0, 0, tinted)
|
|
282
|
+
p2.setCompositionMode(QPainter.CompositionMode.CompositionMode_SourceIn)
|
|
283
|
+
p2.fillRect(dispm.rect(), dis)
|
|
284
|
+
p2.end()
|
|
285
|
+
out.addPixmap(dispm, QIcon.Mode.Disabled, QIcon.State.Off)
|
|
286
|
+
|
|
287
|
+
return out
|
|
288
|
+
|
|
289
|
+
def _retint_zoom_icons(self):
|
|
290
|
+
"""
|
|
291
|
+
Retint only the zoom actions (the ones built from QIcon.fromTheme).
|
|
292
|
+
Call after app palette is applied.
|
|
293
|
+
"""
|
|
294
|
+
pal = QApplication.palette()
|
|
295
|
+
glyph = pal.color(QPalette.ColorRole.ButtonText) # or Text; ButtonText tends to match toolbars well
|
|
296
|
+
|
|
297
|
+
for name in ("act_zoom_out", "act_zoom_in", "act_zoom_1_1", "act_zoom_fit"):
|
|
298
|
+
act = getattr(self, name, None)
|
|
299
|
+
if act is None:
|
|
300
|
+
continue
|
|
301
|
+
|
|
302
|
+
# stash original once so repeated theme flips don't re-tint a tinted icon
|
|
303
|
+
if not hasattr(act, "_base_icon"):
|
|
304
|
+
act._base_icon = act.icon()
|
|
305
|
+
|
|
306
|
+
act.setIcon(self._tint_icon(act._base_icon, glyph))
|
|
307
|
+
|
|
162
308
|
def _dark_palette(self) -> QPalette:
|
|
163
309
|
"""Create a dark theme palette."""
|
|
164
310
|
p = QPalette()
|
|
@@ -172,7 +318,7 @@ class ThemeMixin:
|
|
|
172
318
|
hi = QColor(30, 144, 255) # highlight (dodger blue)
|
|
173
319
|
|
|
174
320
|
p.setColor(QPalette.ColorRole.Window, panel)
|
|
175
|
-
p.setColor(QPalette.ColorRole.WindowText,
|
|
321
|
+
p.setColor(QPalette.ColorRole.WindowText, QColor(255, 255, 255))
|
|
176
322
|
p.setColor(QPalette.ColorRole.Base, bg)
|
|
177
323
|
p.setColor(QPalette.ColorRole.AlternateBase, altbase)
|
|
178
324
|
p.setColor(QPalette.ColorRole.ToolTipBase, panel)
|
|
@@ -270,7 +416,7 @@ class ThemeMixin:
|
|
|
270
416
|
link = QColor(120, 170, 255)
|
|
271
417
|
linkv = QColor(180, 150, 255)
|
|
272
418
|
hi = QColor(95, 145, 230)
|
|
273
|
-
hitxt = QColor(
|
|
419
|
+
hitxt = QColor(20, 20, 20)
|
|
274
420
|
|
|
275
421
|
# Core roles
|
|
276
422
|
p.setColor(QPalette.ColorRole.Window, window)
|
|
@@ -300,7 +446,7 @@ class ThemeMixin:
|
|
|
300
446
|
p.setColor(QPalette.ColorGroup.Disabled, QPalette.ColorRole.WindowText, dis)
|
|
301
447
|
p.setColor(QPalette.ColorGroup.Disabled, QPalette.ColorRole.Base, QColor(58, 58, 58))
|
|
302
448
|
p.setColor(QPalette.ColorGroup.Disabled, QPalette.ColorRole.Highlight, QColor(80, 80, 80))
|
|
303
|
-
p.setColor(QPalette.ColorGroup.Disabled, QPalette.ColorRole.HighlightedText, QColor(
|
|
449
|
+
p.setColor(QPalette.ColorGroup.Disabled, QPalette.ColorRole.HighlightedText, QColor(20, 20, 20))
|
|
304
450
|
|
|
305
451
|
return p
|
|
306
452
|
|