1 /* GTK-based button bar
2 * Copyright (c) 2021 Piotr Miller
3 * e-mail: nwg.piotr@gmail.com
4 * Website: http://nwg.pl
5 * Project: https://github.com/nwg-piotr/nwg-launchers
6 * License: GPL3
7 * *
8 * Credits for window transparency go to AthanasiusOfAlex at https://stackoverflow.com/a/21460337
9 * transparent.cpp
10 * Code adapted from 'alphademo.c' by Mike
11 * (http://plan99.net/~mike/blog--now a dead link--unable to find it.)
12 * as modified by karlphillip for StackExchange:
13 * (https://stackoverflow.com/questions/3908565/how-to-make-gtk-window-background-transparent)
14 * Re-worked for Gtkmm 3.0 by Louis Melahn, L.C. January 31, 2014.
15 * */
16
17 #include "charconv-compat.h"
18 #include "nwg_tools.h"
19 #include "bar.h"
20
BarConfig(const InputParser & parser,const Glib::RefPtr<Gdk::Screen> & screen)21 BarConfig::BarConfig(const InputParser& parser, const Glib::RefPtr<Gdk::Screen>& screen):
22 Config{ parser, "~nwgbar", "~nwgbar", screen }
23 {
24 if (parser.cmdOptionExists("-v")) {
25 orientation = Orientation::Vertical;
26 }
27 if (auto tname = parser.getCmdOption("-t"); !tname.empty()) {
28 definition_file = tname;
29 }
30 if (auto i_size = parser.getCmdOption("-s"); !i_size.empty()) {
31 int i_s;
32 if (parse_number(i_size, i_s)) {
33 if (i_s >= 16 && i_s <= 2048) {
34 icon_size = i_s;
35 } else {
36 Log::error("Size must be in range 16 - 2048\n");
37 }
38 } else {
39 Log::error("Image size should be valid integer in range 16 - 2048\n");
40 }
41 }
42 }
43
BarWindow(Config & config)44 BarWindow::BarWindow(Config& config): PlatformWindow(config) {
45 // scrolled_window -> outer_box -> inner_hbox -> grid
46 grid.set_column_spacing(5);
47 grid.set_row_spacing(5);
48 grid.set_column_homogeneous(true);
49 outer_box.set_spacing(15);
50 inner_hbox.set_name("bar");
51 switch (config.halign) {
52 case HAlign::Left: inner_hbox.pack_start(grid, false, false); break;
53 case HAlign::Right: inner_hbox.pack_end(grid, false, false); break;
54 default: inner_hbox.pack_start(grid, true, false);
55 }
56 switch (config.valign) {
57 case VAlign::Top: outer_box.pack_start(inner_hbox, false, false); break;
58 case VAlign::Bottom: outer_box.pack_end(inner_hbox, false, false); break;
59 default: outer_box.pack_start(inner_hbox, Gtk::PACK_EXPAND_PADDING);
60 }
61 scrolled_window.add(outer_box);
62 add(scrolled_window);
63 show_all_children();
64 }
65
on_button_press_event(GdkEventButton * button)66 bool BarWindow::on_button_press_event(GdkEventButton* button) {
67 (void)button;
68 this->close();
69 return true;
70 }
71
on_key_press_event(GdkEventKey * key_event)72 bool BarWindow::on_key_press_event(GdkEventKey* key_event) {
73 if (key_event -> keyval == GDK_KEY_Escape) {
74 this->close();
75 }
76 //if the event has not been handled, call the base class
77 return CommonWindow::on_key_press_event(key_event);
78 }
79
80 /*
81 * Constructor is required for std::vector::emplace_back to work
82 * It is not needed when compiling with C++20 and greater
83 * */
BarEntry(std::string name,std::string exec,std::string icon)84 BarEntry::BarEntry(std::string name, std::string exec, std::string icon)
85 : name(std::move(name)), exec(std::move(exec)), icon(std::move(icon)) {}
86
BarBox(Glib::ustring name,Glib::ustring exec,Glib::ustring comment)87 BarBox::BarBox(Glib::ustring name, Glib::ustring exec, Glib::ustring comment)
88 : AppBox(std::move(name), std::move(exec), std::move(comment)) {}
89
on_button_press_event(GdkEventButton * event)90 bool BarBox::on_button_press_event(GdkEventButton* event) {
91 (void)event; // suppress warning
92
93 this->activate();
94 return false;
95 }
96
on_activate()97 void BarBox::on_activate() {
98 try {
99 Glib::spawn_command_line_async(exec);
100 } catch (const Glib::SpawnError& error) {
101 Log::error("Failed to run command: ", error.what());
102 } catch (const Glib::ShellError& error) {
103 Log::error("Failed to run command: ", error.what());
104 }
105 dynamic_cast<BarWindow*>(this->get_toplevel())->close();
106 }
107