void Application::processEvents(Context& context) { SDL_Event event; while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_KEYDOWN: case SDL_KEYUP: keyEvent(context, createKeyPressEvent(event.key)); break; case SDL_TEXTINPUT: textInputEvent(context, TextInputEvent(event.text.text)); break; case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: mouseButtonEvent(context, createMouseButtonEvent(event.button, video.getScreen().getClientHeight())); break; case SDL_MOUSEMOTION: mouseMotionEvent(context, createMouseMotionEvent(event.motion, video.getScreen().getClientHeight())); break; case SDL_MOUSEWHEEL: mouseWheelEvent(context, MouseWheelEvent(0, 0, event.wheel.x, event.wheel.y)); break; case SDL_QUIT: requestClose = true; break; default: break; } } }
int Application::exec() { bool done = false; while (!done) { SDL_Event e; if (SDL_WaitEvent(&e)) { switch (e.type) { case SDL_WINDOWEVENT: { Widget *w = widgetByWindowId(e.window.windowID); switch (e.window.event) { case SDL_WINDOWEVENT_SHOWN: std::cout << "Window " << e.window.windowID << " shown" << std::endl; break; case SDL_WINDOWEVENT_HIDDEN: std::cout << "Window " << e.window.windowID << " hidden" << std::endl; break; case SDL_WINDOWEVENT_EXPOSED: { needUpdateWithoutRedraw_ = w; break; } case SDL_WINDOWEVENT_MOVED: break; case SDL_WINDOWEVENT_RESIZED: { w->resize(e.window.data1, e.window.data2); #if __APPLE__==1 SDL_RenderPresent(w->renderer_); // hack for MacOS X #endif break; } case SDL_WINDOWEVENT_MINIMIZED: std::cout << "Window " << e.window.windowID << " minimized" << std::endl; break; case SDL_WINDOWEVENT_MAXIMIZED: std::cout << "Window " << e.window.windowID << " maximized" << std::endl; break; case SDL_WINDOWEVENT_RESTORED: std::cout << "Window " << e.window.windowID << " restored" << std::endl; break; case SDL_WINDOWEVENT_ENTER: std::cout << "Mouse entered window " << e.window.windowID << std::endl; break; case SDL_WINDOWEVENT_LEAVE: std::cout << "Mouse left window " << e.window.windowID << std::endl; break; case SDL_WINDOWEVENT_FOCUS_GAINED: std::cout << "Window " << e.window.windowID << " gained keyboard focus" << std::endl; break; case SDL_WINDOWEVENT_FOCUS_LOST: std::cout << "Window " << e.window.windowID << " lost keyboard focus" << std::endl; break; case SDL_WINDOWEVENT_CLOSE: std::cout << "Window " << e.window.windowID << " closed" << std::endl; break; default: std::cout << "Window " << e.window.windowID << " got unknown event " << static_cast<int>(e.window.event) << std::endl; break; } break; } case SDL_KEYDOWN: { KeyEvent ke { static_cast<KeyEvent::Key>(e.key.keysym.sym), SDL_GetModState(), static_cast<bool>(e.key.repeat) }; auto w = focusWidget(); if (!w) w = widgetByWindowId(e.key.windowID); else if (w->ancestor() != widgetByWindowId(e.key.windowID)) { std::cerr << "Unknown windowID " << e.key.windowID << std::endl; break; } while (w) { if (w->keyPressEvent(ke)) break; w = w->parent(); } break; } case SDL_KEYUP: { KeyEvent ke { static_cast<KeyEvent::Key>(e.key.keysym.sym), SDL_GetModState(), static_cast<bool>(e.key.repeat) }; auto w = focusWidget(); if (!w) w = widgetByWindowId(e.key.windowID); else if (w->ancestor() != widgetByWindowId(e.key.windowID)) { std::cerr << "Unknown windowID " << e.key.windowID << std::endl; break; } while (w) { if (w->keyReleaseEvent(ke)) break; w = w->parent(); } break; } case SDL_TEXTINPUT: { TextInputEvent tie { toUtf16(e.text.text) }; auto w = focusWidget(); if (!w) w = widgetByWindowId(e.key.windowID); else if (w->ancestor() != widgetByWindowId(e.key.windowID)) { std::cerr << "Unknown windowID " << e.key.windowID << std::endl; break; } while (w) { if (w->textInputEvent(tie)) break; w = w->parent(); } break; } case SDL_QUIT: done = true; break; } } const auto isEmpty = (SDL_PeepEvents(&e, 1, SDL_PEEKEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT) == 0); if (isEmpty || SDL_GetTicks() > lastUpdate_ + 1000 / 60) { auto x = SDL_GetTicks(); for (auto w: widgetList_) if (w->needRepaint()) { PaintEvent e; w->internalPaint(e); } if (needUpdateWithoutRedraw_) { needUpdateWithoutRedraw_->updateWithoutRedraw(); needUpdateWithoutRedraw_ = nullptr; } lastUpdate_ = SDL_GetTicks(); std::cout << "Update time: " << lastUpdate_ - x << " " << (lastUpdate_ - x > 0 ? 1000 / (lastUpdate_ - x) : 999)<< "fps" << std::endl; } for (auto obj: deletingObjects_) delete obj; deletingObjects_.clear(); } return 0; }
void Widget::handleTextInput(TextInputEvent &event) { textInputEvent(event); }