drawlib 0.2.3.dev2__py3-none-any.whl → 0.2.3.dev4__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 drawlib might be problematic. Click here for more details.

@@ -0,0 +1,178 @@
1
+ # Copyright (c) 2024 Yuichi Ito (yuichi@yuichi.com)
2
+ #
3
+ # This software is licensed under the Apache License, Version 2.0.
4
+ # For more information, please visit: https://github.com/yuichi110/drawlib
5
+ #
6
+ # This software is provided "as is", without warranty of any kind,
7
+ # express or implied, including but not limited to the warranties of
8
+ # merchantability, fitness for a particular purpose and noninfringement.
9
+
10
+
11
+ """BoxList implementation module."""
12
+
13
+ from typing import Any, List, Literal, Optional, Tuple, Union
14
+
15
+ from drawlib.v0_2.private.core.colors import Colors
16
+ from drawlib.v0_2.private.core.model import ShapeStyle, ShapeTextStyle
17
+ from drawlib.v0_2.private.core.theme import dtheme
18
+ from drawlib.v0_2.private.core_canvas.canvas import rectangle
19
+ from drawlib.v0_2.private.util import error_handler
20
+
21
+
22
+ class BoxList:
23
+ """A class to draw a list of boxes with text, supporting highlighting of certain boxes.
24
+
25
+ Args:
26
+ box_style (Union[str, ShapeStyle, None]): The style for the boxes.
27
+ text_style (Union[str, ShapeTextStyle, None]): The style for the text inside the boxes.
28
+ box_highlight_style (Union[str, ShapeStyle, None]): The style for the highlighted boxes.
29
+ text_highlight_style (Union[str, ShapeTextStyle, None]): The style for the text inside the highlighted boxes.
30
+ """
31
+
32
+ @error_handler
33
+ def __init__(
34
+ self,
35
+ box_style: Union[str, ShapeStyle, None] = None,
36
+ text_style: Union[str, ShapeTextStyle, None] = None,
37
+ box_highlight_style: Union[str, ShapeStyle, None] = None,
38
+ text_highlight_style: Union[str, ShapeTextStyle, None] = None,
39
+ ) -> None:
40
+ """Initialize BoxList.
41
+
42
+ Args:
43
+ box_style (Union[str, ShapeStyle, None]): The style for the boxes.
44
+ text_style (Union[str, ShapeTextStyle, None]): The style for the text inside the boxes.
45
+ box_highlight_style (Union[str, ShapeStyle, None]): The style for the highlighted boxes.
46
+ text_highlight_style (Union[str, ShapeTextStyle, None]):
47
+ The style for the text inside the highlighted boxes.
48
+ """
49
+ if isinstance(box_style, str):
50
+ box_style = dtheme.rectanglestyles.get(box_style)
51
+ if box_style is None:
52
+ box_style = dtheme.rectanglestyles.get()
53
+ box_style.halign = "center"
54
+ box_style.valign = "center"
55
+ self._box_style = box_style
56
+
57
+ if isinstance(text_style, str):
58
+ text_style = dtheme.rectangletextstyles.get(text_style)
59
+ if text_style is None:
60
+ text_style = dtheme.rectangletextstyles.get()
61
+ self._text_style = text_style
62
+
63
+ if isinstance(box_highlight_style, str):
64
+ box_highlight_style = dtheme.rectanglestyles.get(box_highlight_style)
65
+ if box_highlight_style is None:
66
+ box_highlight_style = box_style
67
+ box_highlight_style.halign = "center"
68
+ box_highlight_style.valign = "center"
69
+ self._box_highlight_style = box_highlight_style
70
+
71
+ if isinstance(text_highlight_style, str):
72
+ text_highlight_style = dtheme.rectangletextstyles.get(text_highlight_style)
73
+ if text_highlight_style is None:
74
+ text_highlight_style = text_style
75
+ self._text_highlight_style = text_highlight_style
76
+
77
+ @error_handler
78
+ def draw(
79
+ self,
80
+ xy: Tuple[float, float],
81
+ box_width: float,
82
+ box_height: float,
83
+ items: List[Any],
84
+ highlight_indexs: Optional[List[int]] = None,
85
+ length: Optional[int] = None,
86
+ align: Literal["left", "right", "bottom", "top"] = "left",
87
+ ) -> None:
88
+ """Draws a list of boxes at the specified location.
89
+
90
+ Args:
91
+ xy (Tuple[float, float]): The starting point (x, y) to draw the list of boxes.
92
+ box_width (float): The width of each box.
93
+ box_height (float): The height of each box.
94
+ items (List[Any]): The list of items to be displayed inside the boxes.
95
+ highlight_indexs (Optional[List[int]]):
96
+ The list of indices of the boxes to be highlighted.
97
+ length (Optional[int]): The total number of boxes to be drawn.
98
+ align (Literal["left", "right", "bottom", "top"]):
99
+ The alignment of the boxes relative to the starting point.
100
+
101
+ """
102
+ if highlight_indexs is None:
103
+ highlight_indexs = []
104
+
105
+ if length is not None:
106
+ indexs = range(length)
107
+ else:
108
+ indexs = range(len(items))
109
+
110
+ non_highlight_indexs = [item for item in indexs if item not in highlight_indexs]
111
+ highlight_indexs = [item for item in indexs if item in highlight_indexs]
112
+
113
+ for index in non_highlight_indexs:
114
+ if index <= len(items) - 1:
115
+ text = str(items[index])
116
+ else:
117
+ text = ""
118
+
119
+ self._draw_cell(
120
+ start_xy=xy,
121
+ index=index,
122
+ text=text,
123
+ box_width=box_width,
124
+ box_height=box_height,
125
+ box_style=self._box_style,
126
+ text_style=self._text_style,
127
+ align=align,
128
+ )
129
+
130
+ for index in highlight_indexs:
131
+ if index <= len(items) - 1:
132
+ text = str(items[index])
133
+ else:
134
+ text = ""
135
+
136
+ self._draw_cell(
137
+ start_xy=xy,
138
+ index=index,
139
+ text=text,
140
+ box_width=box_width,
141
+ box_height=box_height,
142
+ box_style=self._box_highlight_style,
143
+ text_style=self._text_highlight_style,
144
+ align=align,
145
+ )
146
+
147
+ @staticmethod
148
+ def _draw_cell(
149
+ start_xy: Tuple[float, float],
150
+ index: int,
151
+ text: str,
152
+ box_width: float,
153
+ box_height: float,
154
+ box_style: ShapeStyle,
155
+ text_style: ShapeTextStyle,
156
+ align: Literal["left", "right", "bottom", "top"],
157
+ ) -> None:
158
+ if align == "left":
159
+ x = start_xy[0] + box_width * (index + 0.5)
160
+ y = start_xy[1] + box_height / 2
161
+ elif align == "right":
162
+ x = start_xy[0] - box_width * (index + 0.5)
163
+ y = start_xy[1] + box_height / 2
164
+ elif align == "bottom":
165
+ x = start_xy[0] + box_width / 2
166
+ y = start_xy[1] + box_height * (index + 0.5)
167
+ else:
168
+ x = start_xy[0] + box_width / 2
169
+ y = start_xy[1] - box_height * (index + 0.5)
170
+
171
+ rectangle(
172
+ xy=(x, y),
173
+ width=box_width,
174
+ height=box_height,
175
+ style=box_style,
176
+ text=text,
177
+ textstyle=text_style,
178
+ )
@@ -28,9 +28,9 @@ def bubblespeech(
28
28
  width: float,
29
29
  height: float,
30
30
  tail_edge: Literal["left", "top", "right", "bottom"],
31
- tail_from_ratio: float,
31
+ tail_start_ratio: float,
32
32
  tail_vertex_xy: Tuple[float, float],
33
- tail_to_ratio: float,
33
+ tail_end_ratio: float,
34
34
  style: Union[ShapeStyle, str, None] = None,
35
35
  text: str = "",
36
36
  textsize: Optional[float] = None,
@@ -43,9 +43,9 @@ def bubblespeech(
43
43
  width (float): The width of the bubble.
44
44
  height (float): The height of the bubble.
45
45
  tail_edge (Literal["left", "top", "right", "bottom"]): The edge on which the tail will be positioned.
46
- tail_from_ratio (float): The ratio along the edge where the tail starts.
46
+ tail_start_ratio (float): The ratio along the edge where the tail starts.
47
47
  tail_vertex_xy (Tuple[float, float]): The (x, y) coordinates of the tail's vertex.
48
- tail_to_ratio (float): The ratio along the edge where the tail ends.
48
+ tail_end_ratio (float): The ratio along the edge where the tail ends.
49
49
  style (Union[ShapeStyle, str, None], optional): The style of the bubble. Defaults to None.
50
50
  text (str, optional): The text to display inside the bubble. Defaults to an empty string.
51
51
  textsize (Optional[float], optional): The size of the text. Defaults to None.
@@ -66,33 +66,33 @@ def bubblespeech(
66
66
  if textsize is not None:
67
67
  textstyle.size = textsize
68
68
 
69
- if tail_from_ratio > tail_to_ratio:
70
- raise ValueError("tail_from_ratio must be smaller than tail_to_ratio.")
71
- if tail_to_ratio > 1.0:
72
- raise ValueError("tail_from_ratio and tail_to_ratio must be smaller than 1.0")
69
+ if tail_start_ratio > tail_end_ratio:
70
+ raise ValueError("tail_start_ratio must be smaller than tail_end_ratio.")
71
+ if tail_end_ratio > 1.0:
72
+ raise ValueError("tail_start_ratio and tail_end_ratio must be smaller than 1.0")
73
73
 
74
74
  x, y = xy
75
75
  xys = []
76
76
  xys.append((x, y)) # left bottom
77
77
  if tail_edge == "left":
78
- xys.append((x, y + height * tail_from_ratio))
78
+ xys.append((x, y + height * tail_start_ratio))
79
79
  xys.append(tail_vertex_xy)
80
- xys.append((x, y + height * tail_to_ratio))
80
+ xys.append((x, y + height * tail_end_ratio))
81
81
  xys.append((x, y + height)) # left top
82
82
  if tail_edge == "top":
83
- xys.append((x + width * tail_from_ratio, y + height))
83
+ xys.append((x + width * tail_start_ratio, y + height))
84
84
  xys.append(tail_vertex_xy)
85
- xys.append((x + width * tail_to_ratio, y + height))
85
+ xys.append((x + width * tail_end_ratio, y + height))
86
86
  xys.append((x + width, y + height)) # right top
87
87
  if tail_edge == "right":
88
- xys.append((x + width, y + height * tail_to_ratio))
88
+ xys.append((x + width, y + height * tail_end_ratio))
89
89
  xys.append(tail_vertex_xy)
90
- xys.append((x + width, y + height * tail_from_ratio))
90
+ xys.append((x + width, y + height * tail_start_ratio))
91
91
  xys.append((x + width, y)) # right bottom
92
92
  if tail_edge == "bottom":
93
- xys.append((x + width * tail_to_ratio, y))
93
+ xys.append((x + width * tail_end_ratio, y))
94
94
  xys.append(tail_vertex_xy)
95
- xys.append((x + width * tail_from_ratio, y))
95
+ xys.append((x + width * tail_start_ratio, y))
96
96
 
97
97
  options = ShapeUtil.get_shape_options(style)
98
98
  canvas._artists.append(Polygon(xy=xys, closed=True, **options))
@@ -0,0 +1,188 @@
1
+ # Copyright (c) 2024 Yuichi Ito (yuichi@yuichi.com)
2
+ #
3
+ # This software is licensed under the Apache License, Version 2.0.
4
+ # For more information, please visit: https://github.com/yuichi110/drawlib
5
+ #
6
+ # This software is provided "as is", without warranty of any kind,
7
+ # express or implied, including but not limited to the warranties of
8
+ # merchantability, fitness for a particular purpose and noninfringement.
9
+
10
+
11
+ """BulletPoints implementation module."""
12
+
13
+ import dataclasses
14
+ from typing import Callable, List, Optional, Tuple, Union
15
+
16
+ from drawlib.v0_2.private.core.colors import Colors
17
+ from drawlib.v0_2.private.core.model import ShapeStyle, TextStyle
18
+ from drawlib.v0_2.private.core.theme import dtheme
19
+ from drawlib.v0_2.private.core_canvas.canvas import circle, text
20
+ from drawlib.v0_2.private.util import error_handler
21
+
22
+
23
+ class BulletPoints:
24
+ """A class to draw a list of bullet points with customizable styles and indentation.
25
+
26
+ Args:
27
+ vertical_margin (float): The vertical space between bullet points.
28
+ indent_width (float): The width of the indentation for each level.
29
+ default_style (Union[str, TextStyle, None]): The default text style for the bullet points.
30
+ """
31
+
32
+ @error_handler
33
+ def __init__(
34
+ self,
35
+ vertical_margin: float,
36
+ indent_width: float,
37
+ default_style: Union[str, TextStyle, None] = None,
38
+ ) -> None:
39
+ """Initialize BulletPoints.
40
+
41
+ Args:
42
+ vertical_margin (float): The vertical space between bullet points.
43
+ indent_width (float): The width of the indentation for each level.
44
+ default_style (Union[str, TextStyle, None]): The default text style for the bullet points.
45
+ """
46
+ self._vertical_margin = vertical_margin
47
+ self._indent_width = indent_width
48
+ if isinstance(default_style, str):
49
+ default_style = dtheme.textstyles.get(default_style)
50
+ if default_style is None:
51
+ default_style = dtheme.textstyles.get()
52
+ self._default_style = default_style
53
+
54
+ self._indent_level = 0
55
+ self._bullet_texts: List[_BulletPointsText] = []
56
+ self._bullet_shape_map: dict[int, _BulletPointsShape] = {}
57
+
58
+ # set default bullet styles
59
+ text_color = default_style.color
60
+ style1 = dtheme.shapestyles.get()
61
+ style1.lcolor = text_color
62
+ style1.fcolor = text_color
63
+ style2 = dtheme.shapestyles.get()
64
+ style2.lcolor = text_color
65
+ style2.fcolor = Colors.Transparent
66
+ self.set_bullet_style(1, circle, style1, args={"radius": 0.5})
67
+ self.set_bullet_style(2, circle, style2, args={"radius": 0.5})
68
+
69
+ @error_handler
70
+ def set_indent(self, level: int) -> None:
71
+ """Sets the indentation level for the next bullet point.
72
+
73
+ Args:
74
+ level (int): The indentation level.
75
+ """
76
+ self._indent_level = level
77
+
78
+ @error_handler
79
+ def set_bullet_style(
80
+ self,
81
+ indent_level: int,
82
+ function: Callable,
83
+ style: Union[str, ShapeStyle],
84
+ args: dict,
85
+ ) -> None:
86
+ """Sets the style and function for drawing bullets at a specific indentation level.
87
+
88
+ Args:
89
+ indent_level (int): The indentation level to apply the style to.
90
+ function (Callable): The function to draw the bullet shape.
91
+ style (Union[str, ShapeStyle]): The style to apply to the bullet shape.
92
+ args (dict): Additional arguments to pass to the drawing function.
93
+ """
94
+ if isinstance(style, str):
95
+ style = dtheme.shapestyles.get(style)
96
+ style.halign = "center"
97
+ style.valign = "center"
98
+
99
+ item = _BulletPointsShape(
100
+ function=function,
101
+ style=style,
102
+ args=args,
103
+ )
104
+
105
+ self._bullet_shape_map[indent_level] = item
106
+
107
+ @error_handler
108
+ def add(
109
+ self,
110
+ text: str,
111
+ style: Union[str, TextStyle, None] = None,
112
+ ) -> None:
113
+ """Adds a bullet point with the specified text and style.
114
+
115
+ Args:
116
+ text (str): The text for the bullet point.
117
+ style (Union[str, TextStyle, None]): The text style for the bullet point.
118
+ """
119
+ if isinstance(style, str):
120
+ style = dtheme.textstyles.get(style)
121
+ elif style is None:
122
+ style = self._default_style
123
+ if style is None:
124
+ style = dtheme.textstyles.get()
125
+ style.halign = "left"
126
+ style.valign = "center"
127
+
128
+ self._bullet_texts.append(
129
+ _BulletPointsText(
130
+ self._indent_level,
131
+ text,
132
+ style,
133
+ )
134
+ )
135
+
136
+ @error_handler
137
+ def draw(
138
+ self,
139
+ xy: Tuple[float, float],
140
+ ) -> None:
141
+ """Draws the list of bullet points starting from the specified location.
142
+
143
+ Args:
144
+ xy (Tuple[float, float]): The starting point (x, y) to draw the bullet points.
145
+ """
146
+ y = xy[1]
147
+ for bullet_text in self._bullet_texts:
148
+ indent = bullet_text.indent
149
+ text_ = bullet_text.text
150
+ textstyle = bullet_text.style
151
+
152
+ x = xy[0] + self._indent_width * indent
153
+ text(
154
+ xy=(x, y),
155
+ text=text_,
156
+ style=textstyle,
157
+ )
158
+
159
+ if indent == 0:
160
+ ...
161
+ elif indent not in self._bullet_shape_map:
162
+ ...
163
+ else:
164
+ bps = self._bullet_shape_map[indent]
165
+ function = bps.function
166
+ shapestyle = bps.style
167
+ args = bps.args
168
+
169
+ x = xy[0] + self._indent_width * (indent - 0.5)
170
+ args["xy"] = (x, y)
171
+ args["style"] = shapestyle
172
+ function(**args)
173
+
174
+ y -= self._vertical_margin
175
+
176
+
177
+ @dataclasses.dataclass
178
+ class _BulletPointsShape:
179
+ function: Callable
180
+ style: ShapeStyle
181
+ args: dict
182
+
183
+
184
+ @dataclasses.dataclass
185
+ class _BulletPointsText:
186
+ indent: int
187
+ text: str
188
+ style: TextStyle
@@ -11,8 +11,15 @@
11
11
 
12
12
  """Smart art module."""
13
13
 
14
+ # Using "bubblespeech as bubblespeech" for explisitly esposing contents.
15
+ # It is good for type checker and IDE.
16
+ # Warnings such as "reportPrivateImportUsage" might be appear if removing it.
17
+
18
+ from drawlib.v0_2.private.smartarts.boxlist import BoxList as BoxList
14
19
  from drawlib.v0_2.private.smartarts.bubblespeech import bubblespeech as bubblespeech
20
+ from drawlib.v0_2.private.smartarts.bulletpoints import BulletPoints as BulletPoints
15
21
  from drawlib.v0_2.private.smartarts.gridlayout import GridLayout as GridLayout
16
22
  from drawlib.v0_2.private.smartarts.pyramid import Pyramid as Pyramid
17
23
  from drawlib.v0_2.private.smartarts.sourcecode import SourceCode as SourceCode
24
+ from drawlib.v0_2.private.smartarts.table import Table as Table
18
25
  from drawlib.v0_2.private.smartarts.tree import TreeNode as TreeNode
@@ -16,11 +16,13 @@ from typing import List, Optional, Tuple, Union
16
16
  from drawlib.v0_2.private.core.model import ShapeStyle, ShapeTextStyle
17
17
  from drawlib.v0_2.private.core.theme import dtheme
18
18
  from drawlib.v0_2.private.core_canvas.canvas import rectangle
19
+ from drawlib.v0_2.private.util import error_handler
19
20
 
20
21
 
21
22
  class GridLayout:
22
23
  """Class for rendering multiple rectangles which fit to grid."""
23
24
 
25
+ @error_handler
24
26
  def __init__(
25
27
  self,
26
28
  num_column: int,
@@ -28,6 +30,7 @@ class GridLayout:
28
30
  default_r: int = 0,
29
31
  default_style: Union[str, ShapeStyle, None] = None,
30
32
  default_textstyle: Union[str, ShapeTextStyle, None] = None,
33
+ default_textangle: Optional[float] = None,
31
34
  ) -> None:
32
35
  """Initialize class."""
33
36
  self._num_column = num_column
@@ -39,9 +42,11 @@ class GridLayout:
39
42
  if isinstance(default_textstyle, str):
40
43
  default_textstyle = dtheme.rectangletextstyles.get(default_textstyle)
41
44
  self._default_textstyle = default_textstyle
45
+ self._default_textangle = default_textangle
42
46
 
43
47
  self._items: List[_GridLayoutItem] = []
44
48
 
49
+ @error_handler
45
50
  def add( # noqa: C901
46
51
  self,
47
52
  column_range: Tuple[int, int],
@@ -50,6 +55,8 @@ class GridLayout:
50
55
  style: Union[str, ShapeStyle, None] = None,
51
56
  text: str = "",
52
57
  textstyle: Union[str, ShapeTextStyle, None] = None,
58
+ textangle: Optional[float] = None,
59
+ text_xy_shift: Optional[Tuple[float, float]] = None,
53
60
  ) -> None:
54
61
  """
55
62
  Add an item to the grid layout.
@@ -66,6 +73,10 @@ class GridLayout:
66
73
  textstyle (Union[str, ShapeTextStyle, None], optional):
67
74
  The text style of the item. Can be a string key for a predefined text style,
68
75
  a ShapeTextStyle object, or None to use the default text style.
76
+ textangle (Optional[float], optional):
77
+ The angle of the text. Default is None, which is same to 0.
78
+ text_xy_shift (Optional[Tuple[float, float]], optional):
79
+ The XY shift of the text. Default is None, which is same to (0, 0).
69
80
 
70
81
  Raises:
71
82
  ValueError: If the column or row ranges are invalid or out of bounds.
@@ -73,20 +84,22 @@ class GridLayout:
73
84
  # validate column
74
85
  c1, c2 = column_range
75
86
  if c1 > c2:
76
- raise ValueError()
87
+ column_range = (c2, c1)
88
+ c1, c2 = c2, c1
77
89
  if c1 < 0:
78
- raise ValueError()
90
+ raise ValueError("Column range must be between 0 ~ last-index.")
79
91
  if c2 > self._num_column:
80
- raise ValueError()
92
+ raise ValueError("Column range must be between 0 ~ last-index.")
81
93
 
82
94
  # validate row
83
95
  r1, r2 = row_range
84
96
  if r1 > r2:
85
- raise ValueError()
97
+ row_range = (r2, r1)
98
+ r1, r2 = r2, r1
86
99
  if r1 < 0:
87
- raise ValueError()
100
+ raise ValueError("Row range must be between 0 ~ last-index.")
88
101
  if r2 > self._num_column:
89
- raise ValueError()
102
+ raise ValueError("Row range must be between 0 ~ last-index.")
90
103
 
91
104
  # string style to Style class
92
105
  if isinstance(style, str):
@@ -101,6 +114,26 @@ class GridLayout:
101
114
  style = self._default_style
102
115
  if textstyle is None:
103
116
  textstyle = self._default_textstyle
117
+ if textangle is None:
118
+ textangle = self._default_textangle
119
+
120
+ # set align left bottom
121
+ if style is None:
122
+ style = self._default_style
123
+ if style is None:
124
+ style = dtheme.rectanglestyles.get()
125
+ else:
126
+ style = style.copy()
127
+ style.halign = "left"
128
+ style.valign = "bottom"
129
+
130
+ # set text angle and xy_shift
131
+ if textstyle is None:
132
+ textstyle = dtheme.rectangletextstyles.get()
133
+ if textangle is not None:
134
+ textstyle.angle = textangle
135
+ if text_xy_shift is not None:
136
+ textstyle.xy_shift = text_xy_shift
104
137
 
105
138
  # push
106
139
  item = _GridLayoutItem(
@@ -113,6 +146,7 @@ class GridLayout:
113
146
  )
114
147
  self._items.append(item)
115
148
 
149
+ @error_handler
116
150
  def draw(
117
151
  self,
118
152
  xy: Tuple[float, float],
@@ -154,6 +188,7 @@ class GridLayout:
154
188
  outer_style=outer_style,
155
189
  )
156
190
 
191
+ @error_handler
157
192
  def draw_flexible( # noqa: C901
158
193
  self,
159
194
  xy: Tuple[float, float],
@@ -182,13 +217,13 @@ class GridLayout:
182
217
  """
183
218
  # validate
184
219
  if len(column_widths) != self._num_column:
185
- raise ValueError()
220
+ raise ValueError('Length of arg "column_widths" does not match to num of columns')
186
221
  if len(column_margins) != self._num_column + 1:
187
- raise ValueError()
222
+ raise ValueError('Length of arg "column_margins" does not match to num of columns + 1')
188
223
  if len(row_heights) != self._num_row:
189
- raise ValueError()
224
+ raise ValueError('Length of arg "row_heights" does not match to num of rows')
190
225
  if len(row_margins) != self._num_row + 1:
191
- raise ValueError()
226
+ raise ValueError('Length of arg "row_margins" does not match to num of rows + 1')
192
227
 
193
228
  # draw outer rectangle
194
229
  if outer_style is not None:
@@ -239,20 +274,6 @@ class GridLayout:
239
274
  width = width - margin_left - margin_right
240
275
  height = height - margin_bottom - margin_top
241
276
 
242
- # set align left bottom
243
- if style is None:
244
- style = self._default_style
245
- if style is None:
246
- style = dtheme.rectanglestyles.get()
247
- else:
248
- style = style.copy()
249
- style.halign = "left"
250
- style.valign = "bottom"
251
-
252
- # apply default text style if specified text style is None
253
- if textstyle is None:
254
- textstyle = self._default_textstyle
255
-
256
277
  # draw
257
278
  rectangle(
258
279
  xy=(xy[0] + lb_xy[0], xy[1] + lb_xy[1]),
@@ -270,6 +291,6 @@ class _GridLayoutItem:
270
291
  column_range: Tuple[int, int]
271
292
  row_range: Tuple[int, int]
272
293
  r: int
273
- style: Optional[ShapeStyle]
294
+ style: ShapeStyle
274
295
  text: str
275
- textstyle: Optional[ShapeTextStyle]
296
+ textstyle: ShapeTextStyle