first
This commit is contained in:
commit
0135d84443
44 changed files with 19813 additions and 0 deletions
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.
|
||||

|
||||
|
||||
|
||||
## 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.
|
||||

|
||||
|
||||
# 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;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue