Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TGtk4Canvas.cxx
Go to the documentation of this file.
1// Author: Sergey Linev, GSI 12/08/2026
2
3/*************************************************************************
4 * Copyright (C) 1995-2026, Rene Brun and Fons Rademakers. *
5 * All rights reserved. *
6 * *
7 * For the licensing terms see $ROOTSYS/LICENSE. *
8 * For the list of contributors see $ROOTSYS/README/CREDITS. *
9 *************************************************************************/
10
11#include "TGtk4Canvas.h"
12
13#include "TGtk4PadPainter.h"
14
15#include "TSystem.h"
16#include "TStyle.h"
17#include "TCanvas.h"
18#include "TROOT.h"
19#include "TClass.h"
20
21#include <cstdio>
22#include <cstring>
23#include <iostream>
24#include <memory>
25
26#include <gtkmm.h>
27
28#include "Gtk4CanvasWindow.h"
29
30using namespace ROOT::Experimental;
31
32/** \class TGtk4Canvas
33 \ingroup gtk4canvas
34 \brief Basic TCanvasImp ABI implementation for Gtk4
35*/
36
37////////////////////////////////////////////////////////////////////////////////
38/// Constructor
39
40TGtk4Canvas::TGtk4Canvas(TCanvas *c, const char *name, Int_t x, Int_t y, UInt_t width, UInt_t height)
42{
43}
44
45////////////////////////////////////////////////////////////////////////////////
46/// Destructor
47
51
52////////////////////////////////////////////////////////////////////////////////
53/// Initialize window for the Gtk4 canvas
54
56{
57 return 111222333; // should not be used at all
58}
59
60////////////////////////////////////////////////////////////////////////////////
61/// Creates pad painter
62
67
68//////////////////////////////////////////////////////////////////////////////////////////
69/// Close canvas - not implemented
70
72{
73}
74
75//////////////////////////////////////////////////////////////////////////////////////////
76/// Show canvas
77
79{
80 if (fCanvasWindow)
81 fCanvasWindow->present();
82}
83
84//////////////////////////////////////////////////////////////////////////////////////////
85/// Returns kTRUE if web canvas has graphical editor
86
91
92//////////////////////////////////////////////////////////////////////////////////////////
93/// Returns kTRUE if web canvas has menu bar
94
96{
97 return (fClientBits & TCanvas::kMenuBar) != 0;
98}
99
100//////////////////////////////////////////////////////////////////////////////////////////
101/// Returns kTRUE if web canvas has status bar
102
107
108//////////////////////////////////////////////////////////////////////////////////////////
109/// Returns kTRUE if tooltips are activated in web canvas
110
115
116//////////////////////////////////////////////////////////////////////////////////////////
117/// Set window position of web canvas
118
120{
121 // not directly possible in gtk4
122 //if (fCanvasWindow)
123 // fCanvasWindow->move(x, y);
124}
125
126//////////////////////////////////////////////////////////////////////////////////////////
127/// Set window size of web canvas
128
130{
131 if (fCanvasWindow)
132 fCanvasWindow->set_default_size(w, h);
133}
134
135//////////////////////////////////////////////////////////////////////////////////////////
136/// Set window title of web canvas
137
138void TGtk4Canvas::SetWindowTitle(const char *newTitle)
139{
140 if (fCanvasWindow)
141 fCanvasWindow->set_title(newTitle);
142}
143
144//////////////////////////////////////////////////////////////////////////////////////////
145/// Set fixed canvas size - not supported yet in gtk
146
148{
150 if ((cw > 0) && (ch > 0)) {
151 // Canvas()->fCw = cw;
152 // Canvas()->fCh = ch;
153 } else {
154 // temporary value, will be reported back from client
155 // Canvas()->fCw = Canvas()->fWindowWidth;
156 // Canvas()->fCh = Canvas()->fWindowHeight;
157 }
158}
159
160//////////////////////////////////////////////////////////////////////////
161/// Set cursor
162
164{
165 const char *id = nullptr;
166 switch(cursor) {
167 case kBottomLeft: id = "sw-resize"; break;
168 case kBottomRight: id = "se-resize"; break;
169 case kTopLeft: id = "nw-resize"; break;
170 case kTopRight: id = "ne-resize"; break;
171 case kBottomSide: id = "s-resize"; break;
172 case kLeftSide: id = "w-resize"; break;
173 case kTopSide: id = "n-resize"; break;
174 case kRightSide: id = "r-resize"; break;
175 case kMove: id = "move"; break;
176 case kCross: id = "crosshair"; break;
177 case kArrowHor: id = "ns-resize"; break;
178 case kArrowVer: id = "ew-resize"; break;
179 case kHand: id = "grab"; break;
180 case kRotate: id = "grab"; break;
181 case kPointer: id = "pointer"; break;
182 case kArrowRight: id = "ew-resize"; break;
183 case kCaret: id = "text"; break;
184 case kWatch: id = "wait"; break;
185 case kNoDrop: id = "no-drop"; break;
186 default: id = "default"; break;
187 }
188 if (id && fDrawArea)
189 fDrawArea->set_cursor(id);
190}
191
192
193
194//////////////////////////////////////////////////////////////////////////////////////////
195/// Iconify browser window
196
198{
199 if (fCanvasWindow)
200 fCanvasWindow->minimize();
201}
202
203//////////////////////////////////////////////////////////////////////////////////////////
204/// Raise browser window
205
207{
208 if (fCanvasWindow)
209 fCanvasWindow->present();
210}
211
212//////////////////////////////////////////////////////////////////////////////////////////
213/// Assign clients bits
214
224
225//////////////////////////////////////////////////////////////////////////////////////////
226/// Returns canvas geometry
227
229{
230 (void) wid;
231 if (fDrawArea) {
232 w = fDrawArea->get_width();
233 h = fDrawArea->get_height();
234 } else {
235 w = 780;
236 h = 580;
237 }
238 // printf("CanvasGeometry %u %u\n", w, h);
239}
240
241
242//////////////////////////////////////////////////////////////////////////////////////////
243/// Returns window geometry including borders and menus
244
246{
247 if (fCanvasWindow) {
248 // gtk4 does not deliver position
249 x = y = 0;
250 w = fCanvasWindow->get_width();
251 h = fCanvasWindow->get_height();
252 } else {
253 x = y = 0;
254 w = 800;
255 h = 600;
256 }
257
258 // printf("WindowGeometry %u %u\n", w, h);
259
260 return 0;
261}
262
263//////////////////////////////////////////////////////////////////////////////////////////
264/// if canvas or any subpad was modified,
265/// invoke gtk4 queue_draw() which will trigger redraw area
266
268{
269 if (!Canvas()->IsAnyNeedRepaint() || !fDrawArea)
270 return kTRUE;
271
272 fDrawArea->queue_draw();
273
274 if (!async) {
275 auto display = fDrawArea->get_display();
276 if (display) {
277 // Flushes all render requests and locks the local thread
278 // until the windowing manager acknowledges processing complete.
279 display->sync();
280 }
281 }
282
283 return kTRUE;
284}
285
286//////////////////////////////////////////////////////////////////////////////////////////
287/// Increment canvas version and force sending data to client - do not wait for reply
288
290{
291 if (fDrawArea)
292 fDrawArea->queue_draw();
293}
294
295
296Glib::RefPtr<Glib::MainContext> gt4k_context;
297Glib::RefPtr<Gtk::Application> gt4k_app;
298
299class TGtk4Timer : public TTimer {
300public:
302 TTimer(milliSec, mode) {}
303
304 void Timeout() override
305 {
306 // just flush all events,
307 // false - do not wait/sleep for next mouse events, just exit
308 while (gt4k_context->pending())
309 gt4k_context->iteration(false);
310 }
311
312};
313
314
315//////////////////////////////////////////////////////////////////////////////////////////////////
316/// Static method to create TGtk4Canvas instance
317/// Used by plugin manager to directly create TGtk4Canvas without gui factory
318
320{
321 static TGtk4Timer *timer = nullptr;
322 if (!timer) {
323
324 Glib::init();
325
326 gt4k_app = Gtk::Application::create("org.example.customloop");
327
328 gt4k_context = Glib::MainContext::get_default();
329
330 timer = new TGtk4Timer(5, kTRUE);
331 timer->TurnOn();
332 }
333
334 auto widget = new Gtk4CanvasWindow(c, width, height);
335
336 auto draw_area = widget->GetDrawArea();
337
338 draw_area->queue_draw();
339
340 widget->present();
341
342 // workaround to let gtk4 time for first rendering of the widget
343 int cnt = 100;
344 while (cnt-- > 0 && (draw_area->get_width() == 0)) {
345 while (gt4k_context->pending())
346 gt4k_context->iteration(false);
347 }
348
349
350 auto imp = new TGtk4Canvas(c, name, x, y, width, height);
351
352 imp->fCanvasWindow = widget;
353 imp->fDrawArea = draw_area;
354
355 // now can set canvas
356 draw_area->SetCanvas(c);
357 draw_area->queue_draw(); // request to update painting
358
359 // set all internal dimensions
360 // c->Resize();
361
362
363 // TODO: maybe apply same logic to adjust canvas dimension as in TRootCanvas
364 // Keep commented code here intentionally to be able find this place when
365 // search for correspondent class members
366
367 // c->fWindowTopX = x;
368 // c->fWindowTopY = y;
369 // c->fWindowWidth = width;
370 // c->fWindowHeight = height;
371 // if (!gROOT->IsBatch() && (height > 25))
372 // height -= 25;
373 // c->fCw = width;
374 // c->fCh = height;
375
376 return imp;
377}
ECursor
Definition GuiTypes.h:373
@ kRightSide
Definition GuiTypes.h:374
@ kBottomSide
Definition GuiTypes.h:374
@ kArrowRight
Definition GuiTypes.h:376
@ kTopLeft
Definition GuiTypes.h:373
@ kBottomRight
Definition GuiTypes.h:373
@ kArrowVer
Definition GuiTypes.h:375
@ kCaret
Definition GuiTypes.h:376
@ kTopSide
Definition GuiTypes.h:374
@ kLeftSide
Definition GuiTypes.h:374
@ kWatch
Definition GuiTypes.h:376
@ kMove
Definition GuiTypes.h:375
@ kTopRight
Definition GuiTypes.h:373
@ kBottomLeft
Definition GuiTypes.h:373
@ kHand
Definition GuiTypes.h:375
@ kCross
Definition GuiTypes.h:375
@ kRotate
Definition GuiTypes.h:375
@ kNoDrop
Definition GuiTypes.h:376
@ kArrowHor
Definition GuiTypes.h:375
@ kPointer
Definition GuiTypes.h:376
#define c(i)
Definition RSha256.hxx:101
#define h(i)
Definition RSha256.hxx:106
long Long_t
Signed long integer 4 bytes (long). Size depends on architecture.
Definition RtypesCore.h:69
constexpr Bool_t kTRUE
Definition RtypesCore.h:108
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t cursor
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize wid
Option_t Option_t TPoint TPoint const char mode
Option_t Option_t width
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t height
char name[80]
Definition TGX11.cxx:142
Glib::RefPtr< Gtk::Application > gt4k_app
Glib::RefPtr< Glib::MainContext > gt4k_context
Int_t InitWindow() override
Initialize window for the Gtk4 canvas.
void Show() override
Show canvas.
void GetCanvasGeometry(Int_t wid, UInt_t &w, UInt_t &h) override
Returns canvas geometry.
Bool_t HasStatusBar() const override
Returns kTRUE if web canvas has status bar.
void RaiseWindow() override
Raise browser window.
void AssignStatusBits(UInt_t bits)
Assign clients bits.
TGtk4Canvas(TCanvas *c, const char *name, Int_t x, Int_t y, UInt_t width, UInt_t height)
Constructor.
Bool_t HasToolTips() const override
Returns kTRUE if tooltips are activated in web canvas.
void Close() override
Close canvas - not implemented.
Bool_t HasEditor() const override
Returns kTRUE if web canvas has graphical editor.
void Iconify() override
Iconify browser window.
static TCanvasImp * NewCanvas(TCanvas *c, const char *name, Int_t x, Int_t y, UInt_t width, UInt_t height)
Static method to create TGtk4Canvas instance Used by plugin manager to directly create TGtk4Canvas wi...
~TGtk4Canvas() override
Destructor.
UInt_t GetWindowGeometry(Int_t &x, Int_t &y, UInt_t &w, UInt_t &h) override
Returns window geometry including borders and menus.
UInt_t fClientBits
! latest status bits from client like editor visible or not
Definition TGtk4Canvas.h:31
void SetWindowPosition(Int_t x, Int_t y) override
Set window position of web canvas.
Bool_t HasMenuBar() const override
Returns kTRUE if web canvas has menu bar.
void ForceUpdate() override
Increment canvas version and force sending data to client - do not wait for reply.
void SetWindowTitle(const char *newTitle) override
Set window title of web canvas.
Gtk4CanvasWindow * fCanvasWindow
Definition TGtk4Canvas.h:27
TVirtualPadPainter * CreatePadPainter() override
Creates pad painter.
Bool_t fFixedSize
! true when fixed-size canvas is configured
Definition TGtk4Canvas.h:30
void SetCanvasSize(UInt_t w, UInt_t h) override
Set fixed canvas size - not supported yet in gtk.
void SetWindowSize(UInt_t w, UInt_t h) override
Set window size of web canvas.
void SetCursor(ECursor cursor) override
Set cursor.
Bool_t PerformUpdate(Bool_t async) override
if canvas or any subpad was modified, invoke gtk4 queue_draw() which will trigger redraw area
ABC describing GUI independent main window (with menubar, scrollbars and a drawing area).
Definition TCanvasImp.h:31
TCanvas * Canvas() const
Definition TCanvasImp.h:59
The Canvas class.
Definition TCanvas.h:23
@ kShowToolTips
Definition TCanvas.h:102
@ kShowToolBar
Definition TCanvas.h:97
@ kShowEventStatus
Definition TCanvas.h:94
@ kMenuBar
Definition TCanvas.h:96
@ kShowEditor
Definition TCanvas.h:98
TGtk4Timer(Long_t milliSec, Bool_t mode)
void Timeout() override
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:886
Handles synchronous and a-synchronous timer events.
Definition TTimer.h:51
virtual void TurnOn()
Add the timer to the system timer list.
Definition TTimer.cxx:246
To make it possible to use GL for 2D graphic in a TPad/TCanvas.
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
Namespace for ROOT features in testing.
Definition TROOT.h:100