Compare commits

..
10 Commits
9 changed files with 175 additions and 149 deletions
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="44px" height="44px" viewBox="0 0 44 44" version="1.1">
<defs>
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #232629; }</style>
</defs>
<g id="surface1" class="ColorScheme-Text" transform="translate(0,13.5)">
<path style=" stroke:none;fill-rule:nonzero;fill:currentColor;" d="M 32.121094 9.878906 C 30.476562 9.601562 28.65625 7.699219 27.839844 5.402344 C 27.375 4.097656 27.199219 2.125 27.476562 1.324219 C 27.71875 0.613281 28.347656 0.382812 28.625 0.898438 C 28.664062 0.980469 28.726562 1.546875 28.757812 2.160156 C 28.863281 4.25 29.320312 5.632812 30.316406 6.867188 C 31.847656 8.761719 33.417969 8.796875 34.800781 6.960938 C 35.917969 5.488281 36.316406 3.945312 36.140625 1.792969 C 36.09375 1.238281 36.082031 0.695312 36.109375 0.585938 C 36.136719 0.476562 36.25 0.292969 36.363281 0.179688 C 36.539062 0.00390625 36.605469 -0.0195312 36.8125 0.0117188 C 36.949219 0.0351562 37.121094 0.109375 37.195312 0.175781 C 37.699219 0.628906 37.933594 2.480469 37.691406 4.105469 C 37.550781 5.050781 37.414062 5.523438 37.074219 6.265625 C 36.148438 8.273438 34.757812 9.589844 33.277344 9.855469 C 32.695312 9.960938 32.632812 9.960938 32.121094 9.878906 Z M 32.121094 9.878906 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:currentColor;" d="M 11.191406 10.164062 C 10.328125 10.03125 9.667969 9.722656 8.886719 9.085938 C 7.757812 8.167969 6.8125 6.328125 6.570312 4.597656 C 6.425781 3.519531 6.550781 1.832031 6.855469 0.804688 C 6.996094 0.320312 7.445312 0.117188 7.730469 0.40625 C 7.894531 0.570312 7.90625 0.878906 7.789062 1.664062 C 7.621094 2.777344 7.941406 4.714844 8.472656 5.78125 C 9.394531 7.632812 10.773438 8.621094 12.078125 8.363281 C 12.765625 8.226562 13.1875 7.976562 13.824219 7.328125 C 14.292969 6.855469 14.464844 6.617188 14.691406 6.148438 C 15.226562 5.035156 15.476562 4.117188 15.667969 2.5625 C 15.777344 1.691406 16.128906 1.253906 16.644531 1.351562 C 16.875 1.398438 17.207031 1.753906 17.308594 2.058594 C 17.664062 3.136719 16.894531 6.117188 15.851562 7.703125 C 15.191406 8.707031 14.195312 9.535156 13.195312 9.914062 C 12.8125 10.058594 11.847656 10.25 11.613281 10.222656 C 11.566406 10.21875 11.378906 10.191406 11.191406 10.164062 Z M 11.191406 10.164062 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:currentColor;" d="M 19.878906 13.800781 C 18.96875 13.511719 18.183594 12.445312 17.933594 11.152344 C 17.886719 10.914062 17.863281 10.417969 17.878906 10.03125 C 17.902344 9.417969 17.925781 9.316406 18.070312 9.160156 C 18.335938 8.875 18.683594 8.957031 18.816406 9.339844 C 18.859375 9.460938 18.894531 9.734375 18.894531 9.949219 C 18.894531 10.734375 19.28125 11.730469 19.785156 12.238281 C 20.285156 12.746094 20.589844 12.667969 21 11.921875 C 21.125 11.695312 21.332031 11.410156 21.460938 11.285156 C 21.667969 11.09375 21.746094 11.0625 22.058594 11.0625 L 22.414062 11.0625 L 22.941406 11.617188 C 23.265625 11.957031 23.523438 12.167969 23.609375 12.167969 C 23.820312 12.167969 24.222656 11.722656 24.445312 11.246094 C 24.644531 10.824219 24.722656 10.515625 24.84375 9.65625 C 24.925781 9.082031 25.042969 8.886719 25.359375 8.78125 C 25.664062 8.679688 25.910156 8.785156 26.132812 9.117188 C 26.332031 9.417969 26.339844 9.976562 26.15625 10.757812 C 25.925781 11.726562 25.574219 12.386719 24.980469 12.988281 C 24.523438 13.445312 24.21875 13.582031 23.652344 13.582031 C 23.101562 13.582031 22.773438 13.441406 22.390625 13.039062 C 22.261719 12.902344 22.121094 12.792969 22.082031 12.792969 C 22.042969 12.796875 21.929688 12.917969 21.828125 13.0625 C 21.359375 13.75 20.613281 14.03125 19.878906 13.800781 Z M 19.878906 13.800781 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:currentColor;" d="M 37.90625 16.839844 C 36.679688 16.523438 35.683594 15.535156 35.230469 14.175781 C 35.0625 13.679688 35.035156 13.476562 35.03125 12.859375 C 35.027344 11.363281 35.585938 10.195312 36.738281 9.289062 C 37.253906 8.886719 37.722656 8.648438 38.621094 8.328125 C 40.253906 7.753906 41.417969 7.984375 42.605469 9.121094 C 43.261719 9.75 43.613281 10.308594 43.863281 11.113281 C 44.027344 11.636719 44.039062 11.761719 44.007812 12.53125 C 43.96875 13.5 43.851562 13.914062 43.394531 14.695312 C 42.800781 15.710938 41.867188 16.417969 40.703125 16.738281 C 39.980469 16.933594 38.492188 16.988281 37.90625 16.839844 Z M 37.90625 16.839844 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:currentColor;" d="M 3.175781 16.914062 C 1.519531 16.53125 0.515625 15.589844 0.128906 14.066406 C -0.03125 13.4375 -0.0429688 12.929688 0.09375 12.292969 C 0.457031 10.5625 1.566406 9.246094 3.105469 8.730469 C 3.613281 8.558594 3.746094 8.542969 4.820312 8.539062 C 6.121094 8.535156 6.207031 8.558594 6.75 9.058594 C 6.90625 9.203125 7.167969 9.390625 7.332031 9.476562 C 7.773438 9.703125 8.566406 10.539062 8.816406 11.042969 C 9.597656 12.609375 9.28125 14.285156 7.941406 15.636719 C 6.988281 16.597656 6.125 16.941406 4.546875 16.984375 C 3.890625 17.003906 3.457031 16.980469 3.175781 16.914062 Z M 3.175781 16.914062 "/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.1 KiB

