first
This commit is contained in:
commit
0135d84443
104
Makefile
Normal file
104
Makefile
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
#STATIC/DYNAMIC
|
||||||
|
#LIB_MODE = STATIC
|
||||||
|
LIB_MODE = DYNAMIC
|
||||||
|
# BUILD/DYN_LIBRARY
|
||||||
|
#IMGUI_MODE = BUILD
|
||||||
|
IMGUI_MODE = DYN_LIBRARY
|
||||||
|
|
||||||
|
CC = gcc
|
||||||
|
CXX = g++
|
||||||
|
|
||||||
|
ASSET_PREFIX = assets/
|
||||||
|
|
||||||
|
|
||||||
|
SRC_DIR = src
|
||||||
|
OBJ_DIR = obj
|
||||||
|
BIN_DIR = bin
|
||||||
|
LIB_DIR = lib
|
||||||
|
|
||||||
|
STATIC_INCLUDE_DIR = include
|
||||||
|
|
||||||
|
CPPFLAGS = -Isrc/imgui -g -D ASSET_DIR=\"$(ASSET_PREFIX)\"
|
||||||
|
CFLAGS = -g -D ASSET_DIR=\"$(ASSET_PREFIX)\"
|
||||||
|
LDFLAGS = -g
|
||||||
|
#global LDLIBS
|
||||||
|
LDLIBS += -L lib/
|
||||||
|
#LDLIBS += -L lib_web/
|
||||||
|
|
||||||
|
LD_DYNAMIC_LIBS = -lraylib -lsdbus-c++ -lmagic #only enable if dynamic mode
|
||||||
|
LD_STATIC_LIBS = -l:libraylib.a #only enable if static mode
|
||||||
|
|
||||||
|
EXTRA_DIRS = $(OBJ_DIR)/rlImGui
|
||||||
|
|
||||||
|
EXE = $(BIN_DIR)/main
|
||||||
|
|
||||||
|
|
||||||
|
#WEBMODE
|
||||||
|
#CC = emcc
|
||||||
|
#CXX = em++
|
||||||
|
#SET ALL TO STATIC, have web version of libraylib.a in libs
|
||||||
|
#ensure glfw is enable
|
||||||
|
#some tinkering may be requiresd to get this working, just make sure
|
||||||
|
#raylib has ES3 on (need to mod make file)
|
||||||
|
#LDFLAGS += -s TOTAL_MEMORY=268435456 -s USE_GLFW=3 -sMIN_WEBGL_VERSION=2 -s FULL_ES3 -s ASYNCIFY
|
||||||
|
#EXE = $(BIN_DIR)/main.html
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
C_SRC += $(wildcard $(SRC_DIR)/*.c) #GET LIST OF ALL C FILES
|
||||||
|
|
||||||
|
CPP_SRC += $(wildcard $(SRC_DIR)/*.cpp) #GET LIST OF ALL CPP FILES
|
||||||
|
CPP_SRC += $(wildcard $(SRC_DIR)/rlImGui/*.cpp) #GET LIST OF ALL CPP FILES
|
||||||
|
|
||||||
|
ifeq ($(IMGUI_MODE), BUILD)
|
||||||
|
CPP_SRC += $(wildcard $(SRC_DIR)/imgui/*.cpp) #GET LIST OF ALL CPP FILES
|
||||||
|
EXTRA_DIRS += $(OBJ_DIR)/imgui
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(IMGUI_MODE), DYN_LIBRARY)
|
||||||
|
LDLIBS += -limgui
|
||||||
|
endif
|
||||||
|
|
||||||
|
#IF DYNAMIC MODE
|
||||||
|
ifeq ($(LIB_MODE), DYNAMIC)
|
||||||
|
LDLIBS += $(LD_DYNAMIC_LIBS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
#IF STATIC MODE
|
||||||
|
ifeq ($(LIB_MODE), STATIC)
|
||||||
|
LDLIBS += $(LD_STATIC_LIBS)
|
||||||
|
CPPFLAGS += -I$(STATIC_INCLUDE_DIR)
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
C_OBJ := $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(C_SRC)) #MAKE LIST OF ALL C OBJECT FILES THAT NEED TO BE BUILT
|
||||||
|
CPP_OBJ := $(patsubst $(SRC_DIR)/%.cpp, $(OBJ_DIR)/%.o, $(CPP_SRC)) #MAKE LIST OF ALL CPP OBJECT FILES THAT NEED TO BE BUILT
|
||||||
|
|
||||||
|
OBJ := $(C_OBJ) $(CPP_OBJ)
|
||||||
|
|
||||||
|
|
||||||
|
all: $(EXE)
|
||||||
|
|
||||||
|
$(EXE): $(OBJ) | $(BIN_DIR)
|
||||||
|
$(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $@
|
||||||
|
|
||||||
|
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c | $(OBJ_DIR)
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
|
||||||
|
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp | $(OBJ_DIR)
|
||||||
|
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
$(BIN_DIR) $(OBJ_DIR): | $(EXTRA_DIRS)
|
||||||
|
mkdir -p $@
|
||||||
|
|
||||||
|
$(EXTRA_DIRS):
|
||||||
|
mkdir -p $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@$(RM) -rv $(BIN_DIR) $(OBJ_DIR)
|
||||||
|
|
||||||
|
.PHONY: all clean
|
||||||
|
|
6
README.md
Normal file
6
README.md
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
# MPRIS MiniPlayer
|
||||||
|
Little program to dispaly whatever media in an mpris compatible player is playing. Recommended to use with playerctl.
|
||||||
|
Makefile should take care of building, you need raylib, imgui, and libmagic installed with headers.
|
||||||
|
|
||||||
|
|
||||||
|
### :) vs (: vs :3 showdown
|
BIN
assets/null.png
Normal file
BIN
assets/null.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 344 B |
0
include/PUT_HEADERS_HERE
Normal file
0
include/PUT_HEADERS_HERE
Normal file
1708
include/raylib.h
Normal file
1708
include/raylib.h
Normal file
File diff suppressed because it is too large
Load diff
2941
include/raymath.h
Normal file
2941
include/raymath.h
Normal file
File diff suppressed because it is too large
Load diff
5262
include/rlgl.h
Normal file
5262
include/rlgl.h
Normal file
File diff suppressed because it is too large
Load diff
0
lib/PUT_STATIC_LIBS_HERE
Normal file
0
lib/PUT_STATIC_LIBS_HERE
Normal file
287
src/main.cpp
Normal file
287
src/main.cpp
Normal file
|
@ -0,0 +1,287 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib-extras [ImGui] example - Docking example
|
||||||
|
*
|
||||||
|
* This is an example of using the ImGui docking features that are part of docking branch
|
||||||
|
* You must replace the default imgui with the code from the docking branch for this to work
|
||||||
|
* https://github.com/ocornut/imgui/tree/docking
|
||||||
|
*
|
||||||
|
* Copyright (c) 2024 Jeffery Myers
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "mpris_connection.hpp"
|
||||||
|
#include <exception>
|
||||||
|
#include <iterator>
|
||||||
|
#include <sdbus-c++/IConnection.h>
|
||||||
|
#include <sdbus-c++/IObject.h>
|
||||||
|
#include <sdbus-c++/IProxy.h>
|
||||||
|
#include <sdbus-c++/Types.h>
|
||||||
|
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||||
|
#include "raylib.h"
|
||||||
|
#include "raymath.h"
|
||||||
|
#include <optional>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "imgui.h"
|
||||||
|
#include "imgui_stdlib.h"
|
||||||
|
#include "rlImGui/rlImGui.h"
|
||||||
|
|
||||||
|
#include "testcpp.hpp"
|
||||||
|
|
||||||
|
#include "stdio.h"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sdbus-c++/sdbus-c++.h>
|
||||||
|
#include <string>
|
||||||
|
extern "C" {
|
||||||
|
#include "testc.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
class RayWindow {
|
||||||
|
public:
|
||||||
|
bool Open = false;
|
||||||
|
|
||||||
|
RenderTexture ViewTexture;
|
||||||
|
|
||||||
|
virtual void Setup() = 0;
|
||||||
|
virtual void Shutdown() = 0;
|
||||||
|
virtual void Show() = 0;
|
||||||
|
virtual void Update() = 0;
|
||||||
|
|
||||||
|
bool Focused = false;
|
||||||
|
|
||||||
|
Rectangle ContentRect = {0};
|
||||||
|
};
|
||||||
|
|
||||||
|
class RayWindowExample {
|
||||||
|
public:
|
||||||
|
RenderTexture ViewTexture;
|
||||||
|
bool Open = true;
|
||||||
|
bool Focused = false;
|
||||||
|
bool Resized = false;
|
||||||
|
ImVec2 PastSize;
|
||||||
|
RayWindowExample() {
|
||||||
|
ViewTexture = LoadRenderTexture(GetScreenWidth(), GetScreenWidth());
|
||||||
|
// ViewTexture = LoadRenderTexture(256, 256);
|
||||||
|
printf("window w,h: %d, %d \n", ViewTexture.texture.width, ViewTexture.texture.height);
|
||||||
|
PastSize = ImVec2{256, 256};
|
||||||
|
Resized = false;
|
||||||
|
}
|
||||||
|
~RayWindowExample() {
|
||||||
|
UnloadRenderTexture(ViewTexture);
|
||||||
|
}
|
||||||
|
void Show() {
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
|
||||||
|
ImGui::SetNextWindowSize(ImVec2(256, 275), ImGuiCond_FirstUseEver);
|
||||||
|
if (ImGui::Begin("Raylib in ImGUI", &Open, ImGuiWindowFlags_NoScrollbar)) {
|
||||||
|
Focused = ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows);
|
||||||
|
ImVec2 DaZone = ImGui::GetContentRegionAvail();
|
||||||
|
rlImGuiImageRenderTexture(&ViewTexture);
|
||||||
|
// rlImGuiImage(&ViewTexture.texture);
|
||||||
|
if (PastSize != DaZone) {
|
||||||
|
Resized = true;
|
||||||
|
} else {
|
||||||
|
Resized = false;
|
||||||
|
}
|
||||||
|
PastSize = DaZone;
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
ImGui::PopStyleVar();
|
||||||
|
}
|
||||||
|
void Update() {
|
||||||
|
if (!Open) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Resized) {
|
||||||
|
UnloadRenderTexture(ViewTexture);
|
||||||
|
ViewTexture = LoadRenderTexture(PastSize.x, PastSize.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
BeginTextureMode(ViewTexture);
|
||||||
|
ClearBackground(SKYBLUE);
|
||||||
|
DrawCircle(0, 0, 35, RED);
|
||||||
|
// DrawPixel(0,0, BLUE);
|
||||||
|
// DrawRectangleLines(0,0,PastSize.x,PastSize.y, RED);
|
||||||
|
Rectangle rec = Rectangle{0, 0, PastSize.x, PastSize.y};
|
||||||
|
// DrawRectangleLinesEx(rec, 2, RED);
|
||||||
|
EndTextureMode();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<std::string> GetMprisServices() {
|
||||||
|
auto connection = sdbus::createSessionBusConnection();
|
||||||
|
|
||||||
|
sdbus::ServiceName dest{"org.freedesktop.DBus"};
|
||||||
|
sdbus::ObjectPath objec{"/org/freedesktop/DBus"};
|
||||||
|
|
||||||
|
auto prox = sdbus::createProxy(dest, objec);
|
||||||
|
sdbus::InterfaceName interfaceName{"org.freedesktop.DBus"};
|
||||||
|
sdbus::MethodName introspect("ListNames");
|
||||||
|
|
||||||
|
auto method = prox->createMethodCall(interfaceName, introspect);
|
||||||
|
auto reply = prox->callMethod(method);
|
||||||
|
std::vector<std::string> res;
|
||||||
|
reply >> res;
|
||||||
|
|
||||||
|
std::vector<std::string> ret;
|
||||||
|
|
||||||
|
for (std::string item : res) {
|
||||||
|
if (item.find("org.mpris.MediaPlayer2") != std::string::npos) {
|
||||||
|
ret.push_back(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
int screenWidth = 1280;
|
||||||
|
int screenHeight = 800;
|
||||||
|
|
||||||
|
// SetConfigFlags(FLAG_MSAA_4X_HINT | FLAG_WINDOW_RESIZABLE);
|
||||||
|
SetConfigFlags(FLAG_MSAA_4X_HINT | FLAG_VSYNC_HINT | FLAG_WINDOW_RESIZABLE);
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib-Extras [ImGui] example - Docking");
|
||||||
|
SetTargetFPS(120);
|
||||||
|
rlImGuiSetup(true);
|
||||||
|
ImGui::GetStyle().AntiAliasedLinesUseTex = false;
|
||||||
|
|
||||||
|
TestC();
|
||||||
|
TestCPPFunc();
|
||||||
|
|
||||||
|
|
||||||
|
bool run = true;
|
||||||
|
|
||||||
|
bool showDemoWindow = false;
|
||||||
|
|
||||||
|
std::vector<std::string> serviceList = GetMprisServices();
|
||||||
|
|
||||||
|
auto current_player = MprisPlayer("org.mpris.MediaPlayer2.playerctld");
|
||||||
|
// current_player.pp();
|
||||||
|
/*
|
||||||
|
auto connection = sdbus::createSessionBusConnection();
|
||||||
|
|
||||||
|
sdbus::ServiceName dest{"org.freedesktop.DBus"};
|
||||||
|
sdbus::ObjectPath objec{"/org/freedesktop/DBus"};
|
||||||
|
|
||||||
|
auto prox = sdbus::createProxy(dest, objec);
|
||||||
|
sdbus::InterfaceName interfaceName{"org.freedesktop.DBus"};
|
||||||
|
sdbus::MethodName introspect("ListNames");
|
||||||
|
|
||||||
|
auto method = prox->createMethodCall(interfaceName, introspect);
|
||||||
|
auto reply = prox->callMethod(method);
|
||||||
|
std::vector<std::string> res;
|
||||||
|
reply >> res;
|
||||||
|
for (std::string item : res) {
|
||||||
|
std::cout << item << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
// if the linked ImGui has docking, enable it.
|
||||||
|
// this will only be true if you use the docking branch of ImGui.
|
||||||
|
#ifdef IMGUI_HAS_DOCK
|
||||||
|
ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// for (json::iterator it = course_info.begin(); it != course_info.end(); ++it) {
|
||||||
|
// std::cout << *it << std::endl;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
while (!WindowShouldClose() &&
|
||||||
|
run) // Detect window close button or ESC key, or a quit from the menu
|
||||||
|
{
|
||||||
|
|
||||||
|
BeginDrawing();
|
||||||
|
ClearBackground(DARKGRAY);
|
||||||
|
|
||||||
|
// start ImGui content
|
||||||
|
rlImGuiBegin();
|
||||||
|
|
||||||
|
// if you want windows to dock to the viewport, call this.
|
||||||
|
#ifdef IMGUI_HAS_DOCK
|
||||||
|
ImGui::DockSpaceOverViewport();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// show a simple menu bar
|
||||||
|
if (ImGui::BeginMainMenuBar()) {
|
||||||
|
if (ImGui::BeginMenu("File")) {
|
||||||
|
#ifdef IMGUI_HAS_DOCK
|
||||||
|
if (ImGui::MenuItem("Enable Docking")) {
|
||||||
|
ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
||||||
|
}
|
||||||
|
if (ImGui::MenuItem("Disable Docking")) {
|
||||||
|
ImGui::GetIO().ConfigFlags &= ~ImGuiConfigFlags_DockingEnable;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (ImGui::MenuItem("Quit"))
|
||||||
|
run = false;
|
||||||
|
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::BeginMenu("Players")) {
|
||||||
|
for (auto item : serviceList) {
|
||||||
|
if (ImGui::MenuItem(item.c_str())) {
|
||||||
|
current_player = MprisPlayer(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::BeginMenu("Window")) {
|
||||||
|
if (ImGui::MenuItem("Demo Window", nullptr, showDemoWindow))
|
||||||
|
showDemoWindow = !showDemoWindow;
|
||||||
|
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
ImGui::EndMainMenuBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
// show some windows
|
||||||
|
|
||||||
|
if (ImGui::Begin("Player Control")) {
|
||||||
|
ImGui::Text("%s", current_player.GetIdentity().c_str());
|
||||||
|
ImGui::Text(
|
||||||
|
"%s",
|
||||||
|
current_player.GetCurrentMetadata()["mpris:artUrl"].get<std::string>().c_str());
|
||||||
|
if (ImGui::Button("Prev")) {
|
||||||
|
current_player.Prev();
|
||||||
|
}
|
||||||
|
if (ImGui::Button("Play/Pause")) {
|
||||||
|
current_player.PausePlay();
|
||||||
|
}
|
||||||
|
if (ImGui::Button("Next")) {
|
||||||
|
current_player.Next();
|
||||||
|
}
|
||||||
|
if (ImGui::Button("Refresh")) {
|
||||||
|
current_player.Refresh();
|
||||||
|
current_player.UpdateTexture();
|
||||||
|
}
|
||||||
|
//rlImGuiImage(¤t_player.tex.tex);
|
||||||
|
rlImGuiImageSize(¤t_player.tex.tex,300,300);
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
|
||||||
|
if (showDemoWindow)
|
||||||
|
ImGui::ShowDemoWindow(&showDemoWindow);
|
||||||
|
|
||||||
|
// end ImGui Content
|
||||||
|
rlImGuiEnd();
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
rlImGuiShutdown();
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
153
src/mpris_connection.cpp
Normal file
153
src/mpris_connection.cpp
Normal file
|
@ -0,0 +1,153 @@
|
||||||
|
#include "mpris_connection.hpp"
|
||||||
|
#include <sdbus-c++/IConnection.h>
|
||||||
|
#include <sdbus-c++/Types.h>
|
||||||
|
#include <string>
|
||||||
|
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||||
|
#include "imgui.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <ostream>
|
||||||
|
#include <magic.h>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
MprisPlayer::MprisPlayer(std::string servicename) {
|
||||||
|
bus_connection = sdbus::createSessionBusConnection();
|
||||||
|
sdbus::ServiceName dest{servicename};
|
||||||
|
sdbus::ObjectPath objec{"/org/mpris/MediaPlayer2"};
|
||||||
|
|
||||||
|
PlayerProxy = sdbus::createProxy(dest, objec);
|
||||||
|
mp2 = "org.mpris.MediaPlayer2.Player";
|
||||||
|
playpause = "PlayPause";
|
||||||
|
Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MprisPlayer::PausePlay() {
|
||||||
|
auto method = PlayerProxy->createMethodCall(mp2, playpause);
|
||||||
|
auto reply = PlayerProxy->callMethod(method);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MprisPlayer::Next() {
|
||||||
|
auto method = PlayerProxy->createMethodCall(mp2, sdbus::MethodName("Next"));
|
||||||
|
try {
|
||||||
|
auto reply = PlayerProxy->callMethod(method);
|
||||||
|
} catch (const std::exception &e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MprisPlayer::Prev() {
|
||||||
|
auto method = PlayerProxy->createMethodCall(mp2, sdbus::MethodName("Previous"));
|
||||||
|
auto reply = PlayerProxy->callMethod(method);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string MprisPlayer::GetIdentity() {
|
||||||
|
return identity;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unordered_map<std::string, sdbus::Variant> MprisPlayer::GetCurrentMetadata() {
|
||||||
|
return current_metadata;
|
||||||
|
}
|
||||||
|
void MprisPlayer::Refresh() {
|
||||||
|
identity = PlayerProxy->getProperty("Identity")
|
||||||
|
.onInterface("org.mpris.MediaPlayer2")
|
||||||
|
.get<std::string>();
|
||||||
|
current_metadata = PlayerProxy->getProperty("Metadata")
|
||||||
|
.onInterface("org.mpris.MediaPlayer2.Player")
|
||||||
|
.get<std::unordered_map<std::string, sdbus::Variant>>();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MprisPlayer::UpdateTexture() {
|
||||||
|
auto metadata = GetCurrentMetadata();
|
||||||
|
std::string filename = metadata["mpris:artUrl"].get<std::string>();
|
||||||
|
if (filename.length() > 0) {
|
||||||
|
if (filename.c_str()[0] == 'f') {
|
||||||
|
std::cout << "parsing as file" << std::endl;
|
||||||
|
std::cout << filename << std::endl;
|
||||||
|
std::string path = filename.substr(7);
|
||||||
|
FILE * f = fopen(path.c_str(), "r");
|
||||||
|
if (f == NULL) {
|
||||||
|
tex = RayTexture();
|
||||||
|
fclose(f);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fseek(f, 0, SEEK_END);
|
||||||
|
long size = ftell(f);
|
||||||
|
rewind(f);
|
||||||
|
unsigned char* buffer = new unsigned char[size];
|
||||||
|
fread(buffer, size, 1, f);
|
||||||
|
|
||||||
|
magic_t magic = magic_open(MAGIC_MIME_TYPE);
|
||||||
|
if (magic == NULL) {
|
||||||
|
tex = RayTexture();
|
||||||
|
delete[] buffer;
|
||||||
|
fclose(f);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (magic_load(magic, NULL) != 0) {
|
||||||
|
tex = RayTexture();
|
||||||
|
delete[] buffer;
|
||||||
|
fclose(f);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *mime_type = magic_file(magic, path.c_str());
|
||||||
|
if (mime_type == NULL) {
|
||||||
|
tex = RayTexture();
|
||||||
|
delete[] buffer;
|
||||||
|
fclose(f);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << mime_type << std::endl;
|
||||||
|
if (strcmp(mime_type, "image/png") == 0 ) {
|
||||||
|
auto img = LoadImageFromMemory(".png", buffer, size);
|
||||||
|
tex = RayTexture(img);
|
||||||
|
UnloadImage(img);
|
||||||
|
} else if (strcmp(mime_type, "image/jpeg") == 0 ) {
|
||||||
|
auto img = LoadImageFromMemory(".jpg", buffer, size);
|
||||||
|
tex = RayTexture(img);
|
||||||
|
UnloadImage(img);
|
||||||
|
} else {
|
||||||
|
tex = RayTexture();
|
||||||
|
}
|
||||||
|
delete[] buffer;
|
||||||
|
fclose(f);
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RayTexture::RayTexture() {
|
||||||
|
tex = LoadTexture(ASSET_DIR "/null.png" );
|
||||||
|
path = ASSET_DIR "/null.png";
|
||||||
|
}
|
||||||
|
|
||||||
|
RayTexture::RayTexture(Image img) {
|
||||||
|
path = "NOPATH";
|
||||||
|
tex = LoadTextureFromImage(img);
|
||||||
|
}
|
||||||
|
|
||||||
|
RayTexture::RayTexture(const RayTexture &other) {
|
||||||
|
path = other.path;
|
||||||
|
auto img = LoadImageFromTexture(other.tex);
|
||||||
|
tex = LoadTextureFromImage(img);
|
||||||
|
UnloadImage(img);
|
||||||
|
}
|
||||||
|
|
||||||
|
RayTexture &RayTexture::operator=(const RayTexture &other) {
|
||||||
|
if (this == &other) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
printf("HERE\n");
|
||||||
|
RayTexture temp(other);
|
||||||
|
std::swap(tex, temp.tex);
|
||||||
|
std::swap(path, temp.path);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
RayTexture::~RayTexture() {
|
||||||
|
if (IsWindowReady()) {
|
||||||
|
UnloadTexture(tex);
|
||||||
|
}
|
||||||
|
}
|
45
src/mpris_connection.hpp
Normal file
45
src/mpris_connection.hpp
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
#ifndef COURSE_H
|
||||||
|
#define COURSE_H
|
||||||
|
|
||||||
|
#include <sdbus-c++/Types.h>
|
||||||
|
#include <unordered_map>
|
||||||
|
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||||
|
#include <imgui.h>
|
||||||
|
#include <memory>
|
||||||
|
#include <raylib.h>
|
||||||
|
#include <sdbus-c++/IConnection.h>
|
||||||
|
#include <sdbus-c++/IProxy.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class RayTexture {
|
||||||
|
public:
|
||||||
|
Texture tex{};
|
||||||
|
std::string path;
|
||||||
|
RayTexture();
|
||||||
|
explicit RayTexture(Image img);
|
||||||
|
RayTexture(const RayTexture& other);
|
||||||
|
RayTexture& operator=(const RayTexture& other);
|
||||||
|
~RayTexture();
|
||||||
|
};
|
||||||
|
|
||||||
|
class MprisPlayer {
|
||||||
|
public:
|
||||||
|
std::unique_ptr<sdbus::IConnection> bus_connection;
|
||||||
|
std::unique_ptr<sdbus::IProxy> PlayerProxy;
|
||||||
|
sdbus::InterfaceName mp2;
|
||||||
|
sdbus::MethodName playpause;
|
||||||
|
RayTexture tex;
|
||||||
|
explicit MprisPlayer(std::string servicename);
|
||||||
|
void PausePlay();
|
||||||
|
void Refresh();
|
||||||
|
void UpdateTexture();
|
||||||
|
void Next();
|
||||||
|
void Prev();
|
||||||
|
std::string identity;
|
||||||
|
std::string GetIdentity();
|
||||||
|
std::unordered_map<std::string, sdbus::Variant> current_metadata;
|
||||||
|
std::unordered_map<std::string, sdbus::Variant> GetCurrentMetadata();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
16
src/rlImGui/LICENSE
Normal file
16
src/rlImGui/LICENSE
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
Copyright (c) 2020-2021 Jeffery Myers
|
||||||
|
|
||||||
|
This software is provided "as-is", without any express or implied warranty. In no event
|
||||||
|
will the authors be held liable for any damages arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose, including commercial
|
||||||
|
applications, and to alter it and redistribute it freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not claim that you
|
||||||
|
wrote the original software. If you use this software in a product, an acknowledgment
|
||||||
|
in the product documentation would be appreciated but is not required.
|
||||||
|
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be misrepresented
|
||||||
|
as being the original software.
|
||||||
|
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
75
src/rlImGui/README.md
Normal file
75
src/rlImGui/README.md
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
# rlImGui
|
||||||
|
<img align="left" src="https://github.com/raysan5/raylib/raw/master/logo/raylib_logo_animation.gif" width="64">
|
||||||
|
A Raylib integration with DearImGui
|
||||||
|
|
||||||
|
rlImgui provides a backend for [Dear ImGui](https://github.com/ocornut/imgui) using [Raylib](https://www.raylib.com/).
|
||||||
|
|
||||||
|
# Building
|
||||||
|
rlImGui is setup to use premake to generate a static library and examples for Visual Studio 2019. Premake can also be used to generate makefiles for linux. rlImGui can be used as a static library, or by direclty including the files into your game project.
|
||||||
|
|
||||||
|
If you wish to use premake, you will need to download the Premake5 executable for your platform from. https://premake.github.io/download
|
||||||
|
|
||||||
|
# Setup
|
||||||
|
|
||||||
|
Using rlImGui in your code is very easy. Once you have included the library, or source files for rlImGui and ImGui in your project, simply do the following.
|
||||||
|
```
|
||||||
|
#include "rlImGui.h" // include the API header
|
||||||
|
|
||||||
|
// before your game loop
|
||||||
|
rlImGuiSetup(true); // sets up ImGui with ether a dark or light default theme
|
||||||
|
|
||||||
|
// inside your game loop, between BeginDrawing() and EndDrawing()
|
||||||
|
rlImGuiBegin(); // starts the ImGui content mode. Make all ImGui calls after this
|
||||||
|
|
||||||
|
rlImGuiEnd(); // ends the ImGui content mode. Make all ImGui calls before this
|
||||||
|
|
||||||
|
// after your game loop is over, before you close the window
|
||||||
|
|
||||||
|
rlImGuiShutdown(); // cleans up ImGui
|
||||||
|
```
|
||||||
|
|
||||||
|
# Examples
|
||||||
|
There are two example programs in the examples folder.
|
||||||
|
|
||||||
|
## Simple
|
||||||
|
This is the most simple use of ImGui in raylib, it just shows the ImGui demo window.
|
||||||
|
![image](https://user-images.githubusercontent.com/322174/136596910-da1b60ae-4a39-48f0-ae84-f568bc396870.png)
|
||||||
|
|
||||||
|
|
||||||
|
## Editor
|
||||||
|
This is a more complex example of ImGui, showing how to use raylib 2d and 3d cameras to draw into ImGui windows using render textures.
|
||||||
|
![image](https://user-images.githubusercontent.com/322174/136596949-033ffe0a-2476-4030-988a-5bf5b6e2ade7.png)
|
||||||
|
|
||||||
|
# Extras
|
||||||
|
|
||||||
|
## rlImGuiColors.h
|
||||||
|
This file has a converter to change Raylib colors into ImGui Colors
|
||||||
|
|
||||||
|
## Font Awesome Icons
|
||||||
|
Support for Font Awesome 6 https://fontawesome.com/ is built into rlImGui and enabled by default. You can simply
|
||||||
|
#include "extras/IconsFontAwesome6.h"
|
||||||
|
To use the ICON_FA macros for any icon in the free set.
|
||||||
|
|
||||||
|
If you wish to disable font awesome support you can #define NO_FONT_AWESOME
|
||||||
|
|
||||||
|
|
||||||
|
# Images
|
||||||
|
Raylib textures can be drawn in ImGui using the following functions
|
||||||
|
```
|
||||||
|
void rlImGuiImage(const Texture *image);
|
||||||
|
void rlImGuiImageSize(const Texture *image, int width, int height);
|
||||||
|
void rlImGuiImageSizeV(const Texture* image, Vector2 size);
|
||||||
|
void rlImGuiImageRect(const Texture* image, int destWidth, int destHeight, Rectangle sourceRect);
|
||||||
|
void rlImGuiImageRenderTexture(const RenderTexture* image);
|
||||||
|
void rlImGuiImageRenderTextureFit(const RenderTexture* image, bool center);
|
||||||
|
|
||||||
|
bool rlImGuiImageButton(const Texture *image);
|
||||||
|
bool rlImGuiImageButtonSize(const char* name, const Texture* image, struct ImVec2 size);
|
||||||
|
```
|
||||||
|
|
||||||
|
# C vs C++
|
||||||
|
ImGui is a C++ library, so rlImGui uses C++ to create the backend and integration with Raylib.
|
||||||
|
The rlImGui.h API only uses features that are common to C and C++, so rlImGui can be built as a static library and used by pure C code. Users of ImGui who wish to use pure C must use an ImGui wrapper, such as [https://github.com/cimgui/cimgui].
|
||||||
|
|
||||||
|
# Low level API
|
||||||
|
If you would like more controll over the ImGui Backend, you can use the low level API that is found in imgui_impl_raylib.h. This is API follows the patterns of other ImGui backends and does not do automatic context management. An example of it's use can be found in imgui_style_example.cpp
|
280
src/rlImGui/examples/asset_browser/asset_browser.cpp
Normal file
280
src/rlImGui/examples/asset_browser/asset_browser.cpp
Normal file
|
@ -0,0 +1,280 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib-extras [ImGui] example - asset browser
|
||||||
|
*
|
||||||
|
* This is a more complex ImGui Integration
|
||||||
|
* It shows how to build windows on top of 2d and 3d views using a render texture
|
||||||
|
*
|
||||||
|
* Copyright (c) 2024 Jeffery Myers
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#define _CRT_NONSTDC_NO_WARNINGS
|
||||||
|
|
||||||
|
#include "asset_browser.h"
|
||||||
|
#include "imgui_utils.h"
|
||||||
|
#include "imgui.h"
|
||||||
|
#include "imgui_internal.h"
|
||||||
|
#include "raylib.h"
|
||||||
|
#include "extras/IconsFontAwesome6.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
|
||||||
|
AssetBrowserPanel::AssetBrowserPanel()
|
||||||
|
{
|
||||||
|
AssetRoot = GetWorkingDirectory();
|
||||||
|
RebuildFolderTree();
|
||||||
|
SetCurrentFolder(&FolderRoot);
|
||||||
|
|
||||||
|
CurrentView = &ListView;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetBrowserPanel::Show()
|
||||||
|
{
|
||||||
|
ShowHeader();
|
||||||
|
|
||||||
|
ImGuiTableFlags flags = ImGuiTableFlags_Resizable | ImGuiTableFlags_SizingStretchSame | ImGuiTableFlags_Borders;
|
||||||
|
|
||||||
|
if (ImGui::BeginTable("AssetBrowserTab", 2, flags, ImGui::GetContentRegionAvail()))
|
||||||
|
{
|
||||||
|
ImGui::TableSetupColumn("FolderView", ImGuiTableColumnFlags_None, 0.25f);
|
||||||
|
ImGui::TableSetupColumn("AssetView", ImGuiTableColumnFlags_None, 0.75f);
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
|
||||||
|
if (ImGui::BeginChild("FolderList", ImGui::GetContentRegionAvail(),ImGuiChildFlags_None, ImGuiWindowFlags_None))
|
||||||
|
{
|
||||||
|
ShowFolderTree();
|
||||||
|
ImGui::EndChild();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ShowFilePane();
|
||||||
|
ImGui::EndTable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetBrowserPanel::RebuildFolderTree()
|
||||||
|
{
|
||||||
|
FolderRoot.Children.clear();
|
||||||
|
|
||||||
|
FolderRoot.FullPath = AssetRoot;
|
||||||
|
FolderRoot.Name = GetFileNameWithoutExt(AssetRoot.c_str());
|
||||||
|
FolderRoot.Parent = nullptr;
|
||||||
|
FolderRoot.Icon = ICON_FA_SERVER;
|
||||||
|
FolderRoot.ForceOpenNextFrame = true;
|
||||||
|
FolderRoot.PopulateChildren();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetBrowserPanel::SetCurrentFolder(FolderInfo* folder)
|
||||||
|
{
|
||||||
|
if (CurrentFolderContents.Folder == folder)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CurrentFolderContents.Folder = folder;
|
||||||
|
CurrentFolderContents.Files.clear();
|
||||||
|
|
||||||
|
if (folder == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
FolderInfo* openFolder = folder;
|
||||||
|
while (openFolder != nullptr)
|
||||||
|
{
|
||||||
|
openFolder->ForceOpenNextFrame = true;
|
||||||
|
openFolder = openFolder->Parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto files = LoadDirectoryFiles(CurrentFolderContents.Folder->FullPath.c_str());
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < files.count; i++)
|
||||||
|
{
|
||||||
|
if (DirectoryExists(files.paths[i]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const char* name = GetFileName(files.paths[i]);
|
||||||
|
if (!name || *name == '.')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
FileInfo& file = CurrentFolderContents.Files.emplace_back();
|
||||||
|
file.FullPath = files.paths[i];
|
||||||
|
file.Name = name;
|
||||||
|
file.Icon = GetFileIcon(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
UnloadDirectoryFiles(files);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetBrowserPanel::FolderInfo::PopulateChildren()
|
||||||
|
{
|
||||||
|
constexpr Color folderColor = { 255,255,145,255 };
|
||||||
|
|
||||||
|
auto folders = LoadDirectoryFiles(FullPath.c_str());
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < folders.count; i++)
|
||||||
|
{
|
||||||
|
if (DirectoryExists(folders.paths[i]))
|
||||||
|
{
|
||||||
|
const char* name = GetFileNameWithoutExt(folders.paths[i]);
|
||||||
|
if (!name || *name == '.')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
FolderInfo& child = Children.emplace_back();
|
||||||
|
child.FullPath = folders.paths[i];
|
||||||
|
child.Name = name;
|
||||||
|
child.Parent = this;
|
||||||
|
child.Tint = folderColor;
|
||||||
|
child.Icon = ICON_FA_FOLDER;
|
||||||
|
child.PopulateChildren();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UnloadDirectoryFiles(folders);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AssetBrowserPanel::ShowFolderTreeNode(FolderInfo& info)
|
||||||
|
{
|
||||||
|
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick;
|
||||||
|
if (info.Children.empty())
|
||||||
|
flags |= ImGuiTreeNodeFlags_Leaf;
|
||||||
|
|
||||||
|
if (CurrentFolderContents.Folder == &info)
|
||||||
|
flags |= ImGuiTreeNodeFlags_Selected;
|
||||||
|
|
||||||
|
if (info.ForceOpenNextFrame)
|
||||||
|
{
|
||||||
|
ImGui::SetNextItemOpen(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool open = ImGui::TreeNodeEx(info.Name.c_str(), flags, "%s %s", info.Icon.c_str(), info.Name.c_str());
|
||||||
|
|
||||||
|
if (info.ForceOpenNextFrame && CurrentFolderContents.Folder == &info)
|
||||||
|
ImGui::ScrollToItem(ImGuiScrollFlags_KeepVisibleCenterY);
|
||||||
|
|
||||||
|
info.ForceOpenNextFrame = false;
|
||||||
|
if (ImGui::IsItemClicked())
|
||||||
|
SetCurrentFolder(&info);
|
||||||
|
|
||||||
|
if (open)
|
||||||
|
{
|
||||||
|
for (auto& node : info.Children)
|
||||||
|
ShowFolderTreeNode(node);
|
||||||
|
|
||||||
|
ImGui::TreePop();
|
||||||
|
}
|
||||||
|
|
||||||
|
return CurrentFolderContents.Folder == &info;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetBrowserPanel::ShowHeader()
|
||||||
|
{
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_ChildBorderSize, 1);
|
||||||
|
if (ImGui::BeginChild("Header", ImVec2{ ImGui::GetContentRegionAvail().x, ImGui::GetFrameHeight() }))
|
||||||
|
{
|
||||||
|
ImGui::Text("%s Root", ICON_FA_FOLDER_OPEN);
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x * 0.33f);
|
||||||
|
ImGui::InputText("###Path", (char*)(CurrentFolderContents.Folder->FullPath.c_str() + AssetRoot.size()), CurrentFolderContents.Folder->FullPath.size(), ImGuiInputTextFlags_ReadOnly);
|
||||||
|
|
||||||
|
ImGui::EndChild();
|
||||||
|
}
|
||||||
|
ImGui::PopStyleVar();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetBrowserPanel::ShowFolderTree()
|
||||||
|
{
|
||||||
|
ShowFolderTreeNode(FolderRoot);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetBrowserPanel::ShowFilePane()
|
||||||
|
{
|
||||||
|
if (ImGui::BeginChild("FileList", ImGui::GetContentRegionAvail(), ImGuiChildFlags_None, ImGuiWindowFlags_None))
|
||||||
|
{
|
||||||
|
if (CurrentView)
|
||||||
|
{
|
||||||
|
auto *item = CurrentView->Show(CurrentFolderContents);
|
||||||
|
if (item)
|
||||||
|
{
|
||||||
|
AssetItemInfo* assetItem = static_cast<AssetItemInfo*>(item);
|
||||||
|
if (!assetItem->IsFile())
|
||||||
|
SetCurrentFolder(static_cast<FolderInfo*>(item));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndChild();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ViewableItem* AssetBrowserPanel::AssetContainer::Reset()
|
||||||
|
{
|
||||||
|
FileItr = Files.begin();
|
||||||
|
FolderItr = Folder->Children.begin();
|
||||||
|
if (FileItr != Files.end())
|
||||||
|
return &(*FileItr);
|
||||||
|
if (FolderItr != Folder->Children.end())
|
||||||
|
return &(*FolderItr);
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t AssetBrowserPanel::AssetContainer::Count()
|
||||||
|
{
|
||||||
|
return Files.size() + Folder->Children.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
ViewableItem* AssetBrowserPanel::AssetContainer::Next()
|
||||||
|
{
|
||||||
|
if (FileItr != Files.end())
|
||||||
|
{
|
||||||
|
FileItr++;
|
||||||
|
if (FileItr != Files.end())
|
||||||
|
return &(*FileItr);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (FolderItr != Folder->Children.end())
|
||||||
|
return &(*FolderItr);
|
||||||
|
else
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FolderItr != Folder->Children.end())
|
||||||
|
{
|
||||||
|
FolderItr++;
|
||||||
|
if (FolderItr != Folder->Children.end())
|
||||||
|
return &(*FolderItr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* AssetBrowserPanel::GetFileIcon(const char* filename)
|
||||||
|
{
|
||||||
|
const char* e = GetFileExtension(filename);
|
||||||
|
|
||||||
|
if (e == nullptr)
|
||||||
|
return ICON_FA_FILE;
|
||||||
|
|
||||||
|
std::string ext = e;
|
||||||
|
|
||||||
|
std::transform(ext.begin(), ext.end(), ext.begin(),
|
||||||
|
[](unsigned char c) { return std::tolower(c); } // correct
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!ext.empty())
|
||||||
|
{
|
||||||
|
if (ext==".png")
|
||||||
|
return ICON_FA_FILE_IMAGE;
|
||||||
|
|
||||||
|
if (ext==".wav" || ext==".mp3" || ext==".oog")
|
||||||
|
return ICON_FA_FILE_AUDIO;
|
||||||
|
|
||||||
|
if (ext==".ttf" || ext==".otf" || ext==".fnt")
|
||||||
|
return ICON_FA_FONT;
|
||||||
|
|
||||||
|
if (ext==".txt" || ext==".md")
|
||||||
|
return ICON_FA_FILE_LINES;
|
||||||
|
|
||||||
|
if (ext==".lua" || ext==".c" || ext==".h" || ext==".cpp")
|
||||||
|
return ICON_FA_FILE_CODE;
|
||||||
|
}
|
||||||
|
return ICON_FA_FILE;
|
||||||
|
}
|
95
src/rlImGui/examples/asset_browser/asset_browser.h
Normal file
95
src/rlImGui/examples/asset_browser/asset_browser.h
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib-extras [ImGui] example - asset browser
|
||||||
|
*
|
||||||
|
* This is a more complex ImGui Integration
|
||||||
|
* It shows how to build windows on top of 2d and 3d views using a render texture
|
||||||
|
*
|
||||||
|
* Copyright (c) 2024 Jeffery Myers
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "item_view.h"
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
class AssetBrowserPanel
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AssetBrowserPanel();
|
||||||
|
|
||||||
|
void Show();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string AssetRoot;
|
||||||
|
|
||||||
|
class AssetItemInfo : public ViewableItem
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
bool File = false;
|
||||||
|
|
||||||
|
public:
|
||||||
|
AssetItemInfo(bool file) : File(file) {}
|
||||||
|
bool IsFile() const { return File; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class FileInfo : public AssetItemInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FileInfo() : AssetItemInfo(true) {}
|
||||||
|
|
||||||
|
std::string FullPath;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FolderInfo : public AssetItemInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FolderInfo() : AssetItemInfo(false) {}
|
||||||
|
|
||||||
|
std::string FullPath;
|
||||||
|
FolderInfo* Parent = nullptr;
|
||||||
|
std::list<FolderInfo> Children;
|
||||||
|
|
||||||
|
bool ForceOpenNextFrame = false;
|
||||||
|
|
||||||
|
void PopulateChildren();
|
||||||
|
};
|
||||||
|
|
||||||
|
FolderInfo FolderRoot;
|
||||||
|
|
||||||
|
class AssetContainer : public ViewableItemContainer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ViewableItem* Reset() override;
|
||||||
|
size_t Count() override;
|
||||||
|
ViewableItem* Next() override;
|
||||||
|
|
||||||
|
FolderInfo* Folder = nullptr;
|
||||||
|
std::vector<FileInfo> Files;
|
||||||
|
|
||||||
|
std::vector<FileInfo>::iterator FileItr;
|
||||||
|
std::list<FolderInfo>::iterator FolderItr;
|
||||||
|
};
|
||||||
|
|
||||||
|
AssetContainer CurrentFolderContents;
|
||||||
|
|
||||||
|
ListItemView ListView;
|
||||||
|
|
||||||
|
ItemView* CurrentView = nullptr;
|
||||||
|
|
||||||
|
void RebuildFolderTree();
|
||||||
|
|
||||||
|
void SetCurrentFolder(FolderInfo* folder);
|
||||||
|
|
||||||
|
bool ShowFolderTreeNode(FolderInfo& folder);
|
||||||
|
void ShowFolderTree();
|
||||||
|
void ShowFilePane();
|
||||||
|
void ShowHeader();
|
||||||
|
|
||||||
|
const char* GetFileIcon(const char* filename);
|
||||||
|
};
|
94
src/rlImGui/examples/asset_browser/imgui_utils.cpp
Normal file
94
src/rlImGui/examples/asset_browser/imgui_utils.cpp
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib-extras [ImGui] example - asset browser
|
||||||
|
*
|
||||||
|
* This is a more complex ImGui Integration
|
||||||
|
* It shows how to build windows on top of 2d and 3d views using a render texture
|
||||||
|
*
|
||||||
|
* Copyright (c) 2024 Jeffery Myers
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "imgui_utils.h"
|
||||||
|
|
||||||
|
#include "imgui.h"
|
||||||
|
#include "imgui_internal.h"
|
||||||
|
|
||||||
|
namespace ImGuiUtils
|
||||||
|
{
|
||||||
|
|
||||||
|
bool IsSpace(char aCharacter)
|
||||||
|
{
|
||||||
|
// all space characters are values 32 or less (space is 32)
|
||||||
|
// so we can convert them to a bitmask and use a single condition
|
||||||
|
const int mask = (1 << (' ' - 1)) | (1 << ('\f' - 1)) | (1 << ('\n' - 1)) | (1 << ('\r' - 1)) | (1 << ('\t' - 1)) | (1 << ('\v' - 1));
|
||||||
|
return (mask & (1 << ((aCharacter && aCharacter <= 32) * (aCharacter - 1)))) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------------------
|
||||||
|
// Todo: Add support for soft-hyphens when using word boundaries?
|
||||||
|
//-------------------------------------------------------------------------------------------------
|
||||||
|
void TextWithEllipsis(const char* string, float aMaxWidth, bool useWordBoundaries, float aSpacing)
|
||||||
|
{
|
||||||
|
char const* partStart = string;
|
||||||
|
char const* partEnd = string;
|
||||||
|
|
||||||
|
ImWchar elipsisChar = ImGui::GetFont()->EllipsisChar;
|
||||||
|
char elipsisText[8];
|
||||||
|
ImTextStrToUtf8(elipsisText, sizeof(elipsisText), &elipsisChar, (&elipsisChar) + 1);
|
||||||
|
|
||||||
|
if (aSpacing < 0.0f) aSpacing = ImGui::GetStyle().ItemSpacing.x;
|
||||||
|
|
||||||
|
float const ellipsisWidth = ImGui::CalcTextSize(elipsisText).x + aSpacing;
|
||||||
|
float width = 0;
|
||||||
|
bool addElipsis = false;
|
||||||
|
|
||||||
|
while (*partStart != 0 )
|
||||||
|
{
|
||||||
|
// Add space to next segment
|
||||||
|
while (IsSpace(*partEnd))
|
||||||
|
partEnd++;
|
||||||
|
|
||||||
|
if (useWordBoundaries)
|
||||||
|
{
|
||||||
|
// get next 'word' by looking for space after non-space
|
||||||
|
while (*partEnd != 0 && !IsSpace(*partEnd))
|
||||||
|
++partEnd;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (*partEnd != 0)
|
||||||
|
++partEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImVec2 const wordSize = ImGui::CalcTextSize(partStart, partEnd);
|
||||||
|
|
||||||
|
// Clearly we have space for this word so just add it
|
||||||
|
if (wordSize.x + width + ellipsisWidth < aMaxWidth)
|
||||||
|
{
|
||||||
|
width += wordSize.x;
|
||||||
|
partStart = partEnd;
|
||||||
|
}
|
||||||
|
// If we're just at the end of the word and we just fit then we can commit here
|
||||||
|
else if (*partEnd == 0 && wordSize.x + width < aMaxWidth)
|
||||||
|
{
|
||||||
|
width += wordSize.x;
|
||||||
|
partStart = partEnd;
|
||||||
|
}
|
||||||
|
// we're done so add elipsis where the current segment starts
|
||||||
|
else
|
||||||
|
{
|
||||||
|
addElipsis = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::TextUnformatted(string, partStart);
|
||||||
|
|
||||||
|
if (addElipsis)
|
||||||
|
{
|
||||||
|
ImGui::SameLine(0.0f, aSpacing);
|
||||||
|
ImGui::TextUnformatted(elipsisText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
19
src/rlImGui/examples/asset_browser/imgui_utils.h
Normal file
19
src/rlImGui/examples/asset_browser/imgui_utils.h
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib-extras [ImGui] example - asset browser
|
||||||
|
*
|
||||||
|
* This is a more complex ImGui Integration
|
||||||
|
* It shows how to build windows on top of 2d and 3d views using a render texture
|
||||||
|
*
|
||||||
|
* Copyright (c) 2024 Jeffery Myers
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace ImGuiUtils
|
||||||
|
{
|
||||||
|
void TextWithEllipsis(const char* string, float maxWidth, bool useWordBoundaries = false, float aSpacing = 0);
|
||||||
|
}
|
47
src/rlImGui/examples/asset_browser/item_view.h
Normal file
47
src/rlImGui/examples/asset_browser/item_view.h
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib-extras [ImGui] example - asset browser
|
||||||
|
*
|
||||||
|
* This is a more complex ImGui Integration
|
||||||
|
* It shows how to build windows on top of 2d and 3d views using a render texture
|
||||||
|
*
|
||||||
|
* Copyright (c) 2024 Jeffery Myers
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
class ViewableItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~ViewableItem() = default;
|
||||||
|
|
||||||
|
std::string Name;
|
||||||
|
std::string Icon;
|
||||||
|
Color Tint = BLANK;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ViewableItemContainer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~ViewableItemContainer() = default;
|
||||||
|
virtual ViewableItem* Reset() = 0;
|
||||||
|
virtual size_t Count() = 0;
|
||||||
|
virtual ViewableItem* Next() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ItemView
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~ItemView() = default;
|
||||||
|
virtual ViewableItem* Show(ViewableItemContainer& container) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ListItemView : public ItemView
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ViewableItem* Show(ViewableItemContainer& container) override;
|
||||||
|
};
|
53
src/rlImGui/examples/asset_browser/item_views.cpp
Normal file
53
src/rlImGui/examples/asset_browser/item_views.cpp
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib-extras [ImGui] example - asset browser
|
||||||
|
*
|
||||||
|
* This is a more complex ImGui Integration
|
||||||
|
* It shows how to build windows on top of 2d and 3d views using a render texture
|
||||||
|
*
|
||||||
|
* Copyright (c) 2024 Jeffery Myers
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "item_view.h"
|
||||||
|
|
||||||
|
#include "imgui.h"
|
||||||
|
#include "imgui_utils.h"
|
||||||
|
#include "rlImGuiColors.h"
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
extern ImFont* IconFont;
|
||||||
|
|
||||||
|
ViewableItem* ListItemView::Show(ViewableItemContainer& container)
|
||||||
|
{
|
||||||
|
ViewableItem* item = container.Reset();
|
||||||
|
|
||||||
|
ViewableItem* selected = nullptr;
|
||||||
|
while (item)
|
||||||
|
{
|
||||||
|
float x = ImGui::GetCursorPosX();
|
||||||
|
|
||||||
|
const char* name = TextFormat("###%s", item->Name.c_str());
|
||||||
|
if (item->Tint.a > 0)
|
||||||
|
ImGui::TextColored(rlImGuiColors::Convert(item->Tint), " %s", item->Icon.c_str());
|
||||||
|
else
|
||||||
|
ImGui::Text(" %s", item->Icon.c_str());
|
||||||
|
|
||||||
|
ImGui::SameLine(0, 0);
|
||||||
|
ImGui::Text(" %s", item->Name.c_str());
|
||||||
|
ImGui::SameLine(0, 0);
|
||||||
|
|
||||||
|
ImGui::SetCursorPosX(x);
|
||||||
|
//ImGui::SetItemAllowOverlap();
|
||||||
|
|
||||||
|
ImGui::Selectable(name);
|
||||||
|
if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(0))
|
||||||
|
{
|
||||||
|
selected = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
item = container.Next();
|
||||||
|
}
|
||||||
|
|
||||||
|
return selected;
|
||||||
|
}
|
96
src/rlImGui/examples/asset_browser/main.cpp
Normal file
96
src/rlImGui/examples/asset_browser/main.cpp
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib-extras [ImGui] example - asset browser
|
||||||
|
*
|
||||||
|
* This is a more complex ImGui Integration
|
||||||
|
* It shows how to build windows on top of 2d and 3d views using a render texture
|
||||||
|
*
|
||||||
|
* Copyright (c) 2024 Jeffery Myers
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
#include "raymath.h"
|
||||||
|
|
||||||
|
#include "imgui.h"
|
||||||
|
#include "rlImGui.h"
|
||||||
|
#include "rlImGuiColors.h"
|
||||||
|
#include "extras/FA6FreeSolidFontData.h"
|
||||||
|
|
||||||
|
#include "asset_browser.h"
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
|
||||||
|
ImFont* IconFont = nullptr;
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
int screenWidth = 1900;
|
||||||
|
int screenHeight = 900;
|
||||||
|
|
||||||
|
SetConfigFlags(FLAG_MSAA_4X_HINT | FLAG_VSYNC_HINT);
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib-Extras [ImGui] example - Asset browser");
|
||||||
|
SetTargetFPS(144);
|
||||||
|
|
||||||
|
rlImGuiBeginInitImGui();
|
||||||
|
ImGui::StyleColorsDark();
|
||||||
|
|
||||||
|
|
||||||
|
static const ImWchar icons_ranges[] = { ICON_MIN_FA, ICON_MAX_FA, 0 };
|
||||||
|
ImFontConfig icons_config;
|
||||||
|
icons_config.MergeMode = true;
|
||||||
|
icons_config.PixelSnapH = true;
|
||||||
|
icons_config.FontDataOwnedByAtlas = false;
|
||||||
|
|
||||||
|
icons_config.GlyphMaxAdvanceX = std::numeric_limits<float>::max();
|
||||||
|
icons_config.RasterizerMultiply = 1.0f;
|
||||||
|
icons_config.OversampleH = 2;
|
||||||
|
icons_config.OversampleV = 1;
|
||||||
|
|
||||||
|
icons_config.GlyphRanges = icons_ranges;
|
||||||
|
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
io.Fonts->AddFontFromMemoryCompressedTTF((void*)fa_solid_900_compressed_data, fa_solid_900_compressed_size, 12, &icons_config, icons_ranges);
|
||||||
|
|
||||||
|
icons_config.MergeMode = false;
|
||||||
|
IconFont = io.Fonts->AddFontFromMemoryCompressedTTF((void*)fa_solid_900_compressed_data, fa_solid_900_compressed_size, 72, &icons_config, icons_ranges);
|
||||||
|
|
||||||
|
rlImGuiEndInitImGui();
|
||||||
|
|
||||||
|
AssetBrowserPanel assetBrowser;
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||||
|
{
|
||||||
|
|
||||||
|
BeginDrawing();
|
||||||
|
ClearBackground(DARKGRAY);
|
||||||
|
|
||||||
|
rlImGuiBegin();
|
||||||
|
|
||||||
|
ImGui::SetNextWindowPos(ImVec2(0, 0));
|
||||||
|
ImGui::SetNextWindowSize(ImVec2(float(GetScreenWidth()), float(GetScreenHeight())));
|
||||||
|
if (ImGui::Begin("Frame", 0, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoSavedSettings))
|
||||||
|
{
|
||||||
|
assetBrowser.Show();
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
|
||||||
|
rlImGuiEnd();
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
rlImGuiShutdown();
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
105
src/rlImGui/examples/docking_example.cpp
Normal file
105
src/rlImGui/examples/docking_example.cpp
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib-extras [ImGui] example - Docking example
|
||||||
|
*
|
||||||
|
* This is an example of using the ImGui docking features that are part of docking branch
|
||||||
|
* You must replace the default imgui with the code from the docking branch for this to work
|
||||||
|
* https://github.com/ocornut/imgui/tree/docking
|
||||||
|
*
|
||||||
|
* Copyright (c) 2024 Jeffery Myers
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
#include "raymath.h"
|
||||||
|
|
||||||
|
#include "imgui.h"
|
||||||
|
#include "rlImGui.h"
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
int screenWidth = 1280;
|
||||||
|
int screenHeight = 800;
|
||||||
|
|
||||||
|
SetConfigFlags(FLAG_MSAA_4X_HINT | FLAG_VSYNC_HINT | FLAG_WINDOW_RESIZABLE | FLAG_WINDOW_HIGHDPI);
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib-Extras [ImGui] example - Docking");
|
||||||
|
SetTargetFPS(144);
|
||||||
|
rlImGuiSetup(true);
|
||||||
|
|
||||||
|
bool run = true;
|
||||||
|
|
||||||
|
bool showDemoWindow = true;
|
||||||
|
|
||||||
|
// if the linked ImGui has docking, enable it.
|
||||||
|
// this will only be true if you use the docking branch of ImGui.
|
||||||
|
#ifdef IMGUI_HAS_DOCK
|
||||||
|
ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
while (!WindowShouldClose() && run) // Detect window close button or ESC key, or a quit from the menu
|
||||||
|
{
|
||||||
|
BeginDrawing();
|
||||||
|
ClearBackground(DARKGRAY);
|
||||||
|
|
||||||
|
// draw something to the raylib window below the GUI.
|
||||||
|
DrawCircle(GetScreenWidth() / 2, GetScreenHeight() / 2, GetScreenHeight() * 0.45f, DARKGREEN);
|
||||||
|
|
||||||
|
// start ImGui content
|
||||||
|
rlImGuiBegin();
|
||||||
|
|
||||||
|
// if you want windows to dock to the viewport, call this.
|
||||||
|
#ifdef IMGUI_HAS_DOCK
|
||||||
|
ImGui::DockSpaceOverViewport(0, NULL, ImGuiDockNodeFlags_PassthruCentralNode); // set ImGuiDockNodeFlags_PassthruCentralNode so that we can see the raylib contents behind the dockspace
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// show a simple menu bar
|
||||||
|
if (ImGui::BeginMainMenuBar())
|
||||||
|
{
|
||||||
|
if (ImGui::BeginMenu("File"))
|
||||||
|
{
|
||||||
|
if (ImGui::MenuItem("Quit"))
|
||||||
|
run = false;
|
||||||
|
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::BeginMenu("Window"))
|
||||||
|
{
|
||||||
|
if (ImGui::MenuItem("Demo Window", nullptr, showDemoWindow))
|
||||||
|
showDemoWindow = !showDemoWindow;
|
||||||
|
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
ImGui::EndMainMenuBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
// show some windows
|
||||||
|
|
||||||
|
if (showDemoWindow)
|
||||||
|
ImGui::ShowDemoWindow(&showDemoWindow);
|
||||||
|
|
||||||
|
if (ImGui::Begin("Test Window"))
|
||||||
|
{
|
||||||
|
ImGui::TextUnformatted("Another window");
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
|
||||||
|
// end ImGui Content
|
||||||
|
rlImGuiEnd();
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
rlImGuiShutdown();
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
392
src/rlImGui/examples/editor.cpp
Normal file
392
src/rlImGui/examples/editor.cpp
Normal file
|
@ -0,0 +1,392 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib-extras [ImGui] example - editor
|
||||||
|
*
|
||||||
|
* This is a more complex ImGui Integration
|
||||||
|
* It shows how to build windows on top of 2d and 3d views using a render texture
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 Jeffery Myers
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
#include "raymath.h"
|
||||||
|
|
||||||
|
#include "imgui.h"
|
||||||
|
#include "rlImGui.h"
|
||||||
|
#include "rlImGuiColors.h"
|
||||||
|
|
||||||
|
bool Quit = false;
|
||||||
|
|
||||||
|
bool ImGuiDemoOpen = false;
|
||||||
|
|
||||||
|
class DocumentWindow
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool Open = false;
|
||||||
|
|
||||||
|
RenderTexture ViewTexture;
|
||||||
|
|
||||||
|
virtual void Setup() = 0;
|
||||||
|
virtual void Shutdown() = 0;
|
||||||
|
virtual void Show() = 0;
|
||||||
|
virtual void Update() = 0;
|
||||||
|
|
||||||
|
bool Focused = false;
|
||||||
|
|
||||||
|
Rectangle ContentRect = { 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
class ImageViewerWindow : public DocumentWindow
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
void Setup() override
|
||||||
|
{
|
||||||
|
Camera.zoom = 1;
|
||||||
|
Camera.target.x = 0;
|
||||||
|
Camera.target.y = 0;
|
||||||
|
Camera.rotation = 0;
|
||||||
|
Camera.offset.x = GetScreenWidth() / 2.0f;
|
||||||
|
Camera.offset.y = GetScreenHeight() / 2.0f;
|
||||||
|
|
||||||
|
ViewTexture = LoadRenderTexture(GetScreenWidth(), GetScreenHeight());
|
||||||
|
ImageTexture = LoadTexture("resources/parrots.png");
|
||||||
|
|
||||||
|
UpdateRenderTexture();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Show() override
|
||||||
|
{
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
|
||||||
|
ImGui::SetNextWindowSizeConstraints(ImVec2(400, 400), ImVec2((float)GetScreenWidth(), (float)GetScreenHeight()));
|
||||||
|
|
||||||
|
Focused = false;
|
||||||
|
|
||||||
|
if (ImGui::Begin("Image Viewer", &Open, ImGuiWindowFlags_NoScrollbar))
|
||||||
|
{
|
||||||
|
// save off the screen space content rectangle
|
||||||
|
ContentRect = { ImGui::GetWindowPos().x + ImGui::GetCursorScreenPos().x, ImGui::GetWindowPos().y + ImGui::GetCursorScreenPos().y, ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y };
|
||||||
|
|
||||||
|
Focused = ImGui::IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows);
|
||||||
|
|
||||||
|
ImVec2 size = ImGui::GetContentRegionAvail();
|
||||||
|
|
||||||
|
// center the scratch pad in the view
|
||||||
|
Rectangle viewRect = { 0 };
|
||||||
|
viewRect.x = ViewTexture.texture.width / 2 - size.x / 2;
|
||||||
|
viewRect.y = ViewTexture.texture.height / 2 - size.y / 2;
|
||||||
|
viewRect.width = size.x;
|
||||||
|
viewRect.height = -size.y;
|
||||||
|
|
||||||
|
if (ImGui::BeginChild("Toolbar", ImVec2(ImGui::GetContentRegionAvail().x, 25)))
|
||||||
|
{
|
||||||
|
ImGui::SetCursorPosX(2);
|
||||||
|
ImGui::SetCursorPosY(3);
|
||||||
|
|
||||||
|
if (ImGui::Button("None"))
|
||||||
|
{
|
||||||
|
CurrentToolMode = ToolMode::None;
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
|
||||||
|
if (ImGui::Button("Move"))
|
||||||
|
{
|
||||||
|
CurrentToolMode = ToolMode::Move;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
switch (CurrentToolMode)
|
||||||
|
{
|
||||||
|
case ToolMode::None:
|
||||||
|
ImGui::TextUnformatted("No Tool");
|
||||||
|
break;
|
||||||
|
case ToolMode::Move:
|
||||||
|
ImGui::TextUnformatted("Move Tool");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::TextUnformatted(TextFormat("camera target X%f Y%f", Camera.target.x, Camera.target.y));
|
||||||
|
ImGui::EndChild();
|
||||||
|
}
|
||||||
|
|
||||||
|
rlImGuiImageRect(&ViewTexture.texture, (int)size.x, (int)size.y, viewRect);
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
ImGui::PopStyleVar();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update() override
|
||||||
|
{
|
||||||
|
if (!Open)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (IsWindowResized())
|
||||||
|
{
|
||||||
|
UnloadRenderTexture(ViewTexture);
|
||||||
|
ViewTexture = LoadRenderTexture(GetScreenWidth(), GetScreenHeight());
|
||||||
|
|
||||||
|
Camera.offset.x = GetScreenWidth() / 2.0f;
|
||||||
|
Camera.offset.y = GetScreenHeight() / 2.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 mousePos = GetMousePosition();
|
||||||
|
|
||||||
|
if (Focused)
|
||||||
|
{
|
||||||
|
if (CurrentToolMode == ToolMode::Move)
|
||||||
|
{
|
||||||
|
// only do this tool when the mouse is in the content area of the window
|
||||||
|
if (IsMouseButtonDown(0) && CheckCollisionPointRec(mousePos, ContentRect))
|
||||||
|
{
|
||||||
|
if (!Dragging)
|
||||||
|
{
|
||||||
|
LastMousePos = mousePos;
|
||||||
|
LastTarget = Camera.target;
|
||||||
|
}
|
||||||
|
Dragging = true;
|
||||||
|
Vector2 mouseDelta = Vector2Subtract(LastMousePos, mousePos);
|
||||||
|
|
||||||
|
mouseDelta.x /= Camera.zoom;
|
||||||
|
mouseDelta.y /= Camera.zoom;
|
||||||
|
Camera.target = Vector2Add(LastTarget, mouseDelta);
|
||||||
|
|
||||||
|
DirtyScene = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Dragging = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Dragging = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DirtyScene)
|
||||||
|
{
|
||||||
|
DirtyScene = false;
|
||||||
|
UpdateRenderTexture();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Texture ImageTexture;
|
||||||
|
Camera2D Camera = { 0 };
|
||||||
|
|
||||||
|
Vector2 LastMousePos = { 0 };
|
||||||
|
Vector2 LastTarget = { 0 };
|
||||||
|
bool Dragging = false;
|
||||||
|
|
||||||
|
bool DirtyScene = false;
|
||||||
|
|
||||||
|
enum class ToolMode
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Move,
|
||||||
|
};
|
||||||
|
|
||||||
|
ToolMode CurrentToolMode = ToolMode::None;
|
||||||
|
|
||||||
|
void UpdateRenderTexture()
|
||||||
|
{
|
||||||
|
BeginTextureMode(ViewTexture);
|
||||||
|
ClearBackground(BLUE);
|
||||||
|
|
||||||
|
// camera with our view offset with a world origin of 0,0
|
||||||
|
BeginMode2D(Camera);
|
||||||
|
|
||||||
|
// center the image at 0,0
|
||||||
|
DrawTexture(ImageTexture, ImageTexture.width / -2, ImageTexture.height / -2, WHITE);
|
||||||
|
|
||||||
|
EndMode2D();
|
||||||
|
EndTextureMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shutdown() override
|
||||||
|
{
|
||||||
|
UnloadRenderTexture(ViewTexture);
|
||||||
|
UnloadTexture(ImageTexture);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SceneViewWindow : public DocumentWindow
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Camera3D Camera = { 0 };
|
||||||
|
|
||||||
|
void Setup() override
|
||||||
|
{
|
||||||
|
ViewTexture = LoadRenderTexture(GetScreenWidth(), GetScreenHeight());
|
||||||
|
|
||||||
|
Camera.fovy = 45;
|
||||||
|
Camera.up.y = 1;
|
||||||
|
Camera.position.y = 3;
|
||||||
|
Camera.position.z = -25;
|
||||||
|
|
||||||
|
Image img = GenImageChecked(256, 256, 32, 32, DARKGRAY, WHITE);
|
||||||
|
GridTexture = LoadTextureFromImage(img);
|
||||||
|
UnloadImage(img);
|
||||||
|
GenTextureMipmaps(&GridTexture);
|
||||||
|
SetTextureFilter(GridTexture, TEXTURE_FILTER_ANISOTROPIC_16X);
|
||||||
|
SetTextureWrap(GridTexture, TEXTURE_WRAP_CLAMP);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shutdown() override
|
||||||
|
{
|
||||||
|
UnloadRenderTexture(ViewTexture);
|
||||||
|
UnloadTexture(GridTexture);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Show() override
|
||||||
|
{
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
|
||||||
|
ImGui::SetNextWindowSizeConstraints(ImVec2(400, 400), ImVec2((float)GetScreenWidth(), (float)GetScreenHeight()));
|
||||||
|
|
||||||
|
if (ImGui::Begin("3D View", &Open, ImGuiWindowFlags_NoScrollbar))
|
||||||
|
{
|
||||||
|
Focused = ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows);
|
||||||
|
// draw the view
|
||||||
|
rlImGuiImageRenderTextureFit(&ViewTexture, true);
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
ImGui::PopStyleVar();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update() override
|
||||||
|
{
|
||||||
|
if (!Open)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (IsWindowResized())
|
||||||
|
{
|
||||||
|
UnloadRenderTexture(ViewTexture);
|
||||||
|
ViewTexture = LoadRenderTexture(GetScreenWidth(), GetScreenHeight());
|
||||||
|
}
|
||||||
|
|
||||||
|
float period = 10;
|
||||||
|
float magnitude = 25;
|
||||||
|
|
||||||
|
Camera.position.x = (float)(sinf((float)GetTime() / period) * magnitude);
|
||||||
|
|
||||||
|
BeginTextureMode(ViewTexture);
|
||||||
|
ClearBackground(SKYBLUE);
|
||||||
|
|
||||||
|
BeginMode3D(Camera);
|
||||||
|
|
||||||
|
// grid of cube trees on a plane to make a "world"
|
||||||
|
DrawPlane(Vector3{ 0, 0, 0 }, Vector2{ 50, 50 }, BEIGE); // simple world plane
|
||||||
|
float spacing = 4;
|
||||||
|
int count = 5;
|
||||||
|
|
||||||
|
for (float x = -count * spacing; x <= count * spacing; x += spacing)
|
||||||
|
{
|
||||||
|
for (float z = -count * spacing; z <= count * spacing; z += spacing)
|
||||||
|
{
|
||||||
|
Vector3 pos = { x, 0.5f, z };
|
||||||
|
|
||||||
|
Vector3 min = { x - 0.5f,0,z - 0.5f };
|
||||||
|
Vector3 max = { x + 0.5f,1,z + 0.5f };
|
||||||
|
|
||||||
|
DrawCube(Vector3{ x, 1.5f, z }, 1, 1, 1, GREEN);
|
||||||
|
DrawCube(Vector3{ x, 0.5f, z }, 0.25f, 1, 0.25f, BROWN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EndMode3D();
|
||||||
|
EndTextureMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
Texture2D GridTexture = { 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
ImageViewerWindow ImageViewer;
|
||||||
|
SceneViewWindow SceneView;
|
||||||
|
|
||||||
|
void DoMainMenu()
|
||||||
|
{
|
||||||
|
if (ImGui::BeginMainMenuBar())
|
||||||
|
{
|
||||||
|
if (ImGui::BeginMenu("File"))
|
||||||
|
{
|
||||||
|
if (ImGui::MenuItem("Exit"))
|
||||||
|
Quit = true;
|
||||||
|
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::BeginMenu("Window"))
|
||||||
|
{
|
||||||
|
ImGui::MenuItem("ImGui Demo", nullptr, &ImGuiDemoOpen);
|
||||||
|
ImGui::MenuItem("Image Viewer", nullptr, &ImageViewer.Open);
|
||||||
|
ImGui::MenuItem("3D View", nullptr, &SceneView.Open);
|
||||||
|
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
ImGui::EndMainMenuBar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
int screenWidth = 1900;
|
||||||
|
int screenHeight = 900;
|
||||||
|
|
||||||
|
SetConfigFlags(FLAG_MSAA_4X_HINT | FLAG_VSYNC_HINT);
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib-Extras [ImGui] example - ImGui Demo");
|
||||||
|
SetTargetFPS(144);
|
||||||
|
rlImGuiSetup(true);
|
||||||
|
ImGui::GetIO().ConfigWindowsMoveFromTitleBarOnly = true;
|
||||||
|
|
||||||
|
ImageViewer.Setup();
|
||||||
|
ImageViewer.Open = true;
|
||||||
|
|
||||||
|
SceneView.Setup();
|
||||||
|
SceneView.Open = true;
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
while (!WindowShouldClose() && !Quit) // Detect window close button or ESC key
|
||||||
|
{
|
||||||
|
ImageViewer.Update();
|
||||||
|
SceneView.Update();
|
||||||
|
|
||||||
|
BeginDrawing();
|
||||||
|
ClearBackground(DARKGRAY);
|
||||||
|
|
||||||
|
rlImGuiBegin();
|
||||||
|
DoMainMenu();
|
||||||
|
|
||||||
|
if (ImGuiDemoOpen)
|
||||||
|
ImGui::ShowDemoWindow(&ImGuiDemoOpen);
|
||||||
|
|
||||||
|
if (ImageViewer.Open)
|
||||||
|
ImageViewer.Show();
|
||||||
|
|
||||||
|
if (SceneView.Open)
|
||||||
|
SceneView.Show();
|
||||||
|
|
||||||
|
rlImGuiEnd();
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
rlImGuiShutdown();
|
||||||
|
|
||||||
|
ImageViewer.Shutdown();
|
||||||
|
SceneView.Shutdown();
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
127
src/rlImGui/examples/imgui_style_example.cpp
Normal file
127
src/rlImGui/examples/imgui_style_example.cpp
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
// Dear ImGui: standalone example application for Raylib with OpenGL
|
||||||
|
// (Raylib is a simple learning library for game development)
|
||||||
|
|
||||||
|
// Learn about Dear ImGui:
|
||||||
|
// - FAQ https://dearimgui.com/faq
|
||||||
|
// - Getting Started https://dearimgui.com/getting-started
|
||||||
|
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||||
|
// - Introduction, links and more at the top of imgui.cpp
|
||||||
|
|
||||||
|
#include "imgui.h"
|
||||||
|
#include "imgui_impl_raylib.h"
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
// Main code
|
||||||
|
int main(int, char**)
|
||||||
|
{
|
||||||
|
// Setup raylib window
|
||||||
|
SetConfigFlags(FLAG_WINDOW_RESIZABLE | FLAG_WINDOW_HIGHDPI);
|
||||||
|
InitWindow(1280, 720, "Dear ImGui Raylib(OpenGL) example");
|
||||||
|
|
||||||
|
// Setup Dear ImGui context
|
||||||
|
ImGui::CreateContext();
|
||||||
|
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||||
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||||
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||||
|
|
||||||
|
// Setup Dear ImGui style
|
||||||
|
ImGui::StyleColorsDark();
|
||||||
|
//ImGui::StyleColorsLight();
|
||||||
|
|
||||||
|
// Setup Platform/Renderer backends
|
||||||
|
ImGui_ImplRaylib_Init();
|
||||||
|
|
||||||
|
// Load Fonts
|
||||||
|
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||||
|
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
||||||
|
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||||
|
// - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
|
||||||
|
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
|
||||||
|
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||||
|
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||||
|
io.Fonts->AddFontDefault();
|
||||||
|
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.0f);
|
||||||
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f);
|
||||||
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f);
|
||||||
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f);
|
||||||
|
ImFont* font = io.Fonts->AddFontFromFileTTF("resources/driusstraight.ttf", 18.0f, nullptr, io.Fonts->GetGlyphRangesJapanese());
|
||||||
|
IM_ASSERT(font != nullptr);
|
||||||
|
|
||||||
|
// required to be called to cache the font texture with raylib
|
||||||
|
ImGui_ImplRaylib_BuildFontAtlas();
|
||||||
|
|
||||||
|
// Our state
|
||||||
|
bool show_demo_window = true;
|
||||||
|
bool show_another_window = false;
|
||||||
|
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
|
||||||
|
|
||||||
|
// Main loop
|
||||||
|
bool done = false;
|
||||||
|
while (!done)
|
||||||
|
{
|
||||||
|
// Poll and handle events (inputs, window resize, etc.)
|
||||||
|
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
|
||||||
|
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
|
||||||
|
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
|
||||||
|
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
|
||||||
|
ImGui_ImplRaylib_ProcessEvents();
|
||||||
|
|
||||||
|
// Start the Dear ImGui frame
|
||||||
|
ImGui_ImplRaylib_NewFrame();
|
||||||
|
ImGui::NewFrame();
|
||||||
|
|
||||||
|
// 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!).
|
||||||
|
if (show_demo_window)
|
||||||
|
ImGui::ShowDemoWindow(&show_demo_window);
|
||||||
|
|
||||||
|
// 2. Show a simple window that we create ourselves. We use a Begin/End pair to create a named window.
|
||||||
|
{
|
||||||
|
static float f = 0.0f;
|
||||||
|
static int counter = 0;
|
||||||
|
|
||||||
|
ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it.
|
||||||
|
|
||||||
|
ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too)
|
||||||
|
ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state
|
||||||
|
ImGui::Checkbox("Another Window", &show_another_window);
|
||||||
|
|
||||||
|
ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f
|
||||||
|
ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color
|
||||||
|
|
||||||
|
if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated)
|
||||||
|
counter++;
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::Text("counter = %d", counter);
|
||||||
|
|
||||||
|
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate);
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Show another simple window.
|
||||||
|
if (show_another_window)
|
||||||
|
{
|
||||||
|
ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked)
|
||||||
|
ImGui::Text("Hello from another window!");
|
||||||
|
if (ImGui::Button("Close Me"))
|
||||||
|
show_another_window = false;
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Rendering
|
||||||
|
ImGui::Render();
|
||||||
|
BeginDrawing();
|
||||||
|
ClearBackground(Color{ (unsigned char)(clear_color.x * 255), (unsigned char)(clear_color.y * 255),(unsigned char)(clear_color.z * 255),(unsigned char)(clear_color.w * 255) });
|
||||||
|
ImGui_ImplRaylib_RenderDrawData(ImGui::GetDrawData());
|
||||||
|
EndDrawing();
|
||||||
|
|
||||||
|
done = WindowShouldClose();
|
||||||
|
}
|
||||||
|
// Cleanup
|
||||||
|
ImGui_ImplRaylib_Shutdown();
|
||||||
|
ImGui::DestroyContext();
|
||||||
|
|
||||||
|
CloseWindow();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
59
src/rlImGui/examples/simple.cpp
Normal file
59
src/rlImGui/examples/simple.cpp
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib-extras [ImGui] example - Simple Integration
|
||||||
|
*
|
||||||
|
* This is a simple ImGui Integration
|
||||||
|
* It is done using C++ but with C style code
|
||||||
|
* It can be done in C as well if you use the C ImGui wrapper
|
||||||
|
* https://github.com/cimgui/cimgui
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 Jeffery Myers
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
#include "raymath.h"
|
||||||
|
|
||||||
|
#include "imgui.h"
|
||||||
|
#include "rlImGui.h"
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
int screenWidth = 1280;
|
||||||
|
int screenHeight = 800;
|
||||||
|
|
||||||
|
SetConfigFlags(FLAG_MSAA_4X_HINT | FLAG_VSYNC_HINT | FLAG_WINDOW_RESIZABLE);
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib-Extras [ImGui] example - simple ImGui Demo");
|
||||||
|
SetTargetFPS(144);
|
||||||
|
rlImGuiSetup(true);
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||||
|
{
|
||||||
|
BeginDrawing();
|
||||||
|
ClearBackground(DARKGRAY);
|
||||||
|
|
||||||
|
// start ImGui Conent
|
||||||
|
rlImGuiBegin();
|
||||||
|
|
||||||
|
// show ImGui Content
|
||||||
|
bool open = true;
|
||||||
|
ImGui::ShowDemoWindow(&open);
|
||||||
|
|
||||||
|
// end ImGui Content
|
||||||
|
rlImGuiEnd();
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
rlImGuiShutdown();
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
4973
src/rlImGui/extras/FA6FreeSolidFontData.h
Normal file
4973
src/rlImGui/extras/FA6FreeSolidFontData.h
Normal file
File diff suppressed because it is too large
Load diff
34
src/rlImGui/extras/FontAwsome_LICENSE.txt
Normal file
34
src/rlImGui/extras/FontAwsome_LICENSE.txt
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
Font Awesome Free License
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
Font Awesome Free is free, open source, and GPL friendly. You can use it for
|
||||||
|
commercial projects, open source projects, or really almost whatever you want.
|
||||||
|
Full Font Awesome Free license: https://fontawesome.com/license/free.
|
||||||
|
|
||||||
|
# Icons: CC BY 4.0 License (https://creativecommons.org/licenses/by/4.0/)
|
||||||
|
In the Font Awesome Free download, the CC BY 4.0 license applies to all icons
|
||||||
|
packaged as SVG and JS file types.
|
||||||
|
|
||||||
|
# Fonts: SIL OFL 1.1 License (https://scripts.sil.org/OFL)
|
||||||
|
In the Font Awesome Free download, the SIL OFL license applies to all icons
|
||||||
|
packaged as web and desktop font files.
|
||||||
|
|
||||||
|
# Code: MIT License (https://opensource.org/licenses/MIT)
|
||||||
|
In the Font Awesome Free download, the MIT license applies to all non-font and
|
||||||
|
non-icon files.
|
||||||
|
|
||||||
|
# Attribution
|
||||||
|
Attribution is required by MIT, SIL OFL, and CC BY licenses. Downloaded Font
|
||||||
|
Awesome Free files already contain embedded comments with sufficient
|
||||||
|
attribution, so you shouldn't need to do anything additional when using these
|
||||||
|
files normally.
|
||||||
|
|
||||||
|
We've kept attribution comments terse, so we ask that you do not actively work
|
||||||
|
to remove them from files, especially code. They're a great way for folks to
|
||||||
|
learn about Font Awesome.
|
||||||
|
|
||||||
|
# Brand Icons
|
||||||
|
All brand icons are trademarks of their respective owners. The use of these
|
||||||
|
trademarks does not indicate endorsement of the trademark holder by Font
|
||||||
|
Awesome, nor vice versa. **Please do not use brand logos for any purpose except
|
||||||
|
to represent the company, product, or service to which they refer.**
|
1396
src/rlImGui/extras/IconsFontAwesome6.h
Normal file
1396
src/rlImGui/extras/IconsFontAwesome6.h
Normal file
File diff suppressed because it is too large
Load diff
54
src/rlImGui/imgui_impl_raylib.h
Normal file
54
src/rlImGui/imgui_impl_raylib.h
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
/**********************************************************************************************
|
||||||
|
*
|
||||||
|
* raylibExtras * Utilities and Shared Components for Raylib
|
||||||
|
*
|
||||||
|
* rlImGui * basic ImGui integration
|
||||||
|
*
|
||||||
|
* LICENSE: ZLIB
|
||||||
|
*
|
||||||
|
* Copyright (c) 2024 Jeffery Myers
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
**********************************************************************************************/
|
||||||
|
|
||||||
|
// dear imgui: Platform Backend for Raylib
|
||||||
|
// (Info: Raylib is a cross-platform general purpose library for handling windows, inputs, graphics context creation, etc. using OpenGL)
|
||||||
|
// This is is the low level ImGui backend for raylib, a higher level API that matches the raylib API can be found in rlImGui.h
|
||||||
|
|
||||||
|
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||||
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
|
// Learn about Dear ImGui:
|
||||||
|
// - FAQ https://dearimgui.com/faq
|
||||||
|
// - Getting Started https://dearimgui.com/getting-started
|
||||||
|
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||||
|
// - Introduction, links and more at the top of imgui.cpp
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "imgui.h" // IMGUI_IMPL_API
|
||||||
|
#ifndef IMGUI_DISABLE
|
||||||
|
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplRaylib_Init(void);
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplRaylib_BuildFontAtlas(void);
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplRaylib_Shutdown(void);
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplRaylib_NewFrame(void);
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplRaylib_RenderDrawData(ImDrawData* draw_data);
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplRaylib_ProcessEvents(void);
|
||||||
|
|
||||||
|
#endif // #ifndef IMGUI_DISABLE
|
2
src/rlImGui/premake-VisualStudio.bat
Normal file
2
src/rlImGui/premake-VisualStudio.bat
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
premake5.exe vs2022
|
||||||
|
pause
|
2
src/rlImGui/premake-mingw.bat
Normal file
2
src/rlImGui/premake-mingw.bat
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
premake5.exe gmake2
|
||||||
|
pause
|
BIN
src/rlImGui/premake5
Normal file
BIN
src/rlImGui/premake5
Normal file
Binary file not shown.
BIN
src/rlImGui/premake5.exe
Normal file
BIN
src/rlImGui/premake5.exe
Normal file
Binary file not shown.
226
src/rlImGui/premake5.lua
Normal file
226
src/rlImGui/premake5.lua
Normal file
|
@ -0,0 +1,226 @@
|
||||||
|
newoption
|
||||||
|
{
|
||||||
|
trigger = "graphics",
|
||||||
|
value = "OPENGL_VERSION",
|
||||||
|
description = "version of OpenGL to build raylib against",
|
||||||
|
allowed = {
|
||||||
|
{ "opengl11", "OpenGL 1.1"},
|
||||||
|
{ "opengl21", "OpenGL 2.1"},
|
||||||
|
{ "opengl33", "OpenGL 3.3"},
|
||||||
|
{ "opengl43", "OpenGL 4.3"}
|
||||||
|
},
|
||||||
|
default = "opengl33"
|
||||||
|
}
|
||||||
|
|
||||||
|
function define_C()
|
||||||
|
language "C"
|
||||||
|
end
|
||||||
|
|
||||||
|
function define_Cpp()
|
||||||
|
language "C++"
|
||||||
|
end
|
||||||
|
|
||||||
|
function string.starts(String,Start)
|
||||||
|
return string.sub(String,1,string.len(Start))==Start
|
||||||
|
end
|
||||||
|
|
||||||
|
function link_to(lib)
|
||||||
|
links (lib)
|
||||||
|
includedirs ("../"..lib.."/include", "../"..lib.."/" )
|
||||||
|
end
|
||||||
|
|
||||||
|
function download_progress(total, current)
|
||||||
|
local ratio = current / total;
|
||||||
|
ratio = math.min(math.max(ratio, 0), 1);
|
||||||
|
local percent = math.floor(ratio * 100);
|
||||||
|
print("Download progress (" .. percent .. "%/100%)")
|
||||||
|
end
|
||||||
|
|
||||||
|
function check_raylib()
|
||||||
|
if(os.isdir("raylib") == false and os.isdir("raylib-master") == false) then
|
||||||
|
if(not os.isfile("raylib-master.zip")) then
|
||||||
|
print("Raylib not found, downloading from github")
|
||||||
|
local result_str, response_code = http.download("https://github.com/raysan5/raylib/archive/refs/heads/master.zip", "raylib-master.zip", {
|
||||||
|
progress = download_progress,
|
||||||
|
headers = { "From: Premake", "Referer: Premake" }
|
||||||
|
})
|
||||||
|
end
|
||||||
|
print("Unzipping to " .. os.getcwd())
|
||||||
|
zip.extract("raylib-master.zip", os.getcwd())
|
||||||
|
os.remove("raylib-master.zip")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function check_imgui()
|
||||||
|
if(os.isdir("imgui") == false and os.isdir("imgui-master") == false) then
|
||||||
|
if(not os.isfile("imgui-master.zip")) then
|
||||||
|
print("imgui not found, downloading from github")
|
||||||
|
local result_str, response_code = http.download("https://github.com/ocornut/imgui/archive/refs/heads/master.zip", "imgui-master.zip", {
|
||||||
|
progress = download_progress,
|
||||||
|
headers = { "From: Premake", "Referer: Premake" }
|
||||||
|
})
|
||||||
|
end
|
||||||
|
print("Unzipping to " .. os.getcwd())
|
||||||
|
zip.extract("imgui-master.zip", os.getcwd())
|
||||||
|
os.remove("imgui-master.zip")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
workspace "rlImGui"
|
||||||
|
configurations { "Debug", "Release" }
|
||||||
|
platforms { "x64"}
|
||||||
|
defaultplatform "x64"
|
||||||
|
|
||||||
|
filter "configurations:Debug"
|
||||||
|
defines { "DEBUG" }
|
||||||
|
symbols "On"
|
||||||
|
|
||||||
|
filter "configurations:Release"
|
||||||
|
defines { "NDEBUG" }
|
||||||
|
optimize "On"
|
||||||
|
|
||||||
|
filter { "platforms:x64" }
|
||||||
|
architecture "x86_64"
|
||||||
|
|
||||||
|
filter { "system:linux" }
|
||||||
|
defines { "_GLFW_X11" }
|
||||||
|
defines { "_GNU_SOURCE" }
|
||||||
|
|
||||||
|
targetdir "bin/%{cfg.buildcfg}/"
|
||||||
|
|
||||||
|
|
||||||
|
cdialect "C99"
|
||||||
|
cppdialect "C++17"
|
||||||
|
check_raylib()
|
||||||
|
check_imgui()
|
||||||
|
|
||||||
|
include ("raylib_premake5.lua")
|
||||||
|
|
||||||
|
project "rlImGui"
|
||||||
|
kind "StaticLib"
|
||||||
|
location "build"
|
||||||
|
targetdir "bin/%{cfg.buildcfg}"
|
||||||
|
language "C++"
|
||||||
|
cdialect "C99"
|
||||||
|
cppdialect "C++17"
|
||||||
|
include_raylib()
|
||||||
|
includedirs { "rlImGui", "imgui", "imgui-master"}
|
||||||
|
vpaths
|
||||||
|
{
|
||||||
|
["Header Files"] = { "*.h"},
|
||||||
|
["Source Files"] = {"*.cpp"},
|
||||||
|
["ImGui Files"] = { "imgui/*.h","imgui/*.cpp", "imgui-master/*.h","imgui-master/*.cpp" },
|
||||||
|
}
|
||||||
|
files {"imgui-master/*.h", "imgui-master/*.cpp", "imgui/*.h", "imgui/*.cpp", "*.cpp", "*.h", "extras/**.h"}
|
||||||
|
|
||||||
|
defines {"IMGUI_DISABLE_OBSOLETE_FUNCTIONS","IMGUI_DISABLE_OBSOLETE_KEYIO"}
|
||||||
|
|
||||||
|
group "Examples"
|
||||||
|
project "simple"
|
||||||
|
kind "ConsoleApp"
|
||||||
|
language "C++"
|
||||||
|
cdialect "C99"
|
||||||
|
cppdialect "C++17"
|
||||||
|
location "build"
|
||||||
|
targetdir "bin/%{cfg.buildcfg}"
|
||||||
|
|
||||||
|
vpaths
|
||||||
|
{
|
||||||
|
["Header Files"] = { "examples/**.h"},
|
||||||
|
["Source Files"] = {"examples/**.cpp", "examples/**.c"},
|
||||||
|
}
|
||||||
|
files {"examples/simple.cpp"}
|
||||||
|
link_raylib()
|
||||||
|
links {"rlImGui"}
|
||||||
|
includedirs {"./", "imgui", "imgui-master" }
|
||||||
|
|
||||||
|
filter "action:vs*"
|
||||||
|
debugdir "$(SolutionDir)"
|
||||||
|
|
||||||
|
|
||||||
|
project "editor"
|
||||||
|
kind "ConsoleApp"
|
||||||
|
language "C++"
|
||||||
|
cdialect "C99"
|
||||||
|
cppdialect "C++17"
|
||||||
|
location "build"
|
||||||
|
targetdir "bin/%{cfg.buildcfg}"
|
||||||
|
|
||||||
|
|
||||||
|
vpaths
|
||||||
|
{
|
||||||
|
["Header Files"] = { "examples/**.h"},
|
||||||
|
["Source Files"] = {"examples/**.cpp", "examples/**.c"},
|
||||||
|
}
|
||||||
|
files {"examples/editor.cpp"}
|
||||||
|
link_raylib()
|
||||||
|
links {"rlImGui"}
|
||||||
|
includedirs {"./", "imgui", "imgui-master" }
|
||||||
|
|
||||||
|
filter "action:vs*"
|
||||||
|
debugdir "$(SolutionDir)"
|
||||||
|
|
||||||
|
|
||||||
|
project "imgui_style_example"
|
||||||
|
kind "ConsoleApp"
|
||||||
|
language "C++"
|
||||||
|
cdialect "C99"
|
||||||
|
cppdialect "C++17"
|
||||||
|
location "build"
|
||||||
|
targetdir "bin/%{cfg.buildcfg}"
|
||||||
|
|
||||||
|
vpaths
|
||||||
|
{
|
||||||
|
["Header Files"] = { "examples/**.h"},
|
||||||
|
["Source Files"] = {"examples/**.cpp", "examples/**.c"},
|
||||||
|
}
|
||||||
|
files {"examples/imgui_style_example.cpp"}
|
||||||
|
link_raylib()
|
||||||
|
links {"rlImGui"}
|
||||||
|
includedirs {"./", "imgui", "imgui-master" }
|
||||||
|
|
||||||
|
filter "action:vs*"
|
||||||
|
debugdir "$(SolutionDir)"
|
||||||
|
|
||||||
|
project "docking_example"
|
||||||
|
kind "ConsoleApp"
|
||||||
|
language "C++"
|
||||||
|
cdialect "C99"
|
||||||
|
cppdialect "C++17"
|
||||||
|
location "build"
|
||||||
|
targetdir "bin/%{cfg.buildcfg}"
|
||||||
|
|
||||||
|
vpaths
|
||||||
|
{
|
||||||
|
["Header Files"] = { "examples/**.h"},
|
||||||
|
["Source Files"] = {"examples/**.cpp", "examples/**.c"},
|
||||||
|
}
|
||||||
|
files {"examples/docking_example.cpp"}
|
||||||
|
link_raylib()
|
||||||
|
links {"rlImGui"}
|
||||||
|
includedirs {"./", "imgui", "imgui-master" }
|
||||||
|
|
||||||
|
filter "action:vs*"
|
||||||
|
debugdir "$(SolutionDir)"
|
||||||
|
|
||||||
|
project "asset_browser"
|
||||||
|
kind "ConsoleApp"
|
||||||
|
language "C++"
|
||||||
|
cdialect "C99"
|
||||||
|
cppdialect "C++17"
|
||||||
|
location "build"
|
||||||
|
targetdir "bin/%{cfg.buildcfg}"
|
||||||
|
|
||||||
|
vpaths
|
||||||
|
{
|
||||||
|
["Header Files"] = { "examples/asset_browser/**.h"},
|
||||||
|
["Source Files"] = {"examples/asset_browser/**.cpp", "examples/asset_browser/**.c"},
|
||||||
|
}
|
||||||
|
files {"examples/asset_browser/**.cpp", "examples/asset_browser/**.h"}
|
||||||
|
link_raylib()
|
||||||
|
links {"rlImGui"}
|
||||||
|
includedirs {"./", "examples/asset_browser/", "imgui", "imgui-master" }
|
||||||
|
|
||||||
|
filter "action:vs*"
|
||||||
|
debugdir "$(SolutionDir)"
|
||||||
|
|
BIN
src/rlImGui/premake5.osx
Normal file
BIN
src/rlImGui/premake5.osx
Normal file
Binary file not shown.
134
src/rlImGui/raylib_premake5.lua
Normal file
134
src/rlImGui/raylib_premake5.lua
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
-- Copyright (c) 2020-2024 Jeffery Myers
|
||||||
|
--
|
||||||
|
--This software is provided "as-is", without any express or implied warranty. In no event
|
||||||
|
--will the authors be held liable for any damages arising from the use of this software.
|
||||||
|
|
||||||
|
--Permission is granted to anyone to use this software for any purpose, including commercial
|
||||||
|
--applications, and to alter it and redistribute it freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
-- 1. The origin of this software must not be misrepresented; you must not claim that you
|
||||||
|
-- wrote the original software. If you use this software in a product, an acknowledgment
|
||||||
|
-- in the product documentation would be appreciated but is not required.
|
||||||
|
--
|
||||||
|
-- 2. Altered source versions must be plainly marked as such, and must not be misrepresented
|
||||||
|
-- as being the original software.
|
||||||
|
--
|
||||||
|
-- 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
|
||||||
|
function platform_defines()
|
||||||
|
defines{"PLATFORM_DESKTOP"}
|
||||||
|
|
||||||
|
filter {"options:graphics=opengl43"}
|
||||||
|
defines{"GRAPHICS_API_OPENGL_43"}
|
||||||
|
|
||||||
|
filter {"options:graphics=opengl33"}
|
||||||
|
defines{"GRAPHICS_API_OPENGL_33"}
|
||||||
|
|
||||||
|
filter {"options:graphics=opengl21"}
|
||||||
|
defines{"GRAPHICS_API_OPENGL_21"}
|
||||||
|
|
||||||
|
filter {"options:graphics=opengl11"}
|
||||||
|
defines{"GRAPHICS_API_OPENGL_11"}
|
||||||
|
|
||||||
|
filter {"system:macosx"}
|
||||||
|
disablewarnings {"deprecated-declarations"}
|
||||||
|
|
||||||
|
filter {"system:linux"}
|
||||||
|
defines {"_GLFW_X11"}
|
||||||
|
defines {"_GNU_SOURCE"}
|
||||||
|
-- This is necessary, otherwise compilation will fail since
|
||||||
|
-- there is no CLOCK_MONOTOMIC. raylib claims to have a workaround
|
||||||
|
-- to compile under c99 without -D_GNU_SOURCE, but it didn't seem
|
||||||
|
-- to work. raylib's Makefile also adds this flag, probably why it went
|
||||||
|
-- unnoticed for so long.
|
||||||
|
-- It compiles under c11 without -D_GNU_SOURCE, because c11 requires
|
||||||
|
-- to have CLOCK_MONOTOMIC
|
||||||
|
-- See: https://github.com/raysan5/raylib/issues/2729
|
||||||
|
|
||||||
|
filter{}
|
||||||
|
end
|
||||||
|
|
||||||
|
function get_raylib_dir()
|
||||||
|
if (os.isdir("raylib-master")) then
|
||||||
|
return "raylib-master"
|
||||||
|
end
|
||||||
|
if (os.isdir("../raylib-master")) then
|
||||||
|
return "raylib-master"
|
||||||
|
end
|
||||||
|
return "raylib"
|
||||||
|
end
|
||||||
|
|
||||||
|
function link_raylib()
|
||||||
|
links {"raylib"}
|
||||||
|
|
||||||
|
raylib_dir = get_raylib_dir();
|
||||||
|
includedirs {raylib_dir .. "/src" }
|
||||||
|
includedirs {raylib_dir .."/src/external" }
|
||||||
|
includedirs {raylib_dir .."/src/external/glfw/include" }
|
||||||
|
platform_defines()
|
||||||
|
filter "action:vs*"
|
||||||
|
defines{"_WINSOCK_DEPRECATED_NO_WARNINGS", "_CRT_SECURE_NO_WARNINGS"}
|
||||||
|
dependson {"raylib"}
|
||||||
|
links {"raylib.lib"}
|
||||||
|
characterset ("MBCS")
|
||||||
|
buildoptions { "/Zc:__cplusplus" }
|
||||||
|
|
||||||
|
filter "system:windows"
|
||||||
|
defines{"_WIN32"}
|
||||||
|
links {"winmm", "gdi32"}
|
||||||
|
libdirs {"bin/%{cfg.buildcfg}"}
|
||||||
|
|
||||||
|
filter "system:linux"
|
||||||
|
links {"pthread", "m", "dl", "rt", "X11"}
|
||||||
|
|
||||||
|
filter "system:macosx"
|
||||||
|
links {"OpenGL.framework", "Cocoa.framework", "IOKit.framework", "CoreFoundation.framework", "CoreAudio.framework", "CoreVideo.framework", "AudioToolbox.framework"}
|
||||||
|
|
||||||
|
filter{}
|
||||||
|
end
|
||||||
|
|
||||||
|
function include_raylib()
|
||||||
|
raylib_dir = get_raylib_dir();
|
||||||
|
includedirs {raylib_dir .."/src" }
|
||||||
|
includedirs {raylib_dir .."/src/external" }
|
||||||
|
includedirs {raylib_dir .."/src/external/glfw/include" }
|
||||||
|
platform_defines()
|
||||||
|
|
||||||
|
filter "action:vs*"
|
||||||
|
defines{"_WINSOCK_DEPRECATED_NO_WARNINGS", "_CRT_SECURE_NO_WARNINGS"}
|
||||||
|
|
||||||
|
filter{}
|
||||||
|
end
|
||||||
|
|
||||||
|
project "raylib"
|
||||||
|
kind "StaticLib"
|
||||||
|
|
||||||
|
platform_defines()
|
||||||
|
|
||||||
|
location "build"
|
||||||
|
language "C"
|
||||||
|
cdialect "C99"
|
||||||
|
cppdialect "C++17"
|
||||||
|
targetdir "bin/%{cfg.buildcfg}"
|
||||||
|
|
||||||
|
filter "action:vs*"
|
||||||
|
defines{"_WINSOCK_DEPRECATED_NO_WARNINGS", "_CRT_SECURE_NO_WARNINGS"}
|
||||||
|
characterset ("MBCS")
|
||||||
|
buildoptions { "/Zc:__cplusplus" }
|
||||||
|
filter{}
|
||||||
|
|
||||||
|
raylib_dir = get_raylib_dir();
|
||||||
|
print ("Using raylib dir " .. raylib_dir);
|
||||||
|
includedirs {raylib_dir .. "/src", raylib_dir .. "/src/external/glfw/include" }
|
||||||
|
vpaths
|
||||||
|
{
|
||||||
|
["Header Files"] = { raylib_dir .. "/src/**.h"},
|
||||||
|
["Source Files/*"] = { raylib_dir .. "/src/**.c"},
|
||||||
|
}
|
||||||
|
files {raylib_dir .. "/src/*.h", raylib_dir .. "/src/*.c"}
|
||||||
|
removefiles {raylib_dir .. "/src/rcore_*.c"}
|
||||||
|
|
||||||
|
filter { "system:macosx", "files:" .. raylib_dir .. "/src/rglfw.c" }
|
||||||
|
compileas "Objective-C"
|
||||||
|
|
||||||
|
filter{}
|
BIN
src/rlImGui/resources/driusstraight.ttf
Normal file
BIN
src/rlImGui/resources/driusstraight.ttf
Normal file
Binary file not shown.
BIN
src/rlImGui/resources/parrots.png
Normal file
BIN
src/rlImGui/resources/parrots.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 288 KiB |
757
src/rlImGui/rlImGui.cpp
Normal file
757
src/rlImGui/rlImGui.cpp
Normal file
|
@ -0,0 +1,757 @@
|
||||||
|
/**********************************************************************************************
|
||||||
|
*
|
||||||
|
* raylibExtras * Utilities and Shared Components for Raylib
|
||||||
|
*
|
||||||
|
* rlImGui * basic ImGui integration
|
||||||
|
*
|
||||||
|
* LICENSE: ZLIB
|
||||||
|
*
|
||||||
|
* Copyright (c) 2024 Jeffery Myers
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
**********************************************************************************************/
|
||||||
|
#include "rlImGui.h"
|
||||||
|
|
||||||
|
#include "imgui_impl_raylib.h"
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
#include "rlgl.h"
|
||||||
|
|
||||||
|
#include "imgui.h"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <limits>
|
||||||
|
#include <map>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#ifndef NO_FONT_AWESOME
|
||||||
|
#include "extras/FA6FreeSolidFontData.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static ImGuiMouseCursor CurrentMouseCursor = ImGuiMouseCursor_COUNT;
|
||||||
|
static MouseCursor MouseCursorMap[ImGuiMouseCursor_COUNT];
|
||||||
|
|
||||||
|
ImGuiContext *GlobalContext = nullptr;
|
||||||
|
|
||||||
|
static std::map<KeyboardKey, ImGuiKey> RaylibKeyMap;
|
||||||
|
|
||||||
|
static bool LastFrameFocused = false;
|
||||||
|
|
||||||
|
static bool LastControlPressed = false;
|
||||||
|
static bool LastShiftPressed = false;
|
||||||
|
static bool LastAltPressed = false;
|
||||||
|
static bool LastSuperPressed = false;
|
||||||
|
|
||||||
|
// internal only functions
|
||||||
|
bool rlImGuiIsControlDown() {
|
||||||
|
return IsKeyDown(KEY_RIGHT_CONTROL) || IsKeyDown(KEY_LEFT_CONTROL);
|
||||||
|
}
|
||||||
|
bool rlImGuiIsShiftDown() {
|
||||||
|
return IsKeyDown(KEY_RIGHT_SHIFT) || IsKeyDown(KEY_LEFT_SHIFT);
|
||||||
|
}
|
||||||
|
bool rlImGuiIsAltDown() {
|
||||||
|
return IsKeyDown(KEY_RIGHT_ALT) || IsKeyDown(KEY_LEFT_ALT);
|
||||||
|
}
|
||||||
|
bool rlImGuiIsSuperDown() {
|
||||||
|
return IsKeyDown(KEY_RIGHT_SUPER) || IsKeyDown(KEY_LEFT_SUPER);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReloadFonts(void) {
|
||||||
|
ImGuiIO &io = ImGui::GetIO();
|
||||||
|
unsigned char *pixels = nullptr;
|
||||||
|
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height, nullptr);
|
||||||
|
Image image = GenImageColor(width, height, BLANK);
|
||||||
|
memcpy(image.data, pixels, width * height * 4);
|
||||||
|
|
||||||
|
Texture2D *fontTexture = (Texture2D *)io.Fonts->TexID;
|
||||||
|
if (fontTexture && fontTexture->id != 0) {
|
||||||
|
UnloadTexture(*fontTexture);
|
||||||
|
MemFree(fontTexture);
|
||||||
|
}
|
||||||
|
|
||||||
|
fontTexture = (Texture2D *)MemAlloc(sizeof(Texture2D));
|
||||||
|
*fontTexture = LoadTextureFromImage(image);
|
||||||
|
UnloadImage(image);
|
||||||
|
io.Fonts->TexID = (ImTextureID)fontTexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *GetClipTextCallback(ImGuiContext *) {
|
||||||
|
return GetClipboardText();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetClipTextCallback(ImGuiContext *, const char *text) {
|
||||||
|
SetClipboardText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ImGuiNewFrame(float deltaTime) {
|
||||||
|
ImGuiIO &io = ImGui::GetIO();
|
||||||
|
|
||||||
|
// Vector2 resolutionScale = GetWindowScaleDPI();
|
||||||
|
Vector2 resolutionScale = Vector2{1, 1};
|
||||||
|
|
||||||
|
#ifndef PLATFORM_DRM
|
||||||
|
if (IsWindowFullscreen()) {
|
||||||
|
int monitor = GetCurrentMonitor();
|
||||||
|
io.DisplaySize.x = float(GetMonitorWidth(monitor));
|
||||||
|
io.DisplaySize.y = float(GetMonitorHeight(monitor));
|
||||||
|
} else {
|
||||||
|
io.DisplaySize.x = float(GetScreenWidth());
|
||||||
|
io.DisplaySize.y = float(GetScreenHeight());
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(__APPLE__)
|
||||||
|
if (!IsWindowState(FLAG_WINDOW_HIGHDPI))
|
||||||
|
resolutionScale = Vector2{1, 1};
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
io.DisplaySize.x = float(GetScreenWidth());
|
||||||
|
io.DisplaySize.y = float(GetScreenHeight());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
io.DisplayFramebufferScale = ImVec2(resolutionScale.x, resolutionScale.y);
|
||||||
|
|
||||||
|
if (deltaTime <= 0)
|
||||||
|
deltaTime = 0.001f;
|
||||||
|
|
||||||
|
io.DeltaTime = deltaTime;
|
||||||
|
|
||||||
|
if (ImGui::GetIO().BackendFlags & ImGuiBackendFlags_HasMouseCursors) {
|
||||||
|
if ((io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) == 0) {
|
||||||
|
ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
|
||||||
|
if (imgui_cursor != CurrentMouseCursor || io.MouseDrawCursor) {
|
||||||
|
CurrentMouseCursor = imgui_cursor;
|
||||||
|
if (io.MouseDrawCursor || imgui_cursor == ImGuiMouseCursor_None) {
|
||||||
|
HideCursor();
|
||||||
|
} else {
|
||||||
|
ShowCursor();
|
||||||
|
|
||||||
|
if (!(io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)) {
|
||||||
|
SetMouseCursor((imgui_cursor > -1 && imgui_cursor < ImGuiMouseCursor_COUNT)
|
||||||
|
? MouseCursorMap[imgui_cursor]
|
||||||
|
: MOUSE_CURSOR_DEFAULT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ImGuiTriangleVert(ImDrawVert &idx_vert) {
|
||||||
|
Color *c;
|
||||||
|
c = (Color *)&idx_vert.col;
|
||||||
|
rlColor4ub(c->r, c->g, c->b, c->a);
|
||||||
|
rlTexCoord2f(idx_vert.uv.x, idx_vert.uv.y);
|
||||||
|
rlVertex2f(idx_vert.pos.x, idx_vert.pos.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ImGuiRenderTriangles(unsigned int count, int indexStart,
|
||||||
|
const ImVector<ImDrawIdx> &indexBuffer,
|
||||||
|
const ImVector<ImDrawVert> &vertBuffer, void *texturePtr) {
|
||||||
|
if (count < 3)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Texture *texture = (Texture *)texturePtr;
|
||||||
|
|
||||||
|
unsigned int textureId = (texture == nullptr) ? 0 : texture->id;
|
||||||
|
|
||||||
|
rlBegin(RL_TRIANGLES);
|
||||||
|
rlSetTexture(textureId);
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i <= (count - 3); i += 3) {
|
||||||
|
ImDrawIdx indexA = indexBuffer[indexStart + i];
|
||||||
|
ImDrawIdx indexB = indexBuffer[indexStart + i + 1];
|
||||||
|
ImDrawIdx indexC = indexBuffer[indexStart + i + 2];
|
||||||
|
|
||||||
|
ImDrawVert vertexA = vertBuffer[indexA];
|
||||||
|
ImDrawVert vertexB = vertBuffer[indexB];
|
||||||
|
ImDrawVert vertexC = vertBuffer[indexC];
|
||||||
|
|
||||||
|
ImGuiTriangleVert(vertexA);
|
||||||
|
ImGuiTriangleVert(vertexB);
|
||||||
|
ImGuiTriangleVert(vertexC);
|
||||||
|
}
|
||||||
|
rlEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void EnableScissor(float x, float y, float width, float height) {
|
||||||
|
rlEnableScissorTest();
|
||||||
|
ImGuiIO &io = ImGui::GetIO();
|
||||||
|
|
||||||
|
ImVec2 scale = io.DisplayFramebufferScale;
|
||||||
|
#if !defined(__APPLE__)
|
||||||
|
if (!IsWindowState(FLAG_WINDOW_HIGHDPI)) {
|
||||||
|
scale.x = 1;
|
||||||
|
scale.y = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
rlScissor((int)(x * scale.x), int((io.DisplaySize.y - (int)(y + height)) * scale.y),
|
||||||
|
(int)(width * scale.x), (int)(height * scale.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetupMouseCursors(void) {
|
||||||
|
MouseCursorMap[ImGuiMouseCursor_Arrow] = MOUSE_CURSOR_ARROW;
|
||||||
|
MouseCursorMap[ImGuiMouseCursor_TextInput] = MOUSE_CURSOR_IBEAM;
|
||||||
|
MouseCursorMap[ImGuiMouseCursor_Hand] = MOUSE_CURSOR_POINTING_HAND;
|
||||||
|
MouseCursorMap[ImGuiMouseCursor_ResizeAll] = MOUSE_CURSOR_RESIZE_ALL;
|
||||||
|
MouseCursorMap[ImGuiMouseCursor_ResizeEW] = MOUSE_CURSOR_RESIZE_EW;
|
||||||
|
MouseCursorMap[ImGuiMouseCursor_ResizeNESW] = MOUSE_CURSOR_RESIZE_NESW;
|
||||||
|
MouseCursorMap[ImGuiMouseCursor_ResizeNS] = MOUSE_CURSOR_RESIZE_NS;
|
||||||
|
MouseCursorMap[ImGuiMouseCursor_ResizeNWSE] = MOUSE_CURSOR_RESIZE_NWSE;
|
||||||
|
MouseCursorMap[ImGuiMouseCursor_NotAllowed] = MOUSE_CURSOR_NOT_ALLOWED;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupFontAwesome(void) {
|
||||||
|
#ifndef NO_FONT_AWESOME
|
||||||
|
static const ImWchar icons_ranges[] = {ICON_MIN_FA, ICON_MAX_FA, 0};
|
||||||
|
ImFontConfig icons_config;
|
||||||
|
icons_config.MergeMode = true;
|
||||||
|
icons_config.PixelSnapH = true;
|
||||||
|
icons_config.FontDataOwnedByAtlas = false;
|
||||||
|
|
||||||
|
icons_config.GlyphMaxAdvanceX = std::numeric_limits<float>::max();
|
||||||
|
icons_config.RasterizerMultiply = 1.0f;
|
||||||
|
icons_config.OversampleH = 2;
|
||||||
|
icons_config.OversampleV = 1;
|
||||||
|
|
||||||
|
icons_config.GlyphRanges = icons_ranges;
|
||||||
|
|
||||||
|
ImGuiIO &io = ImGui::GetIO();
|
||||||
|
|
||||||
|
io.Fonts->AddFontFromMemoryCompressedTTF((void *)fa_solid_900_compressed_data,
|
||||||
|
fa_solid_900_compressed_size, FONT_AWESOME_ICON_SIZE,
|
||||||
|
&icons_config, icons_ranges);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupBackend(void) {
|
||||||
|
ImGuiIO &io = ImGui::GetIO();
|
||||||
|
io.BackendPlatformName = "imgui_impl_raylib";
|
||||||
|
io.BackendFlags |= ImGuiBackendFlags_HasGamepad | ImGuiBackendFlags_HasSetMousePos;
|
||||||
|
|
||||||
|
#ifndef PLATFORM_DRM
|
||||||
|
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
io.MousePos = ImVec2(0, 0);
|
||||||
|
|
||||||
|
ImGuiPlatformIO &platformIO = ImGui::GetPlatformIO();
|
||||||
|
|
||||||
|
platformIO.Platform_SetClipboardTextFn = SetClipTextCallback;
|
||||||
|
platformIO.Platform_GetClipboardTextFn = GetClipTextCallback;
|
||||||
|
|
||||||
|
platformIO.Platform_ClipboardUserData = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rlImGuiEndInitImGui(void) {
|
||||||
|
ImGui::SetCurrentContext(GlobalContext);
|
||||||
|
|
||||||
|
SetupFontAwesome();
|
||||||
|
|
||||||
|
SetupMouseCursors();
|
||||||
|
|
||||||
|
SetupBackend();
|
||||||
|
|
||||||
|
ReloadFonts();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetupKeymap(void) {
|
||||||
|
if (!RaylibKeyMap.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// build up a map of raylib keys to ImGuiKeys
|
||||||
|
RaylibKeyMap[KEY_APOSTROPHE] = ImGuiKey_Apostrophe;
|
||||||
|
RaylibKeyMap[KEY_COMMA] = ImGuiKey_Comma;
|
||||||
|
RaylibKeyMap[KEY_MINUS] = ImGuiKey_Minus;
|
||||||
|
RaylibKeyMap[KEY_PERIOD] = ImGuiKey_Period;
|
||||||
|
RaylibKeyMap[KEY_SLASH] = ImGuiKey_Slash;
|
||||||
|
RaylibKeyMap[KEY_ZERO] = ImGuiKey_0;
|
||||||
|
RaylibKeyMap[KEY_ONE] = ImGuiKey_1;
|
||||||
|
RaylibKeyMap[KEY_TWO] = ImGuiKey_2;
|
||||||
|
RaylibKeyMap[KEY_THREE] = ImGuiKey_3;
|
||||||
|
RaylibKeyMap[KEY_FOUR] = ImGuiKey_4;
|
||||||
|
RaylibKeyMap[KEY_FIVE] = ImGuiKey_5;
|
||||||
|
RaylibKeyMap[KEY_SIX] = ImGuiKey_6;
|
||||||
|
RaylibKeyMap[KEY_SEVEN] = ImGuiKey_7;
|
||||||
|
RaylibKeyMap[KEY_EIGHT] = ImGuiKey_8;
|
||||||
|
RaylibKeyMap[KEY_NINE] = ImGuiKey_9;
|
||||||
|
RaylibKeyMap[KEY_SEMICOLON] = ImGuiKey_Semicolon;
|
||||||
|
RaylibKeyMap[KEY_EQUAL] = ImGuiKey_Equal;
|
||||||
|
RaylibKeyMap[KEY_A] = ImGuiKey_A;
|
||||||
|
RaylibKeyMap[KEY_B] = ImGuiKey_B;
|
||||||
|
RaylibKeyMap[KEY_C] = ImGuiKey_C;
|
||||||
|
RaylibKeyMap[KEY_D] = ImGuiKey_D;
|
||||||
|
RaylibKeyMap[KEY_E] = ImGuiKey_E;
|
||||||
|
RaylibKeyMap[KEY_F] = ImGuiKey_F;
|
||||||
|
RaylibKeyMap[KEY_G] = ImGuiKey_G;
|
||||||
|
RaylibKeyMap[KEY_H] = ImGuiKey_H;
|
||||||
|
RaylibKeyMap[KEY_I] = ImGuiKey_I;
|
||||||
|
RaylibKeyMap[KEY_J] = ImGuiKey_J;
|
||||||
|
RaylibKeyMap[KEY_K] = ImGuiKey_K;
|
||||||
|
RaylibKeyMap[KEY_L] = ImGuiKey_L;
|
||||||
|
RaylibKeyMap[KEY_M] = ImGuiKey_M;
|
||||||
|
RaylibKeyMap[KEY_N] = ImGuiKey_N;
|
||||||
|
RaylibKeyMap[KEY_O] = ImGuiKey_O;
|
||||||
|
RaylibKeyMap[KEY_P] = ImGuiKey_P;
|
||||||
|
RaylibKeyMap[KEY_Q] = ImGuiKey_Q;
|
||||||
|
RaylibKeyMap[KEY_R] = ImGuiKey_R;
|
||||||
|
RaylibKeyMap[KEY_S] = ImGuiKey_S;
|
||||||
|
RaylibKeyMap[KEY_T] = ImGuiKey_T;
|
||||||
|
RaylibKeyMap[KEY_U] = ImGuiKey_U;
|
||||||
|
RaylibKeyMap[KEY_V] = ImGuiKey_V;
|
||||||
|
RaylibKeyMap[KEY_W] = ImGuiKey_W;
|
||||||
|
RaylibKeyMap[KEY_X] = ImGuiKey_X;
|
||||||
|
RaylibKeyMap[KEY_Y] = ImGuiKey_Y;
|
||||||
|
RaylibKeyMap[KEY_Z] = ImGuiKey_Z;
|
||||||
|
RaylibKeyMap[KEY_SPACE] = ImGuiKey_Space;
|
||||||
|
RaylibKeyMap[KEY_ESCAPE] = ImGuiKey_Escape;
|
||||||
|
RaylibKeyMap[KEY_ENTER] = ImGuiKey_Enter;
|
||||||
|
RaylibKeyMap[KEY_TAB] = ImGuiKey_Tab;
|
||||||
|
RaylibKeyMap[KEY_BACKSPACE] = ImGuiKey_Backspace;
|
||||||
|
RaylibKeyMap[KEY_INSERT] = ImGuiKey_Insert;
|
||||||
|
RaylibKeyMap[KEY_DELETE] = ImGuiKey_Delete;
|
||||||
|
RaylibKeyMap[KEY_RIGHT] = ImGuiKey_RightArrow;
|
||||||
|
RaylibKeyMap[KEY_LEFT] = ImGuiKey_LeftArrow;
|
||||||
|
RaylibKeyMap[KEY_DOWN] = ImGuiKey_DownArrow;
|
||||||
|
RaylibKeyMap[KEY_UP] = ImGuiKey_UpArrow;
|
||||||
|
RaylibKeyMap[KEY_PAGE_UP] = ImGuiKey_PageUp;
|
||||||
|
RaylibKeyMap[KEY_PAGE_DOWN] = ImGuiKey_PageDown;
|
||||||
|
RaylibKeyMap[KEY_HOME] = ImGuiKey_Home;
|
||||||
|
RaylibKeyMap[KEY_END] = ImGuiKey_End;
|
||||||
|
RaylibKeyMap[KEY_CAPS_LOCK] = ImGuiKey_CapsLock;
|
||||||
|
RaylibKeyMap[KEY_SCROLL_LOCK] = ImGuiKey_ScrollLock;
|
||||||
|
RaylibKeyMap[KEY_NUM_LOCK] = ImGuiKey_NumLock;
|
||||||
|
RaylibKeyMap[KEY_PRINT_SCREEN] = ImGuiKey_PrintScreen;
|
||||||
|
RaylibKeyMap[KEY_PAUSE] = ImGuiKey_Pause;
|
||||||
|
RaylibKeyMap[KEY_F1] = ImGuiKey_F1;
|
||||||
|
RaylibKeyMap[KEY_F2] = ImGuiKey_F2;
|
||||||
|
RaylibKeyMap[KEY_F3] = ImGuiKey_F3;
|
||||||
|
RaylibKeyMap[KEY_F4] = ImGuiKey_F4;
|
||||||
|
RaylibKeyMap[KEY_F5] = ImGuiKey_F5;
|
||||||
|
RaylibKeyMap[KEY_F6] = ImGuiKey_F6;
|
||||||
|
RaylibKeyMap[KEY_F7] = ImGuiKey_F7;
|
||||||
|
RaylibKeyMap[KEY_F8] = ImGuiKey_F8;
|
||||||
|
RaylibKeyMap[KEY_F9] = ImGuiKey_F9;
|
||||||
|
RaylibKeyMap[KEY_F10] = ImGuiKey_F10;
|
||||||
|
RaylibKeyMap[KEY_F11] = ImGuiKey_F11;
|
||||||
|
RaylibKeyMap[KEY_F12] = ImGuiKey_F12;
|
||||||
|
RaylibKeyMap[KEY_LEFT_SHIFT] = ImGuiKey_LeftShift;
|
||||||
|
RaylibKeyMap[KEY_LEFT_CONTROL] = ImGuiKey_LeftCtrl;
|
||||||
|
RaylibKeyMap[KEY_LEFT_ALT] = ImGuiKey_LeftAlt;
|
||||||
|
RaylibKeyMap[KEY_LEFT_SUPER] = ImGuiKey_LeftSuper;
|
||||||
|
RaylibKeyMap[KEY_RIGHT_SHIFT] = ImGuiKey_RightShift;
|
||||||
|
RaylibKeyMap[KEY_RIGHT_CONTROL] = ImGuiKey_RightCtrl;
|
||||||
|
RaylibKeyMap[KEY_RIGHT_ALT] = ImGuiKey_RightAlt;
|
||||||
|
RaylibKeyMap[KEY_RIGHT_SUPER] = ImGuiKey_RightSuper;
|
||||||
|
RaylibKeyMap[KEY_KB_MENU] = ImGuiKey_Menu;
|
||||||
|
RaylibKeyMap[KEY_LEFT_BRACKET] = ImGuiKey_LeftBracket;
|
||||||
|
RaylibKeyMap[KEY_BACKSLASH] = ImGuiKey_Backslash;
|
||||||
|
RaylibKeyMap[KEY_RIGHT_BRACKET] = ImGuiKey_RightBracket;
|
||||||
|
RaylibKeyMap[KEY_GRAVE] = ImGuiKey_GraveAccent;
|
||||||
|
RaylibKeyMap[KEY_KP_0] = ImGuiKey_Keypad0;
|
||||||
|
RaylibKeyMap[KEY_KP_1] = ImGuiKey_Keypad1;
|
||||||
|
RaylibKeyMap[KEY_KP_2] = ImGuiKey_Keypad2;
|
||||||
|
RaylibKeyMap[KEY_KP_3] = ImGuiKey_Keypad3;
|
||||||
|
RaylibKeyMap[KEY_KP_4] = ImGuiKey_Keypad4;
|
||||||
|
RaylibKeyMap[KEY_KP_5] = ImGuiKey_Keypad5;
|
||||||
|
RaylibKeyMap[KEY_KP_6] = ImGuiKey_Keypad6;
|
||||||
|
RaylibKeyMap[KEY_KP_7] = ImGuiKey_Keypad7;
|
||||||
|
RaylibKeyMap[KEY_KP_8] = ImGuiKey_Keypad8;
|
||||||
|
RaylibKeyMap[KEY_KP_9] = ImGuiKey_Keypad9;
|
||||||
|
RaylibKeyMap[KEY_KP_DECIMAL] = ImGuiKey_KeypadDecimal;
|
||||||
|
RaylibKeyMap[KEY_KP_DIVIDE] = ImGuiKey_KeypadDivide;
|
||||||
|
RaylibKeyMap[KEY_KP_MULTIPLY] = ImGuiKey_KeypadMultiply;
|
||||||
|
RaylibKeyMap[KEY_KP_SUBTRACT] = ImGuiKey_KeypadSubtract;
|
||||||
|
RaylibKeyMap[KEY_KP_ADD] = ImGuiKey_KeypadAdd;
|
||||||
|
RaylibKeyMap[KEY_KP_ENTER] = ImGuiKey_KeypadEnter;
|
||||||
|
RaylibKeyMap[KEY_KP_EQUAL] = ImGuiKey_KeypadEqual;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetupGlobals(void) {
|
||||||
|
LastFrameFocused = IsWindowFocused();
|
||||||
|
LastControlPressed = false;
|
||||||
|
LastShiftPressed = false;
|
||||||
|
LastAltPressed = false;
|
||||||
|
LastSuperPressed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rlImGuiBeginInitImGui(void) {
|
||||||
|
SetupGlobals();
|
||||||
|
if (GlobalContext == nullptr)
|
||||||
|
GlobalContext = ImGui::CreateContext(nullptr);
|
||||||
|
SetupKeymap();
|
||||||
|
|
||||||
|
ImGuiIO &io = ImGui::GetIO();
|
||||||
|
io.Fonts->AddFontDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
void rlImGuiSetup(bool dark) {
|
||||||
|
rlImGuiBeginInitImGui();
|
||||||
|
|
||||||
|
if (dark)
|
||||||
|
ImGui::StyleColorsDark();
|
||||||
|
else
|
||||||
|
ImGui::StyleColorsLight();
|
||||||
|
|
||||||
|
rlImGuiEndInitImGui();
|
||||||
|
}
|
||||||
|
|
||||||
|
void rlImGuiReloadFonts(void) {
|
||||||
|
ImGui::SetCurrentContext(GlobalContext);
|
||||||
|
|
||||||
|
ReloadFonts();
|
||||||
|
}
|
||||||
|
|
||||||
|
void rlImGuiBegin(void) {
|
||||||
|
ImGui::SetCurrentContext(GlobalContext);
|
||||||
|
rlImGuiBeginDelta(GetFrameTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
void rlImGuiBeginDelta(float deltaTime) {
|
||||||
|
ImGui::SetCurrentContext(GlobalContext);
|
||||||
|
|
||||||
|
ImGuiNewFrame(deltaTime);
|
||||||
|
ImGui_ImplRaylib_ProcessEvents();
|
||||||
|
ImGui::NewFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
void rlImGuiEnd(void) {
|
||||||
|
ImGui::SetCurrentContext(GlobalContext);
|
||||||
|
ImGui::Render();
|
||||||
|
ImGui_ImplRaylib_RenderDrawData(ImGui::GetDrawData());
|
||||||
|
}
|
||||||
|
|
||||||
|
void rlImGuiShutdown(void) {
|
||||||
|
if (GlobalContext == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ImGui::SetCurrentContext(GlobalContext);
|
||||||
|
ImGui_ImplRaylib_Shutdown();
|
||||||
|
|
||||||
|
ImGui::DestroyContext(GlobalContext);
|
||||||
|
GlobalContext = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rlImGuiImage(const Texture *image) {
|
||||||
|
if (!image)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (GlobalContext)
|
||||||
|
ImGui::SetCurrentContext(GlobalContext);
|
||||||
|
|
||||||
|
ImGui::Image((ImTextureID)image, ImVec2(float(image->width), float(image->height)));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool rlImGuiImageButton(const char *name, const Texture *image) {
|
||||||
|
if (!image)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (GlobalContext)
|
||||||
|
ImGui::SetCurrentContext(GlobalContext);
|
||||||
|
|
||||||
|
return ImGui::ImageButton(name, (ImTextureID)image,
|
||||||
|
ImVec2(float(image->width), float(image->height)));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool rlImGuiImageButtonSize(const char *name, const Texture *image, ImVec2 size) {
|
||||||
|
if (!image)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (GlobalContext)
|
||||||
|
ImGui::SetCurrentContext(GlobalContext);
|
||||||
|
|
||||||
|
return ImGui::ImageButton(name, (ImTextureID)image, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rlImGuiImageSize(const Texture *image, int width, int height) {
|
||||||
|
if (!image)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (GlobalContext)
|
||||||
|
ImGui::SetCurrentContext(GlobalContext);
|
||||||
|
|
||||||
|
ImGui::Image((ImTextureID)image, ImVec2(float(width), float(height)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void rlImGuiImageSizeV(const Texture *image, Vector2 size) {
|
||||||
|
if (!image)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (GlobalContext)
|
||||||
|
ImGui::SetCurrentContext(GlobalContext);
|
||||||
|
|
||||||
|
ImGui::Image((ImTextureID)image, ImVec2(size.x, size.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
void rlImGuiImageRect(const Texture *image, int destWidth, int destHeight, Rectangle sourceRect) {
|
||||||
|
if (!image)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (GlobalContext)
|
||||||
|
ImGui::SetCurrentContext(GlobalContext);
|
||||||
|
|
||||||
|
ImVec2 uv0;
|
||||||
|
ImVec2 uv1;
|
||||||
|
|
||||||
|
if (sourceRect.width < 0) {
|
||||||
|
uv0.x = -((float)sourceRect.x / image->width);
|
||||||
|
uv1.x = (uv0.x - (float)(fabs(sourceRect.width) / image->width));
|
||||||
|
} else {
|
||||||
|
uv0.x = (float)sourceRect.x / image->width;
|
||||||
|
uv1.x = uv0.x + (float)(sourceRect.width / image->width);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sourceRect.height < 0) {
|
||||||
|
uv0.y = -((float)sourceRect.y / image->height);
|
||||||
|
uv1.y = (uv0.y - (float)(fabs(sourceRect.height) / image->height));
|
||||||
|
} else {
|
||||||
|
uv0.y = (float)sourceRect.y / image->height;
|
||||||
|
uv1.y = uv0.y + (float)(sourceRect.height / image->height);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Image((ImTextureID)image, ImVec2(float(destWidth), float(destHeight)), uv0, uv1);
|
||||||
|
// ImGui::Image((ImTextureID)image, ImVec2(float(destWidth), float(destHeight)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void rlImGuiImageRenderTexture(const RenderTexture *image) {
|
||||||
|
if (!image)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (GlobalContext)
|
||||||
|
ImGui::SetCurrentContext(GlobalContext);
|
||||||
|
|
||||||
|
rlImGuiImageRect(&image->texture, image->texture.width, image->texture.height,
|
||||||
|
Rectangle{0, 0, float(image->texture.width), -float(image->texture.height)});
|
||||||
|
}
|
||||||
|
|
||||||
|
void rlImGuiImageRenderTextureFit(const RenderTexture *image, bool center) {
|
||||||
|
if (!image)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (GlobalContext)
|
||||||
|
ImGui::SetCurrentContext(GlobalContext);
|
||||||
|
|
||||||
|
ImVec2 area = ImGui::GetContentRegionAvail();
|
||||||
|
|
||||||
|
float scale = area.x / image->texture.width;
|
||||||
|
|
||||||
|
float y = image->texture.height * scale;
|
||||||
|
if (y > area.y) {
|
||||||
|
scale = area.y / image->texture.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sizeX = int(image->texture.width * scale);
|
||||||
|
int sizeY = int(image->texture.height * scale);
|
||||||
|
|
||||||
|
if (center) {
|
||||||
|
ImGui::SetCursorPosX(0);
|
||||||
|
ImGui::SetCursorPosX(area.x / 2 - sizeX / 2);
|
||||||
|
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + (area.y / 2 - sizeY / 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
rlImGuiImageRect(&image->texture, sizeX, sizeY,
|
||||||
|
Rectangle{0, 0, float(image->texture.width), -float(image->texture.height)});
|
||||||
|
}
|
||||||
|
|
||||||
|
// raw ImGui backend API
|
||||||
|
bool ImGui_ImplRaylib_Init(void) {
|
||||||
|
SetupGlobals();
|
||||||
|
|
||||||
|
SetupKeymap();
|
||||||
|
|
||||||
|
SetupMouseCursors();
|
||||||
|
|
||||||
|
SetupBackend();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplRaylib_BuildFontAtlas(void) {
|
||||||
|
ReloadFonts();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplRaylib_Shutdown() {
|
||||||
|
ImGuiIO &io = ImGui::GetIO();
|
||||||
|
Texture2D *fontTexture = (Texture2D *)io.Fonts->TexID;
|
||||||
|
|
||||||
|
if (fontTexture) {
|
||||||
|
UnloadTexture(*fontTexture);
|
||||||
|
MemFree(fontTexture);
|
||||||
|
}
|
||||||
|
|
||||||
|
io.Fonts->TexID = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplRaylib_NewFrame(void) {
|
||||||
|
ImGuiNewFrame(GetFrameTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplRaylib_RenderDrawData(ImDrawData *draw_data) {
|
||||||
|
rlDrawRenderBatchActive();
|
||||||
|
rlDisableBackfaceCulling();
|
||||||
|
|
||||||
|
for (int l = 0; l < draw_data->CmdListsCount; ++l) {
|
||||||
|
const ImDrawList *commandList = draw_data->CmdLists[l];
|
||||||
|
|
||||||
|
for (const auto &cmd : commandList->CmdBuffer) {
|
||||||
|
EnableScissor(cmd.ClipRect.x - draw_data->DisplayPos.x,
|
||||||
|
cmd.ClipRect.y - draw_data->DisplayPos.y,
|
||||||
|
cmd.ClipRect.z - (cmd.ClipRect.x - draw_data->DisplayPos.x),
|
||||||
|
cmd.ClipRect.w - (cmd.ClipRect.y - draw_data->DisplayPos.y));
|
||||||
|
if (cmd.UserCallback != nullptr) {
|
||||||
|
cmd.UserCallback(commandList, &cmd);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGuiRenderTriangles(cmd.ElemCount, cmd.IdxOffset, commandList->IdxBuffer,
|
||||||
|
commandList->VtxBuffer, (Texture2D *)cmd.TextureId);
|
||||||
|
rlDrawRenderBatchActive();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rlSetTexture(0);
|
||||||
|
rlDisableScissorTest();
|
||||||
|
rlEnableBackfaceCulling();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleGamepadButtonEvent(ImGuiIO &io, GamepadButton button, ImGuiKey key) {
|
||||||
|
if (IsGamepadButtonPressed(0, button))
|
||||||
|
io.AddKeyEvent(key, true);
|
||||||
|
else if (IsGamepadButtonReleased(0, button))
|
||||||
|
io.AddKeyEvent(key, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleGamepadStickEvent(ImGuiIO &io, GamepadAxis axis, ImGuiKey negKey, ImGuiKey posKey) {
|
||||||
|
constexpr float deadZone = 0.20f;
|
||||||
|
|
||||||
|
float axisValue = GetGamepadAxisMovement(0, axis);
|
||||||
|
|
||||||
|
io.AddKeyAnalogEvent(negKey, axisValue < -deadZone, axisValue < -deadZone ? -axisValue : 0);
|
||||||
|
io.AddKeyAnalogEvent(posKey, axisValue > deadZone, axisValue > deadZone ? axisValue : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImGui_ImplRaylib_ProcessEvents(void) {
|
||||||
|
ImGuiIO &io = ImGui::GetIO();
|
||||||
|
|
||||||
|
bool focused = IsWindowFocused();
|
||||||
|
if (focused != LastFrameFocused)
|
||||||
|
io.AddFocusEvent(focused);
|
||||||
|
LastFrameFocused = focused;
|
||||||
|
|
||||||
|
// handle the modifyer key events so that shortcuts work
|
||||||
|
bool ctrlDown = rlImGuiIsControlDown();
|
||||||
|
if (ctrlDown != LastControlPressed)
|
||||||
|
io.AddKeyEvent(ImGuiMod_Ctrl, ctrlDown);
|
||||||
|
LastControlPressed = ctrlDown;
|
||||||
|
|
||||||
|
bool shiftDown = rlImGuiIsShiftDown();
|
||||||
|
if (shiftDown != LastShiftPressed)
|
||||||
|
io.AddKeyEvent(ImGuiMod_Shift, shiftDown);
|
||||||
|
LastShiftPressed = shiftDown;
|
||||||
|
|
||||||
|
bool altDown = rlImGuiIsAltDown();
|
||||||
|
if (altDown != LastAltPressed)
|
||||||
|
io.AddKeyEvent(ImGuiMod_Alt, altDown);
|
||||||
|
LastAltPressed = altDown;
|
||||||
|
|
||||||
|
bool superDown = rlImGuiIsSuperDown();
|
||||||
|
if (superDown != LastSuperPressed)
|
||||||
|
io.AddKeyEvent(ImGuiMod_Super, superDown);
|
||||||
|
LastSuperPressed = superDown;
|
||||||
|
|
||||||
|
// walk the keymap and check for up and down events
|
||||||
|
for (const auto keyItr : RaylibKeyMap) {
|
||||||
|
if (IsKeyReleased(keyItr.first))
|
||||||
|
io.AddKeyEvent(keyItr.second, false);
|
||||||
|
else if (IsKeyPressed(keyItr.first))
|
||||||
|
io.AddKeyEvent(keyItr.second, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (io.WantCaptureKeyboard) {
|
||||||
|
// add the text input in order
|
||||||
|
unsigned int pressed = GetCharPressed();
|
||||||
|
while (pressed != 0) {
|
||||||
|
io.AddInputCharacter(pressed);
|
||||||
|
pressed = GetCharPressed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!io.WantSetMousePos) {
|
||||||
|
io.AddMousePosEvent((float)GetMouseX(), (float)GetMouseY());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto setMouseEvent = [&io](int rayMouse, int imGuiMouse) {
|
||||||
|
if (IsMouseButtonPressed(rayMouse))
|
||||||
|
io.AddMouseButtonEvent(imGuiMouse, true);
|
||||||
|
else if (IsMouseButtonReleased(rayMouse))
|
||||||
|
io.AddMouseButtonEvent(imGuiMouse, false);
|
||||||
|
};
|
||||||
|
|
||||||
|
setMouseEvent(MOUSE_BUTTON_LEFT, ImGuiMouseButton_Left);
|
||||||
|
setMouseEvent(MOUSE_BUTTON_RIGHT, ImGuiMouseButton_Right);
|
||||||
|
setMouseEvent(MOUSE_BUTTON_MIDDLE, ImGuiMouseButton_Middle);
|
||||||
|
setMouseEvent(MOUSE_BUTTON_FORWARD, ImGuiMouseButton_Middle + 1);
|
||||||
|
setMouseEvent(MOUSE_BUTTON_BACK, ImGuiMouseButton_Middle + 2);
|
||||||
|
|
||||||
|
{
|
||||||
|
Vector2 mouseWheel = GetMouseWheelMoveV();
|
||||||
|
io.AddMouseWheelEvent(mouseWheel.x, mouseWheel.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad && IsGamepadAvailable(0)) {
|
||||||
|
HandleGamepadButtonEvent(io, GAMEPAD_BUTTON_LEFT_FACE_UP, ImGuiKey_GamepadDpadUp);
|
||||||
|
HandleGamepadButtonEvent(io, GAMEPAD_BUTTON_LEFT_FACE_RIGHT, ImGuiKey_GamepadDpadRight);
|
||||||
|
HandleGamepadButtonEvent(io, GAMEPAD_BUTTON_LEFT_FACE_DOWN, ImGuiKey_GamepadDpadDown);
|
||||||
|
HandleGamepadButtonEvent(io, GAMEPAD_BUTTON_LEFT_FACE_LEFT, ImGuiKey_GamepadDpadLeft);
|
||||||
|
|
||||||
|
HandleGamepadButtonEvent(io, GAMEPAD_BUTTON_RIGHT_FACE_UP, ImGuiKey_GamepadFaceUp);
|
||||||
|
HandleGamepadButtonEvent(io, GAMEPAD_BUTTON_RIGHT_FACE_RIGHT, ImGuiKey_GamepadFaceLeft);
|
||||||
|
HandleGamepadButtonEvent(io, GAMEPAD_BUTTON_RIGHT_FACE_DOWN, ImGuiKey_GamepadFaceDown);
|
||||||
|
HandleGamepadButtonEvent(io, GAMEPAD_BUTTON_RIGHT_FACE_LEFT, ImGuiKey_GamepadFaceRight);
|
||||||
|
|
||||||
|
HandleGamepadButtonEvent(io, GAMEPAD_BUTTON_LEFT_TRIGGER_1, ImGuiKey_GamepadL1);
|
||||||
|
HandleGamepadButtonEvent(io, GAMEPAD_BUTTON_LEFT_TRIGGER_2, ImGuiKey_GamepadL2);
|
||||||
|
HandleGamepadButtonEvent(io, GAMEPAD_BUTTON_RIGHT_TRIGGER_1, ImGuiKey_GamepadR1);
|
||||||
|
HandleGamepadButtonEvent(io, GAMEPAD_BUTTON_RIGHT_TRIGGER_2, ImGuiKey_GamepadR2);
|
||||||
|
HandleGamepadButtonEvent(io, GAMEPAD_BUTTON_LEFT_THUMB, ImGuiKey_GamepadL3);
|
||||||
|
HandleGamepadButtonEvent(io, GAMEPAD_BUTTON_RIGHT_THUMB, ImGuiKey_GamepadR3);
|
||||||
|
|
||||||
|
HandleGamepadButtonEvent(io, GAMEPAD_BUTTON_MIDDLE_LEFT, ImGuiKey_GamepadStart);
|
||||||
|
HandleGamepadButtonEvent(io, GAMEPAD_BUTTON_MIDDLE_RIGHT, ImGuiKey_GamepadBack);
|
||||||
|
|
||||||
|
// left stick
|
||||||
|
HandleGamepadStickEvent(io, GAMEPAD_AXIS_LEFT_X, ImGuiKey_GamepadLStickLeft,
|
||||||
|
ImGuiKey_GamepadLStickRight);
|
||||||
|
HandleGamepadStickEvent(io, GAMEPAD_AXIS_LEFT_Y, ImGuiKey_GamepadLStickUp,
|
||||||
|
ImGuiKey_GamepadLStickDown);
|
||||||
|
|
||||||
|
// right stick
|
||||||
|
HandleGamepadStickEvent(io, GAMEPAD_AXIS_RIGHT_X, ImGuiKey_GamepadRStickLeft,
|
||||||
|
ImGuiKey_GamepadRStickRight);
|
||||||
|
HandleGamepadStickEvent(io, GAMEPAD_AXIS_RIGHT_Y, ImGuiKey_GamepadRStickUp,
|
||||||
|
ImGuiKey_GamepadRStickDown);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
200
src/rlImGui/rlImGui.h
Normal file
200
src/rlImGui/rlImGui.h
Normal file
|
@ -0,0 +1,200 @@
|
||||||
|
/**********************************************************************************************
|
||||||
|
*
|
||||||
|
* raylibExtras * Utilities and Shared Components for Raylib
|
||||||
|
*
|
||||||
|
* rlImGui * basic ImGui integration
|
||||||
|
*
|
||||||
|
* LICENSE: ZLIB
|
||||||
|
*
|
||||||
|
* Copyright (c) 2024 Jeffery Myers
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
**********************************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
// Function specifiers in case library is build/used as a shared library
|
||||||
|
// NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll
|
||||||
|
// NOTE: visibility("default") attribute makes symbols "visible" when compiled with -fvisibility=hidden
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#if defined(__TINYC__)
|
||||||
|
#define __declspec(x) __attribute__((x))
|
||||||
|
#endif
|
||||||
|
#if defined(BUILD_LIBTYPE_SHARED)
|
||||||
|
#define RLIMGUIAPI __declspec(dllexport) // We are building the library as a Win32 shared library (.dll)
|
||||||
|
#elif defined(USE_LIBTYPE_SHARED)
|
||||||
|
#define RLIMGUIAPI __declspec(dllimport) // We are using the library as a Win32 shared library (.dll)
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#if defined(BUILD_LIBTYPE_SHARED)
|
||||||
|
#define RLIMGUIAPI __attribute__((visibility("default"))) // We are building as a Unix shared library (.so/.dylib)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef RLIMGUIAPI
|
||||||
|
#define RLIMGUIAPI // Functions defined as 'extern' by default (implicit specifiers)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NO_FONT_AWESOME
|
||||||
|
#include "extras/IconsFontAwesome6.h"
|
||||||
|
#ifndef FONT_AWESOME_ICON_SIZE
|
||||||
|
#define FONT_AWESOME_ICON_SIZE 11
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// High level API. This API is designed in the style of raylib and meant to work with reaylib code.
|
||||||
|
// It will manage it's own ImGui context and call common ImGui functions (like NewFrame and Render) for you
|
||||||
|
// for a lower level API that matches the other ImGui platforms, please see imgui_impl_raylib.h
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets up ImGui, loads fonts and themes
|
||||||
|
/// Calls ImGui_ImplRaylib_Init and sets the theme. Will install Font awesome by default
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="darkTheme">when true(default) the dark theme is used, when false the light theme is used</param>
|
||||||
|
RLIMGUIAPI void rlImGuiSetup(bool darkTheme);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Starts a new ImGui Frame
|
||||||
|
/// Calls ImGui_ImplRaylib_NewFrame, ImGui_ImplRaylib_ProcessEvents, and ImGui::NewFrame together
|
||||||
|
/// </summary>
|
||||||
|
RLIMGUIAPI void rlImGuiBegin(void);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ends an ImGui frame and submits all ImGui drawing to raylib for processing.
|
||||||
|
/// Calls ImGui:Render, an d ImGui_ImplRaylib_RenderDrawData to draw to the current raylib render target
|
||||||
|
/// </summary>
|
||||||
|
RLIMGUIAPI void rlImGuiEnd(void);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Cleanup ImGui and unload font atlas
|
||||||
|
/// Calls ImGui_ImplRaylib_Shutdown
|
||||||
|
/// </summary>
|
||||||
|
RLIMGUIAPI void rlImGuiShutdown(void);
|
||||||
|
|
||||||
|
// Advanced StartupAPI
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Custom initialization. Not needed if you call rlImGuiSetup. Only needed if you want to add custom setup code.
|
||||||
|
/// must be followed by rlImGuiEndInitImGui
|
||||||
|
/// Called by ImGui_ImplRaylib_Init, and does the first part of setup, before fonts are rendered
|
||||||
|
/// </summary>
|
||||||
|
RLIMGUIAPI void rlImGuiBeginInitImGui(void);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// End Custom initialization. Not needed if you call rlImGuiSetup. Only needed if you want to add custom setup code.
|
||||||
|
/// must be proceeded by rlImGuiBeginInitImGui
|
||||||
|
/// Called by ImGui_ImplRaylib_Init and does the second part of setup, and renders fonts.
|
||||||
|
/// </summary>
|
||||||
|
RLIMGUIAPI void rlImGuiEndInitImGui(void);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Forces the font texture atlas to be recomputed and re-cached
|
||||||
|
/// </summary>
|
||||||
|
RLIMGUIAPI void rlImGuiReloadFonts(void);
|
||||||
|
|
||||||
|
// Advanced Update API
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Starts a new ImGui Frame with a specified delta time
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dt">delta time, any value < 0 will use raylib GetFrameTime</param>
|
||||||
|
RLIMGUIAPI void rlImGuiBeginDelta(float deltaTime);
|
||||||
|
|
||||||
|
// ImGui Image API extensions
|
||||||
|
// Purely for convenience in working with raylib textures as images.
|
||||||
|
// If you want to call ImGui image functions directly, simply pass them the pointer to the texture.
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Draw a texture as an image in an ImGui Context
|
||||||
|
/// Uses the current ImGui Cursor position and the full texture size.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="image">The raylib texture to draw</param>
|
||||||
|
RLIMGUIAPI void rlImGuiImage(const Texture *image);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Draw a texture as an image in an ImGui Context at a specific size
|
||||||
|
/// Uses the current ImGui Cursor position and the specified width and height
|
||||||
|
/// The image will be scaled up or down to fit as needed
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="image">The raylib texture to draw</param>
|
||||||
|
/// <param name="width">The width of the drawn image</param>
|
||||||
|
/// <param name="height">The height of the drawn image</param>
|
||||||
|
RLIMGUIAPI void rlImGuiImageSize(const Texture *image, int width, int height);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Draw a texture as an image in an ImGui Context at a specific size
|
||||||
|
/// Uses the current ImGui Cursor position and the specified size
|
||||||
|
/// The image will be scaled up or down to fit as needed
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="image">The raylib texture to draw</param>
|
||||||
|
/// <param name="size">The size of drawn image</param>
|
||||||
|
RLIMGUIAPI void rlImGuiImageSizeV(const Texture* image, Vector2 size);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Draw a portion texture as an image in an ImGui Context at a defined size
|
||||||
|
/// Uses the current ImGui Cursor position and the specified size
|
||||||
|
/// The image will be scaled up or down to fit as needed
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="image">The raylib texture to draw</param>
|
||||||
|
/// <param name="destWidth">The width of the drawn image</param>
|
||||||
|
/// <param name="destHeight">The height of the drawn image</param>
|
||||||
|
/// <param name="sourceRect">The portion of the texture to draw as an image. Negative values for the width and height will flip the image</param>
|
||||||
|
RLIMGUIAPI void rlImGuiImageRect(const Texture* image, int destWidth, int destHeight, Rectangle sourceRect);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Draws a render texture as an image an ImGui Context, automatically flipping the Y axis so it will show correctly on screen
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="image">The render texture to draw</param>
|
||||||
|
RLIMGUIAPI void rlImGuiImageRenderTexture(const RenderTexture* image);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Draws a render texture as an image an ImGui Context, automatically flipping the Y axis so it will show correctly on screen
|
||||||
|
/// Fits the render texture to the available content area
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="image">The render texture to draw</param>
|
||||||
|
/// <param name="center">When true the image will be centered in the content area</param>
|
||||||
|
RLIMGUIAPI void rlImGuiImageRenderTextureFit(const RenderTexture* image, bool center);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Draws a texture as an image button in an ImGui context. Uses the current ImGui cursor position and the full size of the texture
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">The display name and ImGui ID for the button</param>
|
||||||
|
/// <param name="image">The texture to draw</param>
|
||||||
|
/// <returns>True if the button was clicked</returns>
|
||||||
|
bool rlImGuiImageButton(const char* name, const Texture* image);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Draws a texture as an image button in an ImGui context. Uses the current ImGui cursor position and the specified size.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">The display name and ImGui ID for the button</param>
|
||||||
|
/// <param name="image">The texture to draw</param>
|
||||||
|
/// <param name="size">The size of the button</param>
|
||||||
|
/// <returns>True if the button was clicked</returns>
|
||||||
|
RLIMGUIAPI bool rlImGuiImageButtonSize(const char* name, const Texture* image, struct ImVec2 size);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
47
src/rlImGui/rlImGuiColors.h
Normal file
47
src/rlImGui/rlImGuiColors.h
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
/**********************************************************************************************
|
||||||
|
*
|
||||||
|
* raylibExtras * Utilities and Shared Components for Raylib
|
||||||
|
*
|
||||||
|
* rlImGui * basic ImGui integration
|
||||||
|
*
|
||||||
|
* LICENSE: ZLIB
|
||||||
|
*
|
||||||
|
* Copyright (c) 2024 Jeffery Myers
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
**********************************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
#include "imgui.h"
|
||||||
|
|
||||||
|
namespace rlImGuiColors
|
||||||
|
{
|
||||||
|
inline ImVec4 Convert(::Color color)
|
||||||
|
{
|
||||||
|
return ImVec4(color.r / 255.0f, color.g / 255.0f, color.b / 255.0f, color.a / 255.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ::Color Convert(ImVec4 color)
|
||||||
|
{
|
||||||
|
return ::Color{ (unsigned char)(color.x * 255.0f), (unsigned char)(color.y * 255.0f), (unsigned char)(color.z * 255.0f), (unsigned char)(color.w * 255.0f) };
|
||||||
|
}
|
||||||
|
}
|
5
src/testc.c
Normal file
5
src/testc.c
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void TestC() {
|
||||||
|
printf("TestC\n");
|
||||||
|
}
|
6
src/testc.h
Normal file
6
src/testc.h
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#ifndef TESTC_HEADER
|
||||||
|
#define TESTC_HEADER
|
||||||
|
|
||||||
|
void TestC();
|
||||||
|
|
||||||
|
#endif
|
7
src/testcpp.cpp
Normal file
7
src/testcpp.cpp
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
void TestCPPFunc() {
|
||||||
|
cout << "TestCPPFunc" << endl;
|
||||||
|
|
||||||
|
}
|
6
src/testcpp.hpp
Normal file
6
src/testcpp.hpp
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#ifndef TESTCPP_HEADER
|
||||||
|
#define TESTCPP_HEADER
|
||||||
|
|
||||||
|
void TestCPPFunc();
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue