Many changes to setup colours, update window positions, put notes on desktop, etc.

Signed-off-by: Hans Dijkema <hans@dijkewijk.nl>
This commit is contained in:
2025-11-24 14:52:17 +01:00
parent a0ac0420da
commit 80ee3fcadf
9 changed files with 493 additions and 131 deletions

View File

@@ -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

19
Makefile Normal file
View File

@@ -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

View File

@@ -1,6 +1,8 @@
#ifndef GTK_IMPORTS_H
#define GTK_IMPORTS_H
#include <stdlib.h>
/*************************************************************************************
* 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))

View File

@@ -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;

View File

@@ -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) {

BIN
to_desktop.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

4
to_desktop.svg Normal file
View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M18.3137 0.918778C18.6347 1.36819 18.5307 1.99274 18.0812 2.31375L16.4248 3.49692L17.2572 3.67529C20.0236 4.26809 22 6.71287 22 9.5421V10C22 10.5523 21.5523 11 21 11C20.4477 11 20 10.5523 20 10V9.5421C20 7.65595 18.6824 6.02609 16.8381 5.63089L15.9784 5.44667L16.8682 7.00388C17.1423 7.48339 16.9757 8.09425 16.4961 8.36826C16.0166 8.64227 15.4058 8.47567 15.1318 7.99616L13.1318 4.49616C12.8771 4.05058 13.0012 3.48458 13.4188 3.18629L16.9188 0.686284C17.3682 0.365274 17.9927 0.469365 18.3137 0.918778ZM6 12C6 10.8954 6.89543 10 8 10H16C17.1046 10 18 10.8954 18 12V20C18 21.1046 17.1046 22 16 22H8C6.89543 22 6 21.1046 6 20V12ZM16 20V12H8V20H16ZM4 6.00002C2.89543 6.00002 2 6.89545 2 8.00002V16C2 16.5523 2.44772 17 3 17C3.55228 17 4 16.5523 4 16V8.00002H12C12.5523 8.00002 13 7.5523 13 7.00002C13 6.44773 12.5523 6.00002 12 6.00002H4Z" fill="#000000"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -22,6 +22,8 @@ extern "C" {
#include "tr.h"
#include <math.h>
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<unsigned int>(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<std::string, std::string>::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<std::string, std::string>::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<std::string, std::string>(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<std::string, std::string>(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<YellowNotes *>(_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<YellowNote *>::const_iterator it = _notes.begin();
while (it != _notes.end()) {
YellowNote *note = *it;
note->toDesktop();
it++;
}
setCfgOnDesktop(true);
}
void YellowNotes::notesFromDesktop(void *sender)
{ std::list<YellowNote *>::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<ColorSet *>::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<ColorType_t>(i));
std::string bg_color = getBgColor(static_cast<ColorType_t>(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<ColorType_t>(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<ColorType_t>(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<std::string, std::string>(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<GdkEventMask>(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<YellowNote *>(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<ColorType_t>(color);
char *buf = static_cast<char *>(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<ColorType_t>(color);
char *buf = static_cast<char *>(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) {

View File

@@ -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<ColorSet *> _color_sets;
std::list<YellowNote *> _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<YellowNotes *>(obj)