batoolset 0.1.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/list_gui.py +513 -0
- batoolset/GUI/multi_image_display.py +989 -0
- batoolset/GUI/open.py +325 -0
- batoolset/GUI/overlay_hints.py +45 -0
- batoolset/GUI/paint2.py +1345 -0
- batoolset/GUI/scrollablepaint.py +1152 -0
- batoolset/IJ_ROIs/__init__.py +0 -0
- batoolset/IJ_ROIs/tools.py +40 -0
- batoolset/PATH/__init__.py +0 -0
- batoolset/PATH/tools.py +79 -0
- batoolset/SQLite_tools/__init__.py +0 -0
- batoolset/SQLite_tools/tools.py +840 -0
- batoolset/__init__.py +0 -0
- batoolset/binary/__init__.py +0 -0
- batoolset/binary/tools.py +123 -0
- batoolset/binarytools/__init__.py +0 -0
- batoolset/binarytools/cell_center_detector.py +290 -0
- batoolset/clipboard_tools/__init__.py +0 -0
- batoolset/clipboard_tools/tools.py +7 -0
- batoolset/colors/__init__.py +0 -0
- batoolset/colors/colorgen.py +193 -0
- batoolset/colors/tools.py +22 -0
- batoolset/command_line/__init__.py +0 -0
- batoolset/command_line/tools.py +18 -0
- batoolset/dialogs/__init__.py +0 -0
- batoolset/dialogs/opensave.py +228 -0
- batoolset/dicts/__init__.py +0 -0
- batoolset/dicts/tools.py +299 -0
- batoolset/dims/__init__.py +0 -0
- batoolset/dims/tools.py +83 -0
- batoolset/draw/__init__.py +0 -0
- batoolset/draw/shapes/Position.py +183 -0
- batoolset/draw/shapes/__init__.py +0 -0
- batoolset/draw/shapes/automated_alignment_drawing_refactored.py +346 -0
- batoolset/draw/shapes/circle2d.py +99 -0
- batoolset/draw/shapes/compute_optimal_size_all_merged.py +317 -0
- batoolset/draw/shapes/ellipse2d.py +336 -0
- batoolset/draw/shapes/freehand2d.py +235 -0
- batoolset/draw/shapes/group.py +1830 -0
- batoolset/draw/shapes/image2d.py +2469 -0
- batoolset/draw/shapes/line2d.py +575 -0
- batoolset/draw/shapes/point2d.py +257 -0
- batoolset/draw/shapes/polygon2d.py +357 -0
- batoolset/draw/shapes/polyline2d.py +235 -0
- batoolset/draw/shapes/rect2d.py +388 -0
- batoolset/draw/shapes/rectangle2d.py +601 -0
- batoolset/draw/shapes/scalebar.py +304 -0
- batoolset/draw/shapes/serializablefont.py +126 -0
- batoolset/draw/shapes/serializableguiparams.py +10 -0
- batoolset/draw/shapes/square2d.py +103 -0
- batoolset/draw/shapes/textorientation.py +45 -0
- batoolset/draw/shapes/tools.py +467 -0
- batoolset/draw/shapes/transform2D.py +350 -0
- batoolset/draw/shapes/txt2d.py +550 -0
- batoolset/draw/widgets/__init__.py +0 -0
- batoolset/draw/widgets/col.py +343 -0
- batoolset/draw/widgets/image_group.py +248 -0
- batoolset/draw/widgets/image_organizer.py +96 -0
- batoolset/draw/widgets/paint.py +184 -0
- batoolset/draw/widgets/vectorial.py +257 -0
- batoolset/figure/__init__.py +0 -0
- batoolset/figure/alignment.py +814 -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/files/__init__.py +0 -0
- batoolset/files/tools.py +1321 -0
- batoolset/images/__init__.py +0 -0
- batoolset/images/tools.py +81 -0
- batoolset/img.py +5216 -0
- batoolset/linux/__init__.py +0 -0
- batoolset/linux/tools.py +72 -0
- batoolset/lists/__init__.py +0 -0
- batoolset/lists/tools.py +436 -0
- batoolset/luts/__init__.py +0 -0
- batoolset/luts/lut_minimal_test.py +1207 -0
- batoolset/matplolib/__init__.py +0 -0
- batoolset/matplolib/tools.py +44 -0
- batoolset/np_tools/__init__.py +0 -0
- batoolset/np_tools/tools.py +252 -0
- batoolset/np_tools/trash.py +15 -0
- batoolset/pandas_tools/__init__.py +0 -0
- batoolset/pandas_tools/tools.py +880 -0
- batoolset/partials/__init__.py +0 -0
- batoolset/partials/tools.py +83 -0
- batoolset/plot_tools/__init__.py +0 -0
- batoolset/plot_tools/tools.py +70 -0
- batoolset/pyqt/__init__.py +0 -0
- batoolset/pyqt/tools.py +691 -0
- batoolset/re_tools/__init__.py +0 -0
- batoolset/re_tools/tools.py +35 -0
- batoolset/serialization/__init__.py +0 -0
- batoolset/serialization/tools.py +1192 -0
- batoolset/sets/__init__.py +0 -0
- batoolset/sets/tools.py +109 -0
- batoolset/settings/__init__.py +0 -0
- batoolset/settings/global_settings.py +134 -0
- batoolset/strings/__init__.py +0 -0
- batoolset/strings/tools.py +225 -0
- batoolset/ta/__init__.py +0 -0
- batoolset/ta/database/__init__.py +0 -0
- batoolset/ta/database/advanced_sql_plotter.py +1170 -0
- batoolset/ta/database/my_qt_table.py +79 -0
- batoolset/ta/database/preview_and_edit_sqlite_db.py +405 -0
- batoolset/ta/database/sql.py +2141 -0
- batoolset/ta/database/sql_column_name_dialog.py +122 -0
- batoolset/ta/measurements/TAmeasures.py +2226 -0
- batoolset/ta/measurements/__init__.py +0 -0
- batoolset/ta/measurements/measurements3D/__init__.py +0 -0
- batoolset/ta/measurements/measurements3D/get_point_on_surface_if_centroid_is_bad.py +175 -0
- batoolset/ta/measurements/measurements3D/height_map_to_projection.py +82 -0
- batoolset/ta/measurements/measurements3D/measures3D.py +208 -0
- batoolset/ta/measurements/measurements3D/triangulate.py +331 -0
- batoolset/ta/measurements/nematic.py +562 -0
- batoolset/ta/measurements/nematic_measurements.py +107 -0
- batoolset/ta/segmentation/__init__.py +0 -0
- batoolset/ta/segmentation/neo_wshed.py +314 -0
- batoolset/ta/selections/__init__.py +0 -0
- batoolset/ta/selections/selection.py +329 -0
- batoolset/ta/tracking/__init__.py +0 -0
- batoolset/ta/tracking/last_tracking_based_on_matching_or_on_translation_from_mermaid_warp.py +653 -0
- batoolset/ta/tracking/local_to_track_correspondance.py +138 -0
- batoolset/ta/tracking/rapid_detection_of_vertices.py +517 -0
- batoolset/ta/tracking/registration.py +108 -0
- batoolset/ta/tracking/swap_detector_and_fixer.py +296 -0
- batoolset/ta/tracking/track_correction.py +238 -0
- batoolset/ta/tracking/tracking_error_detector_and_fixer.py +3099 -0
- batoolset/ta/tracking/tracking_yet_another_approach_pyramidal_registration_n_neo_swapping_correction.py +725 -0
- batoolset/ta/utils/TA_tools.py +43 -0
- batoolset/ta/utils/__init__.py +0 -0
- batoolset/ta/utils/rps_tools.py +1783 -0
- batoolset/tests/__init__.py +0 -0
- batoolset/tests/rps_tools.py +51 -0
- batoolset/tests/tools.py +10 -0
- batoolset/tools/__init__.py +0 -0
- batoolset/tools/early_stopper_class.py +9 -0
- batoolset/tools/guided_data_recoverer.py +110 -0
- batoolset/tools/logger.py +100 -0
- batoolset/tools/mytimer.py +31 -0
- batoolset/tools/prompt_color.py +160 -0
- batoolset/tools/qthandler.py +118 -0
- batoolset/uitools/__init__.py +0 -0
- batoolset/uitools/blinker.py +56 -0
- batoolset/unsafe/__init__.py +0 -0
- batoolset/unsafe/tools.py +115 -0
- batoolset/utils/__init__.py +0 -0
- batoolset/utils/commontools.py +158 -0
- batoolset/utils/loadlist.py +728 -0
- batoolset/version.py +10 -0
- batoolset/xml/__init__.py +0 -0
- batoolset/xml/tools.py +65 -0
- batoolset/zip_tools/__init__.py +0 -0
- batoolset/zip_tools/tools.py +76 -0
- batoolset-0.1.0.dist-info/LICENSE +24 -0
- batoolset-0.1.0.dist-info/METADATA +45 -0
- batoolset-0.1.0.dist-info/RECORD +162 -0
- batoolset-0.1.0.dist-info/WHEEL +5 -0
- batoolset-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
from batoolset.settings.global_settings import set_UI # set the UI to qtpy
|
|
2
|
+
set_UI()
|
|
3
|
+
from qtpy.QtGui import QTransform,QPen, QColor
|
|
4
|
+
from qtpy.QtCore import QPointF
|
|
5
|
+
from batoolset.figure.alignment import pack2, align2, align_positions
|
|
6
|
+
from batoolset.draw.shapes.rectangle2d import Rectangle2D
|
|
7
|
+
from batoolset.draw.shapes.txt2d import TAText2D
|
|
8
|
+
from batoolset.draw.shapes.Position import Position
|
|
9
|
+
# logger
|
|
10
|
+
from batoolset.tools.logger import TA_logger
|
|
11
|
+
|
|
12
|
+
logger = TA_logger()
|
|
13
|
+
|
|
14
|
+
class ScaleBar(Rectangle2D):
|
|
15
|
+
|
|
16
|
+
# TODO need a scaling factor for the bar if image is itself scaled or ??? --> most likely yes need think about it
|
|
17
|
+
# TODO handle bar color
|
|
18
|
+
def __init__(self, bar_width_in_units=0, legend="", unit_to_pixel_conversion_factor=1, bar_height_in_px=3, placement=Position('bottom-right'), __version__=1.0,**kwargs):
|
|
19
|
+
super(ScaleBar, self).__init__()
|
|
20
|
+
# print('unsupported inputs scale',kwargs)
|
|
21
|
+
self.scale = 1
|
|
22
|
+
self.bar = Rectangle2D(color=None, fill_color=0xFFFFFF, stroke=0)
|
|
23
|
+
self.extra_space = 3
|
|
24
|
+
# print('bar_width_in_units',bar_width_in_units, 'unit_to_pixel_conversion_factor',unit_to_pixel_conversion_factor)
|
|
25
|
+
|
|
26
|
+
self.bar_height_in_px = bar_height_in_px
|
|
27
|
+
self.bar.setWidth(bar_width_in_units / (unit_to_pixel_conversion_factor if unit_to_pixel_conversion_factor else 1))
|
|
28
|
+
self.bar.setHeight(self.bar_height_in_px)
|
|
29
|
+
self.legend = None
|
|
30
|
+
self.setLegend(legend)
|
|
31
|
+
|
|
32
|
+
# print('self.legend inside',self.legend)
|
|
33
|
+
|
|
34
|
+
self.bar_width_in_units = bar_width_in_units
|
|
35
|
+
self.unit_to_pixel_conversion_factor = unit_to_pixel_conversion_factor
|
|
36
|
+
if not isinstance(placement, Position):
|
|
37
|
+
placement = Position(placement)
|
|
38
|
+
self.placement = placement
|
|
39
|
+
self.line_style = None # useless but require for compat with other shapes
|
|
40
|
+
self.__version__ = __version__
|
|
41
|
+
|
|
42
|
+
def setLegend(self, legend):
|
|
43
|
+
if isinstance(legend, str):
|
|
44
|
+
self.legend = TAText2D(legend)
|
|
45
|
+
elif isinstance(legend, TAText2D):
|
|
46
|
+
self.legend = legend
|
|
47
|
+
else:
|
|
48
|
+
self.legend = None
|
|
49
|
+
|
|
50
|
+
def setBarWidth(self, bar_width_in_units):
|
|
51
|
+
self.bar_width_in_units = bar_width_in_units
|
|
52
|
+
self.bar.setWidth(bar_width_in_units / (self.unit_to_pixel_conversion_factor if self.unit_to_pixel_conversion_factor else 1)) # this is ok but this is unscaled!!!
|
|
53
|
+
self.updateBoudingRect()
|
|
54
|
+
|
|
55
|
+
def update_bar_at_scale(self,scale):
|
|
56
|
+
# pass
|
|
57
|
+
# print('bar_width_in_units', self.bar_width_in_units, self.unit_to_pixel_conversion_factor, scale, self.bar.width(), self.width())
|
|
58
|
+
#
|
|
59
|
+
# self.bar.setWidth((self.bar_width_in_units * self.unit_to_pixel_conversion_factor) /scale)
|
|
60
|
+
#
|
|
61
|
+
# print('after', self.bar.width(), self.width()) # --> bar width is computed correctly so why isn't the size ok !!!
|
|
62
|
+
|
|
63
|
+
self.scale = scale
|
|
64
|
+
|
|
65
|
+
self.bar.setWidth((self.bar_width_in_units / (self.unit_to_pixel_conversion_factor if self.unit_to_pixel_conversion_factor else 1.)) / self.scale)
|
|
66
|
+
|
|
67
|
+
# self.packY() # it is the packing that fucks it all
|
|
68
|
+
# print('after2a', self.bar.width(),self.width()) # --> bar width is computed correctly so why isn't the size ok !!!
|
|
69
|
+
self.updateBoudingRect()
|
|
70
|
+
# print('after2b', self.bar.width(),self.width()) # --> bar width is computed correctly so why isn't the size ok !!!
|
|
71
|
+
|
|
72
|
+
# weird bug is here --> it resets the scale --> not what I want
|
|
73
|
+
|
|
74
|
+
# print('after2', self.bar.width(), self.width()) # --> bar width is computed correctly so why isn't the size ok !!!
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def width(self, *args, **kwargs):
|
|
79
|
+
return super().width() # mandatory for proper scaling KEEP
|
|
80
|
+
|
|
81
|
+
def height(self, *args, **kwargs):
|
|
82
|
+
return super().height() # mandatory for proper scaling KEEP
|
|
83
|
+
|
|
84
|
+
def setConversionFactor(self, unit_to_pixel_conversion_factor):
|
|
85
|
+
self.unit_to_pixel_conversion_factor = unit_to_pixel_conversion_factor
|
|
86
|
+
|
|
87
|
+
def draw(self, painter, draw=True, parent=None):
|
|
88
|
+
|
|
89
|
+
# shall I reset scale from painter --> maybe
|
|
90
|
+
# painter.setWorldTransform(QTransform())
|
|
91
|
+
# I need reset scale from painter as it is handled directly in the object
|
|
92
|
+
# then position is not ok but why
|
|
93
|
+
|
|
94
|
+
painter.save()
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
# we dynamically place the bar with respect to the bounding rect
|
|
99
|
+
self.bar.moveCenter(self.center())
|
|
100
|
+
self.bar.moveBottom(self.bottom()-self.bar_height_in_px)
|
|
101
|
+
self.bar.draw(painter=painter)
|
|
102
|
+
if self.legend is not None:
|
|
103
|
+
# we dynamically place the legend based on the bounding rect
|
|
104
|
+
self.legend.moveCenter(self.center())
|
|
105
|
+
self.legend.moveTop(self.top()-self.extra_space/2.)
|
|
106
|
+
self.legend.draw(painter=painter)
|
|
107
|
+
# self.drawAndFill(painter=painter)
|
|
108
|
+
|
|
109
|
+
# the bar should be centered on
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
if False: # just for debug !!!
|
|
113
|
+
painter.setPen(QPen(QColor("Green"),3))
|
|
114
|
+
painter.drawRect(self) # --> definitely the rect is incorrect -−> the error is in the placement of the rect
|
|
115
|
+
|
|
116
|
+
painter.restore()
|
|
117
|
+
def updateBoudingRect(self):
|
|
118
|
+
"""
|
|
119
|
+
updates the image bounding rect depending on content
|
|
120
|
+
:return:
|
|
121
|
+
"""
|
|
122
|
+
|
|
123
|
+
# contient deux objects et est donc la somme des deux
|
|
124
|
+
# --> facile en theorie faire que du packing et de l'alignement à gauche droite ou ailleurs
|
|
125
|
+
# pack in y direction the text and the bar
|
|
126
|
+
extra_space_below = 3 # TODO see how to make it not stuck to the bottom of the image --> it needs be a specificity of the bar and text but not for images --> TODO -> see how to do that
|
|
127
|
+
x = self.x()
|
|
128
|
+
y = self.y()
|
|
129
|
+
# x2 = None
|
|
130
|
+
# y2 = None
|
|
131
|
+
w=None
|
|
132
|
+
h=None
|
|
133
|
+
# the pb is that the shapes are not properly placed with respect to that
|
|
134
|
+
# and if the rect position is properly placed it is reset by wro,g placement of inner objects
|
|
135
|
+
|
|
136
|
+
# x=self.topLeft().x()
|
|
137
|
+
# y=self.topLeft().y()
|
|
138
|
+
|
|
139
|
+
to_pack = [self.bar, self.legend]
|
|
140
|
+
for img in to_pack:
|
|
141
|
+
if img is None:
|
|
142
|
+
continue
|
|
143
|
+
if not w:
|
|
144
|
+
w = img.width()
|
|
145
|
+
if not h:
|
|
146
|
+
h = img.height()
|
|
147
|
+
|
|
148
|
+
try:
|
|
149
|
+
w = max(w, img.width())
|
|
150
|
+
except:
|
|
151
|
+
pass
|
|
152
|
+
# h = max(h, img.height())
|
|
153
|
+
|
|
154
|
+
# try:
|
|
155
|
+
# topLeft = img.topLeft()
|
|
156
|
+
# if x is None:
|
|
157
|
+
# x = topLeft.x()
|
|
158
|
+
# if y is None:
|
|
159
|
+
# y = topLeft.y()
|
|
160
|
+
# x = min(topLeft.x(), x)
|
|
161
|
+
# y = min(topLeft.y(), y)
|
|
162
|
+
#
|
|
163
|
+
# # print(img, img.boundingRect(), type(img))
|
|
164
|
+
# # print(img, img.boundingRect(), type(img), img.boundingRect().height())
|
|
165
|
+
#
|
|
166
|
+
# if x2 is None:
|
|
167
|
+
# x2 = topLeft.x() + img.boundingRect().width()
|
|
168
|
+
# if y2 is None:
|
|
169
|
+
# y2 = topLeft.y() + img.boundingRect().height()
|
|
170
|
+
# x2 = max(topLeft.x() + img.boundingRect().width(), x2)
|
|
171
|
+
# y2 = max(topLeft.y() + img.boundingRect().height(), y2)
|
|
172
|
+
# except:
|
|
173
|
+
# pass
|
|
174
|
+
|
|
175
|
+
h = self.bar.height()
|
|
176
|
+
if self.legend and not isinstance(self.legend,str):
|
|
177
|
+
h = max(h,self.legend.height()) # why is legend size incorrect ???
|
|
178
|
+
|
|
179
|
+
# shall I translate the stuff at the same time ??? -−> maybe
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
if False:
|
|
184
|
+
self.setX(x-self.extra_space)
|
|
185
|
+
self.setY(y-self.extra_space)
|
|
186
|
+
self.setWidth(x2 - x)
|
|
187
|
+
# if not self.legend or self.width()<=self.bar.width():
|
|
188
|
+
self.setWidth(self.width()+self.extra_space*2) # maybe
|
|
189
|
+
self.setHeight(y2 - y)
|
|
190
|
+
# self.setHeight(self.height()+3) # add extra
|
|
191
|
+
self.setHeight(self.height()+self.extra_space*2)
|
|
192
|
+
|
|
193
|
+
self.setWidth(w+2*self.extra_space)
|
|
194
|
+
self.setHeight(h+2*self.extra_space)
|
|
195
|
+
|
|
196
|
+
# MEGA TOOD -> maybe I should only add space or not depending on placement -> check that !!!
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def packY(self, space=3):
|
|
201
|
+
# center in vertical axis then pack
|
|
202
|
+
#
|
|
203
|
+
# last_x = 0
|
|
204
|
+
# last_y = 0
|
|
205
|
+
#
|
|
206
|
+
# to_pack = [self.bar, self.legend]
|
|
207
|
+
# for i in range(len(to_pack)):
|
|
208
|
+
# img = self.images[i]
|
|
209
|
+
# if i != 0:
|
|
210
|
+
# last_y += space
|
|
211
|
+
# img.setTopLeft(img.topLeft().x(), last_y)
|
|
212
|
+
# # get all the bounding boxes and pack them with desired space in between
|
|
213
|
+
# # get first point and last point in x
|
|
214
|
+
# x = img.boundingRect().x()
|
|
215
|
+
# y = img.boundingRect().y()
|
|
216
|
+
# last_x = img.boundingRect().x() + img.boundingRect().width()
|
|
217
|
+
# last_y = img.boundingRect().y() + img.boundingRect().height()
|
|
218
|
+
if self.legend is not None and not isinstance(self.legend, str):
|
|
219
|
+
self.bar.setWidth((self.bar_width_in_units / self.unit_to_pixel_conversion_factor)/self.scale)
|
|
220
|
+
# alignCenterH(self.legend, self.bar)
|
|
221
|
+
align2(align_positions[-1], self.legend, self.bar)
|
|
222
|
+
# align_positions = ['Top', 'Bottom', 'Left', 'Right', 'CenterV', 'CenterH']
|
|
223
|
+
# packY(12, self.legend, self.bar)
|
|
224
|
+
pack2(3, ('-' if self.placement.check_position('top') else '') + 'Y', False, *[self.legend, self.bar])
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
self.updateBoudingRect()
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
# finally just need align right
|
|
235
|
+
|
|
236
|
+
# def setTopLeft(self, *args):
|
|
237
|
+
def setTopLeft(self, *args):
|
|
238
|
+
curP1 = self.topLeft()
|
|
239
|
+
if args:
|
|
240
|
+
if len(args) == 1:
|
|
241
|
+
# assume a QpointF
|
|
242
|
+
super().moveTopLeft(args[0])
|
|
243
|
+
elif len(args) == 2:
|
|
244
|
+
super().moveTopLeft(QPointF(args[0], args[1]))
|
|
245
|
+
else:
|
|
246
|
+
logger.error('invalid args for top left')
|
|
247
|
+
|
|
248
|
+
newP1 = self.topLeft()
|
|
249
|
+
# if
|
|
250
|
+
# # self.setTopLeft(*args)
|
|
251
|
+
# current_pos = self.boundingRect().topLeft()
|
|
252
|
+
# self.translate(point.x() - current_pos.x(), point.y() - current_pos.y())
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
if False:
|
|
256
|
+
# TODO check this code as most of this si probably totally useless
|
|
257
|
+
# curP1 = self.topLeft()
|
|
258
|
+
self.packY()
|
|
259
|
+
# Rectangle2D.setTopLeft(self, *args)
|
|
260
|
+
# Rectangle2D.setTopLeft(self, *args)
|
|
261
|
+
# newP1 = self.topLeft()
|
|
262
|
+
|
|
263
|
+
to_pack = [self.bar, self.legend]
|
|
264
|
+
for img in to_pack:
|
|
265
|
+
if img is not None:
|
|
266
|
+
img.translate(newP1.x() - curP1.x(), newP1.y() - curP1.y())
|
|
267
|
+
# img.translate(self.center().x()-img.center().x(),0)
|
|
268
|
+
|
|
269
|
+
# print('before aazezae', self.getRect())
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
self.updateBoudingRect()
|
|
273
|
+
# print('after qsdqsdqd', self.getRect())
|
|
274
|
+
|
|
275
|
+
# def set_to_scale(self, scale):
|
|
276
|
+
# self.scale = scale
|
|
277
|
+
|
|
278
|
+
# def setcolor
|
|
279
|
+
|
|
280
|
+
# get the bounds of the bar with the associated text
|
|
281
|
+
# center text on bar see how I do in EZF
|
|
282
|
+
|
|
283
|
+
def __repr__(self):
|
|
284
|
+
class_name = type(self).__name__
|
|
285
|
+
memory_address = hex(id(self))
|
|
286
|
+
return f"{class_name}-{memory_address}"
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
# def to_dict(self):
|
|
290
|
+
# x = self.x()
|
|
291
|
+
# y = self.y()
|
|
292
|
+
# width = self.width()
|
|
293
|
+
# height = self.height()
|
|
294
|
+
#
|
|
295
|
+
# # Create a dictionary representation of the values of the super object
|
|
296
|
+
# output_dict = {
|
|
297
|
+
# 'x': x,
|
|
298
|
+
# 'y': y,
|
|
299
|
+
# 'width': width,
|
|
300
|
+
# 'height': height,
|
|
301
|
+
# }
|
|
302
|
+
# # Update the dictionary with the __dict__ of Rectangle2D
|
|
303
|
+
# output_dict.update(self.__dict__)
|
|
304
|
+
# return output_dict
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
from batoolset.draw.shapes.Position import Position
|
|
2
|
+
from batoolset.draw.shapes.txt2d import TAText2D
|
|
3
|
+
from batoolset.pyqt.tools import get_html_text_with_font
|
|
4
|
+
from batoolset.settings.global_settings import set_UI # set the UI to qtpy
|
|
5
|
+
set_UI()
|
|
6
|
+
from qtpy.QtGui import QFont
|
|
7
|
+
from qtpy.QtWidgets import QApplication
|
|
8
|
+
# from qtpy.QtCore import Qt
|
|
9
|
+
import sys
|
|
10
|
+
|
|
11
|
+
class SerializableQFont(QFont):
|
|
12
|
+
|
|
13
|
+
def __init__(self, *args, **kwargs):
|
|
14
|
+
# print('kwargs of qfont', kwargs)
|
|
15
|
+
# print('args of qfont', args)
|
|
16
|
+
|
|
17
|
+
self.foreground = 0x000000
|
|
18
|
+
if 'foreground' in kwargs:
|
|
19
|
+
self.foreground = kwargs['foreground']
|
|
20
|
+
del kwargs['foreground']
|
|
21
|
+
|
|
22
|
+
self.background = 0xFFFFFF
|
|
23
|
+
if 'background' in kwargs:
|
|
24
|
+
self.background = kwargs['background']
|
|
25
|
+
del kwargs['background']
|
|
26
|
+
self.placement = Position('top-left')
|
|
27
|
+
if 'placement' in kwargs:
|
|
28
|
+
if isinstance(kwargs['placement'], Position):
|
|
29
|
+
self.placement = kwargs['placement']
|
|
30
|
+
else:
|
|
31
|
+
self.placement = Position(kwargs['placement'])
|
|
32
|
+
del kwargs['placement']
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
super().__init__(*args, **kwargs)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
# print('kwargs of qfont', kwargs)
|
|
39
|
+
# print('args of qfont', args)
|
|
40
|
+
|
|
41
|
+
# tmp_font = None
|
|
42
|
+
# if args:
|
|
43
|
+
# if isinstance(args[0], SerializableQFont):
|
|
44
|
+
# print('BINGO', args[0].foreground, args[0].background)
|
|
45
|
+
# else:
|
|
46
|
+
# print('PAS BINGO', type(args[0]))
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def to_dict(self):
|
|
52
|
+
"""Convert the SerializableQFont object to a dictionary."""
|
|
53
|
+
return {
|
|
54
|
+
'family': self.family(),
|
|
55
|
+
'size': max(self.pointSize(),1), # just in case pointsize is 0
|
|
56
|
+
'style': self.weight(), # if self.weight() == QFont.Normal else 'Bold'
|
|
57
|
+
'italic': self.italic(),
|
|
58
|
+
'background': self.background,
|
|
59
|
+
'foreground': self.foreground,
|
|
60
|
+
'placement':self.placement.position_to_string(),
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
@staticmethod
|
|
64
|
+
def from_dict(font_dict):
|
|
65
|
+
"""Create a SerializableQFont object from a dictionary."""
|
|
66
|
+
font = SerializableQFont(font_dict.get('family', 'Arial'), pointSize=font_dict.get('size', 12), weight=font_dict.get('style', QFont.Normal), italic=font_dict.get('italic', False), background = font_dict.get('background', None),foreground = font_dict.get('foreground', None), placement=Position(font_dict.get('placement', 'top-left')))
|
|
67
|
+
return font
|
|
68
|
+
|
|
69
|
+
def format_text_with_font(self, text):
|
|
70
|
+
return get_html_text_with_font(text, self)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
# self.foreground
|
|
74
|
+
def get_TaText2D_with_font(self, text):
|
|
75
|
+
if self.foreground is not None:
|
|
76
|
+
text = f'<font color=#{self.foreground:06x}>{text}</font>'
|
|
77
|
+
return TAText2D(self.format_text_with_font(text), placement=self.placement, fill_color=self.background, is_letter=True)
|
|
78
|
+
|
|
79
|
+
def __copy__(self):
|
|
80
|
+
return self
|
|
81
|
+
|
|
82
|
+
def __deepcopy__(self, memo):
|
|
83
|
+
return self
|
|
84
|
+
|
|
85
|
+
# be careful with that because this is what is compared when using == !!! so if poorly implemented this can have dramatic effects
|
|
86
|
+
|
|
87
|
+
def __str__(self):
|
|
88
|
+
# return f"{ self.__class__.__name__} {self.ID}"
|
|
89
|
+
return self.__repr__()
|
|
90
|
+
#
|
|
91
|
+
# def __repr__(self):
|
|
92
|
+
# return self.__str__()
|
|
93
|
+
|
|
94
|
+
def __repr__(self):
|
|
95
|
+
class_name = type(self).__name__
|
|
96
|
+
memory_address = hex(id(self))
|
|
97
|
+
return f"{class_name}-{memory_address}"
|
|
98
|
+
|
|
99
|
+
def main():
|
|
100
|
+
# Create a SerializableQFont object
|
|
101
|
+
font = SerializableQFont()
|
|
102
|
+
font.setFamily('Arial')
|
|
103
|
+
font.setFamily('Comic Sans MS')
|
|
104
|
+
font.setPointSize(12)
|
|
105
|
+
font.setWeight(QFont.Normal)
|
|
106
|
+
font.setItalic(True)
|
|
107
|
+
font.background = 0xFF0000
|
|
108
|
+
font.foreground = 0x0000FF
|
|
109
|
+
|
|
110
|
+
# Convert the SerializableQFont object to a dictionary
|
|
111
|
+
font_dict = font.to_dict()
|
|
112
|
+
print(font_dict)
|
|
113
|
+
|
|
114
|
+
# Convert the SerializableQFont object to a JSON string
|
|
115
|
+
# Create a SerializableQFont object from a dictionary
|
|
116
|
+
font2 = SerializableQFont.from_dict(font_dict)
|
|
117
|
+
print(font2.family(), font2.pointSize(), font2.weight(), font2.italic())
|
|
118
|
+
|
|
119
|
+
# Exit the QApplication
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
if __name__ == '__main__':
|
|
123
|
+
# Initialize the QApplication
|
|
124
|
+
app = QApplication(sys.argv)
|
|
125
|
+
main()
|
|
126
|
+
# sys.exit(app.exec_())
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Here I will store all the GUI parameters (such as Y spacing) so that I can restore them too
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class SerializableGUIparameters():
|
|
5
|
+
# min = None, max = None,
|
|
6
|
+
def __init__(self, space):
|
|
7
|
+
self.space = space
|
|
8
|
+
# see what are the other things I can store
|
|
9
|
+
|
|
10
|
+
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from batoolset.draw.shapes.rectangle2d import Rectangle2D
|
|
4
|
+
from batoolset.settings.global_settings import set_UI # set the UI to qtpy
|
|
5
|
+
set_UI()
|
|
6
|
+
from qtpy.QtCore import QPointF
|
|
7
|
+
|
|
8
|
+
from batoolset.draw.shapes.rect2d import Rect2D
|
|
9
|
+
|
|
10
|
+
from batoolset.tools.logger import TA_logger
|
|
11
|
+
|
|
12
|
+
logger = TA_logger()
|
|
13
|
+
|
|
14
|
+
# Do I need square if I have already the rect2D
|
|
15
|
+
# make it that the code is just a series of instructions so that it is rebuilt on the fly and always works -−> no serialization --> no pb
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class Square2D(Rectangle2D):
|
|
20
|
+
|
|
21
|
+
def __init__(self, *args, x=0, y=0, width=0, color=0xFFFFFF, fill_color=None, opacity=1., stroke=0.65, line_style=None, theta=0, __version__=1.0,**kwargs):
|
|
22
|
+
if len(args) == 3:
|
|
23
|
+
super(Square2D, self).__init__(*args, args[-1])
|
|
24
|
+
elif len(args) == 4:
|
|
25
|
+
logger.error("too many values, square only has, x,y and width")
|
|
26
|
+
else:
|
|
27
|
+
if args:
|
|
28
|
+
super(Square2D, self).__init__(*args) # create empty circle
|
|
29
|
+
else:
|
|
30
|
+
super(Square2D, self).__init__(x, y, width, width) # create empty circle
|
|
31
|
+
self.color = color
|
|
32
|
+
self.fill_color = fill_color
|
|
33
|
+
self.stroke = stroke
|
|
34
|
+
self.opacity = opacity
|
|
35
|
+
self.line_style = line_style
|
|
36
|
+
# rotation
|
|
37
|
+
self.theta = theta
|
|
38
|
+
self.__version__ = __version__
|
|
39
|
+
|
|
40
|
+
def add(self, *args):
|
|
41
|
+
p1 = args[0]
|
|
42
|
+
p2 = args[1]
|
|
43
|
+
|
|
44
|
+
x = p2.x()
|
|
45
|
+
y = p2.y()
|
|
46
|
+
x2 = p1.x()
|
|
47
|
+
y2 = p1.y()
|
|
48
|
+
if p1.x() < p2.x():
|
|
49
|
+
x = p1.x()
|
|
50
|
+
x2 = p2.x()
|
|
51
|
+
if p1.y() < p2.y():
|
|
52
|
+
y = p1.y()
|
|
53
|
+
y2 = p2.y()
|
|
54
|
+
w = abs(x - x2)
|
|
55
|
+
h = abs(y - y2)
|
|
56
|
+
self.setX(x)
|
|
57
|
+
self.setY(y)
|
|
58
|
+
if w < h:
|
|
59
|
+
self.setWidth(h)
|
|
60
|
+
self.setHeight(h)
|
|
61
|
+
else:
|
|
62
|
+
self.setWidth(w)
|
|
63
|
+
self.setHeight(w)
|
|
64
|
+
# self.isSet = True
|
|
65
|
+
|
|
66
|
+
def __repr__(self):
|
|
67
|
+
class_name = type(self).__name__
|
|
68
|
+
memory_address = hex(id(self))
|
|
69
|
+
return f"{class_name}-{memory_address}"
|
|
70
|
+
|
|
71
|
+
if __name__ == '__main__':
|
|
72
|
+
# ça marche --> voici deux examples de shapes
|
|
73
|
+
test = Square2D(0, 0, 200)
|
|
74
|
+
print(test.x(), test.y(), test.width(), test.height())
|
|
75
|
+
print(test.contains(QPointF(50, 50)))
|
|
76
|
+
print(test.contains(QPointF(-1, -1)))
|
|
77
|
+
print(test.contains(QPointF(0, 0)))
|
|
78
|
+
print(test.contains(QPointF(100, 100)))
|
|
79
|
+
print(test.contains(QPointF(100, 100.1)))
|
|
80
|
+
|
|
81
|
+
# p1 = test.p1()
|
|
82
|
+
# print(p1.x(), p1.y())
|
|
83
|
+
# p2 = test.p2()
|
|
84
|
+
# print(p2.x(), p2.y())
|
|
85
|
+
# print(test.arrow)
|
|
86
|
+
# print(test.length()) # sqrt 2 --> 141
|
|
87
|
+
# # if it's an arrow I can add easily all the stuff I need
|
|
88
|
+
#
|
|
89
|
+
# test = Rect2D(0, 0, 1, 1)
|
|
90
|
+
# p1 = test.p1()
|
|
91
|
+
# print(p1.x(), p1.y())
|
|
92
|
+
# p2 = test.p2()
|
|
93
|
+
# print(p2.x(), p2.y())
|
|
94
|
+
# print(test.arrow)
|
|
95
|
+
# import math
|
|
96
|
+
# print(test.length() == math.sqrt(2)) # sqrt 2
|
|
97
|
+
#
|
|
98
|
+
# test2 = Rect2D()
|
|
99
|
+
# p1 = test2.p1()
|
|
100
|
+
# print(p1.x(), p1.y())
|
|
101
|
+
# p2 = test2.p2()
|
|
102
|
+
# print(p2.x(), p2.y())
|
|
103
|
+
# print(test2.arrow)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
def get_angle(text, verbose=False):
|
|
2
|
+
if not text:
|
|
3
|
+
# raise ValueError("Invalid orientation text: {}".format(self.text))
|
|
4
|
+
if verbose:
|
|
5
|
+
print(f'unknown text orientation {text}, assuming horizontal')
|
|
6
|
+
return 0
|
|
7
|
+
# angle =0
|
|
8
|
+
if 'h' in text.lower() or 'x' in text.lower():
|
|
9
|
+
angle = 0
|
|
10
|
+
elif 'v' in text.lower() or 'y' in text.lower():
|
|
11
|
+
angle = 90
|
|
12
|
+
else:
|
|
13
|
+
# raise ValueError("Invalid orientation text: {}".format(self.text))
|
|
14
|
+
if verbose:
|
|
15
|
+
print(f'unknown text orientation {text}, assuming horizontal')
|
|
16
|
+
angle =0
|
|
17
|
+
# if '-' in text:
|
|
18
|
+
# angle=-angle
|
|
19
|
+
return angle
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class TextOrientation:
|
|
23
|
+
def __init__(self, text):
|
|
24
|
+
self.text = text
|
|
25
|
+
|
|
26
|
+
def get_angle(self, verbose=False):
|
|
27
|
+
return get_angle(self.text, verbose=verbose)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
if __name__ == '__main__':
|
|
32
|
+
orientation = TextOrientation('horizontal')
|
|
33
|
+
angle = orientation.get_angle()
|
|
34
|
+
print(angle) # Output: 0
|
|
35
|
+
|
|
36
|
+
orientation = TextOrientation('Vertical')
|
|
37
|
+
angle = orientation.get_angle()
|
|
38
|
+
print(angle) # Output: 90
|
|
39
|
+
|
|
40
|
+
orientation = TextOrientation(None)
|
|
41
|
+
angle = orientation.get_angle(verbose=TextOrientation) # Raises ValueError
|
|
42
|
+
print(angle)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
print(get_angle('-y'))
|