Skip to content

Commit

Permalink
Add ability to hide system cursor (#20)
Browse files Browse the repository at this point in the history
  • Loading branch information
jthomperoo committed Jan 10, 2023
1 parent 3a4e024 commit 28fe5b6
Show file tree
Hide file tree
Showing 14 changed files with 438 additions and 20 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ add_subdirectory (examples/PhysicsResizing)
add_subdirectory (examples/Primitives)
add_subdirectory (examples/Rotator)
add_subdirectory (examples/Sprites)
add_subdirectory (examples/Cursor)

### ===== clang-format ===== ###

Expand Down
51 changes: 47 additions & 4 deletions docs/Documentation/window_management_and_fullscreen.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,28 @@ new JamJar::Standard::WindowSystem(messageBus, window, "canvas-wrapper");

This sets up the `WindowSystem` to manage the window, pointing to the canvas wrapper with the ID `canvas-wrapper`.

This constructor also can take in an initial aspect ratio value, if none is provided a default aspect ratio of `16/9`
is used.
The `WindowSystem` can take in a set of optional properties to set things such as aspect ratio, max resolution, and
if the system cursor should be shown.


```c++
// Using a 4/3 resolution
new JamJar::Standard::WindowSystem(messageBus, window, "canvas-wrapper", 4/3);
new JamJar::Standard::WindowSystem(messageBus, window, "canvas-wrapper", JamJar::Standard::WindowSystemProperties({
.aspectRatio = 4/3
}));
// Using a 4/3 resolution with a max resolution of 400x300
new JamJar::Standard::WindowSystem(messageBus, window, "canvas-wrapper", 4/3, 400, 300);
new JamJar::Standard::WindowSystem(messageBus, window, "canvas-wrapper", JamJar::Standard::WindowSystemProperties({
.aspectRatio = 4/3,
.maxResolutionX = 400,
.maxResolutionY = 300
}));
// Using a 4/3 resolution with a max resolution of 400x300 with a hidden cursor
new JamJar::Standard::WindowSystem(messageBus, window, "canvas-wrapper", JamJar::Standard::WindowSystemProperties({
.aspectRatio = 4/3,
.maxResolutionX = 400,
.maxResolutionY = 300,
.showCursor = false
}));
```

## Canvas Wrapper
Expand Down Expand Up @@ -124,6 +138,35 @@ messageBus->Publish(new JamJar::MessagePayload<std::pair<int, int>>(

This sets the maximum resolution to `400x300`.

### System Cursor

You can choose to hide or show the system cursor. By default this is hidden. You can set this value by providing
a `WindowSystemProperties` when initializing the `WindowSystem`.

At runtime you can choose to show or hide the cursor by sending messages.

To show the cursor you can use:

```c++
messageBus->Publish(new JamJar::Message(JamJar::Standard::WindowSystem::MESSAGE_REQUEST_SHOW_CURSOR));
```
To hide the cursor you can use:
```c++
messageBus->Publish(new JamJar::Message(JamJar::Standard::WindowSystem::MESSAGE_REQUEST_HIDE_CURSOR));
```

When these events are processed the appropriate message will be published to let other systems know if a cursor has
been hidden or shown.

You can listen for these messages by listening out for:

- `JamJar::Standard::WindowSystem::MESSAGE_SHOW_CURSOR`
- `JamJar::Standard::WindowSystem::MESSAGE_HIDE_CURSOR`

These messages have no payload.

## Fullscreen

The `WindowSystem` uses emscripten's fullscreen functions to handle fullscreen interactions (entering and exiting).
Expand Down
49 changes: 49 additions & 0 deletions examples/Cursor/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
cmake_minimum_required(VERSION 3.14)

set (CMAKE_CXX_STANDARD 17)

project(Cursor VERSION 0.0.0)

### ===== dependencies ===== ###

# We don't need to compile the unit tests to use the library
set(JAMJAR_COMPILE_UNIT_TESTS OFF CACHE BOOL "Compile JamJar unit tests")

include(FetchContent)

# This example relies directly on the latest code in the parent directory, if using the library externally instead
# this should be fetched from over the internet, e.g.:
# FetchContent_Declare(JamJar
# GIT_REPOSITORY "git@github.com:jamjarlabs/JamJar.git"
# GIT_TAG "<library version>"
# )

set(JAMJAR_NATIVE_SOURCE_DIR "${CMAKE_SOURCE_DIR}/../../")

FetchContent_Declare(JamJar
SOURCE_DIR ${JAMJAR_NATIVE_SOURCE_DIR}
)

FetchContent_MakeAvailable(JamJar)

### ===== core ===== ###

set(CMAKE_CXX_FLAGS "-s USE_SDL=2")
SET(CMAKE_EXE_LINKER_FLAGS "-s LLD_REPORT_UNDEFINED -s MAX_WEBGL_VERSION=2 -s MIN_WEBGL_VERSION=2 --preload-file ${PROJECT_SOURCE_DIR}/assets@/assets")

set(EXE_SOURCES
src/main.cpp
src/cursor.cpp
src/pointer_controller.cpp
)

add_executable(Cursor ${EXE_SOURCES})

target_include_directories(Cursor
PRIVATE
src
)

target_link_libraries(Cursor PRIVATE JamJar)

configure_file(${PROJECT_SOURCE_DIR}/index.html ${PROJECT_BINARY_DIR}/index.html COPYONLY)
56 changes: 56 additions & 0 deletions examples/Cursor/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Cursor

This is an example that demonstrates how to replace the system cursor with a custom one.

The code is designed to be simple and easy to follow.

## Overview

This example hides the system cursor and replacing it with a smiley face cursor.

If you left click the system cursor will be shown again, if you right click it will be hidden.

## Dependencies

See the dependencies for [JamJar here](../../README.md#Dependencies).

## Running this example

1. Clone down the JamJar project:

```bash
git clone git@github.com:jamjarlabs/JamJar.git
```

2. Navigate the cloned directory:

```bash
cd JamJar
```

3. Use `cmake` to generate the build system and pull down any dependencies:

```bash
emcmake cmake -D CMAKE_EXPORT_COMPILE_COMMANDS=ON . -B build
```

4. Navigate to the generated example build directory:

```bash
cd build/examples/Cursor
```

5. Build the project:

```bash
emmake make
```

6. If you want to view the example, you can now access the generated HTML, if you have Python 3 installed a handy way
to do this is to run:

```bash
python -m http.server
```

Then you should be able to access the game at <http://127.0.0.1:8000/>.
Binary file added examples/Cursor/assets/texture.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
47 changes: 47 additions & 0 deletions examples/Cursor/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<!DOCTYPE html>
<html>
<head>
<title>Cursor</title>
<style>
html,
body {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
flex-direction: column;
margin: 0;
}

#canvas-wrapper {
display: flex;
margin: auto;
width: 100%;
flex-direction: column;
justify-content: center;
flex-grow: 1;
}

#canvas {
margin: auto;
cursor: none;
touch-action: none;
}
</style>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<meta name="HandheldFriendly" content="true" />
</head>
<body>
<h1>Cursor</h1>
<div id="canvas-wrapper">
<canvas id="canvas" oncontextmenu="return false;"></canvas>
</div>
<script>
Module = {};
Module['canvas'] = document.getElementById("canvas");
</script>
<script src="./Cursor"></script>
</body>
</html>
43 changes: 43 additions & 0 deletions examples/Cursor/src/cursor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include "cursor.hpp"
#include "entity/entity.hpp"
#include "game.hpp"
#include "geometry/vector_2d.hpp"
#include "message/message_payload.hpp"
#include "standard/2d/camera/camera.hpp"
#include "standard/2d/sprite/sprite.hpp"
#include "standard/2d/transform/transform.hpp"
#include "standard/file_texture/file_texture_request.hpp"
#include "standard/file_texture/file_texture_system.hpp"
#include <memory>

using JamJar::Color;
using JamJar::Entity;
using JamJar::Material;
using JamJar::Texture;
using JamJar::TextureFilter;
using JamJar::TextureProperties;
using JamJar::Vector2D;
using JamJar::Standard::FileTextureRequest;
using JamJar::Standard::FileTextureSystem;
using JamJar::Standard::LoadTexture;
using JamJar::Standard::_2D::Camera;
using JamJar::Standard::_2D::Sprite;
using JamJar::Standard::_2D::Transform;

Cursor::Cursor(JamJar::MessageBus *messageBus) : Game(messageBus) {}

void Cursor::OnStart() {
LoadTexture(this->messageBus,
new FileTextureRequest({.key = JamJar::hash("smiley"),
.path = "/assets/texture.png",
.properties = TextureProperties({.minFilter = TextureFilter::NEAREST,
.magFilter = TextureFilter::NEAREST})}));

auto camera = new Entity(messageBus);
camera->Add(new Transform());
camera->Add(new Camera(Color(1, 1, 1)));

auto smiley = new JamJar::Entity(messageBus);
smiley->Add(new Transform(Vector2D(0, 0), Vector2D(5, 5)));
smiley->Add(new Sprite(Material(Color(0, 1, 1, 1), Texture(JamJar::hash("smiley")))));
}
16 changes: 16 additions & 0 deletions examples/Cursor/src/cursor.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#ifndef CURSOR_HPP
#define CURSOR_HPP

#include "game.hpp"
#include "message/message_bus.hpp"
#include <memory>

class Cursor : public JamJar::Game {
protected:
virtual void OnStart() override;

public:
Cursor(JamJar::MessageBus *messageBus);
};

#endif
40 changes: 40 additions & 0 deletions examples/Cursor/src/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include "cursor.hpp"
#include "emscripten/html5.h"
#include "entity/entity_manager.hpp"
#include "game.hpp"
#include "message/message_bus.hpp"
#include "message/message_payload.hpp"
#include "pointer_controller.hpp"
#include "standard/2d/interpolation/interpolation_system.hpp"
#include "standard/2d/sprite/sprite_system.hpp"
#include "standard/2d/webgl2/webgl2_system.hpp"
#include "standard/file_texture/file_texture_system.hpp"
#include "standard/sdl2_input/sdl2_input_system.hpp"
#include "standard/window/window_system.hpp"
#include "window.hpp"
#include <SDL2/SDL.h>
#include <iostream>
#include <memory>
#include <stdlib.h>
#include <string>

int main(int argc, char *argv[]) {

auto window = JamJar::GetWindow("Cursor");
auto context = JamJar::GetCanvasContext();

auto messageBus = new JamJar::MessageBus();
new JamJar::EntityManager(messageBus);
auto game = new Cursor(messageBus);
new JamJar::Standard::_2D::WebGL2System(messageBus, window, context);
new JamJar::Standard::_2D::InterpolationSystem(messageBus);
new JamJar::Standard::_2D::SpriteSystem(messageBus);
new JamJar::Standard::FileTextureSystem(messageBus);
new JamJar::Standard::SDL2InputSystem(messageBus);
new JamJar::Standard::WindowSystem(messageBus, window, "canvas-wrapper",
JamJar::Standard::WindowSystemProperties({.showCursor = false}));
new PointerController(messageBus, window);
game->Start();

return 0;
}

0 comments on commit 28fe5b6

Please sign in to comment.