def recalc_size(self): spcy = 20 spcb = 10 self.content_pos = self.position + Vec2(4, spcy) self.content_size = self.size - Vec2(8, spcy + spcb) self.header_size = Vec2(self.size.x, spcy - 2) for chld in self.children: chld.position = self.content_pos chld.size = self.content_size super().recalc_size()
def __init__(self, closeable=False, **kwargs): super().__init__(**kwargs) self._dragged = False self._last_mouse_pos = Vec2(0, 0) self.ext_extra_priority = 0 self._docked = False self.size = (300, 300) self.min_size = Vec2(100, 100) self.closeable = closeable self.recalc_size()
def get_kerning(self, font_name, left_char, right_char, pixel_size=48): for provider in self._mapping[font_name]: v = provider.get_font_kerning(left_char, right_char, size=pixel_size) if v is not None: return v return Vec2(0, 0)
def __init__(self, name=None, text=None): if not hasattr(self, "name"): self.name = name if not hasattr(self, "_position"): self._position = Vec2(0, 0) if not hasattr(self, "_size"): self._size = Vec2(100, 100) if not hasattr(self, "size_hint"): self.size_hint = (None, None) if not hasattr(self, "children") and type(self) != RootNodeB: self.children = [] self.image_id = None self.image_mode = None #Other options are: "fit", "fill" self.image_ratio = 1 self.hidden = False if text is not None: self.__text = text else: self.__text = ""
def recalc_size(self): n = len(self.children) used = 0 size_adjust = self.spc * 2 if self.size_hint_func is None: size_hints = self.size_hints else: size_hints = self.size_hint_func(self, self.size_hints) #[self.size_hint_func(hint) if hint is not None else None for hint in self.size_hints] for hint in size_hints: if hint is not None: n -= 1 used += hint if n == 0: n = 1 if self.vertical: fr = min(self.max_size, (1 - used) / n) size = self.size.x, (self.size.y * fr) advancement_index = 1 else: fr = min(self.max_size, (1 - used) / n) size = self.size.x * fr, (self.size.y) advancement_index = 0 pos = Vec2(*self.position) for hint, child in zip_longest(size_hints, self.children): if hint is not None: if self.vertical: usize = size[0], self.size.y * hint else: usize = self.size.x * hint, size[1] else: usize = size child.position = pos + Vec2(self.spc, self.spc) child.size = (usize[0] - self.spc * 2, usize[1] - self.spc * 2) pos[advancement_index] += usize[advancement_index] super().recalc_size()
def recalc_size(self): self.requires_size_recalculation = False my_corner = self.position + self.size for chld in self.children: if getattr(chld, "ext_docked", True): chld.position = self.position chld.size = self.size else: chld_corner = chld.position + Vec2(chld.size.x, 20) if chld_corner.x > my_corner.x: chld.position.x -= chld_corner.x - my_corner.x if chld_corner.y > my_corner.y: chld.position.y -= chld_corner.y - my_corner.y if chld.position.x < self.position.x: chld.position.x = self.position.x if chld.position.y < self.position.y: chld.position.y = self.position.y if chld.size.x > self.size.x: chld.size.x = self.size.x if chld.size.y > self.size.y: chld.size.y = self.size.y super().recalc_size()
def render_node(self, node: NodeB): self.image_ident = 0 if node.type == "window": self.render_queue.extend(self.text_queue) self.text_queue.clear() if node.hidden: return highlighted = False selected = is_selected_cb.get()(node) if node.type in ["button", "togglebutton", "radiobutton"]: highlighted = node.hovered or getattr(node, "state", False) selected = node.pressed bg_color = None spc = 2 if node.type in [ "button", "textinput", "scrollbar", "togglebutton", "radiobutton", "progressbar", QlibsNodeTypes.COLUMN_DIAGRAM ]: bg_color = self.param_bg_color_sel if node.type == "window": bg_color = self.param_bg_color spc = 0 if bg_color is not None: self.render_queue.append( QueuedBG(pos=node.position + Vec2(spc, spc), size=node.size - Vec2(spc * 2, spc * 2), color=bg_color)) if node.type == "window": self.render_queue.append( QueuedFGOutline(pos=node.position, size=node.size, color=self.param_fg_color)) self.render_queue.append( QueuedBG(pos=node.position, size=node.header_size, color=self.param_fg_color)) if selected or highlighted: color = (0, 0, 0, 0) if highlighted: color = self.param_fg_color_hov if selected: color = self.param_fg_color_sel self.render_queue.append( QueuedFGOutline(pos=node.position + Vec2(spc, spc), size=node.size - Vec2(spc * 2, spc * 2), color=color)) if node.type == "progressbar": size = node.size - Vec2(8, 8) size.x *= node.fraction self.render_queue.append( QueuedBG(pos=node.position + Vec2(4, 4), size=size, color=self.param_fg_color)) if node.type == "scrollbar": size = node.size - Vec2(8, 8) pos = node.position + Vec2(4, 4) pos.y += size.y * (node.pos * 0.9) size.y *= 0.1 self.render_queue.append( QueuedBG(pos=pos, size=size, color=self.param_fg_color)) if node.type == "customrender": self.render_queue.extend(self.text_queue) self.text_queue.clear() viewport = (node.position.x, self.window.height - node.position.y - node.size.y, node.size.x, node.size.y) self.render_queue.append( QueuedCustom(node.render, viewport=viewport)) if node.text is not None: if node.type == "text" or isinstance(node.text, FormattedText): pos = Vec2(*node.position) pos.y = self.window.height - pos.y - node.size.y scissor = tuple(map(int, (*pos, *node.size))) self.text_queue.append( QueuedText( text=node.text, pos=Vec2(node.position.x + 4, node.position.y + node.scale), multiline=node.size.x - 8, scissor=scissor, scale=self.param_max_text_size, )) else: text = node.text used_scale = min(node.size.y, self.param_max_text_size) ident = 8 size = self.font_render.calc_size(text, scale=used_scale) if size > 0 and size > node.size.x - self.image_ident - ident: used_scale *= (node.size.x - self.image_ident - ident) / size size = self.font_render.calc_size(text, scale=used_scale) align_ajust = node.size.x // 2 - size // 2 pos = node.position + node.size // 2 pos.x += self.image_ident + align_ajust - node.size.x // 2 text_height = self.font_render.calc_height(text, scale=used_scale) if text_height == 0: text_height = self.param_max_text_size pos.y += text_height // 2 self.text_queue.append( QueuedText(text=text, pos=pos, scale=used_scale)) if node.type == "textinput" and is_selected_cb.get()(node): cpos = node.position.x + self.font_render.calc_size( text[:node.cursor], scale=used_scale) + align_ajust cy = node.position.y + node.size.y / 2 txh = min(text_height / 2 + 5, (node.size.y) / 2) self.render_queue.append( QueuedFGLine(p0=Vec2(cpos, cy - txh), p1=Vec2(cpos, cy + txh), color=self.param_fg_color_sel, width=1)) if node.type is QlibsNodeTypes.COLUMN_DIAGRAM: if node.displayed_data: mx = max((x.value for x in node.displayed_data)) if mx == 0: scale_y = 1 else: scale_y = 1 / mx spx = 2 bspy = 30 diag_size_y = node.size.y - bspy scale_y *= diag_size_y size_x = min(node.size.x / len(node.displayed_data), 50) for i, datum in enumerate(node.displayed_data): datum_size = datum.value * scale_y pos = Vec2(node.position.x + i * size_x, node.position.y + node.size.y - datum_size) text = str(datum.value) text_scale = 20 text_size = self.font_render.calc_size( text, scale=text_scale) self.render_queue.append( QueuedBG(pos, Vec2(size_x - spx, datum_size), color=self.param_fg_color)) pos = Vec2(*pos) if datum.tag is not None and datum_size < text_scale: pos.y -= text_scale - datum_size self.text_queue.append( QueuedText(text, pos + Vec2( (size_x - text_size) / 2, -4), scale=text_scale)) if datum.tag is not None: text = datum.tag text_size = self.font_render.calc_size( text, scale=text_scale) pos = Vec2(node.position.x + i * size_x, node.position.y + node.size.y) self.text_queue.append( QueuedText(text, pos + Vec2( (size_x - text_size) / 2, -4), scale=text_scale))
def get_font_kerning(self, left_char, right_char, size=48): self.font.set_pixel_sizes(0, size) vec = self.font.get_kerning(left_char, right_char) return Vec2(vec.x, vec.y)
def size(self, val): self._size = Vec2(*val)
def position(self, val): self._position = Vec2(*val)