+2 -7
View File
@@ -17,11 +17,6 @@ install_data(
)
install_data(
join_paths(scalable_dir, ('@0@-tray-dark.svg').format(application_id)),
install_dir: join_paths(get_option('datadir'), 'icons', scalable_dir)
)
install_data(
join_paths(scalable_dir, ('@0@-tray-light.svg').format(application_id)),
install_dir: join_paths(get_option('datadir'), 'icons', scalable_dir)
join_paths(symbolic_dir, ('@0@-tray-symbolic.svg').format(application_id)),
install_dir: join_paths(get_option('datadir'), 'icons', symbolic_dir)
)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 321 KiB

After

Width:  |  Height:  |  Size: 475 KiB

+2 -2
View File
@@ -17,8 +17,8 @@
"sources": [
{
"type": "archive",
"url": "https://gitea.angeltech.jp/Angel-Technologies/MoeMoji/archive/v0.2.0.tar.gz",
"sha256": "16dc80365b04aa76e8d1a39fce46707556fc791d95d53624a9a3e284681cdcf6"
"url": "https://gitea.angeltech.jp/Angel-Technologies/MoeMoji/archive/v0.3.3.tar.gz",
"sha256": "3a002f44bd571f5f5e9f1be0abf9c2395bc14ff831531b3939a71524323cc576"
}
]
}
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 335 KiB

After

Width:  |  Height:  |  Size: 487 KiB

