examples/example.windowing/example.windowing.native.app/example.windowing.cpp
File members: examples/example.windowing/example.windowing.native.app/example.windowing.cpp
// Copyright (c) 2020-2023, NVIDIA CORPORATION. All rights reserved.
//
// NVIDIA CORPORATION and its licensors retain all intellectual property
// and proprietary rights in and to this software, related documentation
// and any modifications thereto. Any use, reproduction, disclosure or
// distribution of this software and related documentation without an express
// license agreement from NVIDIA CORPORATION is strictly prohibited.
//
#ifndef DOXYGEN_BUILD // Just need the full listing
# include <omni/core/ModuleInfo.h>
# include <omni/core/OmniInit.h>
# include <windowing/IWindowSystem.h>
# include <cmath>
// example-begin omni-app-globals
OMNI_APP_GLOBALS("example.windowing.native.app", "Native (C++) example app using example.windowing.");
// example-end omni-app-globals
namespace omni
{
using namespace omni::core;
} // namespace omni
// Demonstrates how to create a custom cursor, in this case a beautiful red circle.
class CustomCursor : public omni::Implements<windowing::ICursor>
{
private:
struct Pixel
{
uint8_t r, g, b, a;
};
public:
// abi /////////////////////////////////////////////////////////////////////////////////////////////////////////////
virtual omni::UInt2 getSize_abi() noexcept
{
return m_size;
}
virtual omni::Int2 getHotSpot_abi() noexcept
{
return m_hotSpot;
}
virtual const uint8_t* getPixels_abi() noexcept
{
return &(m_pixels.data()->r);
}
// implementation details //////////////////////////////////////////////////////////////////////////////////////////
CustomCursor()
{
m_pixels.resize(m_size.w * m_size.h);
memset(m_pixels.data(), 0, m_pixels.size() * sizeof(Pixel));
Pixel* p = m_pixels.data();
for (int r = 0; r < int(m_size.h); ++r)
{
for (int c = 0; c < int(m_size.w); ++c)
{
int x = c - m_hotSpot.x;
int y = r - m_hotSpot.y;
float d = std::sqrt(float((x * x) + (y * y)));
float k = std::abs(d - m_diameter) - m_halfThickness;
if (k < 1.0)
{
if (k < 0.0)
{
k = 0.0;
}
p->r = 255;
p->g = 0;
p->b = 0;
p->a = uint8_t((1.0 - k) * 255);
}
++p;
}
}
}
private:
static constexpr float m_diameter = 25.0f;
static constexpr float m_halfThickness = 1.5f;
static constexpr omni::UInt2 m_size{ 64, 64 };
static constexpr omni::Int2 m_hotSpot{ 32, 32 };
std::vector<Pixel> m_pixels;
};
const char* mods2str(uint32_t mods)
{
static char str[8];
str[0] = (mods & input::fKeyboardModifierFlagShift) ? 's' : '-';
str[1] = (mods & input::fKeyboardModifierFlagControl) ? 'c' : '-';
str[2] = (mods & input::fKeyboardModifierFlagAlt) ? 'a' : '-';
str[3] = (mods & input::fKeyboardModifierFlagSuper) ? 'w' : '-';
str[4] = (mods & input::fKeyboardModifierFlagCapsLock) ? 'l' : '-';
str[5] = (mods & input::fKeyboardModifierFlagNumLock) ? 'n' : '-';
str[6] = '\0';
return str;
}
int main(int argc, char** argv)
{
OMNI_CORE_INIT(argc, argv);
auto windowSystem = omni::createType<windowing::IWindowSystem>();
if (!windowSystem)
{
OMNI_LOG_FATAL("unable to access window system");
return 1;
}
printf("IWindowSystem provided by: '%s'\n", omni::getModuleFilename(windowSystem.get()).c_str());
auto window = windowSystem->createWindow({ 640, 480 }, "example.windowing", windowing::fWindowHintScaleToMonitor);
if (!window)
{
OMNI_LOG_FATAL("unable to create window");
return 1;
}
printf(" ESC: Quit\n");
printf(" F11: Toggle fullscreen\n");
printf(" CTRL-m: Toggle minimized\n");
printf(" SHIFT-Up: Grow window\n");
printf(" SHIFT-Down: Shrink window\n");
printf(" CTRL-c: Copy text to internal clipboard\n");
printf(" CTRL-v: Print text from internal clipboard\n");
printf(" Up: Change cursor\n");
printf(" 1: Enable custom cursor\n");
omni::UInt2 size{ 0, 0 };
window->addOnResizeConsumer([&size](windowing::IWindow* window, omni::UInt2 sz) {
size = sz;
fprintf(stderr, "window resize: %u %u\n", size.w, size.h);
});
windowing::CursorType cursors[] = { windowing::CursorType::eArrow,
windowing::CursorType::eIBeam,
windowing::CursorType::eCrosshair,
windowing::CursorType::eHand,
windowing::CursorType::eHorizontalResize,
windowing::CursorType::eVerticalResize };
size_t cursorIndex = 0;
auto customCursor = omni::steal<windowing::ICursor>(new CustomCursor);
window->addOnKeyboardEventConsumer([&window, &customCursor, &cursors, &cursorIndex](
input::IKeyboard* /*keyboard*/, const input::KeyboardEvent* event) {
if (input::isKeyRelease(*event, input::KeyboardKey::eEscape))
{
window->setShouldClose(true);
}
else if (input::isKeyRelease(*event, input::KeyboardKey::eF11))
{
window->setFullscreen(!window->isFullscreen());
}
else if (input::isOnlyControlDown(*event) && input::isKeyRelease(*event, input::KeyboardKey::eM))
{
window->setMinimized(!window->isMinimized());
}
else if (input::isOnlyShiftDown(*event) && input::isKeyPress(*event, input::KeyboardKey::eUp))
{
auto sz = window->getSize();
if (sz.x > 100)
{
sz.x += 10;
}
if (sz.y > 100)
{
sz.y += 10;
}
window->setSize(sz);
}
else if (input::isOnlyShiftDown(*event) && input::isKeyPress(*event, input::KeyboardKey::eDown))
{
auto sz = window->getSize();
if (sz.x > 100)
{
sz.x -= 10;
}
if (sz.y > 100)
{
sz.y -= 10;
}
window->setSize(sz);
}
else if (input::isOnlyControlDown(*event) && input::isKeyRelease(*event, input::KeyboardKey::eC))
{
window->setClipboardText("hi from example.windowing");
}
else if (input::isOnlyControlDown(*event) && input::isKeyRelease(*event, input::KeyboardKey::eV))
{
const char* text = window->getClipboardText();
fprintf(stderr, "pasted: %s\n", (text ? text : "<empty>"));
}
else if (input::isKeyRelease(*event, input::KeyboardKey::eUp))
{
cursorIndex = (cursorIndex + 1) % CARB_COUNTOF(cursors);
window->setCursor(cursors[cursorIndex]);
}
else if (input::isKeyRelease(*event, input::KeyboardKey::eKey1))
{
fprintf(stderr, "setting custom cursor\n");
window->setCursor(customCursor.get());
}
});
window->addOnMaximizeConsumer([](windowing::IWindow* /*window*/, bool maximized) {
fprintf(stderr, "onMaximize: %s\n", (maximized ? "maximized" : "restored"));
});
window->addOnMinimizeConsumer([](windowing::IWindow* /*window*/, bool minimized) {
fprintf(stderr, "onMinimize: %s\n", (minimized ? "minimized" : "restored"));
});
window->addOnFocusConsumer([](windowing::IWindow* /*window*/, bool focused) {
fprintf(stderr, "onFocus: %s\n", (focused ? "true" : "false"));
});
window->addOnCloseConsumer([](windowing::IWindow* /*window*/) { fprintf(stderr, "onClose\n"); });
window->addOnDropConsumer([](windowing::IWindow* /*window*/, const char* const* paths, uint32_t pathCount) {
fprintf(stderr, "onDrop\n");
for (uint32_t i = 0; i < pathCount; ++i)
{
fprintf(stderr, " %s\n", paths[i]);
}
});
window->addOnContentScaleConsumer([](windowing::IWindow* /*window*/, omni::Float2 scale) {
fprintf(stderr, "onContentScale: %f %f\n", scale.x, scale.y);
});
window->addOnMouseOverConsumer(
[](windowing::IWindow* window, bool over) { fprintf(stderr, "onMouseOver: %s\n", (over ? "true" : "false")); });
window->addOnMouseEventConsumer([](input::IMouse* /*mouse*/, const input::MouseEvent* event) {
switch (event->type)
{
case input::MouseEventType::eButtonPress:
case input::MouseEventType::eButtonRelease:
{
bool isPress = (input::MouseEventType::eButtonPress == event->type);
fprintf(stderr, "button %d %s mods:%s\n", int(event->button), (isPress ? "press" : "release"),
mods2str(event->modifiers));
break;
}
case input::MouseEventType::eMotion:
{
fprintf(stderr, "motion: x:%f y:%f delta: x:%f y:%f mods:%s\n", event->position.x, event->position.y,
event->positionDelta.x, event->positionDelta.y, mods2str(event->modifiers));
break;
}
case input::MouseEventType::eScroll:
{
fprintf(stderr, "scroll: x:%f y:%f %s\n", event->scrollDelta.x, event->scrollDelta.y,
mods2str(event->modifiers));
break;
}
default:
fprintf(stderr, "unknown mouse event\n");
}
});
windowSystem->addOnGamepadConnectConsumer([](input::IGamepad* gamepad, bool isConnected) {
fprintf(stderr, "gamepad %s\n", (isConnected ? "connected" : "disconnected"));
gamepad->addOnStateChangeConsumer([](input::IGamepad* gamepad, const input::GamepadState* oldState,
const input::GamepadState* newState) {
if ((oldState->leftStick.x != newState->leftStick.x) || (oldState->leftStick.y != newState->leftStick.y))
{
fprintf(stderr, "left:%f %f ", newState->leftStick.x, newState->leftStick.y);
}
if ((oldState->rightStick.x != newState->rightStick.x) || (oldState->rightStick.y != newState->rightStick.y))
{
fprintf(stderr, "right:%f %f ", newState->rightStick.x, newState->rightStick.y);
}
if ((oldState->directionPad.x != newState->directionPad.x) ||
(oldState->directionPad.y != newState->directionPad.y))
{
fprintf(stderr, "dpad:%d %d ", newState->directionPad.x, newState->directionPad.y);
}
if (oldState->leftStickButton != newState->leftStickButton)
{
fprintf(stderr, "%c ", ((newState->leftStickButton > 0.0f) ? 'L' : 'l'));
}
if (oldState->rightStickButton != newState->rightStickButton)
{
fprintf(stderr, "%c ", ((newState->rightStickButton > 0.0f) ? 'L' : 'l'));
}
if (oldState->a != newState->a)
{
fprintf(stderr, "%c ", ((newState->a > 0.0f) ? 'A' : 'a'));
}
if (oldState->b != newState->b)
{
fprintf(stderr, "%c ", ((newState->b > 0.0f) ? 'B' : 'b'));
}
if (oldState->x != newState->x)
{
fprintf(stderr, "%c ", ((newState->x > 0.0f) ? 'X' : 'x'));
}
if (oldState->y != newState->y)
{
fprintf(stderr, "%c ", ((newState->y > 0.0f) ? 'Y' : 'y'));
}
if (oldState->select != newState->select)
{
fprintf(stderr, "%s ", (newState->select ? "SEL" : "sel"));
}
if (oldState->start != newState->start)
{
fprintf(stderr, "%s ", (newState->start ? "START" : "start"));
}
if (oldState->leftShoulder != newState->leftShoulder)
{
fprintf(stderr, "%s ", ((newState->leftShoulder > 0.0f) ? "lS" : "ls"));
}
if (oldState->rightShoulder != newState->rightShoulder)
{
fprintf(stderr, "%s ", ((newState->rightShoulder > 0.0f) ? "rS" : "rs"));
}
if (oldState->leftTrigger != newState->leftTrigger)
{
fprintf(stderr, "lt:%f ", newState->leftTrigger);
}
if (oldState->rightTrigger != newState->rightTrigger)
{
fprintf(stderr, "rt:%f ", newState->rightTrigger);
}
fprintf(stderr, "\n");
});
});
window->setShown(true);
while (!window->getShouldClose())
{
windowSystem->pollEvents();
}
fprintf(stderr, "final resize: %u %u\n", size.x, size.y);
fprintf(stderr, "final size: %u %u\n", window->getSize().x, window->getSize().y);
return 0;
}
#endif