From 80ee3fcadf5e1b77fa976a8e69ce450ddfbe38d9 Mon Sep 17 00:00:00 2001 From: Hans Dijkema Date: Mon, 24 Nov 2025 14:52:17 +0100 Subject: [PATCH] Many changes to setup colours, update window positions, put notes on desktop, etc. Signed-off-by: Hans Dijkema --- CMakeLists.txt | 4 +- Makefile | 19 ++ gtk-imports.h | 18 +- gtkloader.cpp | 1 + main.cpp | 4 + to_desktop.png | Bin 0 -> 16264 bytes to_desktop.svg | 4 + yellownotes.cpp | 560 +++++++++++++++++++++++++++++++++++++----------- yellownotes.h | 14 ++ 9 files changed, 493 insertions(+), 131 deletions(-) create mode 100644 Makefile create mode 100644 to_desktop.png create mode 100644 to_desktop.svg diff --git a/CMakeLists.txt b/CMakeLists.txt index fa0b7bd..70e02c1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,9 @@ add_executable(yellownotes main.cpp gtkloader.h gtkloader.cpp gtk-imports.c yellownotes.h yellownotes.cpp - tr.h tr.cpp) + tr.h tr.cpp + utils/whereami.c utils/whereami.h + exe_path.h exe_path.cpp) include(GNUInstallDirs) install(TARGETS yellownotes diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f64453d --- /dev/null +++ b/Makefile @@ -0,0 +1,19 @@ + + +all: release + @echo make install + +install: release + mkdir -p /opt/yellownotes + cp build/release/yellownotes *.svg *.png /opt/yellownotes + +release: build/release/yellownotes + +build/release/yellownotes: exe_path.cpp gtk-imports.c gtkloader.cpp main.cpp tr.cpp yellownotes.cpp utils/whereami.c \ + exe_path.h gtk-imports.h gtkloader.h tr.h yellownotes.h utils/whereami.h + cmake -S . -B build/release + cmake --build build/release --target all + + +clean: + rm -rf build/release diff --git a/gtk-imports.h b/gtk-imports.h index 0282eb8..42b686e 100644 --- a/gtk-imports.h +++ b/gtk-imports.h @@ -1,6 +1,8 @@ #ifndef GTK_IMPORTS_H #define GTK_IMPORTS_H +#include + /************************************************************************************* * boiler plate code to initialize Gtk functions etc. *************************************************************************************/ @@ -68,13 +70,16 @@ typedef void GtkDialog; typedef void GTimer; typedef void GtkComboBoxText; typedef void GtkComboBox; +typedef void GtkGrid; +typedef void GtkColorButton; +typedef void GtkColorChooser; typedef int gboolean; typedef int gint; typedef char gchar; typedef long glong; typedef unsigned long gulong; -typedef unsigned long guint32; +typedef unsigned int guint32; typedef unsigned int guint; typedef long long gint64; typedef unsigned long long guint64; @@ -274,7 +279,7 @@ typedef struct _GdkEventMotion gint16 is_hint; GdkDevice *device; gdouble x_root, y_root; -} GdkEventMotion; +} GdkEventMotion;; typedef struct _GdkEventKey { @@ -649,11 +654,20 @@ DECL(void, gtk_widget_set_vexpand, (GtkWidget* widget, gboolean expand )) DECL(void, gtk_widget_set_hexpand, (GtkWidget* widget, gboolean expand )) DECL(void, gtk_widget_set_halign, (GtkWidget* widget, GtkAlign align )) DECL(void, gtk_widget_set_valign, (GtkWidget* widget, GtkAlign align )) +DECL(GtkWidget*,gtk_grid_new, (void)) +DECL(void, gtk_grid_attach, (GtkGrid* grid, GtkWidget* child, gint left, gint top, gint width, gint height )) + +DECL(GtkWidget*, gtk_color_button_new, (void )) +DECL(void, gtk_color_chooser_set_rgba, (GtkColorChooser* chooser, const GdkRGBA* color )) +DECL(void, gtk_color_chooser_get_rgba, (GtkColorChooser* chooser, GdkRGBA* color )) DECL(gboolean, gtk_widget_translate_coordinates, ( GtkWidget* src_widget, GtkWidget* dest_widget, gint src_x, gint src_y, gint* dest_x, gint* dest_y)) DECL(void, gtk_main, (void)) DECL(void, gtk_main_quit, (void)) +DECL(GdkEvent*, gtk_get_current_event, (void )) +DECL(void, gtk_main_do_event, (GdkEvent* event)) +DECL(void, gdk_event_free, (GdkEvent* event)) DECL(unsigned long, g_signal_connect_data, (GObject *obj, const char *signal, GCallback c_handler, gpointer data, GClosureNotify destroy_data, GConnectFlags connect_flags)) diff --git a/gtkloader.cpp b/gtkloader.cpp index 21edad6..6685ef7 100644 --- a/gtkloader.cpp +++ b/gtkloader.cpp @@ -123,6 +123,7 @@ void GtkLoader::dlopen() "libgio-2.0.so", "libglib-2.0.so", "libgdk-3.so", + "libgdk_pixbuf-2.0.so", NULL }; int i; diff --git a/main.cpp b/main.cpp index 9e88434..e9906c9 100644 --- a/main.cpp +++ b/main.cpp @@ -6,6 +6,7 @@ extern "C" { } #include "yellownotes.h" +#include "exe_path.h" SIGNAL(YellowNotes, on_tray_activate, popupTrayMenu) @@ -22,9 +23,12 @@ static void activate (GtkApplication* app, gpointer user_data) int main(int argc, char **argv) { GtkLoader l; + WhereAmI w; srand(time(NULL)); // seed with current time + std::string my_path = w.containing_folder(); + try { l.loadGtk(); } catch(std::string msg) { diff --git a/to_desktop.png b/to_desktop.png new file mode 100644 index 0000000000000000000000000000000000000000..35b5a1eefd2627d3f337cfeeb021bd661206fa59 GIT binary patch literal 16264 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
{znIbS`;9uutR5BOJdwAo{f9<=-_0h!MY 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 + + + \ No newline at end of file diff --git a/yellownotes.cpp b/yellownotes.cpp index e055c33..f83721c 100644 --- a/yellownotes.cpp +++ b/yellownotes.cpp @@ -22,6 +22,8 @@ extern "C" { #include "tr.h" +#include + static void trim(std::string &s) { size_t start = s.find_first_not_of(" \t\n\r"); size_t end = s.find_last_not_of(" \t\n\r"); @@ -49,6 +51,7 @@ private: GtkImage *_delete_image; GtkImage *_plus_image; GtkImage *_hide_image; + GtkImage *_to_desktop_image; GtkWidget *_title_label; GtkWidget *_title_entry; GtkWidget *_title_separator; @@ -62,16 +65,24 @@ private: std::string _title; bool _hidden; + bool _hidden_loaded; + int _x; int _y; + bool _pos_loaded; + int _width; int _height; + bool _size_loaded; + bool _in_transaction; bool _editing_title; int _save_counter; int _save_id; + bool _double_clicked; + ColorType_t _color; bool _color_changed; @@ -106,11 +117,14 @@ private: void updateWidgetColors(GtkWidget *w); public: - void changed(GtkWidget *sender); - void size_allocated(GtkWidget *sender, GtkAllocation *a); + void resized(int width, int height); + void size_allocated(GtkWidget *sender, GtkAllocation *alloc); + void positioned(GtkWidget *sender, int x, int y); public: void toFront(); + void toDesktop(); + void fromDesktop(); public: bool move_begin(GtkWidget *sender, GdkEventButton *evt); @@ -127,6 +141,7 @@ public: public: std::string title(); bool isHidden(); + void doubleClicked(); public: void load(); @@ -137,6 +152,34 @@ public: ~YellowNote(); }; +class ColorSet +{ +public: + ColorType_t color; + YellowNotes *notes; + bool bg; + +public: + void colorSet(GtkColorButton *sender) { + GdkRGBA rgba; + gtk_color_chooser_get_rgba(sender, &rgba); + std::string c = notes->fromRGBA(rgba); + if (bg) { + notes->setBgColor(color, c); + } else { + notes->setFgColor(color, c); + } + } + + ColorSet(ColorType_t t, bool _bg, YellowNotes *n) { + color = t; + bg = _bg; + notes = n; + } +}; + +SIGNAL(ColorSet, on_color_set, colorSet); + SIGNAL2(YellowNote, on_size_allocated, size_allocated, GtkAllocation) BSIGNAL2(YellowNote, on_button_press, move_begin, GdkEventButton); BSIGNAL2(YellowNote, on_button_release, move_end, GdkEventButton); @@ -156,7 +199,8 @@ static gboolean on_text_save_timeout(gpointer data) } SIGNAL(YellowNotes, on_new_yellow, newNote) -SIGNAL(YellowNotes, on_show, showNotes); +SIGNAL(YellowNotes, on_show, notesFromDesktop); +SIGNAL(YellowNotes, on_to_back, notesToDesktop); SIGNAL(YellowNotes, on_reload, reloadNotes); SIGNAL(YellowNotes, on_setup, setup); SIGNAL(YellowNotes, on_quit, quit) @@ -210,28 +254,108 @@ std::string YellowNotes::notesDir() return notes_dir; } -std::string YellowNotes::css(ColorType_t type) +std::string YellowNotes::fromRGBA(const GdkRGBA &rgba) { - const char *bgs[] = { "#404040", // dark - "#faf32a", // yellow - "#fcbf56", // orange, - "#5df0f5", // blue - "#fc77f4", // Cyaan - "#74fc94", // greeen - "#f7bcbc", // red - "#cdcfd1" // grey + char buf[100]; + + auto to255 = [](double c) { + return static_cast(floor((c * 255) + 0.5)); }; - const char *fgs[] = { "white", - "black", - "black", - "black", - "black", - "black", - "black", - "black" + sprintf(buf, "#%02x%02x%02x", to255(rgba.red), to255(rgba.green), to255(rgba.blue)); + std::string col = buf; + return col; +} + +void YellowNotes::toRGBA(const std::string &col, GdkRGBA &rgba) +{ + auto from_hex = [](std::string hex_num) { + return strtol(hex_num.c_str(), NULL, 16); }; + double red = from_hex(col.substr(1, 2)) / 255.0; + double green = from_hex(col.substr(3, 2)) / 255.0; + double blue = from_hex(col.substr(5, 2)) / 255.0; + double alpha = 1.0; + + rgba.alpha = alpha; + rgba.blue = blue; + rgba.green = green; + rgba.red = red; +} + +std::string YellowNotes::getFgColor(ColorType_t type) +{ + char buf[100]; + sprintf(buf, "fg_color_%d", type); + std::string key = buf; + std::unordered_map::iterator it = _cfg.find(key); + if (it != _cfg.end()) { + return _cfg[key]; + } else { + const char *fgs[] = { "#ffffff", + "#000000", + "#000000", + "#000000", + "#000000", + "#000000", + "#000000", + "#000000" + }; + std::string c(fgs[type]); + return c; + } +} + +std::string YellowNotes::getBgColor(ColorType_t type) +{ + char buf[100]; + sprintf(buf, "bg_color_%d", type); + std::string key = buf; + std::unordered_map::iterator it = _cfg.find(key); + if (it != _cfg.end()) { + return _cfg[key]; + } else { + const char *bgs[] = { + "#404040", // dark + "#faf32a", // yellow + "#fcbf56", // orange, + "#5df0f5", // blue + "#fc77f4", // Cyaan + "#74fc94", // greeen + "#f7bcbc", // red + "#cdcfd1" // grey + }; + std::string c(bgs[type]); + return c; + } +} + +void YellowNotes::setFgColor(ColorType_t type, const std::string &col) +{ + char buf[100]; + sprintf(buf, "fg_color_%d", type); + std::string key = buf; + _cfg.erase(key); + _cfg.insert(std::pair(key, col)); + saveConfig(); +} + +void YellowNotes::setBgColor(ColorType_t type, const std::string &col) +{ + char buf[100]; + sprintf(buf, "bg_color_%d", type); + std::string key = buf; + _cfg.erase(key); + _cfg.insert(std::pair(key, col)); + saveConfig(); +} + +std::string YellowNotes::css(ColorType_t type) +{ + + if (type > LAST) { type = YELLOW; } + auto from_hex = [](std::string hex_num) { return strtol(hex_num.c_str(), NULL, 16); }; @@ -255,14 +379,14 @@ std::string YellowNotes::css(ColorType_t type) std::string css = std::string() + "label, box.horizontal, textview.view, textview.view text, frame, messagedialog.background {\n" - " background-color: " + bgs[type] + ";\n" - " color: " + fgs[type] + ";\n" + " background-color: " + getBgColor(type) + ";\n" + " color: " + getFgColor(type) + ";\n" " font-family: sans;\n" " font-size: " + font_size + ";\n" "}\n" "frame border {\n" " border: none;\n" - " box-shadow: 5px 5px 5px " + darker(bgs[type]) + ";\n" + " box-shadow: 5px 5px 5px " + darker(getBgColor(type)) + ";\n" " margin: 5px;\n" "}\n"; @@ -291,6 +415,7 @@ void YellowNotes::popupTrayMenu(void *sender) GtkMenuItem *new_yellow = gtk_menu_item_new_with_label(_("New Note")); GtkMenuItem *show_notes = gtk_menu_item_new_with_label(_("Show Notes")); + GtkMenuItem *notes_to_back = gtk_menu_item_new_with_label(_("Notes on desktop")); GtkMenuItem *reload_notes = gtk_menu_item_new_with_label(_("Reload Notes")); GtkWidget *sep = gtk_separator_menu_item_new(); @@ -314,6 +439,7 @@ void YellowNotes::popupTrayMenu(void *sender) gtk_menu_shell_append(tray_menu, new_yellow); gtk_menu_shell_append(tray_menu, show_notes); + gtk_menu_shell_append(tray_menu, notes_to_back); gtk_menu_shell_append(tray_menu, reload_notes); gtk_menu_shell_append(tray_menu, sep); @@ -330,6 +456,7 @@ void YellowNotes::popupTrayMenu(void *sender) g_signal_connect(new_yellow, "activate", on_new_yellow, this); g_signal_connect(show_notes, "activate", on_show, this); + g_signal_connect(notes_to_back, "activate", on_to_back, this); g_signal_connect(reload_notes, "activate", on_reload, this); g_signal_connect(setup, "activate", on_setup, this); g_signal_connect(quit, "activate", on_quit, this); @@ -393,6 +520,7 @@ void YellowNotes::loadConfig() } setLang(currentLang()); + } void YellowNotes::saveConfig() @@ -412,6 +540,13 @@ void YellowNotes::saveConfig() } } +gboolean load_notes_timeout(void *_notes) +{ + YellowNotes *notes = static_cast(_notes); + notes->notesToDesktop(nullptr); + return false; +} + void YellowNotes::loadNotes() { gtk_widget_show_all(topLevel()); @@ -437,12 +572,17 @@ void YellowNotes::loadNotes() const auto base_name = entry.path().filename().string(); if (base_name.rfind(".note") > 0) { YellowNote *note = new YellowNote(this, full_name); + //note->fromDesktop(); _notes.push_back(note); } } } gtk_widget_hide(topLevel()); + + if (cfgOnDesktop()) { + g_timeout_add(500, load_notes_timeout, this); + } } void YellowNotes::showNotes(void *sender) @@ -453,7 +593,27 @@ void YellowNotes::showNotes(void *sender) note->toFront(); it++; } +} +void YellowNotes::notesToDesktop(void *sender) +{ + std::list::const_iterator it = _notes.begin(); + while (it != _notes.end()) { + YellowNote *note = *it; + note->toDesktop(); + it++; + } + setCfgOnDesktop(true); +} + +void YellowNotes::notesFromDesktop(void *sender) +{ std::list::const_iterator it = _notes.begin(); + while (it != _notes.end()) { + YellowNote *note = *it; + note->fromDesktop(); + it++; + } + setCfgOnDesktop(false); } void YellowNotes::setupCancel(GtkWidget *sender) @@ -474,17 +634,22 @@ bool YellowNotes::setupDel(GtkWidget *sender, void *evt) void YellowNotes::setupClose(GtkWidget *sender) { if (_dlg != nullptr) { - std::cout << "hey" << std::endl; gtk_dialog_response(_dlg, GTK_RESPONSE_OK); std::string lang = std::string(gtk_combo_box_get_active_id(_langs)); - std::cout << "lang " << lang << std::endl; setCurrentLang(lang); gtk_widget_destroy(_dlg); + + std::list::iterator it; + for(it = _color_sets.begin() ; it != _color_sets.end(); it++) { + ColorSet *s = *it; + delete s; + } + _color_sets.clear(); + _dlg = nullptr; _langs = nullptr; saveConfig(); } else { - std::cout << "close button" << std::endl; } } @@ -504,13 +669,55 @@ void YellowNotes::setup(void *sender) gtk_combo_box_text_append(langs, "en", "English"); gtk_combo_box_text_append(langs, "nl", "Nederlands"); + GtkWidget *lbl_langs = gtk_label_new(_("Language:")); + gtk_widget_set_size_request(lbl_langs, 150, -1); + std::string current_lang = currentLang(); gtk_combo_box_set_active_id(langs, current_lang.c_str()); + gtk_widget_set_size_request(langs, 300, -1); - GtkWidget *hbox = gtk_box_new(GtkOrientation::GTK_ORIENTATION_HORIZONTAL, 5); + GtkGrid *grid = gtk_grid_new(); - gtk_container_add(hbox, langs); - gtk_container_add(content, hbox); + gtk_grid_attach(grid, lbl_langs, 0, 0, 1, 1); + gtk_grid_attach(grid, langs, 1, 0, 2, 1); + + GtkLabel *lbl_fg = gtk_label_new(_("Forground Color")); + GtkLabel *lbl_bg = gtk_label_new(_("Background Color")); + gtk_grid_attach(grid, lbl_fg, 1, 1, 1, 1); + gtk_grid_attach(grid, lbl_bg, 2, 1, 1, 1); + + + int i = ColorType_t::FIRST; + std::string colors[] = { _("Dark"), _("Yellow"), _("Orange"), + _("Blue"), _("Cyan"), _("Green"), _("Red"), _("Grey") }; + + int offset = 2; + + for(;i <= ColorType_t::LAST; i++) { + GtkWidget *lbl = gtk_label_new(colors[i].c_str()); + gtk_grid_attach(grid, lbl, 0, i + offset, 1, 1); + + GdkRGBA bg_rgba, fg_rgba; + std::string fg_color = getFgColor(static_cast(i)); + std::string bg_color = getBgColor(static_cast(i)); + toRGBA(fg_color, fg_rgba); + toRGBA(bg_color, bg_rgba); + + GtkColorButton *fg_btn = gtk_color_button_new(); + gtk_color_chooser_set_rgba(fg_btn, &fg_rgba); + ColorSet *fg = new ColorSet(static_cast(i), false, this); + g_signal_connect(fg_btn, "color_set", on_color_set, fg); + gtk_grid_attach(grid, fg_btn, 1, i + offset, 1, 1); + + GtkColorButton *bg_btn = gtk_color_button_new(); + gtk_color_chooser_set_rgba(bg_btn, &bg_rgba); + ColorSet *bg = new ColorSet(static_cast(i), true, this); + g_signal_connect(bg_btn, "color_set", on_color_set, bg); + gtk_grid_attach(grid, bg_btn, 2, i + offset, 1, 1); + + } + + gtk_container_add(content, grid); g_signal_connect(ok_btn, "clicked", on_setup_ok, this); g_signal_connect(dlg, "close", on_setup_close, this); @@ -527,8 +734,10 @@ void YellowNotes::reloadNotes(void *sender) delete note; it++; } + _notes.clear(); loadNotes(); + showNotes(sender); } @@ -582,6 +791,21 @@ std::string YellowNotes::currentLang() return _cfg[key]; } +bool YellowNotes::cfgOnDesktop() +{ + std::string key("on_desktop"); + return (_cfg[key] == "true") ? true : false; +} + +void YellowNotes::setCfgOnDesktop(bool y) +{ + std::string key("on_desktop"); + _cfg.erase(key); + std::string v = (y) ? "true" : "false"; + _cfg.insert(std::pair(key, v)); + saveConfig(); +} + void YellowNotes::setCurrentLang(const std::string &l) { std::string key("lang"); @@ -654,11 +878,22 @@ YellowNote::YellowNote(YellowNotes *notes, const std::string &filename) _color = ColorType_t::YELLOW; _color_changed = false; + _in_transaction = true; + _hidden_loaded = false; + _pos_loaded = false; + _size_loaded = false; + _double_clicked = false; + _note_widget = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_widget_set_can_focus(_note_widget, true); gtk_window_set_decorated(_note_widget, false); +#ifdef _WIN32 gtk_window_set_type_hint(_note_widget, GDK_WINDOW_TYPE_HINT_POPUP_MENU); gtk_window_set_transient_for(_note_widget, _notes->topLevel()); +#endif +#ifdef __linux + gtk_window_set_type_hint(_note_widget, GdkWindowTypeHint::GDK_WINDOW_TYPE_HINT_UTILITY); +#endif _scroll_widget = gtk_scrolled_window_new(nullptr, nullptr); gtk_widget_set_vexpand(_scroll_widget, true); @@ -712,14 +947,22 @@ YellowNote::YellowNote(YellowNotes *notes, const std::string &filename) width, height, nullptr ); _hide_image = gtk_image_new_from_pixbuf(hide_pixbuf); - gtk_widget_set_halign(_plus_image, GtkAlign::GTK_ALIGN_END); + gtk_widget_set_halign(_hide_image, GtkAlign::GTK_ALIGN_END); g_object_unref(hide_pixbuf); + GdkPixbuf *to_desktop_pixbuf = gdk_pixbuf_new_from_file_at_size(notes->imageFile("to_desktop").c_str(), + width, height, nullptr + ); + _to_desktop_image = gtk_image_new_from_pixbuf(to_desktop_pixbuf); + gtk_widget_set_halign(_to_desktop_image, GtkAlign::GTK_ALIGN_END); + g_object_unref(to_desktop_pixbuf); + gtk_container_add(_note_header, _color_image); gtk_container_add(_note_header, _title_label); gtk_container_add(_note_header, _plus_image); gtk_container_add(_note_header, _delete_image); gtk_container_add(_note_header, _hide_image); + gtk_container_add(_note_header, _to_desktop_image); gtk_container_add(_scroll_widget, _text_widget); @@ -733,6 +976,14 @@ YellowNote::YellowNote(YellowNotes *notes, const std::string &filename) gtk_widget_show_all(_note_widget); + /*while (!gtk_widget_is_visible(_note_widget)) { + GdkEvent *e = gtk_get_current_event(); + if (e != nullptr) { + gtk_main_do_event(e); + gdk_event_free(e); + } + }*/ + //GdkWindow *window = gdk_window_get_effective_toplevel(gtk_widget_get_window(_note_widget)); //gdk_window_set_events(window, static_cast(gdk_window_get_events(window) | GDK_VISIBILITY_NOTIFY_MASK)); //gdk_window_set_override_redirect(window, true); @@ -753,6 +1004,7 @@ YellowNote::YellowNote(YellowNotes *notes, const std::string &filename) g_object_ref(_delete_image); g_object_ref(_plus_image); g_object_ref(_hide_image); + g_object_ref(_to_desktop_image); load(); @@ -766,6 +1018,7 @@ YellowNote::~YellowNote() g_object_unref(_delete_image); g_object_unref(_plus_image); g_object_unref(_hide_image); + g_object_unref(_to_desktop_image); gtk_widget_destroy(_note_widget); _note_widget = nullptr; } @@ -854,6 +1107,7 @@ void YellowNote::updatePosition() void YellowNote::updateSize() { + std::cout << "Update size to: " << _width << ", " << _height << std::endl; gtk_window_resize(_note_widget, _width, _height); } @@ -876,63 +1130,39 @@ void YellowNote::hide() save(); } -void YellowNote::changed(GtkWidget *sender) + +void YellowNote::resized(int width, int height) { - bool sv = false; - - if (_color_changed) { - _color_changed = true; - sv = true; - } - - bool hidden = !gtk_widget_is_visible(_note_widget); - if (hidden != _hidden) { - _hidden = hidden; - sv = true; - } - - int w, h; - gtk_window_get_size(_note_widget, &w, &h); - if (w < 50) { w = 50; } - if (_width != w) { - _width = w; - sv = true; - } - - if (h < 50) { h = 50; } - if (_height != h) { - _height = h; - sv = true; - } - - int x, y; - gtk_window_get_position(_note_widget, &x, &y); - if (x <= 0) { x = 1; } - if (y <= 0) { y = 1; } - if (_x != x) { - _x = x; - sv = true; - } - if (_y != y) { - _y = y; - sv = true; - } - - const char *c_t = gtk_label_get_text (_title_label); - if (c_t != nullptr) { - std::string t(c_t); - if (t != _title) { - _title = t; - sv = true; - } - } - - if (sv) { save(); } + _width = width; + _height = height; + save(); } -void YellowNote::size_allocated(GtkWidget *sender, GtkAllocation *a) +void YellowNote::size_allocated(GtkWidget *sender, GtkAllocation *alloc) { - changed(sender); + std::cout << "loaded: " << _size_loaded << ", " << _pos_loaded << std::endl; + int width = alloc->width; + int height = alloc->height; + //if (_size_loaded) { + std::cout << "width, height = " << width << ", " << height << std::endl; + // _width = width; + // _height = height; + // save(); + // } + if (!_moving) { + if (width != _width || height != _height) { + gtk_window_resize(_note_widget, _width, _height); + } + } +} + +void YellowNote::positioned(GtkWidget *sender, int x, int y) +{ + if (_pos_loaded) { + _x = x; + _y = y; + save(); + } } void YellowNote::toFront() @@ -941,11 +1171,31 @@ void YellowNote::toFront() gtk_window_move(_note_widget, _x, _y); gtk_widget_hide(_note_widget); } else { + std::cout << "to_front x = " << _x << std::endl; + int x = _x; + int y = _y; gtk_window_present(_note_widget); - gtk_window_move(_note_widget, _x, _y); + gtk_window_move(_note_widget, x, y); } } + +void YellowNote::toDesktop() +{ +#ifdef __linux + std::cout << "todesktop: width: " << _width << ", height: " << _height << std::endl; + gtk_window_set_type_hint(_note_widget, GdkWindowTypeHint::GDK_WINDOW_TYPE_HINT_DESKTOP); +#endif +} + +void YellowNote::fromDesktop() +{ +#ifdef __linux + gtk_window_set_type_hint(_note_widget, GdkWindowTypeHint::GDK_WINDOW_TYPE_HINT_UTILITY); +#endif + toFront(); +} + void YellowNote::get_header_screen_coords(int &header_top, int &header_bottom) { int left, top; @@ -1000,6 +1250,9 @@ void YellowNote::adjustTitle(bool mutate) gtk_container_add(_note_header, _delete_image); gtk_container_remove(_note_header, _hide_image); gtk_container_add(_note_header, _hide_image); + gtk_container_remove(_note_header, _to_desktop_image); + gtk_container_add(_note_header, _to_desktop_image); + } bool YellowNote::windowPresented(void *sender, GdkEventVisibility *evt) // TODO according to docs this must not be a pointer @@ -1021,10 +1274,8 @@ void YellowNote::textChanged(void *sender) { if (_in_transaction) return; - std::cout << "Changed " << _save_id << std::endl; _save_counter++; if (_save_id == -1) { - std::cout << "Starting save timer" << std::endl; _save_id = _save_counter; g_timeout_add(1000, on_text_save_timeout, this); } @@ -1033,13 +1284,11 @@ void YellowNote::textChanged(void *sender) bool YellowNote::textSaveTimeout() { if (_save_counter != _save_id) { - std::cout << "Something changed" << std::endl; _save_id = _save_counter; g_timeout_add(1000, on_text_save_timeout, this); return false; } else { _save_id = -1; - std::cout << "Saving" << std::endl; save(); return false; } @@ -1070,6 +1319,21 @@ bool YellowNote::titleFocusOut(GtkWidget *sender, GdkEventFocus *evt) #define AROUND(c, n) ((c >= (n - threshold)) && (c <= (n + threshold))) +gboolean is_dblclk(gpointer d) +{ + YellowNote *n = static_cast(d); + n->doubleClicked(); + return false; + +} + +void YellowNote::doubleClicked() +{ + if (!_double_clicked) { + _notes->notesFromDesktop(nullptr); + } +} + bool YellowNote::move_begin(GtkWidget *sender, GdkEventButton *evt) { int x = evt->x_root; @@ -1093,6 +1357,9 @@ bool YellowNote::move_begin(GtkWidget *sender, GdkEventButton *evt) int hide_left, hide_right; get_screen_left_right(_hide_image, hide_left, hide_right); + int to_desktop_left, to_desktop_right; + get_screen_left_right(_to_desktop_image, to_desktop_left, to_desktop_right); + if (y >= header_top && y <= header_bottom) { if (x >= color_left && x <= color_right) { nextColor(); @@ -1106,6 +1373,10 @@ bool YellowNote::move_begin(GtkWidget *sender, GdkEventButton *evt) hide(); return true; } + if (x >= to_desktop_left && x <= to_desktop_right) { + _notes->notesToDesktop(this); + return true; + } if (x >= delete_left && x <= delete_right) { deleteMe(); return true; @@ -1121,17 +1392,22 @@ bool YellowNote::move_begin(GtkWidget *sender, GdkEventButton *evt) gtk_container_add(_note_header, _delete_image); gtk_container_remove(_note_header, _hide_image); gtk_container_add(_note_header, _hide_image); + gtk_container_remove(_note_header, _to_desktop_image); + gtk_container_add(_note_header, _to_desktop_image); gtk_widget_show(_title_entry); gtk_entry_set_text(_title_entry, _title.c_str()); gtk_widget_grab_focus(_title_entry); _editing_title = true; + _double_clicked = true; return true; } + _double_clicked = false; if (y >= header_top && y <= header_bottom) { _moving = true; _x_orig = evt->x; _y_orig = evt->y; + g_timeout_add(250, is_dblclk, this); return true; } @@ -1172,11 +1448,13 @@ bool YellowNote::moving(GtkWidget *sender, GdkEventMotion *evt) if (_moving) { int the_x = x - _x_orig; int the_y = y - _y_orig; + std::cout << "moving" << std::endl; gtk_window_move(_note_widget, the_x, the_y); + positioned(_note_widget, the_x, the_y); return true; } - if (_resize_bottom || _resize_right || _resize_edge) { + if (_resize_bottom || _resize_right || _resize_edge) { if (_resize_edge) { int left, top; gtk_window_get_position(_note_widget, &left, &top); @@ -1185,6 +1463,9 @@ bool YellowNote::moving(GtkWidget *sender, GdkEventMotion *evt) if (width < 100) { width = 100; } if (height < 60) { height = 60; } gtk_window_resize(_note_widget, width, height); + resized(width, height); + + //size_allocated(_note_box, width, height); return true; } @@ -1196,6 +1477,8 @@ bool YellowNote::moving(GtkWidget *sender, GdkEventMotion *evt) int width = x - left; if (width < 100) { width = 100; } gtk_window_resize(_note_widget, width, h); + resized(width, h); + //size_allocated(_note_box, width, h); return true; } @@ -1207,12 +1490,14 @@ bool YellowNote::moving(GtkWidget *sender, GdkEventMotion *evt) int height = y - top; if (height < 60) { height = 60; } gtk_window_resize(_note_widget, w, height); + resized(w, height); + //size_allocated(_note_box, w, height); return true; } } - int frame_bottom, frame_right; - get_frame_screen_coords(frame_bottom, frame_right); + int frame_bottom, frame_right; + get_frame_screen_coords(frame_bottom, frame_right); int header_top, header_bottom; get_header_screen_coords(header_top, header_bottom); @@ -1258,47 +1543,64 @@ void YellowNote::load() std::filesystem::path p(_filename); + int hidden, x, y, width, height; + ColorType_t c; + std::string title; + size_t s = 0; if (std::filesystem::is_regular_file(p)) { s = std::filesystem::file_size(p); + + FILE *f = fopen(_filename.c_str(), "rt"); + + if (f) { + int version = readInt(f, -1); + + hidden = readInt(f, -1); + x = readInt(f, 200); + y = readInt(f, 200); + width = readInt(f, 300); + height = readInt(f, 200); + + int color; + color = readInt(f, ColorType_t::YELLOW); + c = static_cast(color); + + char *buf = static_cast(malloc(s)); + memset(buf, 0, s); + + fgets(buf, s, f); + title = buf; + trim(title); + + memset(buf, 0, s); + int pos = ftell(f); + int bytes = s - pos; + fread(buf, bytes, 1, f); + + fclose(f); + gtk_text_buffer_set_text(_buffer, buf, strlen(buf)); + free(buf); + + _title = title; + updateTitle(); + + _color = c; + updateColor(); + + _x = x; _y = y; + _pos_loaded = true; + updatePosition(); + + _width = width; _height = height; + _size_loaded = true; + updateSize(); + + _hidden = hidden; + _hidden_loaded = true; + updateHidden(); + } } - FILE *f = fopen(_filename.c_str(), "rt"); - - if (f) { - int version = readInt(f, -1); - - _hidden = readInt(f, -1); - _x = readInt(f, 200); - _y = readInt(f, 200); - _width = readInt(f, 300); - _height = readInt(f, 200); - - int color; - color = readInt(f, ColorType_t::YELLOW); - _color = static_cast(color); - - char *buf = static_cast(malloc(s)); - memset(buf, 0, s); - - fgets(buf, s, f); - _title = buf; - trim(_title); - - memset(buf, 0, s); - int pos = ftell(f); - int bytes = s - pos; - fread(buf, bytes, 1, f); - - fclose(f); - gtk_text_buffer_set_text(_buffer, buf, strlen(buf)); - free(buf); - } - - updateTitle(); - updateColor(); - updatePosition(); - updateSize(); - updateHidden(); _in_transaction = false; } @@ -1309,6 +1611,8 @@ void YellowNote::save() return; } + std::cout << "Saving " << _title << "..." << _size_loaded << ", " << _width << ", h = " << _height << std::endl; + std::filesystem::path p(_filename); FILE *f = fopen(_filename.c_str(), "wt"); if (f) { diff --git a/yellownotes.h b/yellownotes.h index 11d02d5..be20dce 100644 --- a/yellownotes.h +++ b/yellownotes.h @@ -10,6 +10,7 @@ extern "C" { } class YellowNote; +class ColorSet; typedef enum { DARK = 0, @@ -32,6 +33,8 @@ private: void *_dlg; void *_langs; + std::list _color_sets; + std::list _notes; int _font_size; GtkWindow *_toplevel; @@ -58,6 +61,8 @@ public: void popupTrayMenu(void *sender); void newNote(void *sender); void showNotes(void *sender); + void notesToDesktop(void *sender); + void notesFromDesktop(void *sender); void reloadNotes(void *sender); void quit(void *sender); void topLevelHidden(GtkWidget *sender); @@ -70,10 +75,19 @@ public: public: std::string currentLang(); void setCurrentLang(const std::string &l); + bool cfgOnDesktop(); + void setCfgOnDesktop(bool y); + std::string getFgColor(ColorType_t type); + std::string getBgColor(ColorType_t type); + void setFgColor(ColorType_t type, const std::string &col); + void setBgColor(ColorType_t type, const std::string &col); + std::string fromRGBA(const GdkRGBA &rgba); + void toRGBA(const std::string &col, GdkRGBA &rgba); public: YellowNotes(void *app); ~YellowNotes(); + void colorSet(void *sender); }; #define YELLOWNOTES(obj) reinterpret_cast(obj)