Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions etc/plugins/TGuiFactory/P030_TRaylibGuiFactory.C
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
void P030_TRaylibGuiFactory()
{
gPluginMgr->AddHandler("TGuiFactory", "raylib", "ROOT::Experimental::TRaylibGuiFactory",
"ROOTRaylibCanvas", "TRaylibGuiFactory()");
}
2 changes: 2 additions & 0 deletions gui/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ add_subdirectory(guihtml)
add_subdirectory(recorder)
add_subdirectory(treemap)

add_subdirectory(raylibcanvas)

if(webgui)
if(cefweb)
add_subdirectory(cefdisplay)
Expand Down
90 changes: 90 additions & 0 deletions gui/raylibcanvas/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Copyright (C) 1995-2026, Rene Brun and Fons Rademakers.
# All rights reserved.
#
# For the licensing terms see $ROOTSYS/LICENSE.
# For the list of contributors see $ROOTSYS/README/CREDITS.

############################################################################
# CMakeLists.txt file for building ROOT gui/raylibcanvas package
############################################################################

# Find raylib - expects raylib.h in include path and libraylib.a/so on library path
# On Debian/Ubuntu: sudo apt-get install libraylib-dev
# On Arch: sudo pacman -S raylib
# Or build from source: https://github.com/raysan5/raylib

find_path(RAYLIB_INCLUDE_DIR raylib.h
PATHS /usr/include /usr/local/include /opt/raylib/include
DOC "raylib include directory")

find_library(RAYLIB_LIBRARY NAMES raylib raylib.lib libraylib.a libraylib.so
PATHS /usr/lib /usr/local/lib /opt/raylib/lib
DOC "raylib library path")

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(raylib
REQUIRED_VARS RAYLIB_LIBRARY RAYLIB_INCLUDE_DIR)

if(NOT RAYLIB_FOUND)
if(fail-on-missing)
message(FATAL_ERROR "Could NOT find raylib")
else()
message(WARNING "raylib not found, disabling option 'raylibcanvas'")
set(raylibcanv OFF CACHE BOOL "Disabled because raylib not found" FORCE)
return()
endif()
endif()

# Raylib links against GLFW, OpenGL, and platform libs
# On Linux: dl, rt, m, pthread, X11, GL
set(RAYLIB_LINK_LIBRARIES ${RAYLIB_LIBRARY})
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
find_library(GLFW_LIBRARY glfw HINTS /usr/lib /usr/local/lib)
find_library(X11_LIBRARY X11 HINTS /usr/lib /usr/local/lib)
find_library(GL_LIBRARY GL HINTS /usr/lib /usr/local/lib)
if(GLFW_LIBRARY)
list(APPEND RAYLIB_LINK_LIBRARIES ${GLFW_LIBRARY})
endif()
if(X11_LIBRARY)
list(APPEND RAYLIB_LINK_LIBRARIES ${X11_LIBRARY})
endif()
if(GL_LIBRARY)
list(APPEND RAYLIB_LINK_LIBRARIES ${GL_LIBRARY})
endif()
list(APPEND RAYLIB_LINK_LIBRARIES dl rt m pthread)
endif()

