Skip to content
Merged
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
1 change: 1 addition & 0 deletions .github/workflows/root-ci-config/buildconfig/global.txt
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ pyroot=ON
pythia8=OFF
qt6web=OFF
qt6canv=OFF
gtk4canv=OFF
roofit=ON
root7=ON
rootbench=OFF
Expand Down
2 changes: 2 additions & 0 deletions cmake/modules/RootBuildOptions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ ROOT_BUILD_OPTION(opengl ON "Enable support for OpenGL (requires libGL and libGL
ROOT_BUILD_OPTION(pyroot ON "Enable support for automatic Python bindings (PyROOT)")
ROOT_BUILD_OPTION(pythia8 OFF "Enable support for Pythia 8.x [GPL]")
ROOT_BUILD_OPTION(qt6canv OFF "Enable Qt6 canvas (requires Qt6::Gui)")
ROOT_BUILD_OPTION(gtk4canv OFF "Enable GTK4 canvas (requires GTK4)")
ROOT_BUILD_OPTION(qt6web OFF "Enable support for Qt6 web-based display (requires Qt6::WebEngineCore and Qt6::WebEngineWidgets)")
ROOT_BUILD_OPTION(roofit ON "Build the advanced fitting package RooFit, and RooStats for statistical tests. If xml is available, also build HistFactory.")
ROOT_BUILD_OPTION(root7 ON "Build ROOT 7 experimental components of ROOT")
Expand Down Expand Up @@ -245,6 +246,7 @@ if(all)
set(pythia8_defvalue ON)
set(pyroot_defvalue ON)
set(qt6canv_defvalue ON)
set(gtk4canv_defvalue ON)
set(qt6web_defvalue ON)
set(r_defvalue ON)
set(roofit_defvalue ON)
Expand Down
5 changes: 5 additions & 0 deletions etc/plugins/TCanvasImp/P030_TGtk4Canvas.C
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
void P030_TGtk4Canvas()
{
gPluginMgr->AddHandler("TCanvasImp", "TGtk4Canvas", "ROOT::Experimental::TGtk4Canvas",
"ROOTGtk4Canvas", "NewCanvas(TCanvas *, const char *, Int_t, Int_t, UInt_t, UInt_t)");
}
5 changes: 5 additions & 0 deletions etc/plugins/TGuiFactory/P030_TGtk4GuiFactory.C
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
void P030_TGtk4GuiFactory()
{
gPluginMgr->AddHandler("TGuiFactory", "gtk4", "ROOT::Experimental::TGtk4GuiFactory",
"ROOTGtk4Canvas", "TGtk4GuiFactory()");
}
5 changes: 5 additions & 0 deletions etc/plugins/TVirtualPadEditor/P030_TGtk4GedEditor.C
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
void P030_TGtk4GedEditor()
{
gPluginMgr->AddHandler("TVirtualPadEditor", "gtk4", "ROOT::Experimental::TGtk4GedEditor",
"ROOTGtk4Canvas", "TGtk4GedEditor(TCanvas*)");
}
4 changes: 4 additions & 0 deletions gui/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ if(qt6canv)
add_subdirectory(qt6canvas)
endif()

if(gtk4canv)
add_subdirectory(gtk4canvas)
endif()

if(webgui)
if(cefweb)
add_subdirectory(cefdisplay)
Expand Down
46 changes: 46 additions & 0 deletions gui/gtk4canvas/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# 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/gtk4canvas package
############################################################################

find_package(PkgConfig)

pkg_check_modules(GTKMM REQUIRED IMPORTED_TARGET gtkmm-4.0)

if(NOT GTKMM_FOUND)
if(fail-on-missing)
message(FATAL_ERROR "Could NOT find gtkmm-4.0 components")
else()
message(WARNING "GTKMM not found, disabling option 'gtk4canv'")
set(gtk4canv OFF CACHE BOOL "Disabled because GTKMM not found" FORCE)
return()
endif()
endif()


ROOT_STANDARD_LIBRARY_PACKAGE(ROOTGtk4Canvas
HEADERS
TGtk4Canvas.h
TGtk4GuiFactory.h
TGtk4PadPainter.h
TGtk4GedEditor.h
SOURCES
Gtk4DrawArea.cxx
Gtk4CanvasWindow.cxx
Gtk4MethodDialog.cxx
TGtk4ContextMenu.cxx
TGtk4Canvas.cxx
TGtk4GuiFactory.cxx
TGtk4PadPainter.cxx
TGtk4GedEditor.cxx
LIBRARIES
PkgConfig::GTKMM
DEPENDENCIES
Core
Gpad
)
22 changes: 22 additions & 0 deletions gui/gtk4canvas/inc/LinkDef.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Author: Sergey Linev, GSI 12/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. *
*************************************************************************/

#ifdef __CLING__

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

#pragma link C++ class ROOT::Experimental::TGtk4Canvas+;
#pragma link C++ class ROOT::Experimental::TGtk4PadPainter+;
#pragma link C++ class ROOT::Experimental::TGtk4GuiFactory+;
#pragma link C++ class ROOT::Experimental::TGtk4GedEditor+;

#endif
84 changes: 84 additions & 0 deletions gui/gtk4canvas/inc/TGtk4Canvas.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Author: Sergey Linev, GSI 12/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_TGtk4Canvas
#define ROOT_TGtk4Canvas

#include "TCanvasImp.h"

class Gtk4CanvasWindow;
class Gtk4DrawArea;

namespace ROOT {
namespace Experimental {


class TGtk4Canvas : public TCanvasImp {

protected:

Gtk4CanvasWindow *fCanvasWindow = nullptr;
Gtk4DrawArea *fDrawArea = nullptr;

Bool_t fFixedSize = kFALSE; ///<! true when fixed-size canvas is configured
UInt_t fClientBits = 0; ///<! latest status bits from client like editor visible or not

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

void AssignStatusBits(UInt_t bits);


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

Gtk4DrawArea *GetDrawArea() const { return fDrawArea; }

Int_t InitWindow() override;
void Close() override;
void Show() override;

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) override {}
void UpdateDisplay(Int_t = 0, Bool_t = kFALSE) override {}

void ShowMenuBar(Bool_t = kTRUE) override { }
void ShowStatusBar(Bool_t = kTRUE) override { }
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 SetCursor(ECursor cursor) override;
void Iconify() override;
void RaiseWindow() override;

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

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

ClassDefOverride(TGtk4Canvas, 0) // Gtk4 implementation for TCanvasImp
};

} // namespace Experimental
} // namespace ROOT

