Source code for fury.ui.helpers

"""Helper variable or function for UI Elements."""

import numpy as np

from fury.decorators import warn_on_args_to_kwargs

TWO_PI = 2 * np.pi


[docs] @warn_on_args_to_kwargs() def clip_overflow(textblock, width, *, side="right"): """Clips overflowing text of TextBlock2D with respect to width. Parameters ---------- textblock : TextBlock2D The textblock object whose text needs to be clipped. width : int Required width of the clipped text. side : str, optional Clips the overflowing text according to side. It takes values "left" or "right". Returns ------- clipped text : str Clipped version of the text. """ original_str = textblock.message prev_bg = textblock.have_bg clip_idx = check_overflow(textblock, width, overflow_postfix="...", side=side) if clip_idx == 0: return original_str textblock.have_bg = prev_bg return textblock.message
[docs] @warn_on_args_to_kwargs() def wrap_overflow(textblock, wrap_width, *, side="right"): """Wraps overflowing text of TextBlock2D with respect to width. Parameters ---------- textblock : TextBlock2D The textblock object whose text needs to be wrapped. wrap_width : int Required width of the wrapped text. side : str, optional Clips the overflowing text according to side. It takes values "left" or "right". Returns ------- wrapped text : str Wrapped version of the text. """ original_str = textblock.message str_copy = textblock.message wrap_idxs = [] wrap_idx = check_overflow(textblock, wrap_width, overflow_postfix="", side=side) if wrap_idx == 0: return original_str wrap_idxs.append(wrap_idx) while wrap_idx != 0: str_copy = str_copy[wrap_idx:] textblock.message = str_copy wrap_idx = check_overflow(textblock, wrap_width, overflow_postfix="", side=side) if wrap_idx != 0: wrap_idxs.append(wrap_idxs[-1] + wrap_idx + 1) for idx in wrap_idxs: original_str = original_str[:idx] + "\n" + original_str[idx:] textblock.message = original_str return textblock.message
[docs] @warn_on_args_to_kwargs() def check_overflow(textblock, width, *, overflow_postfix="", side="right"): """Checks if the text is overflowing. Parameters ---------- textblock : TextBlock2D The textblock object whose text is to be checked. width: int Required width of the text. overflow_postfix: str, optional Postfix to be added to the text if it is overflowing. Returns ------- mid_ptr: int Overflow index of the text. """ side = side.lower() if side not in ["left", "right"]: raise ValueError("side can only take values 'left' or 'right'") original_str = textblock.message start_ptr = 0 mid_ptr = 0 end_ptr = len(original_str) if side == "left": original_str = original_str[::-1] if textblock.cal_size_from_message()[0] <= width: return 0 while start_ptr < end_ptr: mid_ptr = (start_ptr + end_ptr) // 2 textblock.message = original_str[:mid_ptr] + overflow_postfix if textblock.cal_size_from_message()[0] < width: start_ptr = mid_ptr elif textblock.cal_size_from_message()[0] > width: end_ptr = mid_ptr if ( mid_ptr == (start_ptr + end_ptr) // 2 or textblock.cal_size_from_message()[0] == width ): if side == "left": textblock.message = textblock.message[::-1] return mid_ptr
[docs] def cal_bounding_box_2d(vertices): """Calculate the min, max position and the size of the bounding box. Parameters ---------- vertices : ndarray vertices of the actors. """ if vertices.ndim != 2 or vertices.shape[1] not in [2, 3]: raise IOError("vertices should be a 2D array with shape (n,2) or (n,3).") if vertices.shape[1] == 3: vertices = vertices[:, :-1] min_x, min_y = vertices[0] max_x, max_y = vertices[0] for x, y in vertices: if x < min_x: min_x = x if y < min_y: min_y = y if x > max_x: max_x = x if y > max_y: max_y = y bounding_box_min = np.asarray([min_x, min_y], dtype="int") bounding_box_max = np.asarray([max_x, max_y], dtype="int") bounding_box_size = np.asarray([max_x - min_x, max_y - min_y], dtype="int") return bounding_box_min, bounding_box_max, bounding_box_size
[docs] def rotate_2d(vertices, angle): """Rotate the given vertices by an angle. Parameters ---------- vertices : ndarray vertices of the actors. angle: float Value by which the vertices are rotated in radian. """ if vertices.ndim != 2 or vertices.shape[1] != 3: raise IOError("vertices should be a 2D array with shape (n,3).") rotation_matrix = np.array( [ [np.cos(angle), np.sin(angle), 0], [-np.sin(angle), np.cos(angle), 0], [0, 0, 1], ] ) new_vertices = np.matmul(vertices, rotation_matrix) return new_vertices