set(RAYLIB_IMPORTED_TARGET raylib::raylib)
if(NOT TARGET ${RAYLIB_IMPORTED_TARGET})
add_library(${RAYLIB_IMPORTED_TARGET} INTERFACE IMPORTED)
set_target_properties(${RAYLIB_IMPORTED_TARGET} PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${RAYLIB_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${RAYLIB_LINK_LIBRARIES}")
endif()

ROOT_STANDARD_LIBRARY_PACKAGE(ROOTRaylibCanvas
HEADERS
TRaylibCanvas.h
TRaylibPadPainter.h
TRaylibGuiFactory.h
SOURCES
src/TRaylibCanvas.cxx
src/TRaylibPadPainter.cxx
src/TRaylibGuiFactory.cxx
LIBRARIES
${RAYLIB_IMPORTED_TARGET}
DEPENDENCIES
Core
Gpad
)

target_include_directories(ROOTRaylibCanvas PRIVATE ${RAYLIB_INCLUDE_DIR})

# Platform-specific linker flags for raylib
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
target_link_options(ROOTRaylibCanvas PRIVATE -pthread)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
target_link_libraries(ROOTRaylibCanvas PRIVATE gdi32 winmm opengl32)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
target_link_libraries(ROOTRaylibCanvas PRIVATE "-framework Cocoa" "-framework IOKit" "-framework OpenGL")
endif()
14 changes: 14 additions & 0 deletions gui/raylibcanvas/inc/LinkDef.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#ifdef __CLING__

#pragma link off all globals;
#pragma link off all classes;
#pragma link off all functions;

// #pragma link C++ nestedclasses;
// #pragma link C++ nestedtypedefs;

#pragma link C++ class ROOT::Experimental::TRaylibCanvas+;
#pragma link C++ class ROOT::Experimental::TRaylibPadPainter+;
#pragma link C++ class ROOT::Experimental::TRaylibGuiFactory+;

#endif
106 changes: 106 additions & 0 deletions gui/raylibcanvas/inc/TRaylibCanvas.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// Author: Sergey Linev, GSI 06/08/2026

/*************************************************************************
* Copyright (C) 1995-2026, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/

#ifndef ROOT_TRaylibCanvas
#define ROOT_TRaylibCanvas

#include "TCanvasImp.h"
#include "TString.h"
#include <string>

class TTimer;

namespace ROOT {
namespace Experimental {

class TRaylibPadPainter;

/** \class TRaylibCanvas
\ingroup raylibcanvas
\brief TCanvasImp ABI implementation for raylib immediate-mode rendering

Manages a single raylib window. Each canvas shares the same window
(raylib limitation), with viewport switching via SetCameraMode().

The render loop runs via a TTimer callback that polls input events
and triggers BeginDrawing()/EndDrawing() frames.
*/
class TRaylibCanvas : public TCanvasImp {

protected:
Int_t fWindowWidth = 0; ///<! window width
Int_t fWindowHeight = 0; ///<! window height
Int_t fPosX = 0; ///<! window x position
Int_t fPosY = 0; ///<! window y position
Bool_t fResized = kTRUE; ///<! if window was resized
Bool_t fMenuBar = kTRUE; ///<! use of menu bar
Bool_t fStatusBar = kTRUE; ///<! use of status bar

std::string fWindowTitle; ///<! current window title

TString fStatusMessage;
int fFileMenuSelection = 0;
bool fFileDropdownOpen = false;

static void EnsureRaylibInitialized(int width, int height);

Bool_t PerformUpdate(Bool_t async) override;
TVirtualPadPainter *CreatePadPainter() override;

public:
TRaylibCanvas(TCanvas *c, const char *name, Int_t x, Int_t y, UInt_t width, UInt_t height);
~TRaylibCanvas() override;

// Window lifecycle
Int_t InitWindow() override;
void Close() override;
void Show() override;

// Geometry
UInt_t GetWindowGeometry(Int_t &x, Int_t &y, UInt_t &w, UInt_t &h) override;
void GetCanvasGeometry(Int_t wid, UInt_t &w, UInt_t &h) override;
void ResizeCanvasWindow(Int_t wid) override;
void UpdateDisplay(Int_t = 0, Bool_t = kFALSE) override;

// UI elements (noop — raylib draws them manually if needed)
void ShowMenuBar(Bool_t on = kTRUE) override { fMenuBar = on; fResized = kTRUE; }
void ShowStatusBar(Bool_t on = kTRUE) override { fStatusBar = on; fResized = kTRUE; }
void ShowEditor(Bool_t = kTRUE) override {}
void ShowToolBar(Bool_t = kTRUE) override {}
void ShowToolTips(Bool_t = kTRUE) override {}

void ForceUpdate() override;

void SetWindowPosition(Int_t x, Int_t y) override;
void SetWindowSize(UInt_t w, UInt_t h) override;
void SetWindowTitle(const char *newTitle) override;
void SetCanvasSize(UInt_t w, UInt_t h) override;
void Iconify() override;
void RaiseWindow() override;

Bool_t HasEditor() const override { return kFALSE; }
Bool_t HasMenuBar() const override { return fMenuBar; }
Bool_t HasStatusBar() const override { return fStatusBar; }
Bool_t HasToolBar() const override { return kFALSE; }
Bool_t HasToolTips() const override { return kFALSE; }

void RunRaylib();

// Static factory
static TCanvasImp *NewCanvas(TCanvas *c, const char *name, Int_t x, Int_t y,
UInt_t width, UInt_t height);

ClassDefOverride(TRaylibCanvas, 0) // raylib implementation for TCanvasImp
};

} // namespace Experimental
} // namespace ROOT

#endif
44 changes: 44 additions & 0 deletions gui/raylibcanvas/inc/TRaylibGuiFactory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Author: Sergey Linev, GSI 06/08/2026

/*************************************************************************
* Copyright (C) 1995-2026, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/

#ifndef ROOT_TRaylibGuiFactory
#define ROOT_TRaylibGuiFactory

#include "TGuiFactory.h"

namespace ROOT {
namespace Experimental {

/** \class TRaylibGuiFactory
\ingroup raylibcanvas

Factory for ROOT GUI components using raylib as the rendering backend.
Provides specialization for TCanvasImp class.
*/
class TRaylibGuiFactory : public TGuiFactory {

public:
TRaylibGuiFactory(const char *name = "raylib", const char *title = "ROOT Raylib Gui");
~TRaylibGuiFactory() override = default;

Bool_t UseVirtualX() const override { return kFALSE; }

TCanvasImp *CreateCanvasImp(TCanvas *c, const char *title,
UInt_t width, UInt_t height) override;
TCanvasImp *CreateCanvasImp(TCanvas *c, const char *title,
Int_t x, Int_t y, UInt_t width, UInt_t height) override;

ClassDefOverride(TRaylibGuiFactory, 0) // raylib gui factory
};

} // namespace Experimental
} // namespace ROOT

#endif
Loading
Loading