batoolset-gui 0.2.0__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.
- batoolset/GUI/__init__.py +0 -0
- batoolset/GUI/customdialog.py +136 -0
- batoolset/GUI/exception_handler.py +74 -0
- batoolset/GUI/list_gui.py +514 -0
- batoolset/GUI/multi_image_display.py +1038 -0
- batoolset/GUI/open.py +325 -0
- batoolset/GUI/overlay_hints.py +45 -0
- batoolset/GUI/paint2.py +1369 -0
- batoolset/GUI/scrollablepaint.py +1165 -0
- batoolset/dialogs/__init__.py +0 -0
- batoolset/dialogs/opensave.py +228 -0
- batoolset/drawings/__init__.py +0 -0
- batoolset/drawings/math_text.py +294 -0
- batoolset/drawings/pdf_svg_renderer.py +376 -0
- batoolset/drawings/shapes/Position.py +183 -0
- batoolset/drawings/shapes/__init__.py +0 -0
- batoolset/drawings/shapes/automated_alignment_drawing_refactored.py +346 -0
- batoolset/drawings/shapes/circle2d.py +99 -0
- batoolset/drawings/shapes/compute_optimal_size_all_merged.py +328 -0
- batoolset/drawings/shapes/ellipse2d.py +336 -0
- batoolset/drawings/shapes/freehand2d.py +235 -0
- batoolset/drawings/shapes/group.py +1985 -0
- batoolset/drawings/shapes/image2d.py +3157 -0
- batoolset/drawings/shapes/line2d.py +579 -0
- batoolset/drawings/shapes/point2d.py +257 -0
- batoolset/drawings/shapes/polygon2d.py +357 -0
- batoolset/drawings/shapes/polyline2d.py +235 -0
- batoolset/drawings/shapes/rect2d.py +388 -0
- batoolset/drawings/shapes/rectangle2d.py +601 -0
- batoolset/drawings/shapes/scalebar.py +310 -0
- batoolset/drawings/shapes/serializablefont.py +133 -0
- batoolset/drawings/shapes/serializableguiparams.py +14 -0
- batoolset/drawings/shapes/square2d.py +102 -0
- batoolset/drawings/shapes/test_publication_style.py +220 -0
- batoolset/drawings/shapes/textorientation.py +45 -0
- batoolset/drawings/shapes/tools.py +467 -0
- batoolset/drawings/shapes/transform2D.py +350 -0
- batoolset/drawings/shapes/txt2d.py +615 -0
- batoolset/drawings/svg_clip_renderer.py +247 -0
- batoolset/drawings/svg_embed.py +165 -0
- batoolset/drawings/svg_text_renderer.py +183 -0
- batoolset/drawings/widgets/__init__.py +0 -0
- batoolset/drawings/widgets/col.py +343 -0
- batoolset/drawings/widgets/image_group.py +248 -0
- batoolset/drawings/widgets/image_organizer.py +96 -0
- batoolset/drawings/widgets/paint.py +184 -0
- batoolset/drawings/widgets/vectorial.py +256 -0
- batoolset/figure/__init__.py +0 -0
- batoolset/figure/alignment.py +822 -0
- batoolset/figure/column.py +1117 -0
- batoolset/figure/fig_tools.py +285 -0
- batoolset/figure/minimal_debugger_scale_etc.py +139 -0
- batoolset/figure/panel.py +697 -0
- batoolset/figure/row.py +852 -0
- batoolset/figure/user_selection.py +287 -0
- batoolset/icons/__init__.py +0 -0
- batoolset/icons/tools.py +248 -0
- batoolset/luts/__init__.py +0 -0
- batoolset/luts/lut_minimal_test.py +1308 -0
- batoolset/luts/lutcreatorfromformula.py +209 -0
- batoolset/luts/luteditor.py +243 -0
- batoolset/pyqts/__init__.py +0 -0
- batoolset/pyqts/pleasewaitdialog.py +14 -0
- batoolset/pyqts/tools.py +760 -0
- batoolset/serializations/__init__.py +0 -0
- batoolset/serializations/tools.py +1338 -0
- batoolset/theme.py +647 -0
- batoolset/uis/__init__.py +0 -0
- batoolset/uis/blinker.py +56 -0
- batoolset_gui-0.2.0.dist-info/METADATA +54 -0
- batoolset_gui-0.2.0.dist-info/RECORD +74 -0
- batoolset_gui-0.2.0.dist-info/WHEEL +5 -0
- batoolset_gui-0.2.0.dist-info/licenses/LICENSE +24 -0
- batoolset_gui-0.2.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
from batoolset.pyqts.tools import updateLutLabelPreview
|
|
2
|
+
from batoolset.settings.global_settings import set_UI # set the UI to qtpy
|
|
3
|
+
set_UI()
|
|
4
|
+
import sys
|
|
5
|
+
import random
|
|
6
|
+
from qtpy.QtWidgets import (
|
|
7
|
+
QApplication, QWidget, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit,
|
|
8
|
+
QPushButton, QTextEdit, QGroupBox, QMessageBox, QScrollArea, QSizePolicy,
|
|
9
|
+
)
|
|
10
|
+
from qtpy.QtCore import Qt
|
|
11
|
+
from qtpy.QtGui import QFont
|
|
12
|
+
from batoolset.luts.lut_minimal_test import PaletteCreator, list_available_luts, apply_lut, lsm_LUT_to_numpy
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class PaletteFormulaEditor(QWidget):
|
|
16
|
+
def __init__(self, parent=None):
|
|
17
|
+
super().__init__(parent)
|
|
18
|
+
self.palette = None
|
|
19
|
+
|
|
20
|
+
# Initialize the UI components
|
|
21
|
+
self.initUI()
|
|
22
|
+
|
|
23
|
+
def initUI(self):
|
|
24
|
+
layout = QVBoxLayout()
|
|
25
|
+
|
|
26
|
+
# Preview Panel
|
|
27
|
+
self.preview_group = QGroupBox("Preview")
|
|
28
|
+
preview_layout = QVBoxLayout()
|
|
29
|
+
# Align the QLabel to the center
|
|
30
|
+
|
|
31
|
+
self.previewLabel = QLabel()
|
|
32
|
+
# self.previewLabel.setFixedSize(750,16)
|
|
33
|
+
preview_layout.addWidget(self.previewLabel)
|
|
34
|
+
preview_layout.setAlignment(self.previewLabel, Qt.AlignCenter)
|
|
35
|
+
self.preview_group.setLayout(preview_layout)
|
|
36
|
+
layout.addWidget(self.preview_group)
|
|
37
|
+
|
|
38
|
+
# Formula Panel
|
|
39
|
+
self.formula_group = QGroupBox("Formula")
|
|
40
|
+
formula_layout = QVBoxLayout()
|
|
41
|
+
|
|
42
|
+
h_layout1 = QHBoxLayout()
|
|
43
|
+
h_layout2 = QHBoxLayout()
|
|
44
|
+
|
|
45
|
+
# Red Formula
|
|
46
|
+
self.redLabel = QLabel("Red Formula:")
|
|
47
|
+
self.redFormula = QLineEdit("34")
|
|
48
|
+
self.redFormula.textChanged.connect(self.update_palette)
|
|
49
|
+
|
|
50
|
+
# Green Formula
|
|
51
|
+
self.greenLabel = QLabel("Green Formula:")
|
|
52
|
+
self.greenFormula = QLineEdit("35")
|
|
53
|
+
self.greenFormula.textChanged.connect(self.update_palette)
|
|
54
|
+
|
|
55
|
+
# Blue Formula
|
|
56
|
+
self.blueLabel = QLabel("Blue Formula:")
|
|
57
|
+
self.blueFormula = QLineEdit("36")
|
|
58
|
+
self.blueFormula.textChanged.connect(self.update_palette)
|
|
59
|
+
|
|
60
|
+
# Add to layout
|
|
61
|
+
h_layout1.addWidget(self.redLabel)
|
|
62
|
+
h_layout1.addWidget(self.redFormula)
|
|
63
|
+
h_layout1.addWidget(self.greenLabel)
|
|
64
|
+
h_layout1.addWidget(self.greenFormula)
|
|
65
|
+
h_layout1.addWidget(self.blueLabel)
|
|
66
|
+
h_layout1.addWidget(self.blueFormula)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
# Equation Text Fields
|
|
70
|
+
self.eqLabel1 = QLabel("Eq. #1:")
|
|
71
|
+
self.eq1 = QLineEdit("x")
|
|
72
|
+
self.eq1.textChanged.connect(self.update_palette)
|
|
73
|
+
|
|
74
|
+
self.eqLabel2 = QLabel("Eq. #2:")
|
|
75
|
+
self.eq2 = QLineEdit("x")
|
|
76
|
+
self.eq2.textChanged.connect(self.update_palette)
|
|
77
|
+
|
|
78
|
+
self.eqLabel3 = QLabel("Eq. #3:")
|
|
79
|
+
self.eq3 = QLineEdit("x")
|
|
80
|
+
self.eq3.textChanged.connect(self.update_palette)
|
|
81
|
+
|
|
82
|
+
# Random Button
|
|
83
|
+
self.randomButton = QPushButton("Random")
|
|
84
|
+
self.randomButton.clicked.connect(self.randomize_formulas)
|
|
85
|
+
|
|
86
|
+
# Update Button
|
|
87
|
+
# self.updateButton = QPushButton("Update")
|
|
88
|
+
# self.updateButton.clicked.connect(self.update_palette)
|
|
89
|
+
|
|
90
|
+
if False: # TODO --> really connect this in the future but ok for now
|
|
91
|
+
h_layout2.addWidget(self.eqLabel1)
|
|
92
|
+
h_layout2.addWidget(self.eq1)
|
|
93
|
+
h_layout2.addWidget(self.eqLabel2)
|
|
94
|
+
h_layout2.addWidget(self.eq2)
|
|
95
|
+
h_layout2.addWidget(self.eqLabel3)
|
|
96
|
+
h_layout2.addWidget(self.eq3)
|
|
97
|
+
h_layout2.addWidget(self.randomButton)
|
|
98
|
+
# h_layout2.addWidget(self.updateButton)
|
|
99
|
+
|
|
100
|
+
# Text Area
|
|
101
|
+
self.textArea = QTextEdit()
|
|
102
|
+
self.textArea.setReadOnly(True)
|
|
103
|
+
self.textArea.setText(
|
|
104
|
+
"0: 0\t\t\t1: 0.5\t\t\t2: 1\n"
|
|
105
|
+
"3: x\t\t\t4: x^2\t\t\t5: x^3\n"
|
|
106
|
+
"6: x^4\t\t\t7: sqrt(x)\t\t8: sqrt(sqrt(x))\n"
|
|
107
|
+
"9: sin(90*x)\t\t10: cos(90*x)\t\t11: |x-0.5|\n"
|
|
108
|
+
"12: (2*x-1)^2\t\t13: sin(180*x)\t\t14: |cos(180*x)|\n"
|
|
109
|
+
"15: sin(360*x)\t\t16: cos(360*x)\t\t17: |sin(360*x)|\n"
|
|
110
|
+
"18: |cos(360*x)|\t\t19: |sin(720*x)|\t\t20: |cos(720*x)|\n"
|
|
111
|
+
"21: 3*x\t\t\t22: 3*x-1\t\t23: 3*x-2\n"
|
|
112
|
+
"24: |3*x-1|\t\t25: |3*x-2|\t\t26: (3*x-1)/2\n"
|
|
113
|
+
"27: (3*x-2)/2\t\t28: |(3*x-1)/2|\t\t29: |(3*x-2)/2|\n"
|
|
114
|
+
"30: x/0.32-25/32\t\t31: 2*x-0.84\t\t32: x\n"
|
|
115
|
+
"33: |2*x - 0.5|\t\t34: 2*x\t\t\t35: 2*x - 0.5\n"
|
|
116
|
+
"36: 2*x - 1\t\t37: eq. #1\t\t38: eq. #2\n"
|
|
117
|
+
"39: eq. #3\n\n"
|
|
118
|
+
"NB: negative numbers --> returns the negative of the generated palette\n"
|
|
119
|
+
"NB2: I used Gnuplot numbering for equations to promote compatibility between the 2 softwares\n"
|
|
120
|
+
"NB3: the idea of using formulas to create LUTs is coming from Gnuplot"
|
|
121
|
+
)
|
|
122
|
+
# Set the font to monospace
|
|
123
|
+
font = QFont("Courier New", 12) # You can adjust the font size as needed
|
|
124
|
+
self.textArea.setFont(font)
|
|
125
|
+
|
|
126
|
+
# Disable scrollbars
|
|
127
|
+
self.textArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
|
128
|
+
self.textArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
|
129
|
+
|
|
130
|
+
# Resize QTextEdit to fit its content
|
|
131
|
+
self.textArea.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
|
132
|
+
self.textArea.setMinimumHeight(360) # Set a minimum height to ensure it's usable
|
|
133
|
+
|
|
134
|
+
formula_layout.addLayout(h_layout1)
|
|
135
|
+
formula_layout.addLayout(h_layout2)
|
|
136
|
+
formula_layout.addWidget(self.textArea)
|
|
137
|
+
|
|
138
|
+
self.formula_group.setLayout(formula_layout)
|
|
139
|
+
layout.addWidget(self.formula_group)
|
|
140
|
+
|
|
141
|
+
self.setLayout(layout)
|
|
142
|
+
|
|
143
|
+
self.update_palette()
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def randomize_formulas(self):
|
|
147
|
+
rand = int(self.randomSign(random.uniform(0, 39)))
|
|
148
|
+
self.redFormula.setText(str(rand))
|
|
149
|
+
rand = int(self.randomSign(random.uniform(0, 39)))
|
|
150
|
+
self.greenFormula.setText(str(rand))
|
|
151
|
+
rand = int(self.randomSign(random.uniform(0, 39)))
|
|
152
|
+
self.blueFormula.setText(str(rand))
|
|
153
|
+
self.update_palette()
|
|
154
|
+
|
|
155
|
+
def randomSign(self, nb):
|
|
156
|
+
return nb if random.random() > 0.5 else -nb
|
|
157
|
+
|
|
158
|
+
def update_palette(self):
|
|
159
|
+
if self.check_validity():
|
|
160
|
+
# Here, you would call your function to create and update the palette
|
|
161
|
+
self.palette = self.create_palette(
|
|
162
|
+
self.redFormula.text(),
|
|
163
|
+
self.greenFormula.text(),
|
|
164
|
+
self.blueFormula.text(),
|
|
165
|
+
self.eq1.text(),
|
|
166
|
+
self.eq2.text(),
|
|
167
|
+
self.eq3.text()
|
|
168
|
+
)
|
|
169
|
+
self.show_palette()
|
|
170
|
+
def check_validity(self):
|
|
171
|
+
return all([self.redFormula.text(), self.greenFormula.text(), self.blueFormula.text()])
|
|
172
|
+
|
|
173
|
+
def create_palette(self, red_formula, green_formula, blue_formula, eq1, eq2, eq3):
|
|
174
|
+
# print('red_formula, green_formula, blue_formula, eq1, eq2, eq3', red_formula, green_formula, blue_formula, eq1, eq2, eq3)
|
|
175
|
+
pc = PaletteCreator()
|
|
176
|
+
# lut = pc.create2(None, str(red_formula)+str(eq1), str(green_formula)+str(eq2), str(blue_formula)+str(eq3))
|
|
177
|
+
lut = pc.create2(f'{str(red_formula)},{ str(green_formula)},{str(blue_formula)}', eq1,eq2, eq3)
|
|
178
|
+
|
|
179
|
+
# print('lut', lut)
|
|
180
|
+
|
|
181
|
+
# self.show_palette()
|
|
182
|
+
return lut # Return the LUT for preview
|
|
183
|
+
|
|
184
|
+
def show_palette(self):
|
|
185
|
+
if self.palette is not None:
|
|
186
|
+
# print('show_palette called')
|
|
187
|
+
# Compute the total length based on your button dimensions and spacing
|
|
188
|
+
total_length = 760#(button_width * 16) + (spacing * 15) # Adjust based on columns and spacing
|
|
189
|
+
updateLutLabelPreview(self.palette, self.previewLabel, total_length, height=32)
|
|
190
|
+
else:
|
|
191
|
+
if self.check_validity():
|
|
192
|
+
QMessageBox.warning(self, "No Palette", "No palette to display. Please generate a palette first.")
|
|
193
|
+
|
|
194
|
+
def get_palette(self):
|
|
195
|
+
"""
|
|
196
|
+
Returns the current LUT.
|
|
197
|
+
|
|
198
|
+
:return: The current LUT or None if no LUT has been generated.
|
|
199
|
+
"""
|
|
200
|
+
return self.palette
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
if __name__ == '__main__':
|
|
204
|
+
app = QApplication(sys.argv)
|
|
205
|
+
jar_folder = "" # Provide the correct path if needed
|
|
206
|
+
ex = PaletteFormulaEditor()
|
|
207
|
+
ex.setWindowTitle('Palette Formula Editor')
|
|
208
|
+
ex.show()
|
|
209
|
+
sys.exit(app.exec_())
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
# MEGA TODO --> maybe append the newly created LUTs from formula at the end or add a button to append it to the list and then ask for a name an ddo not allow duplication of names -−> TODO --> think about it
|
|
2
|
+
|
|
3
|
+
from batoolset.GUI.customdialog import CustomDialog
|
|
4
|
+
from batoolset.luts.lutcreatorfromformula import PaletteFormulaEditor
|
|
5
|
+
from batoolset.settings.global_settings import set_UI # set the UI to qtpy
|
|
6
|
+
set_UI()
|
|
7
|
+
import traceback
|
|
8
|
+
from batoolset.files.tools import get_home_dir
|
|
9
|
+
from batoolset.luts.lut_minimal_test import list_available_luts, PaletteCreator
|
|
10
|
+
import sys
|
|
11
|
+
from qtpy.QtWidgets import QApplication, QWidget, QGridLayout, QPushButton, QColorDialog, QLabel, QVBoxLayout, QHBoxLayout, QFileDialog, QMessageBox, QComboBox, QLineEdit, QFormLayout
|
|
12
|
+
from qtpy.QtGui import QColor, QPixmap, QImage
|
|
13
|
+
from qtpy.QtCore import Qt
|
|
14
|
+
from batoolset.pyqts.tools import updateLutLabelPreview
|
|
15
|
+
import numpy as np
|
|
16
|
+
|
|
17
|
+
class PaletteEditor(QWidget):
|
|
18
|
+
def __init__(self, lut=None, parent=None):
|
|
19
|
+
super().__init__(parent)
|
|
20
|
+
|
|
21
|
+
self.button_width = 40 # Example button width
|
|
22
|
+
self.button_height = 20 # Example button height
|
|
23
|
+
self.spacing = 2 # Example spacing
|
|
24
|
+
|
|
25
|
+
self.rows = 16
|
|
26
|
+
self.columns = 16
|
|
27
|
+
self.buttons = {}
|
|
28
|
+
|
|
29
|
+
self.last_used_path = "" # Store the last used path
|
|
30
|
+
|
|
31
|
+
self.initUI()
|
|
32
|
+
|
|
33
|
+
if lut:
|
|
34
|
+
self.setLUT(lut)
|
|
35
|
+
else:
|
|
36
|
+
self.setDefaultLUT()
|
|
37
|
+
|
|
38
|
+
# self.updatePreview()
|
|
39
|
+
total_length = (self.button_width * self.columns) + (self.spacing * (self.columns - 1))
|
|
40
|
+
updateLutLabelPreview(self.getLUT(), self.previewLabel, total_length)
|
|
41
|
+
|
|
42
|
+
def initUI(self):
|
|
43
|
+
mainLayout = QVBoxLayout()
|
|
44
|
+
|
|
45
|
+
# Add QComboBox for selecting LUT models with a label
|
|
46
|
+
comboLayout = QHBoxLayout()
|
|
47
|
+
self.lut_label = QLabel("Select LUT:")
|
|
48
|
+
self.lut_combo = QComboBox()
|
|
49
|
+
available_luts = list_available_luts()
|
|
50
|
+
for lll, lut in enumerate(available_luts):
|
|
51
|
+
if lll == 0:
|
|
52
|
+
continue
|
|
53
|
+
self.lut_combo.addItem(lut)
|
|
54
|
+
|
|
55
|
+
# Select the "gray" entry by default
|
|
56
|
+
self.lut_combo.setCurrentText("GRAY")
|
|
57
|
+
|
|
58
|
+
self.lut_combo.currentIndexChanged.connect(self.setSelectedLUT)
|
|
59
|
+
comboLayout.addWidget(self.lut_label)
|
|
60
|
+
comboLayout.addWidget(self.lut_combo)
|
|
61
|
+
|
|
62
|
+
# Set stretch factors to make the combo box occupy more space
|
|
63
|
+
comboLayout.setStretchFactor(self.lut_label, 1)
|
|
64
|
+
comboLayout.setStretchFactor(self.lut_combo, 7)
|
|
65
|
+
|
|
66
|
+
mainLayout.addLayout(comboLayout)
|
|
67
|
+
|
|
68
|
+
gridLayout = QGridLayout()
|
|
69
|
+
gridLayout.setSpacing(2)
|
|
70
|
+
|
|
71
|
+
for row in range(self.rows):
|
|
72
|
+
for col in range(self.columns):
|
|
73
|
+
button = QPushButton()
|
|
74
|
+
button.setFixedSize(self.button_width, self.button_height)
|
|
75
|
+
button.setStyleSheet("background-color: white;")
|
|
76
|
+
button.clicked.connect(lambda _, r=row, c=col: self.openColorDialog(r, c))
|
|
77
|
+
|
|
78
|
+
gridLayout.addWidget(button, row, col)
|
|
79
|
+
self.buttons[(row, col)] = button
|
|
80
|
+
|
|
81
|
+
self.previewLabel = QLabel()
|
|
82
|
+
gridLayout.addWidget(self.previewLabel, self.rows, 0, 1, self.columns)
|
|
83
|
+
|
|
84
|
+
mainLayout.addLayout(gridLayout)
|
|
85
|
+
|
|
86
|
+
# Add LO and HI buttons
|
|
87
|
+
buttonLayout = QHBoxLayout()
|
|
88
|
+
self.loButton = QPushButton("LO")
|
|
89
|
+
self.loButton.clicked.connect(self.setFirstButton)
|
|
90
|
+
self.hiButton = QPushButton("HI")
|
|
91
|
+
self.hiButton.clicked.connect(self.setLastButton)
|
|
92
|
+
buttonLayout.addWidget(self.loButton)
|
|
93
|
+
buttonLayout.addWidget(self.hiButton)
|
|
94
|
+
|
|
95
|
+
# Add Import and Export buttons
|
|
96
|
+
self.importButton = QPushButton("Import LUT")
|
|
97
|
+
self.importButton.clicked.connect(self.importLUT)
|
|
98
|
+
self.exportButton = QPushButton("Export LUT")
|
|
99
|
+
self.exportButton.clicked.connect(self.exportLUT)
|
|
100
|
+
buttonLayout.addWidget(self.importButton)
|
|
101
|
+
buttonLayout.addWidget(self.exportButton)
|
|
102
|
+
|
|
103
|
+
# Add Formula Editor button
|
|
104
|
+
self.formulaEditorButton = QPushButton("New Lut formula")
|
|
105
|
+
self.formulaEditorButton.clicked.connect(self.openFormulaEditor)
|
|
106
|
+
buttonLayout.addWidget(self.formulaEditorButton)
|
|
107
|
+
|
|
108
|
+
mainLayout.addLayout(buttonLayout)
|
|
109
|
+
|
|
110
|
+
self.setLayout(mainLayout)
|
|
111
|
+
self.setWindowTitle('Palette Editor (256 entries)')
|
|
112
|
+
self.show()
|
|
113
|
+
|
|
114
|
+
def openFormulaEditor(self):
|
|
115
|
+
lut_from_formula = PaletteFormulaEditor(self)
|
|
116
|
+
custom_dialog = CustomDialog(title="Edit text", message="Do you want to proceed?", main_widget=lut_from_formula,
|
|
117
|
+
parent=self, options=['Ok', 'Cancel'],
|
|
118
|
+
auto_adjust=True) # that is really very good --> I can do it like that
|
|
119
|
+
# custom_dialog.adjustSize()
|
|
120
|
+
result = custom_dialog.exec_()
|
|
121
|
+
if result:
|
|
122
|
+
try:
|
|
123
|
+
lut = lut_from_formula.get_palette()
|
|
124
|
+
self.setLUT(lut)
|
|
125
|
+
total_length = (self.button_width * self.columns) + (self.spacing * (self.columns - 1))
|
|
126
|
+
updateLutLabelPreview(self.getLUT(), self.previewLabel, total_length)
|
|
127
|
+
except:
|
|
128
|
+
traceback.print_exc()
|
|
129
|
+
print('invalid lut')
|
|
130
|
+
|
|
131
|
+
def openColorDialog(self, row, col):
|
|
132
|
+
button = self.buttons[(row, col)]
|
|
133
|
+
current_color = button.palette().color(button.backgroundRole())
|
|
134
|
+
|
|
135
|
+
color = QColorDialog.getColor(current_color, self)
|
|
136
|
+
|
|
137
|
+
if color.isValid():
|
|
138
|
+
button.setStyleSheet(f"background-color: {color.name()};")
|
|
139
|
+
# self.updatePreview()
|
|
140
|
+
total_length = (self.button_width * self.columns) + (self.spacing * (self.columns - 1))
|
|
141
|
+
updateLutLabelPreview(self.getLUT(), self.previewLabel, total_length)
|
|
142
|
+
|
|
143
|
+
def getLUT(self):
|
|
144
|
+
lut = []
|
|
145
|
+
for row in range(self.rows):
|
|
146
|
+
for col in range(self.columns):
|
|
147
|
+
button = self.buttons[(row, col)]
|
|
148
|
+
color = button.palette().color(button.backgroundRole())
|
|
149
|
+
lut.append(color.name())
|
|
150
|
+
return lut
|
|
151
|
+
|
|
152
|
+
def setLUT(self, lut):
|
|
153
|
+
if len(lut) != 256:
|
|
154
|
+
raise ValueError("LUT must contain exactly 256 entries")
|
|
155
|
+
|
|
156
|
+
index = 0
|
|
157
|
+
for row in range(self.rows):
|
|
158
|
+
for col in range(self.columns):
|
|
159
|
+
entry = lut[index]
|
|
160
|
+
if isinstance(entry, str):
|
|
161
|
+
# Handle string representation of the color
|
|
162
|
+
color = QColor(entry)
|
|
163
|
+
elif isinstance(entry, (list, np.ndarray)) and len(entry) == 3:
|
|
164
|
+
# Handle [R, G, B] array
|
|
165
|
+
color = QColor(entry[0], entry[1], entry[2])
|
|
166
|
+
else:
|
|
167
|
+
raise ValueError(f"Invalid LUT entry: {entry}")
|
|
168
|
+
|
|
169
|
+
if color.isValid():
|
|
170
|
+
self.buttons[(row, col)].setStyleSheet(f"background-color: {color.name()};")
|
|
171
|
+
index += 1
|
|
172
|
+
|
|
173
|
+
def setDefaultLUT(self):
|
|
174
|
+
default_lut = [f"#{i:02x}{i:02x}{i:02x}" for i in range(256)]
|
|
175
|
+
self.setLUT(default_lut)
|
|
176
|
+
|
|
177
|
+
def setFirstButton(self):
|
|
178
|
+
self.buttons[(0, 0)].setStyleSheet("background-color: #0000FF;")
|
|
179
|
+
total_length = (self.button_width * self.columns) + (self.spacing * (self.columns - 1))
|
|
180
|
+
updateLutLabelPreview(self.getLUT(), self.previewLabel, total_length)
|
|
181
|
+
|
|
182
|
+
def setLastButton(self):
|
|
183
|
+
self.buttons[(self.rows - 1, self.columns - 1)].setStyleSheet("background-color: #FF0000;")
|
|
184
|
+
total_length = (self.button_width * self.columns) + (self.spacing * (self.columns - 1))
|
|
185
|
+
updateLutLabelPreview(self.getLUT(), self.previewLabel, total_length)
|
|
186
|
+
|
|
187
|
+
def importLUT(self):
|
|
188
|
+
options = QFileDialog.Options()
|
|
189
|
+
fileName, _ = QFileDialog.getOpenFileName(self, "Import LUT", self.last_used_path if self.last_used_path else get_home_dir(), "Text Files (*.lut);;All Files (*)", options=options)
|
|
190
|
+
if fileName:
|
|
191
|
+
try:
|
|
192
|
+
with open(fileName, 'r') as file:
|
|
193
|
+
lut = [line.strip() for line in file]
|
|
194
|
+
if len(lut) != 256:
|
|
195
|
+
raise ValueError("LUT must contain exactly 256 entries")
|
|
196
|
+
self.setLUT(lut)
|
|
197
|
+
total_length = (self.button_width * self.columns) + (self.spacing * (self.columns - 1))
|
|
198
|
+
updateLutLabelPreview(self.getLUT(), self.previewLabel, total_length)
|
|
199
|
+
except Exception as e:
|
|
200
|
+
QMessageBox.critical(self, "Error", str(e))
|
|
201
|
+
|
|
202
|
+
def exportLUT(self):
|
|
203
|
+
options = QFileDialog.Options()
|
|
204
|
+
fileName, _ = QFileDialog.getSaveFileName(self, "Export LUT", self.last_used_path if self.last_used_path else get_home_dir(), "Text Files (*.lut);;All Files (*)", options=options)
|
|
205
|
+
if fileName:
|
|
206
|
+
if not fileName.lower().endswith('.lut'):
|
|
207
|
+
fileName=fileName+'.lut'
|
|
208
|
+
try:
|
|
209
|
+
with open(fileName, 'w', encoding='utf-8') as file:
|
|
210
|
+
lut = self.getLUT()
|
|
211
|
+
for color in lut:
|
|
212
|
+
file.write(f"{color}\n")
|
|
213
|
+
|
|
214
|
+
# Update the last used path
|
|
215
|
+
self.last_used_path = fileName
|
|
216
|
+
except Exception as e:
|
|
217
|
+
QMessageBox.critical(self, "Error", str(e))
|
|
218
|
+
|
|
219
|
+
def setSelectedLUT(self):
|
|
220
|
+
selected_lut = self.lut_combo.currentText()
|
|
221
|
+
# lut = list_available_luts()[index + 1] # Adjust index to skip the first entry
|
|
222
|
+
available_luts = list_available_luts()
|
|
223
|
+
lutcreator = PaletteCreator()
|
|
224
|
+
lut_list = lutcreator.list
|
|
225
|
+
if selected_lut in available_luts:
|
|
226
|
+
try:
|
|
227
|
+
lut = lutcreator.create3(lut_list[selected_lut])
|
|
228
|
+
self.setLUT(lut)
|
|
229
|
+
total_length = (self.button_width * self.columns) + (self.spacing * (self.columns - 1))
|
|
230
|
+
updateLutLabelPreview(self.getLUT(), self.previewLabel, total_length)
|
|
231
|
+
except:
|
|
232
|
+
traceback.print_exc()
|
|
233
|
+
print('invalid LUT')
|
|
234
|
+
|
|
235
|
+
if __name__ == '__main__':
|
|
236
|
+
# this is the first version of my LUT editor
|
|
237
|
+
|
|
238
|
+
app = QApplication(sys.argv)
|
|
239
|
+
|
|
240
|
+
# Create PaletteEditor with the default grayscale LUT
|
|
241
|
+
ex = PaletteEditor()
|
|
242
|
+
|
|
243
|
+
sys.exit(app.exec_())
|
|
File without changes
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from batoolset.settings.global_settings import set_UI # set the UI to qtpy
|
|
2
|
+
set_UI()
|
|
3
|
+
from qtpy.QtWidgets import QApplication, QDialog, QLabel, QVBoxLayout
|
|
4
|
+
|
|
5
|
+
class PleaseWaitDialog(QDialog):
|
|
6
|
+
def __init__(self, parent=None):
|
|
7
|
+
super().__init__(parent)
|
|
8
|
+
self.setWindowTitle("Please wait")
|
|
9
|
+
self.setModal(True)
|
|
10
|
+
|
|
11
|
+
label = QLabel("Please wait... The slow process is running.")
|
|
12
|
+
layout = QVBoxLayout()
|
|
13
|
+
layout.addWidget(label)
|
|
14
|
+
self.setLayout(layout)
|