+2 -28
View File
@@ -245,12 +245,8 @@ GVariant *sni_get_property(G_GNUC_UNUSED GDBusConnection *connection,
return g_variant_new_string("MoeMoji");
if (g_strcmp0(property_name, "Status") == 0)
return g_variant_new_string("Active");
if (g_strcmp0(property_name, "IconName") == 0) {
MoeMojiApplication *self = MOEMOJI_APPLICATION(user_data);
return g_variant_new_string(self->tray_icon_name
? self->tray_icon_name
: "jp.angeltech.MoeMoji-tray-dark");
}
if (g_strcmp0(property_name, "IconName") == 0)
return g_variant_new_string("jp.angeltech.MoeMoji-tray-symbolic");
if (g_strcmp0(property_name, "ItemIsMenu") == 0)
return g_variant_new_boolean(FALSE);
if (g_strcmp0(property_name, "Menu") == 0)
@@ -269,25 +265,6 @@ static const GDBusInterfaceVTable sni_vtable = {
.set_property = NULL,
};
static void update_tray_icon(MoeMojiApplication *self) {
AdwStyleManager *sm = adw_style_manager_get_default();
gboolean dark = adw_style_manager_get_dark(sm);
self->tray_icon_name = dark ? "jp.angeltech.MoeMoji-tray-dark"
: "jp.angeltech.MoeMoji-tray-light";
if (self->dbus_conn && self->sni_registration_id > 0) {
g_dbus_connection_emit_signal(self->dbus_conn, NULL, "/StatusNotifierItem",
"org.kde.StatusNotifierItem", "NewIcon", NULL,
NULL);
}
}
static void on_dark_changed(G_GNUC_UNUSED GObject *obj,
G_GNUC_UNUSED GParamSpec *pspec,
gpointer user_data) {
update_tray_icon(MOEMOJI_APPLICATION(user_data));
}
static void setup_sni(MoeMojiApplication *self) {
GError *error = NULL;
self->dbus_conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error);
@@ -547,9 +524,6 @@ static void moemoji_application_startup(GApplication *app) {
}
}
setup_sni(self);
update_tray_icon(self);
g_signal_connect(adw_style_manager_get_default(), "notify::dark",
G_CALLBACK(on_dark_changed), self);
setup_global_shortcuts(self);
}
-1
View File
@@ -13,7 +13,6 @@ struct _MoeMojiApplication {
guint sni_registration_id;
guint menu_registration_id;
gchar *icon_theme_path;
const gchar *tray_icon_name;
GDBusProxy *shortcuts_proxy;
gchar *shortcuts_session_path;
gboolean has_tray;
+155 -110
View File
@@ -9,6 +9,8 @@
G_DEFINE_TYPE(MoeMojiWindow, moemoji_window, GTK_TYPE_APPLICATION_WINDOW)
static void reload_categories(MoeMojiWindow *self);
static void copy_dir_recursive(const char *src, const char *dst);
static void remove_dir_recursive(const char *path);
static void category_widgets_free(gpointer data) {
CategoryWidgets *cw = data;
@@ -59,6 +61,45 @@ char *find_kaomoji_dir(void) {
return NULL;
}
static char *user_kaomoji_dir(void) {
return g_build_filename(g_get_user_data_dir(), "moemoji", "kaomoji", NULL);
}
static void copy_builtins_to_user_dir(void) {
g_autofree char *dst = user_kaomoji_dir();
g_mkdir_with_parents(dst, 0755);
char *src = find_kaomoji_dir();
if (!src)
return;
GDir *dir = g_dir_open(src, 0, NULL);
if (dir) {
const char *name;
while ((name = g_dir_read_name(dir)) != NULL) {
g_autofree char *s = g_build_filename(src, name, NULL);
g_autofree char *d = g_build_filename(dst, name, NULL);
if (g_file_test(s, G_FILE_TEST_IS_DIR) &&
!g_file_test(d, G_FILE_TEST_EXISTS))
copy_dir_recursive(s, d);
}
g_dir_close(dir);
}
g_free(src);
}
static void first_launch_setup(void) {
g_autofree char *dir = user_kaomoji_dir();
if (g_file_test(dir, G_FILE_TEST_IS_DIR)) {
GDir *d = g_dir_open(dir, 0, NULL);
if (d) {
gboolean has_entries = g_dir_read_name(d) != NULL;
g_dir_close(d);
if (has_entries)
return;
}
}
copy_builtins_to_user_dir();
}
static void on_kaomoji_clicked(GtkButton *button, gpointer user_data) {
MoeMojiWindow *self = MOEMOJI_WINDOW(user_data);
const char *full = g_object_get_data(G_OBJECT(button), "full-text");
@@ -150,6 +191,18 @@ static void show_context_popover(GtkWidget *parent, GtkWidget *box, double x,
static void rebuild_pinned_box(MoeMojiWindow *self);
/* Build a flat chip button with an ellipsizing left-aligned label. */
static GtkWidget *make_chip_button(const char *label_text) {
GtkWidget *btn = gtk_button_new_with_label(label_text);
gtk_widget_add_css_class(btn, "category-chip");
gtk_widget_add_css_class(btn, "flat");
gtk_button_set_has_frame(GTK_BUTTON(btn), FALSE);
GtkWidget *lbl = gtk_button_get_child(GTK_BUTTON(btn));
gtk_label_set_xalign(GTK_LABEL(lbl), 0.0);
gtk_label_set_ellipsize(GTK_LABEL(lbl), PANGO_ELLIPSIZE_END);
return btn;
}
static gboolean is_kaomoji_pinned(MoeMojiWindow *self, const char *text) {
g_auto(GStrv) pinned = g_settings_get_strv(self->settings, "pinned-kaomojis");
return g_strv_contains((const char *const *)pinned, text);
@@ -276,6 +329,7 @@ static void add_kaomoji_button(MoeMojiWindow *self, GtkFlowBox *flow,
GtkWidget *button = gtk_button_new_with_label(label_text);
gtk_widget_set_halign(button, GTK_ALIGN_FILL);
GtkWidget *label = gtk_button_get_child(GTK_BUTTON(button));
gtk_widget_add_css_class(label, "kaomoji-label");
gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_END);
gtk_label_set_xalign(GTK_LABEL(label), 0.0);
gtk_widget_add_css_class(button, "kaomoji-button");
@@ -446,7 +500,8 @@ static void set_active_chip(MoeMojiWindow *self, int index) {
}
}
static void scroll_chip_into_view(MoeMojiWindow *self, GtkWidget *chip) {
static void scroll_chip_into_view(G_GNUC_UNUSED MoeMojiWindow *self,
GtkWidget *chip) {
GtkWidget *sw = gtk_widget_get_ancestor(chip, GTK_TYPE_SCROLLED_WINDOW);
if (!sw)
return;
@@ -482,7 +537,14 @@ static void on_chip_clicked(GtkButton *button, gpointer user_data) {
for (guint i = 0; i < self->category_widgets->len; i++) {
CategoryWidgets *cw = g_ptr_array_index(self->category_widgets, i);
if (cw->chip == GTK_WIDGET(button)) {
scroll_to_category(self, (int)i);
set_active_chip(self, (int)i);
graphene_point_t p;
if (gtk_widget_compute_point(cw->header, GTK_WIDGET(self->content_box),
&GRAPHENE_POINT_INIT(0, 0), &p)) {
GtkAdjustment *vadj = gtk_scrolled_window_get_vadjustment(
GTK_SCROLLED_WINDOW(self->kaomoji_scroll));
gtk_adjustment_set_value(vadj, p.y);
}
return;
}
}
@@ -632,19 +694,14 @@ static gint compare_entries(gconstpointer a, gconstpointer b) {
}
static GPtrArray *collect_all_categories(void) {
g_autofree char *user_dir =
g_build_filename(g_get_user_data_dir(), "moemoji", "kaomoji", NULL);
char *kaomoji_dir = find_kaomoji_dir();
g_autofree char *user_dir = user_kaomoji_dir();
GHashTable *seen =
g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
GPtrArray *entries = g_ptr_array_new();
if (g_file_test(user_dir, G_FILE_TEST_IS_DIR))
collect_categories(user_dir, seen, entries);
if (kaomoji_dir)
collect_categories(kaomoji_dir, seen, entries);
g_hash_table_destroy(seen);
g_ptr_array_sort(entries, compare_entries);
g_free(kaomoji_dir);
return entries;
}
@@ -755,15 +812,11 @@ static void on_category_name_changed(G_GNUC_UNUSED GtkEditable *editable,
const char *text =
gtk_editable_get_text(GTK_EDITABLE(self->category_name_entry));
const char *error = NULL;
gboolean valid = TRUE;
if (!is_valid_category_name(text)) {
valid = FALSE;
} else if (category_name_taken(text)) {
if (is_valid_category_name(text) && category_name_taken(text))
error = "A category with this name already exists";
valid = FALSE;
}
gboolean valid = is_valid_category_name(text) && !error;
gtk_widget_set_sensitive(self->category_save_button, valid);
gtk_label_set_text(GTK_LABEL(self->category_error_label), error ? error : "");
gtk_widget_set_visible(self->category_error_label, error != NULL);
@@ -778,8 +831,8 @@ static void on_category_save_clicked(G_GNUC_UNUSED GtkButton *button,
return;
g_autofree char *stripped = g_strstrip(g_strdup(text));
g_autofree char *uuid = g_uuid_string_random();
g_autofree char *cat_path =
g_build_filename(g_get_user_data_dir(), "moemoji", "kaomoji", uuid, NULL);
g_autofree char *udir = user_kaomoji_dir();
g_autofree char *cat_path = g_build_filename(udir, uuid, NULL);
g_mkdir_with_parents(cat_path, 0755);
g_autofree char *name_file = g_build_filename(cat_path, ".name", NULL);
g_file_set_contents(name_file, stripped, -1, NULL);
@@ -893,7 +946,7 @@ static void on_chip_drag_begin(GtkDragSource *source,
static void clear_drop_indicator(GtkWidget *chip_box) {
GtkWidget *active = g_object_get_data(G_OBJECT(chip_box), "active-drop-sep");
if (active) {
gtk_widget_set_visible(active, FALSE);
gtk_widget_set_opacity(active, 0);
g_object_set_data(G_OBJECT(chip_box), "active-drop-sep", NULL);
}
}
@@ -911,7 +964,7 @@ static void show_drop_indicator(GtkWidget *chip, double y) {
else
sep = g_object_get_data(G_OBJECT(chip), "drop-sep-after");
if (sep) {
gtk_widget_set_visible(sep, TRUE);
gtk_widget_set_opacity(sep, 1);
g_object_set_data(G_OBJECT(chip_box), "active-drop-sep", sep);
}
}
@@ -1063,20 +1116,12 @@ static void rebuild_pinned_box(MoeMojiWindow *self) {
for (guint i = 0; pinned[i]; i++) {
const char *text = pinned[i];
gboolean multiline = (strchr(text, '\n') != NULL);
const char *label_text = text;
g_autofree char *first_line = NULL;
if (multiline) {
const char *nl = strchr(text, '\n');
first_line = g_strndup(text, nl - text);
label_text = first_line;
}
GtkWidget *btn = gtk_button_new_with_label(label_text);
gtk_widget_add_css_class(btn, "category-chip");
gtk_widget_add_css_class(btn, "flat");
gtk_button_set_has_frame(GTK_BUTTON(btn), FALSE);
GtkWidget *label = gtk_button_get_child(GTK_BUTTON(btn));
gtk_label_set_xalign(GTK_LABEL(label), 0.0);
gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_END);
GtkWidget *btn = make_chip_button(multiline ? first_line : text);
if (multiline)
g_object_set_data_full(G_OBJECT(btn), "full-text", g_strdup(text),
g_free);
@@ -1125,13 +1170,7 @@ static void reload_categories(MoeMojiWindow *self) {
GtkWidget *chip_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 2);
for (guint i = 0; i < self->category_widgets->len; i++) {
CategoryWidgets *cw = g_ptr_array_index(self->category_widgets, i);
GtkWidget *btn = gtk_button_new_with_label(cw->name);
gtk_widget_add_css_class(btn, "category-chip");
gtk_widget_add_css_class(btn, "flat");
gtk_button_set_has_frame(GTK_BUTTON(btn), FALSE);
GtkWidget *chip_label = gtk_button_get_child(GTK_BUTTON(btn));
gtk_label_set_xalign(GTK_LABEL(chip_label), 0.0);
gtk_label_set_ellipsize(GTK_LABEL(chip_label), PANGO_ELLIPSIZE_END);
GtkWidget *btn = make_chip_button(cw->name);
g_object_set_data_full(G_OBJECT(btn), "cat-path", g_strdup(cw->path),
g_free);
g_object_set_data_full(G_OBJECT(btn), "cat-name", g_strdup(cw->name),
@@ -1161,7 +1200,8 @@ static void reload_categories(MoeMojiWindow *self) {
GtkWidget *sep = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
gtk_widget_add_css_class(sep, "chip-drop-line");
gtk_widget_set_size_request(sep, -1, 2);
gtk_widget_set_visible(sep, FALSE);
gtk_widget_set_opacity(sep, 0);
gtk_widget_set_can_target(sep, FALSE);
gtk_box_append(GTK_BOX(chip_box), sep);
g_object_set_data(G_OBJECT(btn), "drop-sep-before", sep);
if (i > 0) {
@@ -1176,7 +1216,8 @@ static void reload_categories(MoeMojiWindow *self) {
GtkWidget *tail = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
gtk_widget_add_css_class(tail, "chip-drop-line");
gtk_widget_set_size_request(tail, -1, 2);
gtk_widget_set_visible(tail, FALSE);
gtk_widget_set_opacity(tail, 0);
gtk_widget_set_can_target(tail, FALSE);
gtk_box_append(GTK_BOX(chip_box), tail);
g_object_set_data(G_OBJECT(btn), "drop-sep-after", tail);
}
@@ -1466,19 +1507,13 @@ static void on_rename_entry_changed(GtkEditable *editable, gpointer user_data) {
const char *original = g_object_get_data(G_OBJECT(dialog), "original-name");
g_autofree char *stripped = g_strstrip(g_strdup(text));
const char *error = NULL;
gboolean valid = TRUE;
if (stripped[0] == '\0') {
if (stripped[0] == '\0')
error = "Name cannot be empty";
valid = FALSE;
} else if (g_strcmp0(stripped, original) == 0) {
error = NULL;
valid = FALSE;
} else if (category_name_taken(stripped)) {
else if (category_name_taken(stripped))
error = "A category with this name already exists";
valid = FALSE;
}
gboolean valid = !error && g_strcmp0(stripped, original) != 0;
adw_alert_dialog_set_body(dialog, error ? error : "");
adw_alert_dialog_set_response_enabled(dialog, "rename", valid);
}
@@ -1596,8 +1631,7 @@ static void on_export_save_ready(GObject *source, GAsyncResult *res,
g_autofree char *tmpdir = g_dir_make_tmp("moemoji-export-XXXXXX", NULL);
if (!tmpdir)
return;
g_autofree char *user_dir =
g_build_filename(g_get_user_data_dir(), "moemoji", "kaomoji", NULL);
g_autofree char *user_dir = user_kaomoji_dir();
if (g_file_test(user_dir, G_FILE_TEST_IS_DIR)) {
GDir *dir = g_dir_open(user_dir, 0, NULL);
if (dir) {
@@ -1612,23 +1646,6 @@ static void on_export_save_ready(GObject *source, GAsyncResult *res,
g_dir_close(dir);
}
}
char *kaomoji_dir = find_kaomoji_dir();
if (kaomoji_dir) {
GDir *dir = g_dir_open(kaomoji_dir, 0, NULL);
if (dir) {
const char *name;
while ((name = g_dir_read_name(dir)) != NULL) {
g_autofree char *dst = g_build_filename(tmpdir, name, NULL);
if (g_file_test(dst, G_FILE_TEST_IS_DIR))
continue;
g_autofree char *src = g_build_filename(kaomoji_dir, name, NULL);
if (g_file_test(src, G_FILE_TEST_IS_DIR))
copy_dir_recursive(src, dst);
}
g_dir_close(dir);
}
g_free(kaomoji_dir);
}
GSubprocess *tar = g_subprocess_new(G_SUBPROCESS_FLAGS_NONE, NULL, "tar",
"czf", path, "-C", tmpdir, ".", NULL);
if (tar) {
@@ -1665,8 +1682,7 @@ static void on_export_activated(G_GNUC_UNUSED GSimpleAction *action,
}
static void clear_user_categories(void) {
g_autofree char *user_dir =
g_build_filename(g_get_user_data_dir(), "moemoji", "kaomoji", NULL);
g_autofree char *user_dir = user_kaomoji_dir();
GDir *dir = g_dir_open(user_dir, 0, NULL);
if (!dir)
return;
@@ -1680,8 +1696,7 @@ static void clear_user_categories(void) {
}
static void do_import(MoeMojiWindow *self, const char *fpath) {
g_autofree char *user_dir =
g_build_filename(g_get_user_data_dir(), "moemoji", "kaomoji", NULL);
g_autofree char *user_dir = user_kaomoji_dir();
clear_user_categories();
g_mkdir_with_parents(user_dir, 0755);
GSubprocess *tar = g_subprocess_new(G_SUBPROCESS_FLAGS_NONE, NULL, "tar",
@@ -1769,12 +1784,63 @@ static void on_restore_default_order(G_GNUC_UNUSED GSimpleAction *action,
reload_categories(self);
}
static void on_reset_kaomojis_response(AdwAlertDialog *dialog,
GAsyncResult *res, gpointer user_data) {
MoeMojiWindow *self = MOEMOJI_WINDOW(user_data);
const char *response = adw_alert_dialog_choose_finish(dialog, res);
if (g_strcmp0(response, "reset") != 0)
return;
clear_user_categories();
copy_builtins_to_user_dir();
g_settings_reset(self->settings, "category-order");
g_settings_reset(self->settings, "pinned-kaomojis");
reload_categories(self);
}
static void on_reset_kaomojis(G_GNUC_UNUSED GSimpleAction *action,
G_GNUC_UNUSED GVariant *parameter,
gpointer user_data) {
MoeMojiWindow *self = MOEMOJI_WINDOW(user_data);
AdwAlertDialog *dialog = ADW_ALERT_DIALOG(adw_alert_dialog_new(
"Reset Kaomojis?", "This will delete all custom categories and restore "
"the built-in kaomojis. Pinned kaomojis will also "
"be cleared."));
adw_alert_dialog_add_responses(dialog, "cancel", "Cancel", "reset", "Reset",
NULL);
adw_alert_dialog_set_response_appearance(dialog, "reset",
ADW_RESPONSE_DESTRUCTIVE);
adw_alert_dialog_set_default_response(dialog, "cancel");
adw_alert_dialog_set_close_response(dialog, "cancel");
adw_alert_dialog_choose(dialog, GTK_WIDGET(self), NULL,
(GAsyncReadyCallback)on_reset_kaomojis_response,
self);
}
static void reset_chip_controllers(MoeMojiWindow *self) {
for (guint i = 0; i < self->category_widgets->len; i++) {
CategoryWidgets *cw = g_ptr_array_index(self->category_widgets, i);
if (!cw->chip)
continue;
GListModel *controllers = gtk_widget_observe_controllers(cw->chip);
guint n = g_list_model_get_n_items(controllers);
for (guint j = 0; j < n; j++) {
GtkEventController *c = g_list_model_get_item(controllers, j);
if (GTK_IS_DRAG_SOURCE(c) || GTK_IS_DROP_TARGET(c))
gtk_event_controller_reset(c);
g_object_unref(c);
}
g_object_unref(controllers);
}
}
static void on_sidebar_toggled(GtkToggleButton *toggle, gpointer user_data) {
MoeMojiWindow *self = MOEMOJI_WINDOW(user_data);
gboolean active = gtk_toggle_button_get_active(toggle);
GtkWidget *start = gtk_paned_get_start_child(self->paned);
if (start)
gtk_widget_set_visible(start, active);
if (active)
reset_chip_controllers(self);
gtk_button_set_icon_name(GTK_BUTTON(toggle),
active ? "pan-start-symbolic" : "pan-end-symbolic");
}
@@ -1816,6 +1882,7 @@ static void moemoji_window_class_init(MoeMojiWindowClass *klass) {
}
static void moemoji_window_init(MoeMojiWindow *self) {
first_launch_setup();
gtk_widget_init_template(GTK_WIDGET(self));
gtk_widget_add_css_class(GTK_WIDGET(self), "wallpaper-bg");
gtk_widget_add_css_class(GTK_WIDGET(self->content_box), "content-area");
@@ -1885,6 +1952,7 @@ static void moemoji_window_init(MoeMojiWindow *self) {
GMenu *primary_menu = g_menu_new();
g_menu_append(primary_menu, "Export…", "win.export");
g_menu_append(primary_menu, "Import…", "win.import");
g_menu_append(primary_menu, "Reset Kaomojis…", "win.reset-kaomojis");
gtk_menu_button_set_menu_model(GTK_MENU_BUTTON(self->menu_button),
G_MENU_MODEL(primary_menu));
g_object_unref(primary_menu);
@@ -1894,48 +1962,25 @@ static void moemoji_window_init(MoeMojiWindow *self) {
g_ptr_array_new_with_free_func(category_widgets_free);
self->active_chip_index = -1;
GSimpleAction *export_action = g_simple_action_new("export", NULL);
g_signal_connect(export_action, "activate", G_CALLBACK(on_export_activated),
self);
g_action_map_add_action(G_ACTION_MAP(self), G_ACTION(export_action));
g_object_unref(export_action);
GSimpleAction *import_action = g_simple_action_new("import", NULL);
g_signal_connect(import_action, "activate", G_CALLBACK(on_import_activated),
self);
g_action_map_add_action(G_ACTION_MAP(self), G_ACTION(import_action));
g_object_unref(import_action);
GSimpleAction *ctx_rename_cat =
g_simple_action_new("ctx-rename-category", NULL);
g_signal_connect(ctx_rename_cat, "activate",
G_CALLBACK(on_ctx_rename_category), self);
g_action_map_add_action(G_ACTION_MAP(self), G_ACTION(ctx_rename_cat));
g_object_unref(ctx_rename_cat);
GSimpleAction *ctx_delete_cat =
g_simple_action_new("ctx-delete-category", NULL);
g_signal_connect(ctx_delete_cat, "activate",
G_CALLBACK(on_ctx_delete_category), self);
g_action_map_add_action(G_ACTION_MAP(self), G_ACTION(ctx_delete_cat));
g_object_unref(ctx_delete_cat);
GSimpleAction *ctx_delete_emote =
g_simple_action_new("ctx-delete-emote", NULL);
g_signal_connect(ctx_delete_emote, "activate",
G_CALLBACK(on_ctx_delete_emote), self);
g_action_map_add_action(G_ACTION_MAP(self), G_ACTION(ctx_delete_emote));
g_object_unref(ctx_delete_emote);
GSimpleAction *ctx_pin = g_simple_action_new("ctx-pin-emote", NULL);
g_signal_connect(ctx_pin, "activate", G_CALLBACK(on_ctx_pin_emote), self);
g_action_map_add_action(G_ACTION_MAP(self), G_ACTION(ctx_pin));
g_object_unref(ctx_pin);
GSimpleAction *ctx_unpin = g_simple_action_new("ctx-unpin-emote", NULL);
g_signal_connect(ctx_unpin, "activate", G_CALLBACK(on_ctx_unpin_emote), self);
g_action_map_add_action(G_ACTION_MAP(self), G_ACTION(ctx_unpin));
g_object_unref(ctx_unpin);
static const struct {
const char *name;
GCallback cb;
} actions[] = {
{"export", G_CALLBACK(on_export_activated)},
{"import", G_CALLBACK(on_import_activated)},
{"reset-kaomojis", G_CALLBACK(on_reset_kaomojis)},
{"ctx-rename-category", G_CALLBACK(on_ctx_rename_category)},
{"ctx-delete-category", G_CALLBACK(on_ctx_delete_category)},
{"ctx-delete-emote", G_CALLBACK(on_ctx_delete_emote)},
{"ctx-pin-emote", G_CALLBACK(on_ctx_pin_emote)},
{"ctx-unpin-emote", G_CALLBACK(on_ctx_unpin_emote)},
};
for (gsize i = 0; i < G_N_ELEMENTS(actions); i++) {
GSimpleAction *a = g_simple_action_new(actions[i].name, NULL);
g_signal_connect(a, "activate", actions[i].cb, self);
g_action_map_add_action(G_ACTION_MAP(self), G_ACTION(a));
g_object_unref(a);
}
g_signal_connect(self->add_button, "clicked", G_CALLBACK(on_add_clicked),
self);
+1 -1
View File
@@ -4,7 +4,7 @@
padding: 4px 8px;
}
.kaomoji-button label {
.kaomoji-label {
text-align: left;
text-shadow:
-1px -1px 0 rgba(0, 0, 0, 0.6),