aboutsummaryrefslogtreecommitdiff
path: root/src/stardict-view.c
diff options
context:
space:
mode:
authorPřemysl Eric Janouch <p@janouch.name>2021-10-15 23:58:06 +0200
committerPřemysl Eric Janouch <p@janouch.name>2021-10-15 23:59:45 +0200
commit8fb2ce29cf2c493db2d213fc291a8903b05a67f7 (patch)
treec9844b2393b218e8069175a0c6167c98da0625b1 /src/stardict-view.c
parentce92a23551fa0fd8ce5b6405d78805c9fa73e20e (diff)
downloadtdv-8fb2ce29cf2c493db2d213fc291a8903b05a67f7.tar.gz
tdv-8fb2ce29cf2c493db2d213fc291a8903b05a67f7.tar.xz
tdv-8fb2ce29cf2c493db2d213fc291a8903b05a67f7.zip
sdgui: clean up scrolling code
Diffstat (limited to 'src/stardict-view.c')
-rw-r--r--src/stardict-view.c113
1 files changed, 52 insertions, 61 deletions
diff --git a/src/stardict-view.c b/src/stardict-view.c
index ce9eafc..5e7ba35 100644
--- a/src/stardict-view.c
+++ b/src/stardict-view.c
@@ -211,17 +211,56 @@ struct _StardictView
GList *entries; ///< ViewEntry-s within the view
};
+static ViewEntry *
+make_entry (StardictView *self, StardictIterator *iterator)
+{
+ ViewEntry *ve =
+ view_entry_new (iterator, self->matched ? self->matched : "");
+
+ GtkWidget *widget = GTK_WIDGET (self);
+ view_entry_rebuild_layout (ve, gtk_widget_get_pango_context (widget),
+ gtk_widget_get_allocated_width (widget));
+ return ve;
+}
+
static void
-adjust_for_offset (StardictView *self)
+adjust_for_height (StardictView *self)
{
- // FIXME: lots of code duplication with reload(), could be refactored
GtkWidget *widget = GTK_WIDGET (self);
- PangoContext *pc = gtk_widget_get_pango_context (widget);
- const gchar *matched = self->matched ? self->matched : "";
+ StardictIterator *iterator =
+ stardict_iterator_new (self->dict, self->top_position);
- GtkAllocation allocation = {};
- gtk_widget_get_allocation (widget, &allocation);
+ gint missing = gtk_widget_get_allocated_height (widget) + self->top_offset;
+ for (GList *iter = self->entries, *next;
+ next = g_list_next (iter), iter; iter = next)
+ {
+ if (missing > 0)
+ missing -= view_entry_height (iter->data, NULL, NULL);
+ else
+ {
+ view_entry_destroy (iter->data);
+ self->entries = g_list_delete_link (self->entries, iter);
+ }
+ stardict_iterator_next (iterator);
+ }
+
+ GList *append = NULL;
+ while (missing > 0 && stardict_iterator_is_valid (iterator))
+ {
+ ViewEntry *ve = make_entry (self, iterator);
+ missing -= view_entry_height (ve, NULL, NULL);
+ append = g_list_prepend (append, ve);
+ stardict_iterator_next (iterator);
+ }
+ g_object_unref (iterator);
+ self->entries = g_list_concat (self->entries, g_list_reverse (append));
+ gtk_widget_queue_draw (widget);
+}
+
+static void
+adjust_for_offset (StardictView *self)
+{
// If scrolled way up, prepend entries so long as it's possible
StardictIterator *iterator =
stardict_iterator_new (self->dict, self->top_position);
@@ -235,8 +274,7 @@ adjust_for_offset (StardictView *self)
}
self->top_position = stardict_iterator_get_offset (iterator);
- ViewEntry *ve = view_entry_new (iterator, matched);
- view_entry_rebuild_layout (ve, pc, allocation.width);
+ ViewEntry *ve = make_entry (self, iterator);
self->top_offset += view_entry_height (ve, NULL, NULL);
self->entries = g_list_prepend (self->entries, ve);
}
@@ -259,67 +297,20 @@ adjust_for_offset (StardictView *self)
self->top_offset = 0;
// Load replacement trailing entries, or drop those no longer visible
- iterator = stardict_iterator_new (self->dict, self->top_position);
- gint used = -self->top_offset;
- for (GList *iter = self->entries, *next;
- next = g_list_next (iter), iter; iter = next)
- {
- if (used < allocation.height)
- used += view_entry_height (iter->data, NULL, NULL);
- else
- {
- view_entry_destroy (iter->data);
- self->entries = g_list_delete_link (self->entries, iter);
- }
- stardict_iterator_next (iterator);
- }
- while (used < allocation.height && stardict_iterator_is_valid (iterator))
- {
- ViewEntry *ve = view_entry_new (iterator, matched);
- view_entry_rebuild_layout (ve, pc, allocation.width);
- used += view_entry_height (ve, NULL, NULL);
- self->entries = g_list_append (self->entries, ve);
- stardict_iterator_next (iterator);
- }
- g_object_unref (iterator);
-
- gtk_widget_queue_draw (widget);
+ adjust_for_height (self);
}
static void
reload (StardictView *self)
{
- g_list_free_full (self->entries, (GDestroyNotify) view_entry_destroy);
- self->entries = NULL;
-
GtkWidget *widget = GTK_WIDGET (self);
- if (!gtk_widget_get_realized (widget) || !self->dict)
- return;
-
- GtkAllocation allocation = {};
- gtk_widget_get_allocation (widget, &allocation);
-
- PangoContext *pc = gtk_widget_get_pango_context (widget);
- StardictIterator *iterator =
- stardict_iterator_new (self->dict, self->top_position);
-
- gint used = 0;
- const gchar *matched = self->matched ? self->matched : "";
- while (used < allocation.height && stardict_iterator_is_valid (iterator))
- {
- ViewEntry *ve = view_entry_new (iterator, matched);
- view_entry_rebuild_layout (ve, pc, allocation.width);
- used += view_entry_height (ve, NULL, NULL);
- self->entries = g_list_prepend (self->entries, ve);
- stardict_iterator_next (iterator);
- }
- g_object_unref (iterator);
- self->entries = g_list_reverse (self->entries);
-
- // Right now, we're being lazy--this could be integrated here
- adjust_for_offset (self);
+ g_list_free_full (self->entries, (GDestroyNotify) view_entry_destroy);
+ self->entries = NULL;
gtk_widget_queue_draw (widget);
+
+ if (gtk_widget_get_realized (widget) && self->dict)
+ adjust_for_height (self);
}
static gint