def text_wrapped(s): """ Word wrapping text display widget. Recommended for long chunks of text. """ def f(): imgui.push_text_wrap_pos() imgui.text(s) imgui.pop_text_wrap_pos() return lift(f)
def columns(elems, identifier=None, vert_borders=True, hor_borders=True, widths=None): """ Table, using the imgui columns API. Args: elems (List[List[Widget]]): 2D array of widgets. A list containing another list for each row. len() of the first row defines the amount of columns, that will be rendered. > Do note, that despite the first row defines the amount of rendered columns, all rows still must have the the same len(). < identifier (str): Name of the widget. vert_borders (bool): Toggle vertical borders on/off. hor_borders (bool): Toggle horizontal borders on/off. widths (List[Union[int,float]]): is an optional vector of column widths in pixels. May contain None values. Returns: `concur.core.orr` wrapping the column widget including all its rows. """ n_columns = len(elems[0]) if widths is None: widths = [] if hor_borders: sep = [separator(), *[nothing() for _ in range(n_columns - 1)]] n, i = 1, 1 while i < len(elems): elems.insert(i, sep) i += (n + 1) accum = [lift(imgui.columns, n_columns, identifier, vert_borders)] for i, w in enumerate(widths): if w is not None: accum.append(lift(imgui.set_column_width, i, w)) for row in elems: assert len(row) == n_columns for widget in row: accum.append(widget) accum.append(lift(imgui.next_column)) accum.append(lift(imgui.columns, 1)) return orr(accum)
def test_window(): """ ImGui test window with a multitude of widgets. """ return lift(imgui.show_test_window)
def text_colored(s, color): """ Passive colored text display widget. """ r, g, b, a = color_to_rgba_tuple(color) return lift(imgui.text_colored, s, r, g, b, a)
def same_line(): """ Call between widgets to layout them horizontally. This is Consider using `concur.widgets.orr_same_line` instead as it is more robust. """ return lift(imgui.same_line)
def text(s): """ Passive text display widget. """ return lift(imgui.text, s)
def spacing(): """ Extra vertical space. """ return lift(imgui.spacing)
def separator(): """ Horizontal separator. """ return lift(imgui.separator)
def group(widget): return orr([lift(imgui.begin_group), widget, lift(imgui.end_group)])
def dummy(width, height): """ Add a dummy element of a given `width` and `height`. Useful for custom-sized vertical and horizontal spacings. """ return lift(imgui.dummy, width, height)
def _frame(content_gen, show_grid, tf, event_gen): min_tick_spacing = 50 viewport_s = [r + o for r, o in zip(tf.view_s, margins)] viewport_c = np.concatenate([ np.matmul(tf.s2c, [*viewport_s[:2], 1])[:2], np.matmul(tf.s2c, [*viewport_s[2:], 1])[:2] ]) bg = draw.rect_filled(*tf.view_s, (1, 1, 1, 1)) if viewport_s[2] <= viewport_s[0] or viewport_s[3] <= viewport_s[1]: return bg def ticks(a, b, max_n_ticks): a, b = min(a, b), max(a, b) w = b - a min_sep = w / max_n_ticks candidates = np.array( [10**np.floor(np.log10(min_sep)) * f for f in [1, 2, 5, 10]]) sep = candidates[candidates > min_sep] if len(sep) == 0: return [] else: sep = sep[0] return np.arange(np.ceil(a / sep) * sep, b + 1e-10, sep) hticks_c = ticks(viewport_c[3], viewport_c[1], (viewport_s[3] - viewport_s[1]) / min_tick_spacing) vticks_c = ticks(viewport_c[2], viewport_c[0], (viewport_s[2] - viewport_s[0]) / min_tick_spacing) hticks_s = np.matmul( tf.c2s, np.stack([np.zeros_like(hticks_c), hticks_c, np.ones_like(hticks_c)]))[1] vticks_s = np.matmul( tf.c2s, np.stack([vticks_c, np.zeros_like(vticks_c), np.ones_like(vticks_c)]))[0] def tick_labels(): def tick_format(ticks_c, align): mag = max(1, abs(ticks_c[0]), abs(ticks_c[-1])) stride = abs(ticks_c[1] - ticks_c[0]) if len(ticks_c) > 1 else 1 some_negative = ticks_c[0] < 0 or ticks_c[-1] < 0 msd = int(np.floor(np.log10(mag))) lsd = int(np.minimum(0, np.floor(np.log10(stride)))) if 1 + msd - lsd + (lsd < 0) + some_negative > 6: format = f"{{:{align}6.1g}}" else: format = f"{{:{align}6.{-lsd}f}}" return format print( f"msd: {msd}, stride: {lsd}, n_chars: {1 + msd - lsd + (lsd < 0) + some_negative}" ) format_x = f"{{:<6.{-lsd}f}}" format_y = f"{{:>6.{-lsd}f}}" xtick_labels = [ draw.text( tick_format(vticks_c, "<").format(tc), ts, viewport_s[3], (0, 0, 0, 1)) for ts, tc in zip(vticks_s, vticks_c) ] ytick_labels = [ draw.text( tick_format(hticks_c, ">").format(tc), viewport_s[0] - 45, ts - 7, (0, 0, 0, 1)) for ts, tc in zip(hticks_s, hticks_c) ] return orr(xtick_labels + ytick_labels) def grid(): hlines = [ draw.line(tf.view_s[0], tick, tf.view_s[2], tick, (0, 0, 0, 0.3)) for tick in hticks_s ] vlines = [ draw.line(tick, tf.view_s[1], tick, tf.view_s[3], (0, 0, 0, 0.3)) for tick in vticks_s ] return orr(hlines + vlines) return orr([ bg, lift(imgui.push_clip_rect, *viewport_s, True), optional(content_gen is not None, content_gen, tf, event_gen), optional(show_grid, grid), lift(imgui.pop_clip_rect), draw.rect(*viewport_s, (0, 0, 0, 1)), tick_labels(), ])