# Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved. # # NVIDIA CORPORATION and its licensors retain all intellectual property # and proprietary rights in and to this software, related documentation # and any modifications thereto. Any use, reproduction, disclosure or # distribution of this software and related documentation without an express # license agreement from NVIDIA CORPORATION is strictly prohibited. import os import imgui import imgui.integrations.glfw from . import glfw_window from . import imgui_utils from . import text_utils #---------------------------------------------------------------------------- class ImguiWindow(glfw_window.GlfwWindow): def __init__(self, *, title='ImguiWindow', font=None, font_sizes=range(14,24), **glfw_kwargs): if font is None: font = text_utils.get_default_font() font_sizes = {int(size) for size in font_sizes} super().__init__(title=title, **glfw_kwargs) # Init fields. self._imgui_context = None self._imgui_renderer = None self._imgui_fonts = None self._cur_font_size = max(font_sizes) # Delete leftover imgui.ini to avoid unexpected behavior. if os.path.isfile('imgui.ini'): os.remove('imgui.ini') # Init ImGui. self._imgui_context = imgui.create_context() self._imgui_renderer = _GlfwRenderer(self._glfw_window) self._attach_glfw_callbacks() imgui.get_io().ini_saving_rate = 0 # Disable creating imgui.ini at runtime. imgui.get_io().mouse_drag_threshold = 0 # Improve behavior with imgui_utils.drag_custom(). self._imgui_fonts = {size: imgui.get_io().fonts.add_font_from_file_ttf(font, size) for size in font_sizes} self._imgui_renderer.refresh_font_texture() def close(self): self.make_context_current() self._imgui_fonts = None if self._imgui_renderer is not None: self._imgui_renderer.shutdown() self._imgui_renderer = None if self._imgui_context is not None: #imgui.destroy_context(self._imgui_context) # Commented out to avoid creating imgui.ini at the end. self._imgui_context = None super().close() def _glfw_key_callback(self, *args): super()._glfw_key_callback(*args) self._imgui_renderer.keyboard_callback(*args) @property def font_size(self): return self._cur_font_size @property def spacing(self): return round(self._cur_font_size * 0.4) def set_font_size(self, target): # Applied on next frame. self._cur_font_size = min((abs(key - target), key) for key in self._imgui_fonts.keys())[1] def begin_frame(self): # Begin glfw frame. super().begin_frame() # Process imgui events. self._imgui_renderer.mouse_wheel_multiplier = self._cur_font_size / 10 if self.content_width > 0 and self.content_height > 0: self._imgui_renderer.process_inputs() # Begin imgui frame. imgui.new_frame() imgui.push_font(self._imgui_fonts[self._cur_font_size]) imgui_utils.set_default_style(spacing=self.spacing, indent=self.font_size, scrollbar=self.font_size+4) def end_frame(self): imgui.pop_font() imgui.render() imgui.end_frame() self._imgui_renderer.render(imgui.get_draw_data()) super().end_frame() #---------------------------------------------------------------------------- # Wrapper class for GlfwRenderer to fix a mouse wheel bug on Linux. class _GlfwRenderer(imgui.integrations.glfw.GlfwRenderer): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.mouse_wheel_multiplier = 1 def scroll_callback(self, window, x_offset, y_offset): self.io.mouse_wheel += y_offset * self.mouse_wheel_multiplier #----------------------------------------------------------------------------