Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
Gtk4CanvasWindow.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/* gtkmm example Copyright (C) 2002 gtkmm development team
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, see <https://www.gnu.org/licenses/>.
25 */
26
27#include "Gtk4CanvasWindow.h"
28
29#include <gtkmm.h>
30
31#include <iostream>
32#include <filesystem>
33
34#include "TROOT.h"
35#include "TTimer.h"
36#include "TFile.h"
37#include "TCanvas.h"
38#include "TError.h"
39#include "TApplication.h"
40
41
46
48 const char *fPixmap;
49 const char *fTipText;
52 void *fButton;
53};
54
56 // { filename, tooltip, staydown, id, button}
57 { "newcanvas.xpm", "New", kFALSE, kFileNewCanvas, 0 },
58 { "open.xpm", "Open", kFALSE, kFileOpen, 0 },
59 { "save.xpm", "Save As", kFALSE, kFileSaveAs, 0 },
60 { "printer.xpm", "Print", kFALSE, kFilePrint, 0 },
61 { "", "", kFALSE, -1, 0 },
62 { "interrupt.xpm", "Interrupt", kFALSE, kOptionInterrupt,0 },
63 { "refresh2.xpm", "Refresh", kFALSE, kOptionRefresh, 0 },
64 { "", "", kFALSE, -1, 0 },
65 { "inspect.xpm", "Inspect", kFALSE, kInspectRoot, 0 },
66// { "browser.xpm", "Browser", kFALSE, kToolsBrowser, 0 },
67 { "", "", kFALSE, -1, 0 },
68 { "pointer.xpm", "Modify", kFALSE, kToolModify, 0 },
69 { "arc.xpm", "Arc", kFALSE, kToolArc, 0 },
70 { "line.xpm", "Line", kFALSE, kToolLine, 0 },
71 { "arrow.xpm", "Arrow", kFALSE, kToolArrow, 0 },
72 { "diamond.xpm", "Diamond", kFALSE, kToolDiamond, 0 },
73 { "ellipse.xpm", "Ellipse", kFALSE, kToolEllipse, 0 },
74 { "pad.xpm", "Pad", kFALSE, kToolPad, 0 },
75 { "pave.xpm", "Pave", kFALSE, kToolPave, 0 },
76 { "pavelabel.xpm", "Pave Label", kFALSE, kToolPLabel, 0 },
77 { "pavetext.xpm", "Pave Text", kFALSE, kToolPText, 0 },
78 { "pavestext.xpm", "Paves Text", kFALSE, kToolPsText, 0 },
79 { "graph.xpm", "Graph", kFALSE, kToolGraph, 0 },
80 { "curlyline.xpm", "Curly Line", kFALSE, kToolCurlyLine, 0 },
81 { "curlyarc.xpm", "Curly Arc", kFALSE, kToolCurlyArc, 0 },
82 { "latex.xpm", "Text/Latex", kFALSE, kToolLatex, 0 },
83 { "marker.xpm", "Marker", kFALSE, kToolMarker, 0 },
84 { "cut.xpm", "Graphical Cut", kFALSE, kToolCutG, 0 },
85 { 0, 0, kFALSE, 0, 0 }
86};
87
88
89
90/** \class Gtk4CanvasWindow
91 \ingroup gtk4canvas
92*/
93
94
96: m_Box(Gtk::Orientation::VERTICAL),
97 m_ToolBar(Gtk::Orientation::HORIZONTAL, 4)
98{
99 set_title("canvas widget");
100 set_default_size(width, height);
101
102 set_child(m_Box); //We can put a MenuBar at the top of the box and other stuff below it.
103
104 // all actions used with canvas
105
106
107 fillMenuBar(canv);
108
109 fillToolBar();
110
111 m_ToolBar.set_visible(canv->TestBit(TCanvas::kShowToolBar));
112 m_Box.append(m_ToolBar);
113
114 m_DrawArea.set_has_tooltip(canv->TestBit(TCanvas::kShowToolTips));
115 m_DrawArea.set_hexpand(true);
116 m_DrawArea.set_vexpand(true);
117 m_Box.append(m_DrawArea);
118
119 m_DrawArea.status_changed().connect(sigc::mem_fun(*this, &Gtk4CanvasWindow::on_status_changed));
120
121 fContextId = m_StatusBar.get_context_id("main_status");
122 m_StatusBar.push("Ready to draw", fContextId);
124 m_Box.append(m_StatusBar);
125}
126
130
131////////////////////////////////////////////////////////////////////////////////
132/// Fill or update canvas save menu
133/// Only performed when canvas name is changed
134
136{
137 std::string name = canv ? canv->GetName() : "";
138 if (name.empty())
139 name = "c1";
140
141 if (fCanvasFileName == name)
142 return;
143
145
146 fSaveMenu->remove_all();
147
148 auto &fmts = GetSupportedFileFormats();
149 R__ASSERT(fmts.size() % 3 == 0);
150 for (std::size_t p = 0; p < fmts.size(); p += 3) {
151 std::string ext = fmts[p+1];
152 // cannot define filters with same extension - cannot distinguish which was selected
153 if ((ext != "C") && (ext != fmts[p + 2]))
154 continue;
155 fSaveMenu->append(fCanvasFileName + "." + ext, "canvas.save_" + ext);
156 }
157}
158
160{
161 m_action_group = Gio::SimpleActionGroup::create();
162
163 m_action_group->add_action("new", []() { std::cout << "New canvas Clicked!\n"; });
164 m_action_group->add_action("open", [this]() { on_openRootFile(); });
165 m_action_group->add_action("saveas", [this]() { on_saveCanvasAs(); });
166
167 auto &fmts = GetSupportedFileFormats();
168 R__ASSERT(fmts.size() % 3 == 0);
169 for (std::size_t p = 0; p < fmts.size(); p += 3) {
170 std::string ext = fmts[p+1];
171 std::string opt = fmts[p+2];
172 // cannot define filters with same extension - cannot distinguish which was selected
173 if ((ext != "C") && (ext != opt))
174 continue;
175 m_action_group->add_action("save_" + ext, [this, ext, opt]() { on_saveCanvas(ext, opt); });
176 }
177
178 m_action_group->add_action("close", [this]() { close(); });
179 m_action_group->add_action("quit", []() {
180 gROOT->SetInterrupt(kTRUE);
181
182 if (gApplication)
183 TTimer::SingleShot(100, "TApplication", gApplication, "Terminate()");
184 });
185
186 bool isShowToolbar = canv->TestBit(TCanvas::kShowToolBar);
187
188 bool isShowEventStatus = canv->TestBit(TCanvas::kShowEventStatus);
189
190 bool isShowToolTips = canv->TestBit(TCanvas::kShowToolTips);
191
192 bool isShowMenuBar = canv->TestBit(TCanvas::kMenuBar);
193
194 auto toggle_toolbar = Gio::SimpleAction::create_bool("show-toolbar", isShowToolbar);
195 toggle_toolbar->signal_change_state().connect(sigc::mem_fun(*this, &Gtk4CanvasWindow::on_show_toolbar_changed));
196 m_action_group->add_action(toggle_toolbar);
197
198 auto toggle_statusbar = Gio::SimpleAction::create_bool("show-eventstatus", isShowEventStatus);
199 toggle_statusbar->signal_change_state().connect(sigc::mem_fun(*this, &Gtk4CanvasWindow::on_show_eventstatus_changed));
200 m_action_group->add_action(toggle_statusbar);
201
202 auto toggle_tooltip = Gio::SimpleAction::create_bool("show-tooltip", isShowToolTips);
203 toggle_tooltip->signal_change_state().connect(sigc::mem_fun(*this, &Gtk4CanvasWindow::on_show_tooltip_changed));
204 m_action_group->add_action(toggle_tooltip);
205
206
207 // Bind actions to an identifier prefix name string ("win.new", "win.copy", etc.)
208 insert_action_group("canvas", m_action_group);
209
210 // 3. Construct the Abstract Menu Tree Model
211 auto menu_model = Gio::Menu::create();
212
213
214 // --- SECTION "File"
215
216 auto sec1 = Gio::Menu::create();
217 sec1->append("New Canvas", "canvas.new");
218 sec1->append("Open", "canvas.open");
219 sec1->append("Close Canvas", "canvas.close");
220
221 auto sec2 = Gio::Menu::create();
222
223 fSaveMenu = Gio::Menu::create();
224 fillSaveMenu(canv);
225 sec2->append_submenu("Save", fSaveMenu);
226 sec2->append("Save as...", "canvas.saveas");
227
228 auto sec3 = Gio::Menu::create();
229 sec3->append("Quit ROOT", "canvas.quit");
230
231 auto file_menu = Gio::Menu::create();
232 file_menu->append_section(sec1);
233 file_menu->append_section(sec2);
234 file_menu->append_section(sec3);
235
236 // Attach File structure onto root Menu Model Bar
237 menu_model->append_submenu("File", file_menu);
238
239
240 // --- SECTION "Edit"
241 auto edit_menu = Gio::Menu::create();
242 edit_menu->append("Clear pad", "canvas.clearpad");
243 edit_menu->append("Clear canvas", "canvas.clearcanvas");
244
245 // CREATE A SUB-MENU ITEM (Nested Layer)
246 auto special_paste_submenu = Gio::Menu::create();
247 special_paste_submenu->append("Paste Text Only", "canvas.paste");
248 special_paste_submenu->append("Paste with Formatting", "canvas.paste");
249
250 // Nest the submenu inside the parent Edit menu container
251 edit_menu->append_submenu("Paste Special...", special_paste_submenu);
252
253 // Attach Edit structure onto root Menu Model Bar
254 menu_model->append_submenu("Edit", edit_menu);
255
256
257 // --- SECTION "View"
258 auto view_menu = Gio::Menu::create();
259 view_menu->append("Editor", "canvas.show-editor");
260 view_menu->append("Toolbar", "canvas.show-toolbar");
261 view_menu->append("Event Status", "canvas.show-eventstatus");
262 view_menu->append("Tooltip", "canvas.show-tooltip");
263
264 menu_model->append_submenu("View", view_menu);
265
266 // 4. Instantiate the PopoverMenuBar from our structured menu tree
267 // Gtk::PopoverMenuBar requires a Glib::RefPtr<Gio::MenuModel>
268 auto menu_bar = Gtk::make_managed<Gtk::PopoverMenuBar>(menu_model);
269
270 menu_bar->set_visible(isShowMenuBar);
271
272 menu_bar->signal_state_flags_changed().connect([this](Gtk::StateFlags) {
274 });
275
276 m_Box.append(*menu_bar);
277}
278
279
280Gtk::Image* create_resized_xpm_image(const char *filename)
281{
282 // 2. Initialize a pointer for our final texture image
283 Glib::RefPtr<Gdk::Texture> texture;
284
285 try {
286 // Load the original XPM file safely into a Pixbuf
287 auto original_pixbuf = Gdk::Pixbuf::create_from_file(filename);
288
289 // Force-resize the XPM image to precisely 16x16 using Bilinear interpolation
290 auto scaled_pixbuf = original_pixbuf->scale_simple(16, 16, Gdk::InterpType::BILINEAR);
291
292 // Convert the scaled Pixbuf into a GTK4 Paintable Texture
293 texture = Gdk::Texture::create_for_pixbuf(scaled_pixbuf);
294
295 } catch (const Glib::FileError& e) {
296 std::cerr << "File system error: " << e.what() << std::endl;
297 return nullptr; // Returns an empty image
298 } catch (const Gdk::PixbufError& e) {
299 std::cerr << "Failed to parse XPM image format: " << e.what() << std::endl;
300 return nullptr; // Returns an empty image
301 }
302
303 // 3. Create the GTK4 Image widget directly from the validated texture
304 auto image = Gtk::make_managed<Gtk::Image>(texture);
305
306 return image;
307}
308
309
311{
312
313 auto css_provider = Gtk::CssProvider::create();
314
315 // Target the button widget structure to minimize interior padding spaces
316 css_provider->load_from_data("button { padding: 2px 2px; min-width: 0; min-height: 0; }");
317
318 for (int i = 0; toolBarData[i].fPixmap; i++) {
319 auto btn = &(toolBarData[i]);
320 if (strlen(btn->fPixmap) == 0) {
321 // fToolBar->addSeparator();
322 auto separator = Gtk::make_managed<Gtk::Separator>(Gtk::Orientation::VERTICAL);
323 m_ToolBar.append(*separator);
324 continue;
325 }
326
327 auto button = Gtk::make_managed<Gtk::Button>();
328
329 TString iconname = TROOT::GetIconPath();
330 iconname.Append("/");
331 iconname.Append(btn->fPixmap);
332
333 // 2. Load the icon from the file path
334 auto image = create_resized_xpm_image(iconname.Data());
335
336 if (image)
337 button->set_child(*image);
338
339 button->get_style_context()->add_provider(css_provider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
340
341 button->set_tooltip_text(btn->fTipText);
342
343 button->signal_clicked().connect([this, btn]() {
344 clickToolButton(btn->fId);
345 });
346
347
348 m_ToolBar.append(*button);
349 }
350}
351
353{
354 auto canv = m_DrawArea.GetCanvas();
355 switch (id) {
356 case kFileNewCanvas:
358 break;
359 case kFileOpen:
361 break;
362 case kFileSaveAs:
364 break;
365 case kFilePrint:
367 break;
368 case kOptionInterrupt: gROOT->SetInterrupt(); break;
369 case kOptionRefresh:
370 if (canv) {
371 canv->Modified(kTRUE);
372 // trigger update of the paint widget, paint will be called
373 canv->Update();
374 }
375 break;
376 case kInspectRoot:
377 if (canv) {
378 canv->cd();
379 gROOT->Inspect();
380 canv->Update();
381 }
382 break;
383
384 case kToolsBrowser: break;
385 case kToolModify: gROOT->SetEditorMode(); break;
386 case kToolArc: gROOT->SetEditorMode("Arc"); break;
387 case kToolLine: gROOT->SetEditorMode("Line"); break;
388 case kToolArrow: gROOT->SetEditorMode("Arrow"); break;
389 case kToolDiamond: gROOT->SetEditorMode("Diamond"); break;
390 case kToolEllipse: gROOT->SetEditorMode("Ellipse"); break;
391 case kToolPad: gROOT->SetEditorMode("Pad"); break;
392 case kToolPave: gROOT->SetEditorMode("Pave"); break;
393 case kToolPLabel: gROOT->SetEditorMode("PaveLabel"); break;
394 case kToolPText: gROOT->SetEditorMode("PaveText"); break;
395 case kToolPsText: gROOT->SetEditorMode("PavesText"); break;
396 case kToolGraph: gROOT->SetEditorMode("PolyLine"); break;
397 case kToolCurlyLine: gROOT->SetEditorMode("CurlyLine"); break;
398 case kToolCurlyArc: gROOT->SetEditorMode("CurlyArc"); break;
399 case kToolLatex: gROOT->SetEditorMode("Text"); break;
400 case kToolMarker: gROOT->SetEditorMode("Marker"); break;
401 case kToolCutG: gROOT->SetEditorMode("CutG"); break;
402 }
403}
404
406{
407 m_StatusBar.remove_all_messages(fContextId);
408 m_StatusBar.push(msg, fContextId);
409}
410
412{
413 bool is_checked = Glib::VariantBase::cast_dynamic<Glib::Variant<bool>>(value).get();
414
415 m_ToolBar.set_visible(is_checked);
416
417 // Remember to update the actual action state so the checkmark reflects visually
418 auto action = m_action_group->lookup_action("show-toolbar");
419 if (action) {
420 auto simple_action = std::dynamic_pointer_cast<Gio::SimpleAction>(action);
421 simple_action->set_state(value);
422 }
423}
424
426{
427 bool is_checked = Glib::VariantBase::cast_dynamic<Glib::Variant<bool>>(value).get();
428
429 m_StatusBar.set_visible(is_checked);
430
431 // Remember to update the actual action state so the checkmark reflects visually
432 auto action = m_action_group->lookup_action("show-eventstatus");
433 if (action) {
434 auto simple_action = std::dynamic_pointer_cast<Gio::SimpleAction>(action);
435 simple_action->set_state(value);
436 }
437}
438
440{
441 bool is_checked = Glib::VariantBase::cast_dynamic<Glib::Variant<bool>>(value).get();
442
443 m_DrawArea.set_has_tooltip(is_checked);
444
445 // Remember to update the actual action state so the checkmark reflects visually
446 auto action = m_action_group->lookup_action("show-tooltip");
447 if (action) {
448 auto simple_action = std::dynamic_pointer_cast<Gio::SimpleAction>(action);
449 simple_action->set_state(value);
450 }
451
452}
453
455{
456 if (!m_file_dialog) {
457 m_file_dialog = Gtk::FileDialog::create();
458 m_file_dialog->set_title("Select a ROOT File");
459 m_file_dialog->set_modal(true);
460
461 auto filter_root_files = Gtk::FileFilter::create();
462 filter_root_files->set_name("ROOT files (*.root)");
463 filter_root_files->add_pattern("*.root");
464
465 auto filter_xml_files = Gtk::FileFilter::create();
466 filter_xml_files->set_name("ROOT XML files (*.xml)");
467 filter_xml_files->add_pattern("*.xml");
468
469 auto filter_all_files = Gtk::FileFilter::create();
470 filter_all_files->set_name("All files (*.*)");
471 filter_all_files->add_pattern("*.*");
472
473 auto filters_list = Gio::ListStore<Gtk::FileFilter>::create();
474 filters_list->append(filter_root_files);
475 filters_list->append(filter_xml_files);
476 filters_list->append(filter_all_files);
477
478 m_file_dialog->set_filters(filters_list);
479
480 // Optional: Set which filter is selected by default (e.g., Images)
481 m_file_dialog->set_default_filter(filter_root_files);
482 }
483
484 m_file_dialog->open(*this, sigc::mem_fun(*this, &Gtk4CanvasWindow::on_file_selected));
485}
486
487////////////////////////////////////////////////////////////////////////////////
488/// Signal handler when open file dialog select file
489
490void Gtk4CanvasWindow::on_file_selected(const Glib::RefPtr<Gio::AsyncResult> &result)
491{
492 try {
493 // Retrieve the selected file reference
494 Glib::RefPtr<Gio::File> file = m_file_dialog->open_finish(result);
495
496 TFile::Open(file->get_path().c_str(), "update");
497
498 } catch (const Gtk::DialogError &err) {
499 // Triggers if the user cancels or closes the dialog window
500 // std::cout << "Dialog closed or dismissed: " << err.what() << std::endl;
501 }
502}
503
504////////////////////////////////////////////////////////////////////////////////
505/// Return vector with supported file formats with description and print option
506/// To be moved in base class
507
508const std::vector<std::string> &Gtk4CanvasWindow::GetSupportedFileFormats() const
509{
510 static std::vector<std::string> lst = {
511 "Post Script", "ps", "ps",
512 "Post Script Portrait", "ps", "Portrait",
513 "Post Script Landscape", "ps", "Landscape",
514 "Encapsulated Post Script", "eps", "eps",
515 "Encapsulated Post Script preview", "eps", "Preview",
516 "GIF format", "gif", "gif",
517 "PDF format", "pdf", "pdf",
518 "SVG format", "svg", "svg",
519 "XPM format", "xpm", "xpm",
520 "PNG format", "png", "png",
521 "JPG format", "jpg", "jpg",
522 "BMP format", "bmp", "bmp",
523 "TIFF format", "tiff", "tiff",
524 "C++ Macro", "C", "cxx",
525 "json file", "json", "json",
526 "html file", "html", "html",
527 "root file", "root", "root"
528 };
529 return lst;
530}
531
532
533////////////////////////////////////////////////////////////////////////////////
534/// Save canvas with specified format
535
536void Gtk4CanvasWindow::on_saveCanvas(const std::string &fmt, const std::string &opt)
537{
538 auto canv = m_DrawArea.GetCanvas();
539 if (!canv)
540 return;
541 std::string fname = fCanvasFileName + "." + fmt;
542 canv->Print(fname.c_str(), opt.c_str());
543}
544
545
546////////////////////////////////////////////////////////////////////////////////
547/// Start Save as dialog
548
550{
551 if (!m_save_dialog) {
552 m_save_dialog = Gtk::FileDialog::create();
553 m_save_dialog->set_title("Save canvas as");
554 m_save_dialog->set_modal(true);
555
556 auto filters_list = Gio::ListStore<Gtk::FileFilter>::create();
557
558 auto &fmts = GetSupportedFileFormats();
559 R__ASSERT(fmts.size() % 3 == 0);
560 for (std::size_t p = 0; p < fmts.size(); p += 3) {
561 std::string ext = fmts[p + 1];
562 // cannot define filters with same extension - cannot distinguish which was selected
563 if ((ext != "C") && (ext != fmts[p + 2]))
564 continue;
565 auto name = TString::Format("%s (*.%s)", fmts[p].c_str(), ext.c_str());
566 auto pattern = TString::Format("(*.%s)", ext.c_str());
567
568 auto filter = Gtk::FileFilter::create();
569 filter->set_name(name.Data());
570 filter->add_pattern(pattern.Data());
571 filters_list->append(filter);
572
573 if (fmts[p+1] == "png")
574 m_save_dialog->set_default_filter(filter);
575 }
576
577 m_save_dialog->set_filters(filters_list);
578 }
579
580 auto canv = m_DrawArea.GetCanvas();
581 if (canv) {
582 std::string name = canv->GetName();
583 m_save_dialog->set_initial_name(name + ".png");
584 }
585
586 m_save_dialog->save(*this, sigc::mem_fun(*this, &Gtk4CanvasWindow::on_save_selected));
587}
588
589////////////////////////////////////////////////////////////////////////////////
590/// Signal handler when save as dialog select file
591
592void Gtk4CanvasWindow::on_save_selected(const Glib::RefPtr<Gio::AsyncResult> &result)
593{
594 auto canv = m_DrawArea.GetCanvas();
595 if (!canv)
596 return;
597
598 try {
599 Glib::RefPtr<Gio::File> file = m_save_dialog->save_finish(result);
600
601 std::string raw_path = file->get_path();
602 std::filesystem::path sys_path(raw_path);
603 std::string extension = sys_path.extension().string(); //
604 std::string print_opt;
605
606 auto &fmts = GetSupportedFileFormats();
607 R__ASSERT(fmts.size() % 3 == 0);
608 for (std::size_t p = 0; p < fmts.size(); p += 3) {
609 if (extension == "." + fmts[p + 1]) {
610 print_opt = fmts[p + 2];
611 break;
612 }
613 }
614
615 if (print_opt.empty())
616 ::Error("Gtk4CanvasWindow::on_save_selected", "Cannot detect file format from selected extension %s", extension.c_str());
617 else {
618 printf("Store canvas %s as %s opt %s\n", canv->ClassName(), raw_path.c_str(), print_opt.c_str());
619 canv->Print(raw_path.c_str(), print_opt.c_str());
620 }
621
622 } catch (const Gtk::DialogError &err) {
623 }
624}
625
626
Gtk::Image * create_resized_xpm_image(const char *filename)
static ToolBarData_t toolBarData[]
@ kOptionInterrupt
@ kToolLatex
@ kToolPLabel
@ kToolPad
@ kFilePrint
@ kToolDiamond
@ kToolCurlyLine
@ kToolLine
@ kFileSaveAs
@ kToolEllipse
@ kToolPsText
@ kToolModify
@ kToolArrow
@ kToolArc
@ kToolsBrowser
@ kToolPave
@ kFileNewCanvas
@ kOptionRefresh
@ kInspectRoot
@ kToolPText
@ kToolCurlyArc
@ kToolGraph
@ kToolCutG
@ kToolMarker
@ kFileOpen
#define e(i)
Definition RSha256.hxx:103
constexpr Bool_t kFALSE
Definition RtypesCore.h:109
constexpr Bool_t kTRUE
Definition RtypesCore.h:108
R__EXTERN TApplication * gApplication
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
Definition TError.h:139
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:208
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
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
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t button
char name[80]
Definition TGX11.cxx:142
#define gROOT
Definition TROOT.h:417
void on_show_tooltip_changed(const Glib::VariantBase &)
Glib::RefPtr< Gtk::FileDialog > m_file_dialog
void on_show_eventstatus_changed(const Glib::VariantBase &)
Glib::RefPtr< Gio::SimpleActionGroup > m_action_group
void on_status_changed(const char *msg)
Gtk4DrawArea m_DrawArea
const std::vector< std::string > & GetSupportedFileFormats() const
Return vector with supported file formats with description and print option To be moved in base class...
void on_saveCanvas(const std::string &fname, const std::string &opt)
Save canvas with specified format.
void on_save_selected(const Glib::RefPtr< Gio::AsyncResult > &result)
Signal handler when save as dialog select file.
unsigned int fContextId
std::string fCanvasFileName
void fillSaveMenu(TCanvas *canv)
Fill or update canvas save menu Only performed when canvas name is changed.
void on_file_selected(const Glib::RefPtr< Gio::AsyncResult > &result)
Signal handler when open file dialog select file.
void on_show_toolbar_changed(const Glib::VariantBase &)
Gtk::Statusbar m_StatusBar
Glib::RefPtr< Gio::Menu > fSaveMenu
void clickToolButton(int id)
Gtk4CanvasWindow(TCanvas *canv=nullptr, unsigned width=400, unsigned height=200)
void fillMenuBar(TCanvas *canv)
void on_saveCanvasAs()
Start Save as dialog.
Glib::RefPtr< Gtk::FileDialog > m_save_dialog
sigc::signal< void(const char *) status_changed)()
TCanvas * GetCanvas() const
The Canvas class.
Definition TCanvas.h:23
static TCanvas * MakeDefCanvas()
Static function to build a default canvas.
Definition TCanvas.cxx:1536
@ kShowToolTips
Definition TCanvas.h:102
@ kShowToolBar
Definition TCanvas.h:97
@ kShowEventStatus
Definition TCanvas.h:94
@ kMenuBar
Definition TCanvas.h:96
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
Create / open a file.
Definition TFile.cxx:3802
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:204
const char * GetName() const override
Returns name of object.
Definition TPad.h:273
static const TString & GetIconPath()
Get the icon path in the installation. Static utility function.
Definition TROOT.cxx:3502
Basic string class.
Definition TString.h:137
const char * Data() const
Definition TString.h:385
TString & Append(const char *cs)
Definition TString.h:582
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2460
static void SingleShot(Int_t milliSec, const char *receiver_class, void *receiver, const char *method)
This static function calls a slot after a given time interval.
Definition TTimer.cxx:261
const char * fPixmap
const char * fTipText