sdtui: lay the groundwork for formatted entries
This commit is contained in:
parent
6f7fbbb438
commit
bc939712cb
70
src/sdtui.c
70
src/sdtui.c
|
@ -194,6 +194,7 @@ struct view_entry
|
||||||
{
|
{
|
||||||
gchar * word; ///< Word
|
gchar * word; ///< Word
|
||||||
GPtrArray * definitions; ///< Word definition entries (gchar *)
|
GPtrArray * definitions; ///< Word definition entries (gchar *)
|
||||||
|
GPtrArray * formatting; ///< chtype * or NULL per definition
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dictionary
|
struct dictionary
|
||||||
|
@ -275,10 +276,12 @@ view_entry_split_add (ViewEntry *ve, const gchar *text)
|
||||||
if (nl != p)
|
if (nl != p)
|
||||||
{
|
{
|
||||||
g_ptr_array_add (ve->definitions, g_strndup (p, nl - p));
|
g_ptr_array_add (ve->definitions, g_strndup (p, nl - p));
|
||||||
|
g_ptr_array_add (ve->formatting, NULL);
|
||||||
}
|
}
|
||||||
if (*p)
|
if (*p)
|
||||||
{
|
{
|
||||||
g_ptr_array_add (ve->definitions, g_strdup (p));
|
g_ptr_array_add (ve->definitions, g_strdup (p));
|
||||||
|
g_ptr_array_add (ve->formatting, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,6 +298,7 @@ view_entry_new (StardictIterator *iterator)
|
||||||
g_return_val_if_fail (entry != NULL, NULL);
|
g_return_val_if_fail (entry != NULL, NULL);
|
||||||
|
|
||||||
ve->definitions = g_ptr_array_new_with_free_func (g_free);
|
ve->definitions = g_ptr_array_new_with_free_func (g_free);
|
||||||
|
ve->formatting = g_ptr_array_new_with_free_func (g_free);
|
||||||
gboolean found_anything_displayable = FALSE;
|
gboolean found_anything_displayable = FALSE;
|
||||||
for (const GList *fields = stardict_entry_get_fields (entry); fields; )
|
for (const GList *fields = stardict_entry_get_fields (entry); fields; )
|
||||||
{
|
{
|
||||||
|
@ -341,6 +345,7 @@ view_entry_free (ViewEntry *ve)
|
||||||
{
|
{
|
||||||
g_free (ve->word);
|
g_free (ve->word);
|
||||||
g_ptr_array_free (ve->definitions, TRUE);
|
g_ptr_array_free (ve->definitions, TRUE);
|
||||||
|
g_ptr_array_free (ve->formatting, TRUE);
|
||||||
g_slice_free1 (sizeof *ve, ve);
|
g_slice_free1 (sizeof *ve, ve);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -777,10 +782,11 @@ row_buffer_init (RowBuffer *self, Application *app)
|
||||||
|
|
||||||
/// Replace invalid chars and push all codepoints to the array w/ attributes.
|
/// Replace invalid chars and push all codepoints to the array w/ attributes.
|
||||||
static void
|
static void
|
||||||
row_buffer_append (RowBuffer *self, const gchar *str, chtype attrs)
|
row_buffer_append_length (RowBuffer *self,
|
||||||
|
const gchar *text, glong length, chtype attrs)
|
||||||
{
|
{
|
||||||
glong ucs4_len;
|
glong ucs4_len;
|
||||||
gunichar *ucs4 = g_utf8_to_ucs4_fast (str, -1, &ucs4_len);
|
gunichar *ucs4 = g_utf8_to_ucs4_fast (text, length, &ucs4_len);
|
||||||
for (glong i = 0; i < ucs4_len; i++)
|
for (glong i = 0; i < ucs4_len; i++)
|
||||||
{
|
{
|
||||||
// XXX: this is very crude as it disrespects combining marks
|
// XXX: this is very crude as it disrespects combining marks
|
||||||
|
@ -793,6 +799,47 @@ row_buffer_append (RowBuffer *self, const gchar *str, chtype attrs)
|
||||||
g_free (ucs4);
|
g_free (ucs4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
row_buffer_append (RowBuffer *self, const gchar *text, chtype attrs)
|
||||||
|
{
|
||||||
|
row_buffer_append_length (self, text, -1, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Combine attributes, taking care to replace colour bits entirely
|
||||||
|
static void
|
||||||
|
row_buffer_merge_attributes (chtype *target, int merged)
|
||||||
|
{
|
||||||
|
if (merged & A_COLOR)
|
||||||
|
*target = (*target & ~A_COLOR) | merged;
|
||||||
|
else
|
||||||
|
*target |= merged;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
row_buffer_append_with_formatting (RowBuffer *self,
|
||||||
|
const gchar *text, const chtype *formatting, chtype default_attrs)
|
||||||
|
{
|
||||||
|
if (!formatting)
|
||||||
|
{
|
||||||
|
row_buffer_append (self, text, default_attrs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*text)
|
||||||
|
{
|
||||||
|
glong chunk_length = 1;
|
||||||
|
while (text[chunk_length] && formatting[chunk_length] == *formatting)
|
||||||
|
chunk_length++;
|
||||||
|
|
||||||
|
chtype merged = default_attrs;
|
||||||
|
row_buffer_merge_attributes (&merged, *formatting);
|
||||||
|
row_buffer_append_length (self, text, chunk_length, merged);
|
||||||
|
|
||||||
|
text += chunk_length;
|
||||||
|
formatting += chunk_length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Pop as many codepoints as needed to free up "space" character cells.
|
/// Pop as many codepoints as needed to free up "space" character cells.
|
||||||
/// Given the suffix nature of combining marks, this should work pretty fine.
|
/// Given the suffix nature of combining marks, this should work pretty fine.
|
||||||
static gint
|
static gint
|
||||||
|
@ -995,16 +1042,6 @@ app_show_help (Application *self)
|
||||||
app_show_message (self, lines, G_N_ELEMENTS (lines));
|
app_show_message (self, lines, G_N_ELEMENTS (lines));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Combine attributes, taking care to replace colour bits entirely
|
|
||||||
static void
|
|
||||||
app_merge_attributes (int *target, int merged)
|
|
||||||
{
|
|
||||||
if (merged & A_COLOR)
|
|
||||||
*target = (*target & ~A_COLOR) | merged;
|
|
||||||
else
|
|
||||||
*target |= merged;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Redraw the dictionary view.
|
/// Redraw the dictionary view.
|
||||||
static void
|
static void
|
||||||
app_redraw_view (Application *self)
|
app_redraw_view (Application *self)
|
||||||
|
@ -1029,11 +1066,11 @@ app_redraw_view (Application *self)
|
||||||
ViewEntry *ve = g_ptr_array_index (self->entries, i);
|
ViewEntry *ve = g_ptr_array_index (self->entries, i);
|
||||||
for (; k < ve->definitions->len; k++)
|
for (; k < ve->definitions->len; k++)
|
||||||
{
|
{
|
||||||
int attrs = ((self->top_position + i) & 1)
|
chtype attrs = ((self->top_position + i) & 1)
|
||||||
? APP_ATTR (ODD) : APP_ATTR (EVEN);
|
? APP_ATTR (ODD) : APP_ATTR (EVEN);
|
||||||
|
|
||||||
if (shown == self->selected)
|
if (shown == self->selected)
|
||||||
app_merge_attributes (&attrs, self->focused
|
row_buffer_merge_attributes (&attrs, self->focused
|
||||||
? APP_ATTR (SELECTION) : APP_ATTR (DEFOCUSED));
|
? APP_ATTR (SELECTION) : APP_ATTR (DEFOCUSED));
|
||||||
|
|
||||||
gboolean last = k + 1 == ve->definitions->len;
|
gboolean last = k + 1 == ve->definitions->len;
|
||||||
|
@ -1058,8 +1095,9 @@ app_redraw_view (Application *self)
|
||||||
|
|
||||||
row_buffer_init (&buf, self);
|
row_buffer_init (&buf, self);
|
||||||
row_buffer_append (&buf, " ", attrs);
|
row_buffer_append (&buf, " ", attrs);
|
||||||
row_buffer_append (&buf,
|
row_buffer_append_with_formatting (&buf,
|
||||||
g_ptr_array_index (ve->definitions, k), attrs);
|
g_ptr_array_index (ve->definitions, k),
|
||||||
|
g_ptr_array_index (ve->formatting, k), attrs);
|
||||||
row_buffer_finish (&buf, COLS - left_width, attrs);
|
row_buffer_finish (&buf, COLS - left_width, attrs);
|
||||||
|
|
||||||
if ((gint) ++shown == LINES - TOP_BAR_CUTOFF)
|
if ((gint) ++shown == LINES - TOP_BAR_CUTOFF)
|
||||||
|
|
Loading…
Reference in New Issue