text: # -*- coding: utf-8 -*-
  from __future__ import absolute_import
  
  from pyglet.window import key, mouse
  
  import imgui
  
  from . import compute_fb_scale
  from .opengl import FixedPipelineRenderer
  
  
  class PygletMixin(object):
      REVERSE_KEY_MAP = {
          key.TAB: imgui.KEY_TAB,
          key.LEFT: imgui.KEY_LEFT_ARROW,
          key.RIGHT: imgui.KEY_RIGHT_ARROW,
          key.UP: imgui.KEY_UP_ARROW,
          key.DOWN: imgui.KEY_DOWN_ARROW,
          key.PAGEUP: imgui.KEY_PAGE_UP,
          key.PAGEDOWN: imgui.KEY_PAGE_DOWN,
          key.HOME: imgui.KEY_HOME,
          key.END: imgui.KEY_END,
          key.DELETE: imgui.KEY_DELETE,
          key.SPACE: imgui.KEY_SPACE,
          key.BACKSPACE: imgui.KEY_BACKSPACE,
          key.RETURN: imgui.KEY_ENTER,
          key.ESCAPE: imgui.KEY_ESCAPE,
          key.A: imgui.KEY_A,
          key.C: imgui.KEY_C,
          key.V: imgui.KEY_V,
          key.X: imgui.KEY_X,
          key.Y: imgui.KEY_Y,
          key.Z: imgui.KEY_Z,
      }
  
      def _map_keys(self):
          key_map = self.io.key_map
  
          # note: we cannot use default mechanism of mapping keys
          #       because pyglet uses weird key translation scheme
          for value in self.REVERSE_KEY_MAP.values():
              key_map[value] = value
  
      def on_mouse_motion(self, x, y, dx, dy):
          self.io.mouse_pos = x, self.io.display_size.y - y
  
      def on_key_press(self, key, mods):
          if key in self.REVERSE_KEY_MAP:
              self.io.keys_down[self.REVERSE_KEY_MAP[key]] = True
  
      def on_key_release(self, key, mods):
          if key in self.REVERSE_KEY_MAP:
              self.io.keys_down[self.REVERSE_KEY_MAP[key]] = False
  
      def on_text(self, text):
          io = imgui.get_io()
  
          for char in text:
              io.add_input_character(ord(char))
  
      def on_mouse_drag(self, x, y, dx, dy, button, modifiers):
          self.io.mouse_pos = x, self.io.display_size.y - y
  
          if button == mouse.LEFT:
              self.io.mouse_down[0] = 1
  
          if button == mouse.MIDDLE:
              self.io.mouse_down[1] = 1
  
          if button == mouse.RIGHT:
              self.io.mouse_down[2] = 1
  
      def on_mouse_press(self, x, y, button, modifiers):
          self.io.mouse_pos = x, self.io.display_size.y - y
  
          if button == mouse.LEFT:
              self.io.mouse_down[0] = 1
  
          if button == mouse.MIDDLE:
              self.io.mouse_down[1] = 1
  
          if button == mouse.RIGHT:
              self.io.mouse_down[2] = 1
  
      def on_mouse_release(self, x, y, button, modifiers):
          self.io.mouse_pos = x, self.io.display_size.y - y
  
          if button == mouse.LEFT:
              self.io.mouse_down[0] = 0
  
          if button == mouse.MIDDLE:
              self.io.mouse_down[1] = 0
  
          if button == mouse.RIGHT:
              self.io.mouse_down[2] = 0
  
      def on_mouse_scroll(self, x, y, mods, scroll):
          self.io.mouse_wheel = scroll
  
      def on_resize(self, width, height):
          self.io.display_size = width, height
  
  
  class PygletRenderer(PygletMixin, FixedPipelineRenderer):
      def __init__(self, window, attach_callbacks=True):
          super(PygletRenderer, self).__init__()
          window_size = window.get_size()
          viewport_size = window.get_viewport_size()
  
          self.io.display_size = window_size
          self.io.display_fb_scale = compute_fb_scale(window_size, viewport_size)
  
          self._map_keys()
  
          if attach_callbacks:
              window.push_handlers(
                  self.on_mouse_motion,
                  self.on_key_press,
                  self.on_key_release,
                  self.on_text,
                  self.on_mouse_drag,
                  self.on_mouse_press,
                  self.on_mouse_release,
                  self.on_mouse_scroll,
                  self.on_resize,
              )
  