#endif
105 changes: 105 additions & 0 deletions gui/gtk4canvas/inc/TGtk4GedEditor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// Author: Sergey Linev, GSI 30/10/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_TGtk4GedEditor
#define ROOT_TGtk4GedEditor

#include "TVirtualPadEditor.h"
#include "TQObject.h"

#include <functional>

class TVirtualPad;
class TAttMarker;
class TAttText;
class TAttLine;
class TAttFill;
class TClass;

class Gtk4MethodDialog;

namespace Gtk {
class DropDown;
class SpinButton;
class ColorDialogButton;
}


namespace ROOT {
namespace Experimental {

class TGtk4GedEditor : public TVirtualPadEditor, public TObject, public TQObject {

protected:

TCanvas *fCanvas = nullptr;
TVirtualPad *fPad = nullptr;
TObject *fModel = nullptr;
Bool_t fGlobal = kTRUE;

Gtk4MethodDialog *fDialog = nullptr;

TAttLine *fAttLine = nullptr;
TAttFill *fAttFill = nullptr;
TAttText *fAttText = nullptr;
TAttMarker *fAttMarker = nullptr;

Gtk::ColorDialogButton* m_line_color = nullptr;
Gtk::DropDown *m_line_style = nullptr;
Gtk::SpinButton *m_line_width = nullptr;

Gtk::ColorDialogButton* m_fill_color = nullptr;
Gtk::ColorDialogButton* m_text_color = nullptr;
Gtk::ColorDialogButton* m_marker_color = nullptr;

Int_t GetRootColor(Gtk::ColorDialogButton* btn);

void FillDialogsElements();

void ModifiedPad();

void FillGed(TClass *cl);

void on_ok_button_clicked();

public:

TGtk4GedEditor(TCanvas *c = nullptr);
virtual ~TGtk4GedEditor();

Bool_t IsGlobal() const override { return fGlobal; }
void SetGlobal(Bool_t on) override { fGlobal = on; }

TCanvas* GetCanvas() const override { return fCanvas; }

void ConnectToCanvas(TCanvas *c);
void DisconnectFromCanvas();
void SetCanvas(TCanvas *c);

void Show() override;
void Hide() override;

void RecursiveRemove(TObject* obj) override;

virtual void SetModel(TVirtualPad* pad, TObject* obj, Int_t event);

// specific editors
void AddTAttLine(TAttLine *);
void AddTAttFill(TAttFill *);
void AddTAttText(TAttText *);
void AddTAttMarker(TAttMarker *);

ClassDefOverride(TGtk4GedEditor, 0) // Implementation for Ged Editor with GTK4
};

} // namespace Experimental
} // namespace ROOT

#endif
41 changes: 41 additions & 0 deletions gui/gtk4canvas/inc/TGtk4GuiFactory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Author: Sergey Linev 12/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_TGtk4GuiFactory
#define ROOT_TGtk4GuiFactory

#include "TGuiFactory.h"

namespace ROOT {
namespace Experimental {

class TGtk4GuiFactory : public TGuiFactory {

public:
TGtk4GuiFactory(const char *name = "gtk4", const char *title = "ROOT Gtk4 GUI Factory");
~TGtk4GuiFactory() override {}

Bool_t UseVirtualX() const override { return kFALSE; }

TApplicationImp *CreateApplicationImp(const char *classname, int *argc, char **argv) override;

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;

TContextMenuImp *CreateContextMenuImp(TContextMenu *c, const char *name, const char *title) override;

ClassDefOverride(TGtk4GuiFactory,0) //Factory for Gtk4 GUI components
};

} // namespace Experimental
} // namespace ROOT


#endif
Loading
Loading