Skip to content

Commit

Permalink
Merge pull request #115 from EnigmaCurry/master
Browse files Browse the repository at this point in the history
File drag and drop support [Pyglet Only]
  • Loading branch information
einarf committed Oct 11, 2020
2 parents b752780 + 1e14963 commit b303504
Show file tree
Hide file tree
Showing 3 changed files with 164 additions and 1 deletion.
104 changes: 104 additions & 0 deletions examples/drag_drop_file_input.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
"""
6 cubes with drag and drop texture loading.
For each box, locate an image in your File Manager, and drag and drop onto the box.
Currently only working with the Pyglet backend.
"""
from pathlib import Path
import os

import moderngl
import moderngl_window

from pyrr import Matrix44


class Cubes(moderngl_window.WindowConfig):
title = "Cubes"
resizable = True
aspect_ratio = None
resource_dir = Path(__file__).parent.resolve() / 'resources'

def __init__(self, **kwargs):
super().__init__(**kwargs)

# Load the 6 different boxes with different vertex formats
self.box_top_left = self.load_scene('scenes/box/box-T2F_V3F.obj')
self.box_top_middle = self.load_scene('scenes/box/box-T2F_V3F.obj')
self.box_top_right = self.load_scene('scenes/box/box-T2F_V3F.obj')
self.box_bottom_left = self.load_scene('scenes/box/box-T2F_V3F.obj')
self.box_bottom_middle = self.load_scene('scenes/box/box-T2F_V3F.obj')
self.box_bottom_right = self.load_scene('scenes/box/box-T2F_V3F.obj')

self.resize(*self.wnd.size)

def render(self, time, frame_time):
self.ctx.enable_only(moderngl.DEPTH_TEST | moderngl.CULL_FACE)
rot = Matrix44.from_eulers((time, time/2, time/3))

# Box top left
view = Matrix44.from_translation((-5, 2, -10), dtype='f4')
self.box_top_left.draw(self.projection, view * rot)

# Box top middle
view = Matrix44.from_translation((0, 2, -10), dtype='f4')
self.box_top_middle.draw(self.projection, view * rot)

# Box top right
view = Matrix44.from_translation((5, 2, -10), dtype='f4')
self.box_top_right.draw(self.projection, view * rot)

# Box bottom left
view = Matrix44.from_translation((-5, -2, -10), dtype='f4')
self.box_bottom_left.draw(self.projection, view * rot)

# Box bottom middle
view = Matrix44.from_translation((0, -2, -10), dtype='f4')
self.box_bottom_middle.draw(self.projection, view * rot)

# Box bottom right
view = Matrix44.from_translation((5, -2, -10), dtype='f4')
self.box_bottom_right.draw(self.projection, view * rot)

def resize(self, width, height):
self.ctx.viewport = 0, 0, width, height
self.projection = Matrix44.perspective_projection(45, width / height, 1, 50, dtype='f4')

def _load_texture(self, path):
tex = self.load_texture_2d(os.path.relpath(path, self.resource_dir))
print(type(tex))
return tex

def files_dropped_event(self, x, y, paths):
if x < self.wnd._window.width * 0.33:
if y < self.wnd._window.height * 0.5:
# Modify top left box
self.box_top_left.materials[0].mat_texture.texture = \
self._load_texture(paths[0])
else:
# Modify bottom left box
self.box_bottom_left.materials[0].mat_texture.texture = \
self._load_texture(paths[0])
elif x < self.wnd._window.width * 0.66:
if y < self.wnd._window.height * 0.5:
# Modify top middle box
self.box_top_middle.materials[0].mat_texture.texture = \
self._load_texture(paths[0])
else:
# Modify bottom middle box
self.box_bottom_middle.materials[0].mat_texture.texture = \
self._load_texture(paths[0])
else:
if y < self.wnd._window.height * 0.5:
# Modify top right box
self.box_top_right.materials[0].mat_texture.texture = \
self._load_texture(paths[0])
else:
# Modify bottom right box
self.box_bottom_right.materials[0].mat_texture.texture = \
self._load_texture(paths[0])
print(paths)

if __name__ == '__main__':
Cubes.run()
45 changes: 44 additions & 1 deletion moderngl_window/context/base/window.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import logging
import sys
import weakref
from typing import Any, Tuple, Type
from typing import Any, Tuple, Type, List

