GPG_Canvas::GPG_Canvas(GHOST_IWindow* window) : GPC_Canvas(0, 0), m_window(window) { if (m_window) { GHOST_Rect bnds; m_window->getClientBounds(bnds); this->Resize(bnds.getWidth(), bnds.getHeight()); } }
GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_TEventType type, GHOST_IWindow *Iwindow) { GHOST_TInt32 x_screen, y_screen; GHOST_SystemWin32 *system = (GHOST_SystemWin32 *) getSystem(); GHOST_WindowWin32 *window = (GHOST_WindowWin32 *) Iwindow; system->getCursorPosition(x_screen, y_screen); /* TODO: CHECK IF THIS IS A TABLET EVENT */ bool is_tablet = false; if (is_tablet == false && window->getCursorGrabModeIsWarp()) { GHOST_TInt32 x_new = x_screen; GHOST_TInt32 y_new = y_screen; GHOST_TInt32 x_accum, y_accum; GHOST_Rect bounds; /* fallback to window bounds */ if (window->getCursorGrabBounds(bounds) == GHOST_kFailure) { window->getClientBounds(bounds); } /* could also clamp to screen bounds * wrap with a window outside the view will fail atm */ bounds.wrapPoint(x_new, y_new, 2); /* offset of one incase blender is at screen bounds */ window->getCursorGrabAccum(x_accum, y_accum); if (x_new != x_screen || y_new != y_screen) { /* when wrapping we don't need to add an event because the * setCursorPosition call will cause a new event after */ system->setCursorPosition(x_new, y_new); /* wrap */ window->setCursorGrabAccum(x_accum + (x_screen - x_new), y_accum + (y_screen - y_new)); } else { return new GHOST_EventCursor(system->getMilliSeconds(), GHOST_kEventCursorMove, window, x_screen + x_accum, y_screen + y_accum ); } } else { return new GHOST_EventCursor(system->getMilliSeconds(), GHOST_kEventCursorMove, window, x_screen, y_screen ); } return NULL; }
bool ofxFenster::setupOpenGL(int l, int t, int w, int h, int screenMode) { STR_String title("window"); GHOST_TWindowState state=GHOST_kWindowStateNormal; if(screenMode==OF_FULLSCREEN) { isFullscreen=true; state=GHOST_kWindowStateFullScreen; } win = GHOST_ISystem::getSystem()->createWindow(title, l, t, w, h, state, GHOST_kDrawingContextTypeOpenGL, false, false); if (!win) { ofLog(OF_LOG_ERROR, "HOUSTON WE GOT A PROBLEM! could not create window"); return false; } //get background color. not working yet because opengl renderer does not exist yet, so fill with black //float * bgPtr = ofBgColorPtr(); //bgColor.set(bgPtr[0]*255,bgPtr[1]*255,bgPtr[2]*255, bgPtr[3]*255); //bClearAuto = ofbClearBg(); setActive(); bgColor.set(0,0,0); //ofClear(bgColor.r, bgColor.g, bgColor.b, bgColor.a); //update sizes GHOST_Rect rect; win->getClientBounds(rect); height=rect.getHeight(); width=rect.getWidth(); pos.x=rect.m_l; pos.y=rect.m_t; //initial clear glClearColor(.55, .55, .55, 0.0); glClear(GL_COLOR_BUFFER_BIT); setDragAndDrop(true); setup(); return true; }
bool GPG_Application::processEvent(GHOST_IEvent* event) { bool handled = true; switch (event->getType()) { case GHOST_kEventUnknown: break; case GHOST_kEventButtonDown: handled = handleButton(event, true); break; case GHOST_kEventButtonUp: handled = handleButton(event, false); break; case GHOST_kEventWheel: handled = handleWheel(event); break; case GHOST_kEventCursorMove: handled = handleCursorMove(event); break; case GHOST_kEventKeyDown: handleKey(event, true); break; case GHOST_kEventKeyUp: handleKey(event, false); break; case GHOST_kEventWindowClose: case GHOST_kEventQuit: m_exitRequested = KX_EXIT_REQUEST_OUTSIDE; break; case GHOST_kEventWindowActivate: handled = false; break; case GHOST_kEventWindowDeactivate: handled = false; break; // The player now runs as often as it can (repsecting vsync and fixedtime). // This allows the player to break 100fps, but this code is being left here // as reference. (see EngineNextFrame) //case GHOST_kEventWindowUpdate: // { // GHOST_IWindow* window = event->getWindow(); // if (!m_system->validWindow(window)) break; // // Update the state of the game engine // if (m_kxsystem && !m_exitRequested) // { // // Proceed to next frame // window->activateDrawingContext(); // // first check if we want to exit // m_exitRequested = m_ketsjiengine->GetExitCode(); // // // kick the engine // bool renderFrame = m_ketsjiengine->NextFrame(); // if (renderFrame) // { // // render the frame // m_ketsjiengine->Render(); // } // } // m_exitString = m_ketsjiengine->GetExitString(); // } // break; // case GHOST_kEventWindowSize: { GHOST_IWindow* window = event->getWindow(); if (!m_system->validWindow(window)) break; if (m_canvas) { GHOST_Rect bnds; window->getClientBounds(bnds); m_canvas->Resize(bnds.getWidth(), bnds.getHeight()); m_ketsjiengine->Resize(); } } break; default: handled = false; break; } return handled; }
static void View(GHOST_IWindow* window, bool stereo, int eye = 0) { window->activateDrawingContext(); GHOST_Rect bnds; int noOfScanlines = 0, lowerScanline = 0; int verticalBlankingInterval = 32; // hard coded for testing purposes, display device dependant float left, right, bottom, top; float nearplane, farplane, zeroPlane, distance; float eyeSeparation = 0.62f; window->getClientBounds(bnds); // viewport if(stereo) { if(nVidiaWindows) { // handled by nVidia driver so act as normal (explicitly put here since // it -is- stereo) glViewport(0, 0, bnds.getWidth(), bnds.getHeight()); } else { // generic cross platform above-below stereo noOfScanlines = (bnds.getHeight() - verticalBlankingInterval) / 2; switch(eye) { case LEFT_EYE: // upper half of window lowerScanline = bnds.getHeight() - noOfScanlines; break; case RIGHT_EYE: // lower half of window lowerScanline = 0; break; } } } else { noOfScanlines = bnds.getHeight(); lowerScanline = 0; } glViewport(0, lowerScanline, bnds.getWidth(), noOfScanlines); // projection left = -6.0; right = 6.0; bottom = -4.8f; top = 4.8f; nearplane = 5.0; farplane = 60.0; if(stereo) { zeroPlane = 0.0; distance = 14.5; switch(eye) { case LEFT_EYE: StereoProjection(left, right, bottom, top, nearplane, farplane, zeroPlane, distance, -eyeSeparation / 2.0); break; case RIGHT_EYE: StereoProjection(left, right, bottom, top, nearplane, farplane, zeroPlane, distance, eyeSeparation / 2.0); break; } } else { // left = -w; // right = w; // bottom = -h; // top = h; glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(left, right, bottom, top, 5.0, 60.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0, 0.0, -40.0); } glClearColor(.2f,0.0f,0.0f,0.0f); }
bool BSP_GhostTestApp3D:: processEvent( GHOST_IEvent* event ){ bool handled = false; switch(event->getType()) { case GHOST_kEventWindowSize: case GHOST_kEventWindowActivate: UpdateFrame(); case GHOST_kEventWindowUpdate: DrawPolies(); handled = true; break; case GHOST_kEventButtonDown: { int x,y; m_system->getCursorPosition(x,y); int wx,wy; m_window->screenToClient(x,y,wx,wy); GHOST_TButtonMask button = static_cast<GHOST_TEventButtonData *>(event->getData())->button; if (button == GHOST_kButtonMaskLeft) { m_rotation_settings[m_current_object].m_moving = true; m_rotation_settings[m_current_object].x_old = x; m_rotation_settings[m_current_object].y_old = y; } else if (button == GHOST_kButtonMaskRight) { m_translation_settings[m_current_object].m_moving = true; m_translation_settings[m_current_object].x_old = x; m_translation_settings[m_current_object].y_old = y; } else m_window->invalidate(); handled = true; break; } case GHOST_kEventButtonUp: { GHOST_TButtonMask button = static_cast<GHOST_TEventButtonData *>(event->getData())->button; if (button == GHOST_kButtonMaskLeft) { m_rotation_settings[m_current_object].m_moving = false; m_rotation_settings[m_current_object].x_old = 0; m_rotation_settings[m_current_object].y_old = 0; } else if (button == GHOST_kButtonMaskRight) { m_translation_settings[m_current_object].m_moving = false; m_translation_settings[m_current_object].x_old; m_translation_settings[m_current_object].y_old; } m_window->invalidate(); handled = true; break; } case GHOST_kEventCursorMove: { int x,y; m_system->getCursorPosition(x,y); int wx,wy; m_window->screenToClient(x,y,wx,wy); if (m_rotation_settings[m_current_object].m_moving) { m_rotation_settings[m_current_object].m_angle_x = MT_Scalar(wx)/20; m_rotation_settings[m_current_object].x_old = wx; m_rotation_settings[m_current_object].m_angle_y = MT_Scalar(wy)/20; m_rotation_settings[m_current_object].y_old = wy; m_window->invalidate(); } if (m_translation_settings[m_current_object].m_moving) { // project current objects bounding box center into screen space. // unproject mouse point into object space using z-value from // projected bounding box center. GHOST_Rect bounds; m_window->getClientBounds(bounds); int w_h = bounds.getHeight(); y = w_h - wy; x = wx; double mvmatrix[16]; double projmatrix[16]; GLint viewport[4]; double px, py, pz,sz; /* Get the matrices needed for gluUnProject */ glGetIntegerv(GL_VIEWPORT, viewport); glGetDoublev(GL_MODELVIEW_MATRIX, mvmatrix); glGetDoublev(GL_PROJECTION_MATRIX, projmatrix); // work out the position of the end effector in screen space GLdouble ex,ey,ez; ex = m_translation_settings[m_current_object].m_t_x; ey = m_translation_settings[m_current_object].m_t_y; ez = m_translation_settings[m_current_object].m_t_z; gluProject(ex, ey, ez, mvmatrix, projmatrix, viewport, &px, &py, &sz); gluUnProject((GLdouble) x, (GLdouble) y, sz, mvmatrix, projmatrix, viewport, &px, &py, &pz); m_translation_settings[m_current_object].m_t_x = px; m_translation_settings[m_current_object].m_t_y = py; m_translation_settings[m_current_object].m_t_z = pz; m_window->invalidate(); } handled = true; break; } case GHOST_kEventKeyDown : { GHOST_TEventKeyData *kd = static_cast<GHOST_TEventKeyData *>(event->getData()); switch(kd->key) { case GHOST_kKeyI: { // now intersect meshes. Operate(e_csg_intersection); handled = true; m_window->invalidate(); break; } case GHOST_kKeyU: { Operate(e_csg_union); handled = true; m_window->invalidate(); break; } case GHOST_kKeyD: { Operate(e_csg_difference); handled = true; m_window->invalidate(); break; } case GHOST_kKeyA: { m_scale_settings[m_current_object] *= 1.1; handled = true; m_window->invalidate(); break; } case GHOST_kKeyZ: { m_scale_settings[m_current_object] *= 0.8; handled = true; m_window->invalidate(); break; } case GHOST_kKeyR: m_render_modes[m_current_object]++; if (m_render_modes[m_current_object] > e_last_render_mode) { m_render_modes[m_current_object] = e_first_render_mode; } handled = true; m_window->invalidate(); break; case GHOST_kKeyB: handled = true; m_window->invalidate(); break; case GHOST_kKeyQ: m_finish_me_off = true; handled = true; break; case GHOST_kKeyS: Swap(m_current_object); m_window->invalidate(); handled = true; break; case GHOST_kKeySpace: // increment the current object only if the object is not being // manipulated. if (! (m_rotation_settings[m_current_object].m_moving || m_translation_settings[m_current_object].m_moving)) { m_current_object ++; if (m_current_object >= m_meshes.size()) { m_current_object = 0; } } m_window->invalidate(); handled = true; break; default : break; } } default : break; } return handled; };
void GHOST_SystemSDL::processEvent(SDL_Event *sdl_event) { GHOST_Event * g_event= NULL; switch(sdl_event->type) { case SDL_WINDOWEVENT: { SDL_WindowEvent &sdl_sub_evt= sdl_event->window; GHOST_WindowSDL *window= findGhostWindow(SDL_GetWindowFromID(sdl_sub_evt.windowID)); //assert(window != NULL); // can be NULL on close window. switch (sdl_sub_evt.event) { case SDL_WINDOWEVENT_EXPOSED: g_event= new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowUpdate, window); break; case SDL_WINDOWEVENT_RESIZED: g_event= new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window); break; case SDL_WINDOWEVENT_MOVED: g_event= new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowMove, window); break; case SDL_WINDOWEVENT_FOCUS_GAINED: g_event= new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowActivate, window); break; case SDL_WINDOWEVENT_FOCUS_LOST: g_event= new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowDeactivate, window); break; case SDL_WINDOWEVENT_CLOSE: g_event= new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowClose, window); break; } } break; case SDL_QUIT: g_event= new GHOST_Event(getMilliSeconds(), GHOST_kEventQuit, NULL); break; case SDL_MOUSEMOTION: { SDL_MouseMotionEvent &sdl_sub_evt= sdl_event->motion; SDL_Window *sdl_win= SDL_GetWindowFromID(sdl_sub_evt.windowID); GHOST_WindowSDL *window= findGhostWindow(sdl_win); assert(window != NULL); int x_win, y_win; SDL_GetWindowPosition(sdl_win, &x_win, &y_win); GHOST_TInt32 x_root= sdl_sub_evt.x + x_win; GHOST_TInt32 y_root= sdl_sub_evt.y + y_win; #if 0 if(window->getCursorGrabMode() != GHOST_kGrabDisable && window->getCursorGrabMode() != GHOST_kGrabNormal) { GHOST_TInt32 x_new= x_root; GHOST_TInt32 y_new= y_root; GHOST_TInt32 x_accum, y_accum; GHOST_Rect bounds; /* fallback to window bounds */ if(window->getCursorGrabBounds(bounds)==GHOST_kFailure) window->getClientBounds(bounds); /* could also clamp to screen bounds * wrap with a window outside the view will fail atm */ bounds.wrapPoint(x_new, y_new, 8); /* offset of one incase blender is at screen bounds */ window->getCursorGrabAccum(x_accum, y_accum); // cant use setCursorPosition because the mouse may have no focus! if(x_new != x_root || y_new != y_root) { if (1 ) { //xme.time > m_last_warp) { /* when wrapping we don't need to add an event because the * setCursorPosition call will cause a new event after */ SDL_WarpMouseInWindow(sdl_win, x_new - x_win, y_new - y_win); /* wrap */ window->setCursorGrabAccum(x_accum + (x_root - x_new), y_accum + (y_root - y_new)); // m_last_warp= lastEventTime(xme.time); } else { // setCursorPosition(x_new, y_new); /* wrap but don't accumulate */ SDL_WarpMouseInWindow(sdl_win, x_new - x_win, y_new - y_win); } g_event = new GHOST_EventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, x_new, y_new); } else { g_event = new GHOST_EventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, x_root + x_accum, y_root + y_accum); } } else #endif { g_event= new GHOST_EventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, x_root, y_root); } break; } case SDL_MOUSEBUTTONUP: case SDL_MOUSEBUTTONDOWN: { SDL_MouseButtonEvent &sdl_sub_evt= sdl_event->button; GHOST_TButtonMask gbmask= GHOST_kButtonMaskLeft; GHOST_TEventType type= (sdl_sub_evt.state==SDL_PRESSED) ? GHOST_kEventButtonDown : GHOST_kEventButtonUp; GHOST_WindowSDL *window= findGhostWindow(SDL_GetWindowFromID(sdl_sub_evt.windowID)); assert(window != NULL); /* process rest of normal mouse buttons */ if(sdl_sub_evt.button == SDL_BUTTON_LEFT) gbmask= GHOST_kButtonMaskLeft; else if(sdl_sub_evt.button == SDL_BUTTON_MIDDLE) gbmask= GHOST_kButtonMaskMiddle; else if(sdl_sub_evt.button == SDL_BUTTON_RIGHT) gbmask= GHOST_kButtonMaskRight; /* these buttons are untested! */ else if(sdl_sub_evt.button == SDL_BUTTON_X1) gbmask= GHOST_kButtonMaskButton4; else if(sdl_sub_evt.button == SDL_BUTTON_X2) gbmask= GHOST_kButtonMaskButton5; else break; g_event= new GHOST_EventButton(getMilliSeconds(), type, window, gbmask); break; } case SDL_MOUSEWHEEL: { SDL_MouseWheelEvent &sdl_sub_evt= sdl_event->wheel; GHOST_WindowSDL *window= findGhostWindow(SDL_GetWindowFromID(sdl_sub_evt.windowID)); assert(window != NULL); g_event= new GHOST_EventWheel(getMilliSeconds(), window, sdl_sub_evt.y); } break; case SDL_KEYDOWN: case SDL_KEYUP: { SDL_KeyboardEvent &sdl_sub_evt= sdl_event->key; SDL_Keycode sym= sdl_sub_evt.keysym.sym; GHOST_TEventType type= (sdl_sub_evt.state == SDL_PRESSED) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp; GHOST_WindowSDL *window= findGhostWindow(SDL_GetWindowFromID(sdl_sub_evt.windowID)); assert(window != NULL); GHOST_TKey gkey= convertSDLKey(sdl_sub_evt.keysym.scancode); /* note, the sdl_sub_evt.keysym.sym is truncated, for unicode support ghost has to be modified */ /* printf("%d\n", sym); */ if(sym > 127) { switch(sym) { case SDLK_KP_DIVIDE: sym= '/'; break; case SDLK_KP_MULTIPLY: sym= '*'; break; case SDLK_KP_MINUS: sym= '-'; break; case SDLK_KP_PLUS: sym= '+'; break; case SDLK_KP_1: sym= '1'; break; case SDLK_KP_2: sym= '2'; break; case SDLK_KP_3: sym= '3'; break; case SDLK_KP_4: sym= '4'; break; case SDLK_KP_5: sym= '5'; break; case SDLK_KP_6: sym= '6'; break; case SDLK_KP_7: sym= '7'; break; case SDLK_KP_8: sym= '8'; break; case SDLK_KP_9: sym= '9'; break; case SDLK_KP_0: sym= '0'; break; case SDLK_KP_PERIOD: sym= '.'; break; default: sym= 0; break; } } else { if(sdl_sub_evt.keysym.mod & (KMOD_LSHIFT|KMOD_RSHIFT)) { /* lame US keyboard assumptions */ if(sym >= 'a' && sym <= ('a' + 32)) { sym -= 32; } else { switch(sym) { case '`': sym= '~'; break; case '1': sym= '!'; break; case '2': sym= '@'; break; case '3': sym= '#'; break; case '4': sym= '$'; break; case '5': sym= '%'; break; case '6': sym= '^'; break; case '7': sym= '&'; break; case '8': sym= '*'; break; case '9': sym= '('; break; case '0': sym= ')'; break; case '-': sym= '_'; break; case '=': sym= '+'; break; case '[': sym= '{'; break; case ']': sym= '}'; break; case '\\': sym= '|'; break; case ';': sym= ':'; break; case '\'': sym= '"'; break; case ',': sym= '<'; break; case '.': sym= '>'; break; case '/': sym= '?'; break; default: break; } } } } g_event= new GHOST_EventKey(getMilliSeconds(), type, window, gkey, sym); } break; } if (g_event) { pushEvent(g_event); } }
bool GPG_Application::processEvent(GHOST_IEvent* event) { bool handled = true; switch (event->getType()) { case GHOST_kEventUnknown: break; case GHOST_kEventButtonDown: handled = handleButton(event, true); break; case GHOST_kEventButtonUp: handled = handleButton(event, false); break; case GHOST_kEventWheel: handled = handleWheel(event); break; case GHOST_kEventCursorMove: handled = handleCursorMove(event); break; case GHOST_kEventKeyDown: handleKey(event, true); break; case GHOST_kEventKeyUp: handleKey(event, false); break; case GHOST_kEventWindowClose: case GHOST_kEventQuit: m_exitRequested = KX_EXIT_REQUEST_OUTSIDE; break; case GHOST_kEventWindowActivate: handled = false; break; case GHOST_kEventWindowDeactivate: handled = false; break; case GHOST_kEventWindowUpdate: { GHOST_IWindow* window = event->getWindow(); if (!m_system->validWindow(window)) break; // Update the state of the game engine if (m_kxsystem && !m_exitRequested) { // Proceed to next frame window->activateDrawingContext(); // first check if we want to exit m_exitRequested = m_ketsjiengine->GetExitCode(); // kick the engine bool renderFrame = m_ketsjiengine->NextFrame(); if (renderFrame) { // render the frame m_ketsjiengine->Render(); } } m_exitString = m_ketsjiengine->GetExitString(); } break; case GHOST_kEventWindowSize: { GHOST_IWindow* window = event->getWindow(); if (!m_system->validWindow(window)) break; if (m_canvas) { GHOST_Rect bnds; window->getClientBounds(bnds); m_canvas->Resize(bnds.getWidth(), bnds.getHeight()); } } break; default: handled = false; break; } return handled; }
bool ofxFensterManager::processEvent(GHOST_IEvent* event) { if(event->getType()==GHOST_kEventUnknown) return false; GHOST_IWindow* window = event->getWindow(); bool handled = true; ofxFenster* win=getFensterByHandler(window); GHOST_Rect winPos; //why on every process...? window->getWindowBounds(winPos); switch (event->getType()) { //////////////////// MOUSE case GHOST_kEventCursorMove: { GHOST_TEventCursorData* bd=(GHOST_TEventCursorData*)event->getData(); GHOST_TInt32 x,y; window->screenToClient(bd->x, bd->y, x, y); ofPoint p(x, y); p.y -= 1; if(win->isButtonDown) { //win->mouseDragged(bd->x-winPos.m_l, bd->y-winPos.m_t, win->buttonDown); win->mouseDragged(p.x, p.y, win->buttonDown); } else { //win->mouseMoved(bd->x-winPos.m_l, bd->y-winPos.m_t); win->mouseMoved(p.x, p.y); } break; } case GHOST_kEventWheel: { break; } case GHOST_kEventButtonDown: { GHOST_TEventButtonData* bd=(GHOST_TEventButtonData*)event->getData(); win->isButtonDown=true; win->buttonDown=bd->button; win->mousePressed(bd->button); break; } case GHOST_kEventButtonUp: { GHOST_TEventButtonData* bd=(GHOST_TEventButtonData*)event->getData(); win->isButtonDown=false; win->mouseReleased(bd->button); break; } ////////////////// KEYBOARD case GHOST_kEventKeyUp: { int key=handleKeyData((GHOST_TEventKeyData*) event->getData()); if(key==OF_KEY_ESC) break; win->keyReleased(key); break; } case GHOST_kEventKeyDown: { int key=handleKeyData((GHOST_TEventKeyData*) event->getData()); if(key==OF_KEY_ESC) ofExit(0); win->keyPressed(key); break; } ////////////////// WINDOW case GHOST_kEventWindowSize: { GHOST_Rect rect; window->getClientBounds(rect); win->windowResized(rect.getWidth(), rect.getHeight()); break; } case GHOST_kEventWindowMove: { GHOST_Rect rect; window->getWindowBounds(rect); //cout << rect.m_t << endl; //GHOST_TInt32 x,y; //window->screenToClient(rect.m_l, rect.m_t, x, y); win->windowMoved(rect.m_l, rect.m_t); break; } case GHOST_kEventWindowUpdate: { win->draw(); window->swapBuffers(); break; } case GHOST_kEventWindowActivate: { break; } case GHOST_kEventWindowDeactivate: { break; } case GHOST_kEventWindowClose: { deleteFenster(win); break; } //drag and drop case GHOST_kEventDraggingEntered: { GHOST_TEventDragnDropData* dragnDropData = (GHOST_TEventDragnDropData*)((GHOST_IEvent*)event)->getData(); //needs to be handled, but of doesn't really provide anything out of the box break; } case GHOST_kEventDraggingUpdated: { GHOST_TEventDragnDropData* dragnDropData = (GHOST_TEventDragnDropData*)((GHOST_IEvent*)event)->getData(); //needs to be handled, but of doesn't really provide anything out of the box break; } case GHOST_kEventDraggingExited: { GHOST_TEventDragnDropData* dragnDropData = (GHOST_TEventDragnDropData*)((GHOST_IEvent*)event)->getData(); //needs to be handled, but of doesn't really provide anything out of the box break; } case GHOST_kEventDraggingDropDone: { GHOST_TEventDragnDropData* dragnDropData = (GHOST_TEventDragnDropData*)((GHOST_IEvent*)event)->getData(); if(dragnDropData->dataType == GHOST_kDragnDropTypeFilenames){//TODO: STRING AND BITMAP IS ALSO SUPPORTED IN GHOST static ofDragInfo info; GHOST_TStringArray *strArray = (GHOST_TStringArray*)dragnDropData->data; for (int i=0;i<strArray->count;i++){ const char* filename = (char*)strArray->strings[i]; info.files.push_back(filename); } info.position.set(dragnDropData->x, dragnDropData->y); //TODO check if drag'n'drop position is actually correct win->fileDropped(info); } break; } } return handled; }