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.
Files changed (162) hide show
  1. batoolset/GUI/__init__.py +0 -0
  2. batoolset/GUI/list_gui.py +513 -0
  3. batoolset/GUI/multi_image_display.py +989 -0
  4. batoolset/GUI/open.py +325 -0
  5. batoolset/GUI/overlay_hints.py +45 -0
  6. batoolset/GUI/paint2.py +1345 -0
  7. batoolset/GUI/scrollablepaint.py +1152 -0
  8. batoolset/IJ_ROIs/__init__.py +0 -0
  9. batoolset/IJ_ROIs/tools.py +40 -0
  10. batoolset/PATH/__init__.py +0 -0
  11. batoolset/PATH/tools.py +79 -0
  12. batoolset/SQLite_tools/__init__.py +0 -0
  13. batoolset/SQLite_tools/tools.py +840 -0
  14. batoolset/__init__.py +0 -0
  15. batoolset/binary/__init__.py +0 -0
  16. batoolset/binary/tools.py +123 -0
  17. batoolset/binarytools/__init__.py +0 -0
  18. batoolset/binarytools/cell_center_detector.py +290 -0
  19. batoolset/clipboard_tools/__init__.py +0 -0
  20. batoolset/clipboard_tools/tools.py +7 -0
  21. batoolset/colors/__init__.py +0 -0
  22. batoolset/colors/colorgen.py +193 -0
  23. batoolset/colors/tools.py +22 -0
  24. batoolset/command_line/__init__.py +0 -0
  25. batoolset/command_line/tools.py +18 -0
  26. batoolset/dialogs/__init__.py +0 -0
  27. batoolset/dialogs/opensave.py +228 -0
  28. batoolset/dicts/__init__.py +0 -0
  29. batoolset/dicts/tools.py +299 -0
  30. batoolset/dims/__init__.py +0 -0
  31. batoolset/dims/tools.py +83 -0
  32. batoolset/draw/__init__.py +0 -0
  33. batoolset/draw/shapes/Position.py +183 -0
  34. batoolset/draw/shapes/__init__.py +0 -0
  35. batoolset/draw/shapes/automated_alignment_drawing_refactored.py +346 -0
  36. batoolset/draw/shapes/circle2d.py +99 -0
  37. batoolset/draw/shapes/compute_optimal_size_all_merged.py +317 -0
  38. batoolset/draw/shapes/ellipse2d.py +336 -0
  39. batoolset/draw/shapes/freehand2d.py +235 -0
  40. batoolset/draw/shapes/group.py +1830 -0
  41. batoolset/draw/shapes/image2d.py +2469 -0
  42. batoolset/draw/shapes/line2d.py +575 -0
  43. batoolset/draw/shapes/point2d.py +257 -0
  44. batoolset/draw/shapes/polygon2d.py +357 -0
  45. batoolset/draw/shapes/polyline2d.py +235 -0
  46. batoolset/draw/shapes/rect2d.py +388 -0
  47. batoolset/draw/shapes/rectangle2d.py +601 -0
  48. batoolset/draw/shapes/scalebar.py +304 -0
  49. batoolset/draw/shapes/serializablefont.py +126 -0
  50. batoolset/draw/shapes/serializableguiparams.py +10 -0
  51. batoolset/draw/shapes/square2d.py +103 -0
  52. batoolset/draw/shapes/textorientation.py +45 -0
  53. batoolset/draw/shapes/tools.py +467 -0
  54. batoolset/draw/shapes/transform2D.py +350 -0
  55. batoolset/draw/shapes/txt2d.py +550 -0
  56. batoolset/draw/widgets/__init__.py +0 -0
  57. batoolset/draw/widgets/col.py +343 -0
  58. batoolset/draw/widgets/image_group.py +248 -0
  59. batoolset/draw/widgets/image_organizer.py +96 -0
  60. batoolset/draw/widgets/paint.py +184 -0
  61. batoolset/draw/widgets/vectorial.py +257 -0
  62. batoolset/figure/__init__.py +0 -0
  63. batoolset/figure/alignment.py +814 -0
  64. batoolset/figure/column.py +1117 -0
  65. batoolset/figure/fig_tools.py +285 -0
  66. batoolset/figure/minimal_debugger_scale_etc.py +139 -0
  67. batoolset/figure/panel.py +697 -0
  68. batoolset/figure/row.py +852 -0
  69. batoolset/figure/user_selection.py +287 -0
  70. batoolset/files/__init__.py +0 -0
  71. batoolset/files/tools.py +1321 -0
  72. batoolset/images/__init__.py +0 -0
  73. batoolset/images/tools.py +81 -0
  74. batoolset/img.py +5216 -0
  75. batoolset/linux/__init__.py +0 -0
  76. batoolset/linux/tools.py +72 -0
  77. batoolset/lists/__init__.py +0 -0
  78. batoolset/lists/tools.py +436 -0
  79. batoolset/luts/__init__.py +0 -0
  80. batoolset/luts/lut_minimal_test.py +1207 -0
  81. batoolset/matplolib/__init__.py +0 -0
  82. batoolset/matplolib/tools.py +44 -0
  83. batoolset/np_tools/__init__.py +0 -0
  84. batoolset/np_tools/tools.py +252 -0
  85. batoolset/np_tools/trash.py +15 -0
  86. batoolset/pandas_tools/__init__.py +0 -0
  87. batoolset/pandas_tools/tools.py +880 -0
  88. batoolset/partials/__init__.py +0 -0
  89. batoolset/partials/tools.py +83 -0
  90. batoolset/plot_tools/__init__.py +0 -0
  91. batoolset/plot_tools/tools.py +70 -0
  92. batoolset/pyqt/__init__.py +0 -0
  93. batoolset/pyqt/tools.py +691 -0
  94. batoolset/re_tools/__init__.py +0 -0
  95. batoolset/re_tools/tools.py +35 -0
  96. batoolset/serialization/__init__.py +0 -0
  97. batoolset/serialization/tools.py +1192 -0
  98. batoolset/sets/__init__.py +0 -0
  99. batoolset/sets/tools.py +109 -0
  100. batoolset/settings/__init__.py +0 -0
  101. batoolset/settings/global_settings.py +134 -0
  102. batoolset/strings/__init__.py +0 -0
  103. batoolset/strings/tools.py +225 -0
  104. batoolset/ta/__init__.py +0 -0
  105. batoolset/ta/database/__init__.py +0 -0
  106. batoolset/ta/database/advanced_sql_plotter.py +1170 -0
  107. batoolset/ta/database/my_qt_table.py +79 -0
  108. batoolset/ta/database/preview_and_edit_sqlite_db.py +405 -0
  109. batoolset/ta/database/sql.py +2141 -0
  110. batoolset/ta/database/sql_column_name_dialog.py +122 -0
  111. batoolset/ta/measurements/TAmeasures.py +2226 -0
  112. batoolset/ta/measurements/__init__.py +0 -0
  113. batoolset/ta/measurements/measurements3D/__init__.py +0 -0
  114. batoolset/ta/measurements/measurements3D/get_point_on_surface_if_centroid_is_bad.py +175 -0
  115. batoolset/ta/measurements/measurements3D/height_map_to_projection.py +82 -0
  116. batoolset/ta/measurements/measurements3D/measures3D.py +208 -0
  117. batoolset/ta/measurements/measurements3D/triangulate.py +331 -0
  118. batoolset/ta/measurements/nematic.py +562 -0
  119. batoolset/ta/measurements/nematic_measurements.py +107 -0
  120. batoolset/ta/segmentation/__init__.py +0 -0
  121. batoolset/ta/segmentation/neo_wshed.py +314 -0
  122. batoolset/ta/selections/__init__.py +0 -0
  123. batoolset/ta/selections/selection.py +329 -0
  124. batoolset/ta/tracking/__init__.py +0 -0
  125. batoolset/ta/tracking/last_tracking_based_on_matching_or_on_translation_from_mermaid_warp.py +653 -0
  126. batoolset/ta/tracking/local_to_track_correspondance.py +138 -0
  127. batoolset/ta/tracking/rapid_detection_of_vertices.py +517 -0
  128. batoolset/ta/tracking/registration.py +108 -0
  129. batoolset/ta/tracking/swap_detector_and_fixer.py +296 -0
  130. batoolset/ta/tracking/track_correction.py +238 -0
  131. batoolset/ta/tracking/tracking_error_detector_and_fixer.py +3099 -0
  132. batoolset/ta/tracking/tracking_yet_another_approach_pyramidal_registration_n_neo_swapping_correction.py +725 -0
  133. batoolset/ta/utils/TA_tools.py +43 -0
  134. batoolset/ta/utils/__init__.py +0 -0
  135. batoolset/ta/utils/rps_tools.py +1783 -0
  136. batoolset/tests/__init__.py +0 -0
  137. batoolset/tests/rps_tools.py +51 -0
  138. batoolset/tests/tools.py +10 -0
  139. batoolset/tools/__init__.py +0 -0
  140. batoolset/tools/early_stopper_class.py +9 -0
  141. batoolset/tools/guided_data_recoverer.py +110 -0
  142. batoolset/tools/logger.py +100 -0
  143. batoolset/tools/mytimer.py +31 -0
  144. batoolset/tools/prompt_color.py +160 -0
  145. batoolset/tools/qthandler.py +118 -0
  146. batoolset/uitools/__init__.py +0 -0
  147. batoolset/uitools/blinker.py +56 -0
  148. batoolset/unsafe/__init__.py +0 -0
  149. batoolset/unsafe/tools.py +115 -0
  150. batoolset/utils/__init__.py +0 -0
  151. batoolset/utils/commontools.py +158 -0
  152. batoolset/utils/loadlist.py +728 -0
  153. batoolset/version.py +10 -0
  154. batoolset/xml/__init__.py +0 -0
  155. batoolset/xml/tools.py +65 -0
  156. batoolset/zip_tools/__init__.py +0 -0
  157. batoolset/zip_tools/tools.py +76 -0
  158. batoolset-0.1.0.dist-info/LICENSE +24 -0
  159. batoolset-0.1.0.dist-info/METADATA +45 -0
  160. batoolset-0.1.0.dist-info/RECORD +162 -0
  161. batoolset-0.1.0.dist-info/WHEEL +5 -0
  162. 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'))