Browse Source

Platform: documentation updates.

Sdl2Application is now taken as base implementation (it was GLUT
previously) and all others are copying/referencing the documentation
from it. When SDL2 is included in all major distributions (Ubuntu, I'm
looking at you), it will replace GLUT as the default application.
pull/34/head
Vladimír Vondruš 13 years ago
parent
commit
75ac846df1
  1. 36
      src/Platform/AbstractXApplication.h
  2. 133
      src/Platform/GlutApplication.h
  3. 10
      src/Platform/GlxApplication.h
  4. 55
      src/Platform/NaClApplication.h
  5. 139
      src/Platform/Sdl2Application.h
  6. 12
      src/Platform/WindowlessGlxApplication.h
  7. 18
      src/Platform/WindowlessNaClApplication.h
  8. 10
      src/Platform/XEglApplication.h

36
src/Platform/AbstractXApplication.h

@ -87,21 +87,21 @@ class AbstractXApplication {
this is faster than public pure virtual destructor */ this is faster than public pure virtual destructor */
~AbstractXApplication(); ~AbstractXApplication();
/** @copydoc GlutApplication::createContext() */ /** @copydoc Sdl2Application::createContext() */
void createContext(const Configuration& configuration); void createContext(const Configuration& configuration);
/** @{ @name Drawing functions */ /** @{ @name Drawing functions */
/** @copydoc GlutApplication::viewportEvent() */ /** @copydoc Sdl2Application::viewportEvent() */
virtual void viewportEvent(const Vector2i& size) = 0; virtual void viewportEvent(const Vector2i& size) = 0;
/** @copydoc GlutApplication::drawEvent() */ /** @copydoc Sdl2Application::drawEvent() */
virtual void drawEvent() = 0; virtual void drawEvent() = 0;
/** @copydoc GlutApplication::swapBuffers() */ /** @copydoc Sdl2Application::swapBuffers() */
void swapBuffers(); void swapBuffers();
/** @copydoc GlutApplication::redraw() */ /** @copydoc Sdl2Application::redraw() */
void redraw() { flags |= Flag::Redraw; } void redraw() { flags |= Flag::Redraw; }
/*@}*/ /*@}*/
@ -170,7 +170,8 @@ CORRADE_ENUMSET_OPERATORS(AbstractXApplication::Flags)
@brief %Configuration @brief %Configuration
Double-buffered OpenGL context. Double-buffered OpenGL context.
@see AbstractXApplication(), createContext() @see @ref GlxApplication(), @ref XEglApplication(), @ref createContext(),
@ref tryCreateContext()
@todo GLX_ARB_create_context_robustness/EGL_EXT_create_context_robustness @todo GLX_ARB_create_context_robustness/EGL_EXT_create_context_robustness
*/ */
class AbstractXApplication::Configuration { class AbstractXApplication::Configuration {
@ -219,8 +220,9 @@ class AbstractXApplication::Configuration {
/** /**
@brief Base for input events @brief Base for input events
@see KeyEvent, MouseEvent, MouseMoveEvent, keyPressEvent(), keyReleaseEvent(), @see @ref KeyEvent, @ref MouseEvent, @ref MouseMoveEvent, @ref keyPressEvent(),
mousePressEvent(), mouseReleaseEvent(), mouseMoveEvent() @ref keyReleaseEvent(), @ref mousePressEvent(), @ref mouseReleaseEvent(),
@ref mouseMoveEvent()
*/ */
class AbstractXApplication::InputEvent { class AbstractXApplication::InputEvent {
InputEvent(const InputEvent&) = delete; InputEvent(const InputEvent&) = delete;
@ -233,7 +235,7 @@ class AbstractXApplication::InputEvent {
/** /**
* @brief %Modifier * @brief %Modifier
* *
* @see Modifiers, modifiers() * @see @ref Modifiers, @ref modifiers()
*/ */
enum class Modifier: unsigned int { enum class Modifier: unsigned int {
Shift = ShiftMask, /**< Shift */ Shift = ShiftMask, /**< Shift */
@ -274,7 +276,7 @@ class AbstractXApplication::InputEvent {
/** /**
* @brief Set of modifiers * @brief Set of modifiers
* *
* @see modifiers() * @see @ref modifiers()
*/ */
typedef Containers::EnumSet<Modifier, unsigned int> Modifiers; typedef Containers::EnumSet<Modifier, unsigned int> Modifiers;
@ -296,10 +298,10 @@ class AbstractXApplication::InputEvent {
*/ */
typedef Containers::EnumSet<Button, unsigned int> Buttons; typedef Containers::EnumSet<Button, unsigned int> Buttons;
/** @copydoc GlutApplication::InputEvent::setAccepted() */ /** @copydoc Sdl2Application::InputEvent::setAccepted() */
void setAccepted(bool accepted = true) { _accepted = accepted; } void setAccepted(bool accepted = true) { _accepted = accepted; }
/** @copydoc GlutApplication::InputEvent::isAccepted() */ /** @copydoc Sdl2Application::InputEvent::isAccepted() */
constexpr bool isAccepted() const { return _accepted; } constexpr bool isAccepted() const { return _accepted; }
/** @brief Modifiers */ /** @brief Modifiers */
@ -326,7 +328,7 @@ CORRADE_ENUMSET_OPERATORS(AbstractXApplication::InputEvent::Buttons)
/** /**
@brief Key event @brief Key event
@see keyPressEvent(), keyReleaseEvent() @see @ref keyPressEvent(), @ref keyReleaseEvent()
*/ */
class AbstractXApplication::KeyEvent: public AbstractXApplication::InputEvent { class AbstractXApplication::KeyEvent: public AbstractXApplication::InputEvent {
friend class AbstractXApplication; friend class AbstractXApplication;
@ -335,7 +337,7 @@ class AbstractXApplication::KeyEvent: public AbstractXApplication::InputEvent {
/** /**
* @brief Key * @brief Key
* *
* @see key() * @see @ref key()
*/ */
enum class Key: KeySym { enum class Key: KeySym {
Enter = XK_Return, /**< Enter */ Enter = XK_Return, /**< Enter */
@ -426,7 +428,7 @@ class AbstractXApplication::KeyEvent: public AbstractXApplication::InputEvent {
/** /**
@brief Mouse event @brief Mouse event
@see MouseMoveEvent, mousePressEvent(), mouseReleaseEvent() @see @ref MouseMoveEvent, @ref mousePressEvent(), @ref mouseReleaseEvent()
*/ */
class AbstractXApplication::MouseEvent: public AbstractXApplication::InputEvent { class AbstractXApplication::MouseEvent: public AbstractXApplication::InputEvent {
friend class AbstractXApplication; friend class AbstractXApplication;
@ -435,7 +437,7 @@ class AbstractXApplication::MouseEvent: public AbstractXApplication::InputEvent
/** /**
* @brief Mouse button * @brief Mouse button
* *
* @see button() * @see @ref button()
*/ */
enum class Button: unsigned int { enum class Button: unsigned int {
Left = Button1, /**< Left button */ Left = Button1, /**< Left button */
@ -461,7 +463,7 @@ class AbstractXApplication::MouseEvent: public AbstractXApplication::InputEvent
/** /**
@brief Mouse move event @brief Mouse move event
@see MouseEvent, mouseMoveEvent() @see @ref MouseEvent, @ref mouseMoveEvent()
*/ */
class AbstractXApplication::MouseMoveEvent: public AbstractXApplication::InputEvent { class AbstractXApplication::MouseMoveEvent: public AbstractXApplication::InputEvent {
friend class AbstractXApplication; friend class AbstractXApplication;

133
src/Platform/GlutApplication.h

@ -90,15 +90,7 @@ class GlutApplication {
class MouseEvent; class MouseEvent;
class MouseMoveEvent; class MouseMoveEvent;
/** /** @copydoc Sdl2Application::Sdl2Application(const Arguments&, const Configuration&) */
* @brief Default constructor
* @param arguments Application arguments
* @param configuration %Configuration
*
* Creates application with default or user-specified configuration.
* See Configuration for more information. The program exits if the
* context cannot be created, see below for an alternative.
*/
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
explicit GlutApplication(const Arguments& arguments, const Configuration& configuration = Configuration()); explicit GlutApplication(const Arguments& arguments, const Configuration& configuration = Configuration());
#else #else
@ -107,19 +99,10 @@ class GlutApplication {
explicit GlutApplication(const Arguments& arguments); explicit GlutApplication(const Arguments& arguments);
#endif #endif
/** /** @copydoc Sdl2Application::Sdl2Application(const Arguments&, std::nullptr_t) */
* @brief Constructor
* @param arguments Application arguments
*
* Unlike above, the context is not created and must be created later
* with createContext() or tryCreateContext().
*/
explicit GlutApplication(const Arguments& arguments, std::nullptr_t); explicit GlutApplication(const Arguments& arguments, std::nullptr_t);
/** /** @copydoc Sdl2Application::exec() */
* @brief Execute main loop
* @return Value for returning from `main()`.
*/
int exec() { int exec() {
glutMainLoop(); glutMainLoop();
return 0; return 0;
@ -130,74 +113,31 @@ class GlutApplication {
faster than public pure virtual destructor */ faster than public pure virtual destructor */
~GlutApplication(); ~GlutApplication();
/** /** @copydoc Sdl2Application::createContext() */
* @brief Create context with given configuration
*
* Must be called if and only if the context wasn't created by the
* constructor itself. The program exits if the context cannot be
* created, see tryCreateContext() for an alternative.
*/
void createContext(const Configuration& configuration); void createContext(const Configuration& configuration);
/** /** @copydoc Sdl2Application::tryCreateContext() */
* @brief Try to create context with given configuration
*
* Unlike createContext() returns `false` if the context cannot be
* created, `true` otherwise.
*/
bool tryCreateContext(const Configuration& configuration); bool tryCreateContext(const Configuration& configuration);
/** @{ @name Drawing functions */ /** @{ @name Drawing functions */
/** /** @copydoc Sdl2Application::viewportEvent() */
* @brief Viewport event
*
* Called when window size changes. You should pass the new size to
* DefaultFramebuffer::setViewport() and possibly elsewhere (cameras,
* other framebuffers...).
*
* Note that this function might not get called at all if the window
* size doesn't change. You are responsible for configuring the initial
* state yourself, viewport of default framebuffer can be retrieved
* from @ref DefaultFramebuffer::viewport().
*/
virtual void viewportEvent(const Vector2i& size) = 0; virtual void viewportEvent(const Vector2i& size) = 0;
/** /** @copydoc Sdl2Application::drawEvent() */
* @brief Draw event
*
* Called when the screen is redrawn. You should clean the framebuffer
* using Framebuffer::clear() and then add your own drawing functions,
* such as calling SceneGraph::AbstractCamera::draw(). After drawing
* is finished, call swapBuffers(). If you want to draw immediately
* again, call also redraw().
*/
virtual void drawEvent() = 0; virtual void drawEvent() = 0;
/** /** @copydoc Sdl2Application::swapBuffers() */
* @brief Swap buffers
*
* Paints currently rendered framebuffer on screen.
*/
void swapBuffers() { glutSwapBuffers(); } void swapBuffers() { glutSwapBuffers(); }
/** /** @copydoc Sdl2Application::redraw() */
* @brief Redraw immediately
*
* Marks the window for redrawing, resulting in call to drawEvent()
* in the next iteration.
*/
void redraw() { glutPostRedisplay(); } void redraw() { glutPostRedisplay(); }
/*@}*/ /*@}*/
/** @{ @name Keyboard handling */ /** @{ @name Keyboard handling */
/** /** @copydoc Sdl2Application::keyPressEvent() */
* @brief Key press event
*
* Called when an key is pressed. Default implementation does nothing.
*/
virtual void keyPressEvent(KeyEvent& event); virtual void keyPressEvent(KeyEvent& event);
/** /**
@ -226,7 +166,7 @@ class GlutApplication {
/** /**
* @brief Enable or disable mouse tracking * @brief Enable or disable mouse tracking
* *
* When mouse tracking is enabled, mouseMoveEvent() is called even * When mouse tracking is enabled, @ref mouseMoveEvent() is called even
* when no button is pressed. Mouse tracking is disabled by default. * when no button is pressed. Mouse tracking is disabled by default.
*/ */
void setMouseTracking(bool enabled) { void setMouseTracking(bool enabled) {
@ -244,20 +184,10 @@ class GlutApplication {
} }
protected: protected:
/** /** @copydoc Sdl2Application::mousePressEvent() */
* @brief Mouse press event
*
* Called when mouse button is pressed. Default implementation does
* nothing.
*/
virtual void mousePressEvent(MouseEvent& event); virtual void mousePressEvent(MouseEvent& event);
/** /** @copydoc Sdl2Application::mouseReleaseEvent() */
* @brief Mouse release event
*
* Called when mouse button is released. Default implementation does
* nothing.
*/
virtual void mouseReleaseEvent(MouseEvent& event); virtual void mouseReleaseEvent(MouseEvent& event);
/** /**
@ -265,7 +195,7 @@ class GlutApplication {
* *
* Called when any mouse button is pressed and mouse is moved. Default * Called when any mouse button is pressed and mouse is moved. Default
* implementation does nothing. * implementation does nothing.
* @see setMouseTracking() * @see @ref setMouseTracking()
*/ */
virtual void mouseMoveEvent(MouseMoveEvent& event); virtual void mouseMoveEvent(MouseMoveEvent& event);
@ -297,7 +227,7 @@ class GlutApplication {
@brief %Configuration @brief %Configuration
Double-buffered RGBA window with depth and stencil buffers. Double-buffered RGBA window with depth and stencil buffers.
@see GlutApplication(), createContext() @see @ref GlutApplication(), @ref createContext(), @ref tryCreateContext()
*/ */
class GlutApplication::Configuration { class GlutApplication::Configuration {
Configuration(const Configuration&) = delete; Configuration(const Configuration&) = delete;
@ -362,8 +292,8 @@ class GlutApplication::Configuration {
/** /**
@brief Base for input events @brief Base for input events
@see KeyEvent, MouseEvent, MouseMoveEvent, keyPressEvent(), mousePressEvent(), @see @ref KeyEvent, @ref MouseEvent, @ref MouseMoveEvent, @ref keyPressEvent(),
mouseReleaseEvent(), mouseMoveEvent() @ref mousePressEvent(), @ref mouseReleaseEvent(), @ref mouseMoveEvent()
*/ */
class GlutApplication::InputEvent { class GlutApplication::InputEvent {
InputEvent(const InputEvent&) = delete; InputEvent(const InputEvent&) = delete;
@ -372,15 +302,10 @@ class GlutApplication::InputEvent {
InputEvent& operator=(InputEvent&&) = delete; InputEvent& operator=(InputEvent&&) = delete;
public: public:
/** /** @copydoc Sdl2Application::InputEvent::setAccepted() */
* @brief Set event as accepted
*
* If the event is ignored (i.e., not set as accepted), it might be
* propagated elsewhere. By default is each event ignored.
*/
void setAccepted(bool accepted = true) { _accepted = accepted; } void setAccepted(bool accepted = true) { _accepted = accepted; }
/** @brief Whether the event is accepted */ /** @copydoc Sdl2Application::InputEvent::isAccepted() */
constexpr bool isAccepted() const { return _accepted; } constexpr bool isAccepted() const { return _accepted; }
protected: protected:
@ -395,7 +320,7 @@ class GlutApplication::InputEvent {
/** /**
@brief Key event @brief Key event
@see keyPressEvent() @see @ref keyPressEvent()
*/ */
class GlutApplication::KeyEvent: public GlutApplication::InputEvent { class GlutApplication::KeyEvent: public GlutApplication::InputEvent {
friend class GlutApplication; friend class GlutApplication;
@ -404,7 +329,7 @@ class GlutApplication::KeyEvent: public GlutApplication::InputEvent {
/** /**
* @brief Key * @brief Key
* *
* @see key() * @see @ref key()
*/ */
enum class Key: int { enum class Key: int {
Up = GLUT_KEY_UP, /**< Up arrow */ Up = GLUT_KEY_UP, /**< Up arrow */
@ -445,7 +370,7 @@ class GlutApplication::KeyEvent: public GlutApplication::InputEvent {
/** /**
@brief Mouse event @brief Mouse event
@see MouseMoveEvent, mousePressEvent(), mouseReleaseEvent() @see @ref MouseMoveEvent, @ref mousePressEvent(), @ref mouseReleaseEvent()
*/ */
class GlutApplication::MouseEvent: public GlutApplication::InputEvent { class GlutApplication::MouseEvent: public GlutApplication::InputEvent {
friend class GlutApplication; friend class GlutApplication;
@ -454,7 +379,7 @@ class GlutApplication::MouseEvent: public GlutApplication::InputEvent {
/** /**
* @brief Mouse button * @brief Mouse button
* *
* @see button() * @see @ref button()
*/ */
enum class Button: int { enum class Button: int {
Left = GLUT_LEFT_BUTTON, /**< Left button */ Left = GLUT_LEFT_BUTTON, /**< Left button */
@ -480,7 +405,7 @@ class GlutApplication::MouseEvent: public GlutApplication::InputEvent {
/** /**
@brief Mouse move event @brief Mouse move event
@see MouseEvent, mouseMoveEvent() @see @ref MouseEvent, @ref mouseMoveEvent()
*/ */
class GlutApplication::MouseMoveEvent: public GlutApplication::InputEvent { class GlutApplication::MouseMoveEvent: public GlutApplication::InputEvent {
friend class GlutApplication; friend class GlutApplication;
@ -489,7 +414,7 @@ class GlutApplication::MouseMoveEvent: public GlutApplication::InputEvent {
/** /**
* @brief Mouse button * @brief Mouse button
* *
* @see Buttons, buttons() * @see @ref Buttons, @ref buttons()
*/ */
enum class Button: UnsignedByte { enum class Button: UnsignedByte {
/** /**
@ -502,7 +427,7 @@ class GlutApplication::MouseMoveEvent: public GlutApplication::InputEvent {
/** /**
* @brief Set of mouse buttons * @brief Set of mouse buttons
* *
* @see buttons() * @see @ref buttons()
*/ */
typedef Containers::EnumSet<Button, UnsignedByte> Buttons; typedef Containers::EnumSet<Button, UnsignedByte> Buttons;
@ -523,9 +448,9 @@ class GlutApplication::MouseMoveEvent: public GlutApplication::InputEvent {
@brief Entry point for GLUT-based applications @brief Entry point for GLUT-based applications
@param className Class name @param className Class name
Can be with GlutApplication subclasses used as equivalent to the following Can be with @ref Magnum::Platform::GlutApplication "Platform::GlutApplication"
code to achieve better portability, see @ref portability-applications for more subclasses used as equivalent to the following code to achieve better
information. portability, see @ref portability-applications for more information.
@code @code
int main(int argc, char** argv) { int main(int argc, char** argv) {
className app({argc, argv}); className app({argc, argv});

10
src/Platform/GlxApplication.h

@ -66,10 +66,10 @@ to simplify porting.
*/ */
class GlxApplication: public AbstractXApplication { class GlxApplication: public AbstractXApplication {
public: public:
/** @copydoc GlutApplication::GlutApplication(const Arguments&, const Configuration&) */ /** @copydoc Sdl2Application::GlutApplication(const Arguments&, const Configuration&) */
explicit GlxApplication(const Arguments& arguments, const Configuration& configuration = Configuration()); explicit GlxApplication(const Arguments& arguments, const Configuration& configuration = Configuration());
/** @copydoc GlutApplication::GlutApplication(const Arguments&, std::nullptr_t) */ /** @copydoc Sdl2Application::GlutApplication(const Arguments&, std::nullptr_t) */
explicit GlxApplication(const Arguments& arguments, std::nullptr_t); explicit GlxApplication(const Arguments& arguments, std::nullptr_t);
protected: protected:
@ -82,9 +82,9 @@ class GlxApplication: public AbstractXApplication {
@brief Entry point for GLX-based applications @brief Entry point for GLX-based applications
@param className Class name @param className Class name
Can be used with GlxApplication subclasses as equivalent to the following code Can be used with @ref Magnum::Platform::GlxApplication "Platform::GlxApplication"
to achieve better portability, see @ref portability-applications for more subclasses as equivalent to the following code to achieve better portability,
information. see @ref portability-applications for more information.
@code @code
int main(int argc, char** argv) { int main(int argc, char** argv) {
className app({argc, argv}); className app({argc, argv});

55
src/Platform/NaClApplication.h

@ -148,7 +148,7 @@ class NaClApplication: public pp::Instance, public pp::Graphics3DClient, public
class MouseEvent; class MouseEvent;
class MouseMoveEvent; class MouseMoveEvent;
/** @copydoc GlutApplication::GlutApplication(const Arguments&, const Configuration&) */ /** @copydoc Sdl2Application::Sdl2Application(const Arguments&, const Configuration&) */
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
explicit NaClApplication(const Arguments& arguments, const Configuration& configuration = Configuration()); explicit NaClApplication(const Arguments& arguments, const Configuration& configuration = Configuration());
#else #else
@ -157,7 +157,7 @@ class NaClApplication: public pp::Instance, public pp::Graphics3DClient, public
explicit NaClApplication(const Arguments& arguments); explicit NaClApplication(const Arguments& arguments);
#endif #endif
/** @copydoc GlutApplication::GlutApplication(const Arguments&, std::nullptr_t) */ /** @copydoc Sdl2Application::Sdl2Application(const Arguments&, std::nullptr_t) */
explicit NaClApplication(const Arguments& arguments, std::nullptr_t); explicit NaClApplication(const Arguments& arguments, std::nullptr_t);
/** @brief Whether the application runs fullscreen */ /** @brief Whether the application runs fullscreen */
@ -178,24 +178,24 @@ class NaClApplication: public pp::Instance, public pp::Graphics3DClient, public
faster than public pure virtual destructor */ faster than public pure virtual destructor */
~NaClApplication(); ~NaClApplication();
/** @copydoc GlutApplication::createContext() */ /** @copydoc Sdl2Application::createContext() */
void createContext(const Configuration& configuration); void createContext(const Configuration& configuration);
/** @copydoc GlutApplication::tryCreateContext() */ /** @copydoc Sdl2Application::tryCreateContext() */
bool tryCreateContext(const Configuration& configuration); bool tryCreateContext(const Configuration& configuration);
/** @{ @name Drawing functions */ /** @{ @name Drawing functions */
/** @copydoc GlutApplication::viewportEvent() */ /** @copydoc Sdl2Application::viewportEvent() */
virtual void viewportEvent(const Vector2i& size) = 0; virtual void viewportEvent(const Vector2i& size) = 0;
/** @copydoc GlutApplication::drawEvent() */ /** @copydoc Sdl2Application::drawEvent() */
virtual void drawEvent() = 0; virtual void drawEvent() = 0;
/** @copydoc GlutApplication::swapBuffers() */ /** @copydoc Sdl2Application::swapBuffers() */
void swapBuffers(); void swapBuffers();
/** @copydoc GlutApplication::redraw() */ /** @copydoc Sdl2Application::redraw() */
void redraw() { flags |= Flag::Redraw; } void redraw() { flags |= Flag::Redraw; }
/*@}*/ /*@}*/
@ -232,8 +232,8 @@ class NaClApplication: public pp::Instance, public pp::Graphics3DClient, public
* @brief Enable or disable mouse locking * @brief Enable or disable mouse locking
* *
* When mouse is locked, the cursor is hidden and only * When mouse is locked, the cursor is hidden and only
* MouseMoveEvent::relativePosition() is changing, absolute position * @ref MouseMoveEvent::relativePosition() is changing, absolute
* stays the same. * position stays the same.
*/ */
void setMouseLocked(bool enabled); void setMouseLocked(bool enabled);
@ -309,7 +309,7 @@ class NaClApplication: public pp::Instance, public pp::Graphics3DClient, public
@brief %Configuration @brief %Configuration
Double-buffered RGBA canvas with depth and stencil buffers. Double-buffered RGBA canvas with depth and stencil buffers.
@see NaClApplication(), createContext() @see @ref NaClApplication(), @ref createContext()
*/ */
class NaClApplication::Configuration { class NaClApplication::Configuration {
Configuration(const Configuration&) = delete; Configuration(const Configuration&) = delete;
@ -357,10 +357,11 @@ class NaClApplication::Configuration {
/** /**
@brief Base for input events @brief Base for input events
If you accept the event, call setAccepted(), otherwise the event will be If you accept the event, call @ref setAccepted(), otherwise the event will be
propagated to the browser. propagated to the browser.
@see KeyEvent, MouseEvent, MouseMoveEvent, keyPressEvent(), keyReleaseEvent(), @see @ref KeyEvent, @ref MouseEvent, @ref MouseMoveEvent, @ref keyPressEvent(),
mousePressEvent(), mouseReleaseEvent(), mouseMoveEvent() @ref keyReleaseEvent(), @ref mousePressEvent(), @ref mouseReleaseEvent(),
@ref mouseMoveEvent()
*/ */
class NaClApplication::InputEvent { class NaClApplication::InputEvent {
InputEvent(const InputEvent&) = delete; InputEvent(const InputEvent&) = delete;
@ -373,7 +374,7 @@ class NaClApplication::InputEvent {
* @brief %Modifier * @brief %Modifier
* *
* @todo AltGr + PP_INPUTEVENT_MODIFIER_ISKEYPAD, PP_INPUTEVENT_MODIFIER_ISAUTOREPEAT * @todo AltGr + PP_INPUTEVENT_MODIFIER_ISKEYPAD, PP_INPUTEVENT_MODIFIER_ISAUTOREPEAT
* @see Modifiers, modifiers() * @see @ref Modifiers, @ref modifiers()
*/ */
enum class Modifier: std::uint32_t { enum class Modifier: std::uint32_t {
Shift = PP_INPUTEVENT_MODIFIER_SHIFTKEY, /**< Shift */ Shift = PP_INPUTEVENT_MODIFIER_SHIFTKEY, /**< Shift */
@ -414,7 +415,7 @@ class NaClApplication::InputEvent {
/** /**
* @brief Set of modifiers * @brief Set of modifiers
* *
* @see modifiers() * @see @ref modifiers()
*/ */
typedef Containers::EnumSet<Modifier, std::uint32_t> Modifiers; typedef Containers::EnumSet<Modifier, std::uint32_t> Modifiers;
@ -469,8 +470,8 @@ class NaClApplication::InputEvent {
/** /**
@brief Key event @brief Key event
See InputEvent for more information. See also @ref InputEvent for more information.
@see keyPressEvent(), keyReleaseEvent() @see @ref keyPressEvent(), @ref keyReleaseEvent()
*/ */
class NaClApplication::KeyEvent: public NaClApplication::InputEvent { class NaClApplication::KeyEvent: public NaClApplication::InputEvent {
friend class NaClApplication; friend class NaClApplication;
@ -480,7 +481,7 @@ class NaClApplication::KeyEvent: public NaClApplication::InputEvent {
* @brief Key * @brief Key
* *
* @todo Slash, percent, equal to be compatible with *XApplication * @todo Slash, percent, equal to be compatible with *XApplication
* @see key() * @see @ref key()
*/ */
enum class Key: std::uint32_t { enum class Key: std::uint32_t {
Enter = 0x0D, /**< Enter */ Enter = 0x0D, /**< Enter */
@ -564,8 +565,8 @@ class NaClApplication::KeyEvent: public NaClApplication::InputEvent {
/** /**
@brief Mouse event @brief Mouse event
See InputEvent for more information. See also @ref InputEvent for more information.
@see MouseMoveEvent, mousePressEvent(), mouseReleaseEvent() @see @ref MouseMoveEvent, @ref mousePressEvent(), @ref mouseReleaseEvent()
*/ */
class NaClApplication::MouseEvent: public NaClApplication::InputEvent { class NaClApplication::MouseEvent: public NaClApplication::InputEvent {
friend class NaClApplication; friend class NaClApplication;
@ -574,7 +575,7 @@ class NaClApplication::MouseEvent: public NaClApplication::InputEvent {
/** /**
* @brief Button * @brief Button
* *
* @see button() * @see @ref button()
*/ */
enum class Button: unsigned int { enum class Button: unsigned int {
Left = PP_INPUTEVENT_MOUSEBUTTON_LEFT, /**< Left button */ Left = PP_INPUTEVENT_MOUSEBUTTON_LEFT, /**< Left button */
@ -598,8 +599,8 @@ class NaClApplication::MouseEvent: public NaClApplication::InputEvent {
/** /**
@brief Mouse move event @brief Mouse move event
See InputEvent for more information. See also @ref InputEvent for more information.
@see MouseEvent, mouseMoveEvent() @see @ref MouseEvent, @ref mouseMoveEvent()
*/ */
class NaClApplication::MouseMoveEvent: public NaClApplication::InputEvent { class NaClApplication::MouseMoveEvent: public NaClApplication::InputEvent {
friend class NaClApplication; friend class NaClApplication;
@ -642,9 +643,9 @@ namespace Implementation {
@brief Entry point for NaCl application @brief Entry point for NaCl application
@param application Application class name @param application Application class name
See NaClApplication and @ref portability-applications for more information. See @ref Magnum::Platform::NaClApplication "Platform::NaClApplication" and
When no other application header is included this macro is also aliased to @ref portability-applications for more information. When no other application
`MAGNUM_APPLICATION_MAIN()`. header is included this macro is also aliased to `MAGNUM_APPLICATION_MAIN()`.
*/ */
/* look at that insane placement of __attribute__. WTF. */ /* look at that insane placement of __attribute__. WTF. */
#define MAGNUM_NACLAPPLICATION_MAIN(application) \ #define MAGNUM_NACLAPPLICATION_MAIN(application) \

139
src/Platform/Sdl2Application.h

@ -135,7 +135,15 @@ class Sdl2Application {
class MouseEvent; class MouseEvent;
class MouseMoveEvent; class MouseMoveEvent;
/** @copydoc GlutApplication::GlutApplication(const Arguments&, const Configuration&) */ /**
* @brief Default constructor
* @param arguments Application arguments
* @param configuration %Configuration
*
* Creates application with default or user-specified configuration.
* See @ref Configuration for more information. The program exits if
* the context cannot be created, see below for an alternative.
*/
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
explicit Sdl2Application(const Arguments& arguments, const Configuration& configuration = Configuration()); explicit Sdl2Application(const Arguments& arguments, const Configuration& configuration = Configuration());
#else #else
@ -144,10 +152,19 @@ class Sdl2Application {
explicit Sdl2Application(const Arguments& arguments); explicit Sdl2Application(const Arguments& arguments);
#endif #endif
/** @copydoc GlutApplication::GlutApplication(const Arguments&, std::nullptr_t) */ /**
* @brief Constructor
* @param arguments Application arguments
*
* Unlike above, the context is not created and must be created later
* with @ref createContext() or @ref tryCreateContext().
*/
explicit Sdl2Application(const Arguments& arguments, std::nullptr_t); explicit Sdl2Application(const Arguments& arguments, std::nullptr_t);
/** @copydoc GlutApplication::exec() */ /**
* @brief Execute main loop
* @return Value for returning from `main()`.
*/
int exec(); int exec();
/** @brief Exit application main loop */ /** @brief Exit application main loop */
@ -158,31 +175,73 @@ class Sdl2Application {
faster than public pure virtual destructor */ faster than public pure virtual destructor */
~Sdl2Application(); ~Sdl2Application();
/** @copydoc GlutApplication::createContext() */ /**
* @brief Create context with given configuration
*
* Must be called if and only if the context wasn't created by the
* constructor itself. The program exits if the context cannot be
* created, see @ref tryCreateContext() for an alternative.
*/
void createContext(const Configuration& configuration); void createContext(const Configuration& configuration);
/** @copydoc GlutApplication::tryCreateContext() */ /**
* @brief Try to create context with given configuration
*
* Unlike @ref createContext() returns `false` if the context cannot be
* created, `true` otherwise.
*/
bool tryCreateContext(const Configuration& configuration); bool tryCreateContext(const Configuration& configuration);
/** @{ @name Drawing functions */ /** @{ @name Drawing functions */
/** @copydoc GlutApplication::viewportEvent() */ /**
* @brief Viewport event
*
* Called when window size changes. You should pass the new size to
* @ref DefaultFramebuffer::setViewport() and possibly elsewhere
* (cameras, other framebuffers...).
*
* Note that this function might not get called at all if the window
* size doesn't change. You are responsible for configuring the initial
* state yourself, viewport of default framebuffer can be retrieved
* from @ref DefaultFramebuffer::viewport().
*/
virtual void viewportEvent(const Vector2i& size) = 0; virtual void viewportEvent(const Vector2i& size) = 0;
/** @copydoc GlutApplication::drawEvent() */ /**
* @brief Draw event
*
* Called when the screen is redrawn. You should clean the framebuffer
* using @ref DefaultFramebuffer::clear() and then add your own drawing
* functions. After drawing is finished, call @ref swapBuffers(). If
* you want to draw immediately again, call also @ref redraw().
*/
virtual void drawEvent() = 0; virtual void drawEvent() = 0;
/** @copydoc GlutApplication::swapBuffers() */ /**
* @brief Swap buffers
*
* Paints currently rendered framebuffer on screen.
*/
void swapBuffers(); void swapBuffers();
/** @copydoc GlutApplication::redraw() */ /**
* @brief Redraw immediately
*
* Marks the window for redrawing, resulting in call to @ref drawEvent()
* in the next iteration.
*/
void redraw() { flags |= Flag::Redraw; } void redraw() { flags |= Flag::Redraw; }
/*@}*/ /*@}*/
/** @{ @name Keyboard handling */ /** @{ @name Keyboard handling */
/** @copydoc GlutApplication::keyPressEvent() */ /**
* @brief Key press event
*
* Called when an key is pressed. Default implementation does nothing.
*/
virtual void keyPressEvent(KeyEvent& event); virtual void keyPressEvent(KeyEvent& event);
/** /**
@ -210,10 +269,20 @@ class Sdl2Application {
void setMouseLocked(bool enabled); void setMouseLocked(bool enabled);
protected: protected:
/** @copydoc GlutApplication::mousePressEvent() */ /**
* @brief Mouse press event
*
* Called when mouse button is pressed. Default implementation does
* nothing.
*/
virtual void mousePressEvent(MouseEvent& event); virtual void mousePressEvent(MouseEvent& event);
/** @copydoc GlutApplication::mouseReleaseEvent() */ /**
* @brief Mouse release event
*
* Called when mouse button is released. Default implementation does
* nothing.
*/
virtual void mouseReleaseEvent(MouseEvent& event); virtual void mouseReleaseEvent(MouseEvent& event);
/** /**
@ -263,7 +332,7 @@ CORRADE_ENUMSET_OPERATORS(Sdl2Application::Flags)
Centered non-resizable window with double-buffered OpenGL context and 24bit Centered non-resizable window with double-buffered OpenGL context and 24bit
depth buffer. depth buffer.
@see Sdl2Application(), createContext() @see @ref Sdl2Application(), @ref createContext(), @ref tryCreateContext()
*/ */
class Sdl2Application::Configuration { class Sdl2Application::Configuration {
Configuration(const Configuration&) = delete; Configuration(const Configuration&) = delete;
@ -275,7 +344,7 @@ class Sdl2Application::Configuration {
/** /**
* @brief Window flag * @brief Window flag
* *
* @see Flags, setFlags() * @see @ref Flags, @ref setFlags()
*/ */
enum class Flag: Uint32 { enum class Flag: Uint32 {
Resizable = SDL_WINDOW_RESIZABLE, /**< Resizable window */ Resizable = SDL_WINDOW_RESIZABLE, /**< Resizable window */
@ -289,7 +358,7 @@ class Sdl2Application::Configuration {
/** /**
* @brief Window flags * @brief Window flags
* *
* @see setFlags() * @see @ref setFlags()
*/ */
typedef Containers::EnumSet<Flag, Uint32, SDL_WINDOW_RESIZABLE| typedef Containers::EnumSet<Flag, Uint32, SDL_WINDOW_RESIZABLE|
SDL_WINDOW_FULLSCREEN|SDL_WINDOW_HIDDEN|SDL_WINDOW_MAXIMIZED| SDL_WINDOW_FULLSCREEN|SDL_WINDOW_HIDDEN|SDL_WINDOW_MAXIMIZED|
@ -367,8 +436,9 @@ CORRADE_ENUMSET_OPERATORS(Sdl2Application::Configuration::Flags)
/** /**
@brief Base for input events @brief Base for input events
@see KeyEvent, MouseEvent, MouseMoveEvent, keyPressEvent(), keyReleaseEvent(), @see @ref KeyEvent, @ref MouseEvent, @ref MouseMoveEvent, @ref keyPressEvent(),
mousePressEvent(), mouseReleaseEvent(), mouseMoveEvent() @ref keyReleaseEvent(), @ref mousePressEvent(), @ref mouseReleaseEvent(),
@ref mouseMoveEvent()
*/ */
class Sdl2Application::InputEvent { class Sdl2Application::InputEvent {
InputEvent(const InputEvent&) = delete; InputEvent(const InputEvent&) = delete;
@ -380,8 +450,8 @@ class Sdl2Application::InputEvent {
/** /**
* @brief %Modifier * @brief %Modifier
* *
* @see Modifiers, KeyEvent::modifiers(), MouseEvent::modifiers(), * @see @ref Modifiers, @ref KeyEvent::modifiers(),
* MouseMoveEvent::modifiers() * @ref MouseEvent::modifiers(), @ref MouseMoveEvent::modifiers()
*/ */
enum class Modifier: Uint16 { enum class Modifier: Uint16 {
Shift = KMOD_SHIFT, /**< Shift */ Shift = KMOD_SHIFT, /**< Shift */
@ -396,15 +466,22 @@ class Sdl2Application::InputEvent {
/** /**
* @brief Set of modifiers * @brief Set of modifiers
* *
* @see KeyEvent::modifiers(), MouseEvent::modifiers(), * @see @ref KeyEvent::modifiers(), @ref MouseEvent::modifiers(),
* MouseMoveEvent::modifiers() * @ref MouseMoveEvent::modifiers()
*/ */
typedef Containers::EnumSet<Modifier, Uint16> Modifiers; typedef Containers::EnumSet<Modifier, Uint16> Modifiers;
/** @copydoc GlutApplication::InputEvent::setAccepted() */ /**
* @brief Set event as accepted
*
* If the event is ignored (i.e., not set as accepted), it might be
* propagated elsewhere, for example to another screen when using
* @ref BasicScreenedApplication "ScreenedApplication". By default is
* each event ignored and thus propagated.
*/
void setAccepted(bool accepted = true) { _accepted = accepted; } void setAccepted(bool accepted = true) { _accepted = accepted; }
/** @copydoc GlutApplication::InputEvent::isAccepted() */ /** @brief Whether the event is accepted */
constexpr bool isAccepted() const { return _accepted; } constexpr bool isAccepted() const { return _accepted; }
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
@ -421,7 +498,7 @@ class Sdl2Application::InputEvent {
/** /**
@brief Key event @brief Key event
@see keyPressEvent(), keyReleaseEvent() @see @ref keyPressEvent(), @ref keyReleaseEvent()
*/ */
class Sdl2Application::KeyEvent: public Sdl2Application::InputEvent { class Sdl2Application::KeyEvent: public Sdl2Application::InputEvent {
friend class Sdl2Application; friend class Sdl2Application;
@ -430,7 +507,7 @@ class Sdl2Application::KeyEvent: public Sdl2Application::InputEvent {
/** /**
* @brief Key * @brief Key
* *
* @see key() * @see @ref key()
*/ */
enum class Key: SDL_Keycode { enum class Key: SDL_Keycode {
Enter = SDLK_RETURN, /**< Enter */ Enter = SDLK_RETURN, /**< Enter */
@ -521,7 +598,7 @@ class Sdl2Application::KeyEvent: public Sdl2Application::InputEvent {
/** /**
@brief Mouse event @brief Mouse event
@see MouseMoveEvent, mousePressEvent(), mouseReleaseEvent() @see @ref MouseMoveEvent, @ref mousePressEvent(), @ref mouseReleaseEvent()
*/ */
class Sdl2Application::MouseEvent: public Sdl2Application::InputEvent { class Sdl2Application::MouseEvent: public Sdl2Application::InputEvent {
friend class Sdl2Application; friend class Sdl2Application;
@ -530,7 +607,7 @@ class Sdl2Application::MouseEvent: public Sdl2Application::InputEvent {
/** /**
* @brief Mouse button * @brief Mouse button
* *
* @see button() * @see @ref button()
*/ */
enum class Button: Uint8 { enum class Button: Uint8 {
Left = SDL_BUTTON_LEFT, /**< Left button */ Left = SDL_BUTTON_LEFT, /**< Left button */
@ -565,7 +642,7 @@ class Sdl2Application::MouseEvent: public Sdl2Application::InputEvent {
/** /**
@brief Mouse move event @brief Mouse move event
@see MouseEvent, mouseMoveEvent() @see @ref MouseEvent, @ref mouseMoveEvent()
*/ */
class Sdl2Application::MouseMoveEvent: public Sdl2Application::InputEvent { class Sdl2Application::MouseMoveEvent: public Sdl2Application::InputEvent {
friend class Sdl2Application; friend class Sdl2Application;
@ -624,9 +701,9 @@ class Sdl2Application::MouseMoveEvent: public Sdl2Application::InputEvent {
@brief Entry point for SDL2-based applications @brief Entry point for SDL2-based applications
@param className Class name @param className Class name
Can be used with Sdl2Application subclasses as equivalent to the following Can be used with @ref Magnum::Platform::Sdl2Application "Platform::Sdl2Application"
code to achieve better portability, see @ref portability-applications for more subclasses as equivalent to the following code to achieve better portability,
information. see @ref portability-applications for more information.
@code @code
int main(int argc, char** argv) { int main(int argc, char** argv) {
className app({argc, argv}); className app({argc, argv});

12
src/Platform/WindowlessGlxApplication.h

@ -83,7 +83,7 @@ class WindowlessGlxApplication {
class Configuration; class Configuration;
/** @copydoc GlutApplication::GlutApplication(const Arguments&, const Configuration&) */ /** @copydoc Sdl2Application::Sdl2Application(const Arguments&, const Configuration&) */
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
explicit WindowlessGlxApplication(const Arguments& arguments, const Configuration& configuration = Configuration()); explicit WindowlessGlxApplication(const Arguments& arguments, const Configuration& configuration = Configuration());
#else #else
@ -92,7 +92,7 @@ class WindowlessGlxApplication {
explicit WindowlessGlxApplication(const Arguments& arguments); explicit WindowlessGlxApplication(const Arguments& arguments);
#endif #endif
/** @copydoc GlutApplication::GlutApplication(const Arguments&, std::nullptr_t) */ /** @copydoc Sdl2Application::Sdl2Application(const Arguments&, std::nullptr_t) */
explicit WindowlessGlxApplication(const Arguments& arguments, std::nullptr_t); explicit WindowlessGlxApplication(const Arguments& arguments, std::nullptr_t);
/** /**
@ -106,7 +106,7 @@ class WindowlessGlxApplication {
thus this is faster than public pure virtual destructor */ thus this is faster than public pure virtual destructor */
~WindowlessGlxApplication(); ~WindowlessGlxApplication();
/** @copydoc GlutApplication::createContext() */ /** @copydoc Sdl2Application::createContext() */
void createContext(const Configuration& configuration); void createContext(const Configuration& configuration);
private: private:
@ -120,7 +120,8 @@ class WindowlessGlxApplication {
/** /**
@brief %Configuration @brief %Configuration
@see WindowlessGlxApplication(), createContext() @see @ref WindowlessGlxApplication(), @ref createContext(),
@ref tryCreateContext()
*/ */
class WindowlessGlxApplication::Configuration { class WindowlessGlxApplication::Configuration {
Configuration(const Configuration&) = delete; Configuration(const Configuration&) = delete;
@ -137,7 +138,8 @@ class WindowlessGlxApplication::Configuration {
@brief Entry point for windowless GLX application @brief Entry point for windowless GLX application
@param className Class name @param className Class name
Can be used as equivalent to the following code to achieve better portability, Can be used with @ref Magnum::Platform::WindowlessGlxApplication "Platform::WindowlessGlxApplication"
subclasses as equivalent to the following code to achieve better portability,
see @ref portability-applications for more information. see @ref portability-applications for more information.
@code @code
int main(int argc, char** argv) { int main(int argc, char** argv) {

18
src/Platform/WindowlessNaClApplication.h

@ -100,7 +100,7 @@ class WindowlessNaClApplication: public pp::Instance, public pp::Graphics3DClien
class Configuration; class Configuration;
/** @copydoc GlutApplication::GlutApplication(const Arguments&, const Configuration&) */ /** @copydoc Sdl2Application::Sdl2Application(const Arguments&, const Configuration&) */
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
explicit WindowlessNaClApplication(const Arguments& arguments, const Configuration& configuration = Configuration()); explicit WindowlessNaClApplication(const Arguments& arguments, const Configuration& configuration = Configuration());
#else #else
@ -109,7 +109,7 @@ class WindowlessNaClApplication: public pp::Instance, public pp::Graphics3DClien
explicit WindowlessNaClApplication(const Arguments& arguments); explicit WindowlessNaClApplication(const Arguments& arguments);
#endif #endif
/** @copydoc GlutApplication::GlutApplication(const Arguments&, std::nullptr_t) */ /** @copydoc Sdl2Application::Sdl2Application(const Arguments&, std::nullptr_t) */
explicit WindowlessNaClApplication(const Arguments& arguments, std::nullptr_t); explicit WindowlessNaClApplication(const Arguments& arguments, std::nullptr_t);
/** /**
@ -123,10 +123,10 @@ class WindowlessNaClApplication: public pp::Instance, public pp::Graphics3DClien
thus this is faster than public pure virtual destructor */ thus this is faster than public pure virtual destructor */
~WindowlessNaClApplication(); ~WindowlessNaClApplication();
/** @copydoc GlutApplication::createContext() */ /** @copydoc Sdl2Application::createContext() */
void createContext(const Configuration& configuration); void createContext(const Configuration& configuration);
/** @copydoc GlutApplication::tryCreateContext() */ /** @copydoc Sdl2Application::tryCreateContext() */
bool tryCreateContext(const Configuration& configuration); bool tryCreateContext(const Configuration& configuration);
private: private:
@ -146,7 +146,8 @@ class WindowlessNaClApplication: public pp::Instance, public pp::Graphics3DClien
/** /**
@brief %Configuration @brief %Configuration
@see WindowlessNaClApplication(), createContext(), tryCreateContext() @see @ref WindowlessNaClApplication(), @ref createContext(),
@ref tryCreateContext()
*/ */
class WindowlessNaClApplication::Configuration { class WindowlessNaClApplication::Configuration {
Configuration(const Configuration&) = delete; Configuration(const Configuration&) = delete;
@ -177,9 +178,10 @@ namespace Implementation {
@brief Entry point for windowless NaCl application @brief Entry point for windowless NaCl application
@param application Application class name @param application Application class name
See WindowlessNaClApplication and @ref portability-applications for more See @ref Magnum::Platform::WindowlessNaClApplication "Platform::WindowlessNaClApplication"
information. When no other windowless application header is included this macro and @ref portability-applications for more information. When no other
is also aliased to `MAGNUM_WINDOWLESSAPPLICATION_MAIN()`. windowless application header is included this macro is also aliased to
`MAGNUM_WINDOWLESSAPPLICATION_MAIN()`.
*/ */
/* look at that insane placement of __attribute__. WTF. */ /* look at that insane placement of __attribute__. WTF. */
#define MAGNUM_WINDOWLESSNACLAPPLICATION_MAIN(application) \ #define MAGNUM_WINDOWLESSNACLAPPLICATION_MAIN(application) \

10
src/Platform/XEglApplication.h

@ -67,10 +67,10 @@ to simplify porting.
*/ */
class XEglApplication: public AbstractXApplication { class XEglApplication: public AbstractXApplication {
public: public:
/** @copydoc GlutApplication::GlutApplication(const Arguments&, const Configuration&) */ /** @copydoc Sdl2Application::GlutApplication(const Arguments&, const Configuration&) */
explicit XEglApplication(const Arguments& arguments, const Configuration& configuration = Configuration()); explicit XEglApplication(const Arguments& arguments, const Configuration& configuration = Configuration());
/** @copydoc GlutApplication::GlutApplication(const Arguments&, std::nullptr_t) */ /** @copydoc Sdl2Application::GlutApplication(const Arguments&, std::nullptr_t) */
explicit XEglApplication(const Arguments& arguments, std::nullptr_t); explicit XEglApplication(const Arguments& arguments, std::nullptr_t);
protected: protected:
@ -83,9 +83,9 @@ class XEglApplication: public AbstractXApplication {
@brief Entry point for X/EGL-based applications @brief Entry point for X/EGL-based applications
@param className Class name @param className Class name
Can be used with XEglApplication subclasses as equivalent to the following code Can be used with @ref Magnum::Platform::XEglApplication "Platform::XEglApplication"
to achieve better portability, see @ref portability-applications for more subclasses as equivalent to the following code to achieve better portability,
information. see @ref portability-applications for more information.
@code @code
int main(int argc, char** argv) { int main(int argc, char** argv) {
className app({argc, argv}); className app({argc, argv});

Loading…
Cancel
Save