added margins

This commit is contained in:
iLLiCiTiT 2020-01-13 12:45:46 +01:00
parent 449fb26aa7
commit 43fbdbf8fe

View file

@ -9,6 +9,15 @@ class BaseObj:
obj_type = None
available_parents = []
all_style_keys = [
"font-family", "font-size", "font-color", "font-bold", "font-italic",
"bg-color", "bg-alter-color",
"alignment-vertical", "alignment-horizontal",
"padding", "padding-left", "padding-right",
"padding-top", "padding-bottom",
"margin", "margin-left", "margin-right",
"margin-top", "margin-bottom", "width", "height"
]
def __init__(self, parent, style={}, name=None):
if not self.obj_type:
@ -34,9 +43,7 @@ class BaseObj:
self._style = style
self.id = uuid4()
self.parent = parent
self.name = name
self._style = style
self.items = {}
self.final_style = None
@ -51,18 +58,41 @@ class BaseObj:
"font-italic": False,
"bg-color": None,
"bg-alter-color": None,
"alignment-vertical": "left",
"alignment-vertical": "right",
"alignment-horizontal": "top",
"padding": 0,
"margin": 0,
},
"layer": {},
"image": {},
"text": {},
"table": {},
"table-item": {},
"table-item-col-0": {},
"#MyName": {}
"main_frame": {
"padding": 0,
"margin": 0
},
"layer": {
"padding": 0,
"margin": 0
},
"image": {
"padding": 0,
"margin": 0
},
"text": {
# "alignment-vertical": "left",
# "alignment-horizontal": "top",
"padding": 0,
"margin": 0
},
"table": {
"padding": 0,
"margin": 0
},
"table-item": {
"padding": 0,
"margin": 0
},
"__not_implemented__": {
"table-item-col-0": {},
"#MyName": {}
}
}
return default_style_v1
@ -97,10 +127,18 @@ class BaseObj:
style = self.main_style
for key, value in self._style.items():
if key in style:
style[key].update(value)
else:
if key in self.all_style_keys:
# TODO which variant is right?
style[self.obj_type][key] = value
# style["*"][key] = value
else:
if key not in style:
style[key] = {}
if isinstance(style[key], dict):
style[key].update(value)
else:
style[key] = value
if self.is_drawing:
self.final_style = style
@ -110,9 +148,8 @@ class BaseObj:
@property
def style(self):
style = self.full_style
style.update(self._style)
base = style.get("*", style.get("global")) or {}
base = style.get("*") or {}
obj_specific = style.get(self.obj_type) or {}
name_specific = {}
if self.name:
@ -128,49 +165,121 @@ class BaseObj:
return output
@property
def pos_x(self):
def item_pos_x(self):
return 0
@property
def pos_y(self):
def item_pos_y(self):
return 0
@property
def pos_start(self):
return (self.pos_x, self.pos_y)
def content_pos_x(self):
pos_x = self.item_pos_x
margin = self.style["margin"]
margin_left = self.style.get("margin-left") or margin
margin_right = self.style.get("margin-right") or margin
return pos_x + margin_left
@property
def pos_end(self):
pos_x, pos_y = self.pos_start
def content_pos_y(self):
pos_y = self.item_pos_y
margin = self.style["margin"]
margin_top = self.style.get("margin-top") or margin
margin_bottom = self.style.get("margin-bottom") or margin
return pos_y + margin_top
@property
def value_pos_x(self):
pos_x = self.content_pos_x * 1
padding = self.style["padding"]
padding_left = self.style.get("padding-left") or padding
pos_x += padding_left
return pos_x
@property
def value_pos_y(self):
pos_y = self.content_pos_y * 1
padding = self.style["padding"]
padding_top = self.style.get("padding-top") or padding
pos_y += padding_top
return pos_y
@property
def value_pos_start(self):
return (self.value_pos_x, self.value_pos_y)
@property
def value_pos_end(self):
pos_x, pos_y = self.value_pos_start
pos_x += self.width
pos_y += self.height
return (pos_x, pos_y)
@property
def max_width(self):
return self.style.get("max-width") or (self.width * 1)
def content_pos_start(self):
return (self.content_pos_x, self.content_pos_y)
@property
def max_height(self):
return self.style.get("max-height") or (self.height * 1)
def content_pos_end(self):
pos_x, pos_y = self.content_pos_start
pos_x += self.content_width
pos_y += self.content_height
return (pos_x, pos_y)
@property
def max_content_width(self):
width = self.max_width
def value_width(self):
raise NotImplementedError(
"Attribute <content_width> is not implemented <{}>".format(
self.__class__.__name__
)
)
@property
def value_height(self):
raise NotImplementedError(
"Attribute <content_width> is not implemented for <{}>".format(
self.__class__.__name__
)
)
@property
def content_width(self):
width = self.value_width
padding = self.style["padding"]
padding_left = self.style.get("padding-left") or padding
padding_right = self.style.get("padding-right") or padding
return (width - (padding_left + padding_right))
return width + padding_left + padding_right
@property
def max_content_height(self):
height = self.max_height
def content_height(self):
height = self.value_height
padding = self.style["padding"]
padding_top = self.style.get("padding-top") or padding
padding_bottom = self.style.get("padding-bottom") or padding
return (height - (padding_top + padding_bottom))
return height + padding_top + padding_bottom
@property
def width(self):
width = self.content_width
margin = self.style["margin"]
margin_left = self.style.get("margin-left") or margin
margin_right = self.style.get("margin-right") or margin
return width + margin_left + margin_right
@property
def height(self):
height = self.content_height
margin = self.style["margin"]
margin_top = self.style.get("margin-top") or margin
margin_bottom = self.style.get("margin-bottom") or margin
return height + margin_bottom + margin_top
def add_item(self, item):
self.items[item.id] = item
@ -187,11 +296,26 @@ class MainFrame(BaseObj):
available_parents = [None]
def __init__(self, width, height, *args, **kwargs):
kwargs["parent"] = None
super(MainFrame, self).__init__(*args, **kwargs)
self._width = width
self._height = height
self._is_drawing = False
@property
def value_width(self):
width = 0
for item in self.items.values():
width += item.width
return width
@property
def value_height(self):
height = 0
for item in self.items.values():
height += item.height
return height
@property
def width(self):
return self._width
@ -226,19 +350,19 @@ class Layer(BaseObj):
self._direction = direction
@property
def pos_x(self):
def item_pos_x(self):
if self.parent.obj_type == self.obj_type:
pos_x = self.parent.item_pos_x(self.id)
pos_x = self.parent.child_pos_x(self.id)
else:
pos_x = self.parent.pos_x
pos_x = self.parent.value_pos_x
return pos_x
@property
def pos_y(self):
def item_pos_y(self):
if self.parent.obj_type == self.obj_type:
pos_y = self.parent.item_pos_y(self.id)
pos_y = self.parent.child_pos_y(self.id)
else:
pos_y = self.parent.pos_y
pos_y = self.parent.value_pos_y
return pos_y
@property
@ -250,30 +374,21 @@ class Layer(BaseObj):
return 0
return self._direction
def item_pos_x(self, item_id):
pos_x = self.pos_x
def child_pos_x(self, item_id):
pos_x = self.value_pos_x
margin = self.style["margin"]
margin_left = self.style.get("margin-left") or margin
pos_x += margin_left
if self.direction != 0:
for id, item in self.items.items():
if id == item_id:
if item_id == id:
break
pos_x += item.width
pos_x += item.height
if item.obj_type != "image":
pos_x += 1
return pos_x
def item_pos_y(self, item_id):
pos_y = self.pos_y
def child_pos_y(self, item_id):
pos_y = self.value_pos_y
margin = self.style["margin"]
margin_top = self.style.get("margin-top") or margin
pos_y += margin_top
if self.direction != 1:
for id, item in self.items.items():
if item_id == id:
@ -281,21 +396,15 @@ class Layer(BaseObj):
pos_y += item.height
if item.obj_type != "image":
pos_y += 1
return pos_y
@property
def height(self):
margin = self.style["margin"]
margin_top = self.style.get("margin-top") or margin
margin_bottom = self.style.get("margin-bottom") or margin
height = (margin_top + margin_bottom)
def value_height(self):
height = 0
for item in self.items.values():
if self.direction == 0:
if height > item.height:
continue
# times 1 because won't get object pointer but number
height = item.height * 1
else:
@ -308,24 +417,19 @@ class Layer(BaseObj):
return height
@property
def width(self):
margin = self.style["margin"]
margin_left = self.style.get("margin-left") or margin
margin_right = self.style.get("margin-right") or margin
width = (margin_left + margin_right)
def value_width(self):
width = 0
for item in self.items.values():
if self.direction == 0:
if width > item.width:
continue
# times 1 because won't get object pointer but number
width = item.width * 1
else:
width += item.width
min_width = self.style.get("min-width")
if min_width > width:
if min_width and min_width > width:
return min_width
return width
@ -344,80 +448,12 @@ class BaseItem(BaseObj):
super(BaseItem, self).__init__(*args, **kwargs)
@property
def pos_x(self):
return self.parent.item_pos_x(self.id)
def item_pos_x(self):
return self.parent.child_pos_x(self.id)
@property
def pos_y(self):
return self.parent.item_pos_y(self.id)
@property
def content_pos_x(self):
padding = self.style["padding"]
padding_left = self.style.get("padding-left") or padding
margin = self.style["margin"]
margin_left = self.style.get("margin-left") or margin
return self.pos_x + margin_left + padding_left
@property
def content_pos_y(self):
padding = self.style["padding"]
padding_top = self.style.get("padding-top") or padding
margin = self.style["margin"]
margin_top = self.style.get("margin-top") or margin
return self.pos_y + margin_top + padding_top
@property
def content_width(self):
raise NotImplementedError(
"Attribute <content_width> is not implemented"
)
@property
def content_height(self):
raise NotImplementedError(
"Attribute <content_height> is not implemented"
)
@property
def width(self):
width = self.content_width
padding = self.style["padding"]
padding_left = self.style.get("padding-left") or padding
padding_right = self.style.get("padding-right") or padding
margin = self.style["margin"]
margin_left = self.style.get("margin-left") or margin
margin_right = self.style.get("margin-right") or margin
return (
width +
margin_left + margin_right +
padding_left + padding_right
)
@property
def height(self):
height = self.content_height
padding = self.style["padding"]
padding_top = self.style.get("padding-top") or padding
padding_bottom = self.style.get("padding-bottom") or padding
margin = self.style["margin"]
margin_top = self.style.get("margin-top") or margin
margin_bottom = self.style.get("margin-bottom") or margin
return (
height
+ margin_bottom + margin_top
+ padding_top + padding_bottom
)
def item_pos_y(self):
return self.parent.child_pos_y(self.id)
def add_item(self, *args, **kwargs):
raise Exception("Can't add item to an item, use layers instead.")
@ -440,20 +476,20 @@ class ItemImage(BaseItem):
def draw(self, image, drawer):
paste_image = Image.open(self.image_path)
paste_image = paste_image.resize(
(self.content_width, self.content_height),
(self.value_width, self.value_height),
Image.ANTIALIAS
)
image.paste(
paste_image,
(self.content_pos_x, self.content_pos_y)
(self.value_pos_x, self.value_pos_y)
)
@property
def content_width(self):
def value_width(self):
return self.style.get("width")
@property
def content_height(self):
def value_height(self):
return self.style.get("height")
@ -467,35 +503,27 @@ class ItemText(BaseItem):
def draw(self, image, drawer):
bg_color = self.style["bg-color"]
if bg_color and bg_color.lower() != "transparent":
padding = self.style["padding"]
padding_left = self.style.get("padding-left") or padding
padding_right = self.style.get("padding-right") or padding
padding_top = self.style.get("padding-top") or padding
padding_bottom = self.style.get("padding-bottom") or padding
# TODO border outline styles
drawer.rectangle(
(self.pos_start, self.pos_end),
(self.content_pos_start, self.content_pos_end),
fill=bg_color,
outline=None
)
text_pos_start = (self.content_pos_x, self.content_pos_y)
font_color = self.style["font-color"]
font_family = self.style["font-family"]
font_size = self.style["font-size"]
font = ImageFont.truetype(font_family, font_size)
drawer.text(
text_pos_start,
self.value_pos_start,
self.value,
font=font,
fill=font_color
)
@property
def content_width(self):
def value_width(self):
font_family = self.style["font-family"]
font_size = self.style["font-size"]
@ -504,7 +532,7 @@ class ItemText(BaseItem):
return width
@property
def content_height(self):
def value_height(self):
font_family = self.style["font-family"]
font_size = self.style["font-size"]
@ -571,15 +599,9 @@ class ItemTable(BaseItem):
def draw(self, image, drawer):
bg_color = self.style["bg-color"]
if bg_color and bg_color.lower() != "transparent":
padding = self.style["padding"]
padding_left = self.style.get("padding-left") or padding
padding_right = self.style.get("padding-right") or padding
padding_top = self.style.get("padding-top") or padding
padding_bottom = self.style.get("padding-bottom") or padding
# TODO border outline styles
drawer.rectangle(
(self.pos_start, self.pos_end),
(self.content_pos_start, self.content_pos_end),
fill=bg_color,
outline=None
)
@ -588,7 +610,7 @@ class ItemTable(BaseItem):
value.draw(image, drawer)
@property
def content_width(self):
def value_width(self):
row_heights, col_widths = self.size_values
width = 0
for _width in col_widths:
@ -599,7 +621,7 @@ class ItemTable(BaseItem):
return width
@property
def content_height(self):
def value_height(self):
row_heights, col_widths = self.size_values
height = 0
for _height in row_heights:
@ -611,8 +633,8 @@ class ItemTable(BaseItem):
def pos_info_by_cord(self, cord_x, cord_y):
row_heights, col_widths = self.size_values
pos_x = self.pos_x
pos_y = self.pos_y
pos_x = self.value_pos_x
pos_y = self.value_pos_y
width = 0
height = 0
for idx, value in enumerate(col_widths):
@ -627,12 +649,6 @@ class ItemTable(BaseItem):
break
pos_y += value
padding = self.style["padding"]
padding_left = self.style.get("padding-left") or padding
padding_top = self.style.get("padding-top") or padding
pos_x += padding_left
pos_y += padding_top
return (pos_x, pos_y, width, height)
def filled_style(self, cord_x, cord_y):
@ -652,7 +668,7 @@ class TableField(BaseItem):
self.value = value
@property
def content_width(self):
def value_width(self):
font_family = self.style["font-family"]
font_size = self.style["font-size"]
@ -661,7 +677,7 @@ class TableField(BaseItem):
return width
@property
def content_height(self):
def value_height(self):
font_family = self.style["font-family"]
font_size = self.style["font-size"]
@ -669,15 +685,19 @@ class TableField(BaseItem):
height = font.getsize(self.value)[1] + 1
return height
def content_pos_x(self, pos_x, width):
padding = self.style["padding"]
padding_left = self.style.get("padding-left") or padding
return pos_x + padding_left
@property
def item_pos_x(self):
pos_x, pos_y, width, height = (
self.parent.pos_info_by_cord(self.cord_x, self.cord_y)
)
return pos_x
def content_pos_y(self, pos_y, height):
padding = self.style["padding"]
padding_top = self.style.get("padding-top") or padding
return pos_y + padding_top
@property
def item_pos_y(self):
pos_x, pos_y, width, height = (
self.parent.pos_info_by_cord(self.cord_x, self.cord_y)
)
return pos_y
def draw(self, image, drawer):
pos_x, pos_y, width, height = (
@ -700,18 +720,13 @@ class TableField(BaseItem):
outline=None
)
text_pos_start = (
self.content_pos_x(pos_x, width),
self.content_pos_y(pos_y, height)
)
font_color = self.style["font-color"]
font_family = self.style["font-family"]
font_size = self.style["font-size"]
font = ImageFont.truetype(font_family, font_size)
drawer.text(
text_pos_start,
self.value_pos_start,
self.value,
font=font,
fill=font_color