text: # -*- coding: utf-8 -*-
  from __future__ import absolute_import
  
  import glfw
  import imgui
  
  from . import compute_fb_scale
  from .opengl import ProgrammablePipelineRenderer
  
  
  class GlfwRenderer(ProgrammablePipelineRenderer):
      def __init__(self, window, attach_callbacks=True):
          super(GlfwRenderer, self).__init__()
          self.window = window
  
          if attach_callbacks:
              glfw.set_key_callback(self.window, self.keyboard_callback)
              glfw.set_cursor_pos_callback(self.window, self.mouse_callback)
              glfw.set_window_size_callback(self.window, self.resize_callback)
              glfw.set_char_callback(self.window, self.char_callback)
              glfw.set_scroll_callback(self.window, self.scroll_callback)
  
          self.io.display_size = glfw.get_framebuffer_size(self.window)
          self.io.get_clipboard_text_fn = self._get_clipboard_text
          self.io.set_clipboard_text_fn = self._set_clipboard_text
  
          self._map_keys()
          self._gui_time = None
  
      def _get_clipboard_text(self):
          return glfw.get_clipboard_string(self.window)
  
      def _set_clipboard_text(self, text):
          glfw.set_clipboard_string(self.window, text)
  
      def _map_keys(self):
          key_map = self.io.key_map
  
          key_map[imgui.KEY_TAB] = glfw.KEY_TAB
          key_map[imgui.KEY_LEFT_ARROW] = glfw.KEY_LEFT
          key_map[imgui.KEY_RIGHT_ARROW] = glfw.KEY_RIGHT
          key_map[imgui.KEY_UP_ARROW] = glfw.KEY_UP
          key_map[imgui.KEY_DOWN_ARROW] = glfw.KEY_DOWN
          key_map[imgui.KEY_PAGE_UP] = glfw.KEY_PAGE_UP
          key_map[imgui.KEY_PAGE_DOWN] = glfw.KEY_PAGE_DOWN
          key_map[imgui.KEY_HOME] = glfw.KEY_HOME
          key_map[imgui.KEY_END] = glfw.KEY_END
          key_map[imgui.KEY_INSERT] = glfw.KEY_INSERT
          key_map[imgui.KEY_DELETE] = glfw.KEY_DELETE
          key_map[imgui.KEY_BACKSPACE] = glfw.KEY_BACKSPACE
          key_map[imgui.KEY_SPACE] = glfw.KEY_SPACE
          key_map[imgui.KEY_ENTER] = glfw.KEY_ENTER
          key_map[imgui.KEY_ESCAPE] = glfw.KEY_ESCAPE
          key_map[imgui.KEY_PAD_ENTER] = glfw.KEY_KP_ENTER
          key_map[imgui.KEY_A] = glfw.KEY_A
          key_map[imgui.KEY_C] = glfw.KEY_C
          key_map[imgui.KEY_V] = glfw.KEY_V
          key_map[imgui.KEY_X] = glfw.KEY_X
          key_map[imgui.KEY_Y] = glfw.KEY_Y
          key_map[imgui.KEY_Z] = glfw.KEY_Z
  
      def keyboard_callback(self, window, key, scancode, action, mods):
          # perf: local for faster access
          io = self.io
  
          if action == glfw.PRESS:
              io.keys_down[key] = True
          elif action == glfw.RELEASE:
              io.keys_down[key] = False
  
          io.key_ctrl = (
              io.keys_down[glfw.KEY_LEFT_CONTROL] or
              io.keys_down[glfw.KEY_RIGHT_CONTROL]
          )
  
          io.key_alt = (
              io.keys_down[glfw.KEY_LEFT_ALT] or
              io.keys_down[glfw.KEY_RIGHT_ALT]
          )
  
          io.key_shift = (
              io.keys_down[glfw.KEY_LEFT_SHIFT] or
              io.keys_down[glfw.KEY_RIGHT_SHIFT]
          )
  
          io.key_super = (
              io.keys_down[glfw.KEY_LEFT_SUPER] or
              io.keys_down[glfw.KEY_RIGHT_SUPER]
          )
  
      def char_callback(self, window, char):
          io = imgui.get_io()
  
          if 0 < char < 0x10000:
              io.add_input_character(char)
  
      def resize_callback(self, window, width, height):
          self.io.display_size = width, height
  
      def mouse_callback(self, *args, **kwargs):
          pass
  
      def scroll_callback(self, window, x_offset, y_offset):
          self.io.mouse_wheel_horizontal = x_offset
          self.io.mouse_wheel = y_offset
  
      def process_inputs(self):
          io = imgui.get_io()
  
          window_size = glfw.get_window_size(self.window)
          fb_size = glfw.get_framebuffer_size(self.window)
  
          io.display_size = window_size
          io.display_fb_scale = compute_fb_scale(window_size, fb_size)
          io.delta_time = 1.0/60
  
          if glfw.get_window_attrib(self.window, glfw.FOCUSED):
              io.mouse_pos = glfw.get_cursor_pos(self.window)
          else:
              io.mouse_pos = -1, -1
  
          io.mouse_down[0] = glfw.get_mouse_button(self.window, 0)
          io.mouse_down[1] = glfw.get_mouse_button(self.window, 1)
          io.mouse_down[2] = glfw.get_mouse_button(self.window, 2)
  
          current_time = glfw.get_time()
  
          if self._gui_time:
              self.io.delta_time = current_time - self._gui_time
          else:
              self.io.delta_time = 1. / 60.
          if(io.delta_time <= 0.0): io.delta_time = 1./ 1000.
  
          self._gui_time = current_time
  