import moderngl
from moderngl_window.context.base import KeyModifiers, BaseKeys
Expand Down Expand Up @@ -128,6 +128,7 @@ def __init__(
self._mouse_drag_event_func = dummy_func
self._mouse_scroll_event_func = dummy_func
self._unicode_char_entered_func = dummy_func
self._files_dropped_event_func = dummy_func

# Internal states
self._ctx = None # type: moderngl.Context
Expand Down Expand Up @@ -445,6 +446,7 @@ def config(self, config):
self.unicode_char_entered_func = getattr(
config, "unicode_char_entered", dummy_func
)
self.files_dropped_event_func = getattr(config, "files_dropped_event", dummy_func)

self._config = weakref.ref(config)

Expand Down Expand Up @@ -476,11 +478,21 @@ def close_func(self):
"""callable: Get or set the close callable"""
return self._close_func

@property
def files_dropped_event_func(self):
"""callable: Get or set the files_dropped callable"""
return self._files_dropped_event_func

@close_func.setter
@require_callable
def close_func(self, func):
self._close_func = func

@files_dropped_event_func.setter
@require_callable
def files_dropped_event_func(self, func):
self._files_dropped_event_func = func

@property
def iconify_func(self):
"""callable: Get or set ehe iconify/show/hide callable"""
Expand Down Expand Up @@ -596,6 +608,27 @@ def _handle_mouse_button_state_change(self, button: int, pressed: bool):
else:
raise ValueError("Incompatible mouse button number: {}".format(button))

def _convert_window_coordinates(self, x, y, x_flipped=False, y_flipped=False):
"""
Convert window coordinates to top-left coordinate space.
The default origin is the top left corner of the window.
Args :
x_flipped (bool) - if the input x origin is flipped
y_flipped (bool) - if the input y origin is flipped
Returns:
tuple (x, y) of converted window coordinates
If you are converting from bottom origin coordinates use x_flipped=True
If you are converting from right origin coordinates use y_flipped=True
"""
if not y_flipped and not x_flipped:
return (x, y)
elif y_flipped and not x_flipped:
return (x, self.height - y)
else:
return(self.width - x, self.height - y)

def is_key_pressed(self, key) -> bool:
"""Returns: The press state of a key"""
return self._key_pressed_map.get(key) is True
Expand Down Expand Up @@ -1007,6 +1040,16 @@ def resize(self, width: int, height: int):
def close(self):
"""Called when the window is closed"""

def files_dropped(self, x:int , y:int, paths:List[str]):
"""
Called when files dropped onto the window
Args:
x (int): X location in window where file was dropped
y (int): Y location in window where file was dropped
paths (list): List of file paths dropped
"""

def iconify(self, iconified: bool):
"""
Called when the window is minimized/iconified
Expand Down
16 changes: 16 additions & 0 deletions moderngl_window/context/pyglet/window.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ def __init__(self, **kwargs):
vsync=self._vsync,
fullscreen=self._fullscreen,
config=config,
file_drops=True
)

self.cursor = self._cursor
Expand All @@ -72,6 +73,7 @@ def __init__(self, **kwargs):
self._window.event(self.on_text)
self._window.event(self.on_show)
self._window.event(self.on_hide)
self._window.event(self.on_file_drop)

self.init_mgl_context()
self._buffer_width, self._buffer_height = self._window.get_framebuffer_size()
Expand Down Expand Up @@ -322,6 +324,20 @@ def on_hide(self):
"""Called when window is minimized"""
self._iconify_func(True)

def on_file_drop(self, x, y, paths):
"""Called when files dropped onto the window
Args:
x (int): X location in window where file was dropped
y (int): Y location in window where file was dropped
paths (list): List of file paths dropped
"""
# pyglet coordinate origin is in the bottom left corner of the window
# mglw coordinate origin is in the top left corner of the window
# convert pyglet coordinates to mglw coordinates:
(x, y) = self._convert_window_coordinates(x, y, y_flipped=True)
self._files_dropped_event_func(x, y, paths)

def destroy(self):
"""Destroy the pyglet window"""
pass
Expand Down

0 comments on commit b303504

Please sign in to comment.