aboutsummaryrefslogtreecommitdiff
path: root/src/sdgtk.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sdgtk.c')
-rw-r--r--src/sdgtk.c144
1 files changed, 18 insertions, 126 deletions
diff --git a/src/sdgtk.c b/src/sdgtk.c
index c104f38..3565bc6 100644
--- a/src/sdgtk.c
+++ b/src/sdgtk.c
@@ -1,7 +1,7 @@
/*
* StarDict GTK+ UI
*
- * Copyright (c) 2020, Přemysl Eric Janouch <p@janouch.name>
+ * Copyright (c) 2020 - 2021, Přemysl Eric Janouch <p@janouch.name>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
@@ -24,6 +24,7 @@
#include "config.h"
#include "stardict.h"
#include "utils.h"
+#include "stardict-view.h"
typedef struct dictionary Dictionary;
@@ -40,7 +41,7 @@ static struct
GtkWidget *window; ///< Top-level window
GtkWidget *notebook; ///< Notebook with tabs
GtkWidget *entry; ///< Search entry widget
- GtkWidget *grid; ///< Entries container
+ GtkWidget *view; ///< Entries view
gint dictionary; ///< Index of the current dictionary
Dictionary *dictionaries; ///< All open dictionaries
@@ -86,99 +87,6 @@ init (gchar **filenames, GError **e)
}
static void
-add_row (StardictIterator *iterator, gint row, gint *height_acc)
-{
- Dictionary *dict = &g.dictionaries[g.dictionary];
-
- StardictEntry *entry = stardict_iterator_get_entry (iterator);
- g_return_if_fail (entry != NULL);
- StardictEntryField *field = entry->fields->data;
- g_return_if_fail (g_ascii_islower (field->type));
-
- GtkEntryBuffer *buf = gtk_entry_get_buffer (GTK_ENTRY (g.entry));
- const gchar *input_utf8 = gtk_entry_buffer_get_text (buf);
- g_return_if_fail (input_utf8 != NULL);
-
- const gchar *word_str = stardict_iterator_get_word (iterator);
- gsize common_prefix = stardict_longest_common_collation_prefix
- (dict->dict, word_str, input_utf8);
- gchar *pre = g_markup_escape_text (word_str, common_prefix),
- *post = g_markup_escape_text (word_str + common_prefix, -1),
- *marked_up = g_strdup_printf ("<u>%s</u>%s", pre, post);
-
- GtkWidget *word = gtk_label_new (marked_up);
- gtk_label_set_use_markup (GTK_LABEL (word), TRUE);
- gtk_label_set_ellipsize (GTK_LABEL (word), PANGO_ELLIPSIZE_END);
- gtk_label_set_selectable (GTK_LABEL (word), TRUE);
- gtk_label_set_xalign (GTK_LABEL (word), 0);
- gtk_label_set_yalign (GTK_LABEL (word), 0);
- // FIXME: they can't be deselected by just clicking outside of them
- gtk_widget_set_can_focus (word, FALSE);
-
- g_free (pre);
- g_free (post);
- g_free (marked_up);
-
- GtkWidget *desc = gtk_label_new (field->data);
- gtk_label_set_ellipsize (GTK_LABEL (desc), PANGO_ELLIPSIZE_END);
- gtk_label_set_selectable (GTK_LABEL (desc), TRUE);
- gtk_label_set_xalign (GTK_LABEL (desc), 0);
- gtk_widget_set_can_focus (desc, FALSE);
-
- g_object_unref (entry);
-
- if (iterator->offset % 2 == 0)
- {
- GtkStyleContext *ctx;
- ctx = gtk_widget_get_style_context (word);
- gtk_style_context_add_class (ctx, "odd");
- ctx = gtk_widget_get_style_context (desc);
- gtk_style_context_add_class (ctx, "odd");
- }
-
- gtk_grid_attach (GTK_GRID (g.grid), word, 0, row, 1, 1);
- gtk_grid_attach (GTK_GRID (g.grid), desc, 1, row, 1, 1);
-
- gtk_widget_show (word);
- gtk_widget_show (desc);
-
- gint minimum_word = 0, minimum_desc = 0;
- gtk_widget_get_preferred_height (word, &minimum_word, NULL);
- gtk_widget_get_preferred_height (desc, &minimum_desc, NULL);
- *height_acc += MAX (minimum_word, minimum_desc);
-}
-
-static void
-reload (GtkWidget *grid)
-{
- Dictionary *dict = &g.dictionaries[g.dictionary];
-
- GList *children = gtk_container_get_children (GTK_CONTAINER (grid));
- for (GList *iter = children; iter != NULL; iter = g_list_next (iter))
- gtk_widget_destroy (GTK_WIDGET (iter->data));
- g_list_free (children);
-
- gint window_height = 0;
- gtk_window_get_size (GTK_WINDOW (g.window), NULL, &window_height);
- if (window_height <= 0)
- return;
-
- StardictIterator *iterator =
- stardict_iterator_new (dict->dict, dict->position);
- gint row = 0, height_acc = 0;
- while (stardict_iterator_is_valid (iterator))
- {
- add_row (iterator, row++, &height_acc);
- if (height_acc >= window_height)
- break;
-
- stardict_iterator_next (iterator);
- }
- gtk_widget_show_all (grid);
- g_object_unref (iterator);
-}
-
-static void
search (Dictionary *dict)
{
GtkEntryBuffer *buf = gtk_entry_get_buffer (GTK_ENTRY (g.entry));
@@ -188,13 +96,16 @@ search (Dictionary *dict)
stardict_dict_search (dict->dict, input_utf8, NULL);
dict->position = stardict_iterator_get_offset (iterator);
g_object_unref (iterator);
+
+ stardict_view_set_position (STARDICT_VIEW (g.view),
+ dict->dict, dict->position);
+ stardict_view_set_matched (STARDICT_VIEW (g.view), input_utf8);
}
static void
on_changed (G_GNUC_UNUSED GtkWidget *widget, G_GNUC_UNUSED gpointer data)
{
search (&g.dictionaries[g.dictionary]);
- reload (g.grid);
}
static void
@@ -231,7 +142,6 @@ on_switch_page (G_GNUC_UNUSED GtkWidget *widget, G_GNUC_UNUSED GtkWidget *page,
{
g.dictionary = page_num;
search (&g.dictionaries[g.dictionary]);
- reload (g.grid);
}
static gboolean
@@ -317,12 +227,8 @@ main (int argc, char *argv[])
if (!init (filenames, &error))
die_with_dialog (error->message);
- // Some Adwaita stupidity and our own additions
- const char *style = "notebook header tab { padding: 2px 8px; margin: 0; }"
- "grid { border-top: 1px solid rgba(0, 0, 0, 0.2); background: white; }"
- "grid label { padding: 0 5px; "
- "/*border-bottom: 1px solid rgba(0, 0, 0, 0.2);*/ }"
- "grid label.odd { background: rgba(0, 0, 0, 0.05); }";
+ // Some Adwaita stupidity
+ const char *style = "notebook header tab { padding: 2px 8px; margin: 0; }";
GdkScreen *screen = gdk_screen_get_default ();
GtkCssProvider *provider = gtk_css_provider_new ();
@@ -330,20 +236,6 @@ main (int argc, char *argv[])
gtk_style_context_add_provider_for_screen (screen,
GTK_STYLE_PROVIDER (provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
- g.grid = gtk_grid_new ();
- gtk_grid_set_column_homogeneous (GTK_GRID (g.grid), TRUE);
-
- // FIXME: we'd rather like to trim the contents, not make it scrollable.
- // This just limits the allocation.
- // TODO: probably create a whole new custom widget, everything is text
- // anyway and mostly handled by Pango, including pango_layout_xy_to_index()
- // - I don't know where to get selection colour but inversion works, too
- GtkWidget *scrolled_window = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
- GTK_POLICY_NEVER, GTK_POLICY_EXTERNAL);
- gtk_widget_set_can_focus (scrolled_window, FALSE);
- gtk_container_add (GTK_CONTAINER (scrolled_window), g.grid);
-
g.notebook = gtk_notebook_new ();
g_signal_connect (g.notebook, "switch-page",
G_CALLBACK (on_switch_page), NULL);
@@ -375,21 +267,28 @@ main (int argc, char *argv[])
// TODO: attach to the "key-press-event" signal and implement ^W at least,
// though ^U is working already! Note that bindings can be done in CSS
// as well, if we have any extra specially for the editor
- g_signal_connect (g.entry, "changed", G_CALLBACK (on_changed), g.grid);
+ g_signal_connect (g.entry, "changed", G_CALLBACK (on_changed), g.view);
+ // TODO: make the entry have a background colour, rather than transparency
gtk_entry_set_has_frame (GTK_ENTRY (g.entry), FALSE);
// TODO: supposedly attach to "key-press-event" here and react to
// PageUp/PageDown and up/down arrow keys... either here or in the Entry
g.window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_default_size (GTK_WINDOW (g.window), 300, 600);
g_signal_connect (g.window, "destroy",
G_CALLBACK (on_destroy), NULL);
g_signal_connect (g.window, "key-press-event",
G_CALLBACK (on_key_press), NULL);
+
GtkWidget *superbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 1);
gtk_container_add (GTK_CONTAINER (g.window), superbox);
gtk_container_add (GTK_CONTAINER (superbox), g.notebook);
gtk_container_add (GTK_CONTAINER (superbox), g.entry);
- gtk_box_pack_end (GTK_BOX (superbox), scrolled_window, TRUE, TRUE, 0);
+ gtk_container_add (GTK_CONTAINER (superbox),
+ gtk_separator_new (GTK_ORIENTATION_HORIZONTAL));
+
+ g.view = stardict_view_new ();
+ gtk_box_pack_end (GTK_BOX (superbox), g.view, TRUE, TRUE, 0);
for (gsize i = 0; i < g.dictionaries_len; i++)
{
@@ -403,13 +302,6 @@ main (int argc, char *argv[])
g_signal_connect (clipboard, "owner-change",
G_CALLBACK (on_selection), NULL);
- // Make sure to fill up the window with entries once we're resized
- // XXX: this is rather inefficient as we rebuild everything each time
- g_signal_connect (g.window, "configure-event",
- G_CALLBACK (on_changed), NULL);
- g_signal_connect (g.window, "map-event",
- G_CALLBACK (on_changed), NULL);
-
gtk_widget_grab_focus (g.entry);
gtk_widget_show_all (g.window);
gtk_main ();