88 int old_width = pango_layout_get_width(tb->
layout);
89 pango_layout_set_width(
96 pango_layout_set_width(tb->
layout, old_width);
103 gint y, G_GNUC_UNUSED
void *user_data) {
116 pango_layout_xy_to_index(tb->
layout, x * PANGO_SCALE, y * PANGO_SCALE, &i,
137 tbfc->
pfd = pango_font_description_from_string(font);
141 PangoLayout *layout = pango_layout_new(
p_context);
142 pango_layout_set_font_description(layout, tbfc->
pfd);
143 pango_layout_set_text(layout,
"aAjb", -1);
145 pango_layout_get_pixel_extents(layout, NULL, &rect);
146 tbfc->
height = rect.y + rect.height;
147 g_object_unref(layout);
151 g_hash_table_insert(
tbfc_cache, (
char *)font, tbfc);
153 pango_font_description_free(tbfc->
pfd);
160 pango_layout_set_font_description(tb->
layout, tbfc->
pfd);
170 PangoTabArray *tabs = pango_tab_array_new(g_list_length(dists), TRUE);
173 for (
const GList *iter = g_list_first(dists); iter != NULL;
174 iter = g_list_next(iter), i++) {
181 pango_tab_array_set_tab(tabs, i, PANGO_TAB_LEFT, px);
184 pango_layout_set_tabs(tb->
layout, tabs);
186 pango_tab_array_free(tabs);
187 g_list_free_full(dists, g_free);
193 const char *text,
double xalign,
double yalign) {
206 tb->
emode = PANGO_ELLIPSIZE_END;
217 pango_layout_set_wrap(tb->
layout, PANGO_WRAP_WORD_CHAR);
229 if (txt == NULL || (*txt) ==
'\0') {
232 const char *placeholder =
266 {
"normal.normal",
"selected.normal",
"alternate.normal"},
268 {
"normal.urgent",
"selected.urgent",
"alternate.urgent"},
270 {
"normal.active",
"selected.active",
"alternate.active"},
306 pango_layout_set_attributes(tb->
layout, NULL);
314 size_t l = g_utf8_strlen(tb->
text, -1);
316 memset(
string,
'*', l);
318 pango_layout_set_text(tb->
layout,
string, l);
320 pango_layout_set_markup(tb->
layout, tb->
text, -1);
322 pango_layout_set_text(tb->
layout, tb->
text, -1);
329 return pango_layout_get_text(tb->
layout);
335 return pango_layout_get_attributes(tb->
layout);
341 pango_layout_set_attributes(tb->
layout, list);
350 const gchar *last_pointer = NULL;
353 tb->
text = g_strdup(
"Invalid string.");
355 if (g_utf8_validate(text, -1, &last_pointer)) {
356 tb->
text = g_strdup(text);
358 if (last_pointer != NULL) {
360 tb->
text = g_strndup(text, (last_pointer - text));
362 tb->
text = g_strdup(
"Invalid UTF-8 string.");
383 pango_layout_set_width(tb->
layout, -1);
389 pango_layout_set_ellipsize(tb->
layout, PANGO_ELLIPSIZE_MIDDLE);
393 pango_layout_set_ellipsize(tb->
layout, PANGO_ELLIPSIZE_NONE);
400 pango_layout_set_width(
417 pango_layout_set_width(
437 g_object_unref(tb->
layout);
457 int y = (pango_font_metrics_get_ascent(tb->
tbfc->
metrics) -
458 pango_layout_get_baseline(tb->
layout)) /
460 int line_width = 0, line_height = 0;
462 pango_layout_get_pixel_size(tb->
layout, &line_width, &line_height);
466 top = (tb->
widget.
h - bottom - line_height - top) * tb->
yalign + top;
479 cairo_set_operator(draw, CAIRO_OPERATOR_OVER);
480 cairo_set_source_rgb(draw, 0.0, 0.0, 0.0);
488 cairo_move_to(draw, x, top);
490 cairo_reset_clip(draw);
491 pango_cairo_show_layout(draw, tb->
layout);
498 const char *text = pango_layout_get_text(tb->
layout);
500 int cursor_offset = MIN(tb->
cursor, g_utf8_strlen(text, -1));
503 char *offset = g_utf8_offset_to_pointer(text, cursor_offset);
504 pango_layout_get_cursor_pos(tb->
layout, offset - text, &pos, NULL);
505 int cursor_x = pos.x / PANGO_SCALE;
506 int cursor_y = pos.y / PANGO_SCALE;
507 int cursor_height = pos.height / PANGO_SCALE;
508 int cursor_width = 2;
509 cairo_rectangle(draw, x + cursor_x, y + cursor_y, cursor_width,
525 int length = (tb->
text == NULL) ? 0 : g_utf8_strlen(tb->
text, -1);
526 tb->
cursor = MAX(0, MIN(length, pos));
560 if (tb->
text == NULL) {
564 gchar *c = g_utf8_offset_to_pointer(tb->
text, tb->
cursor);
565 while ((c = g_utf8_next_char(c))) {
566 gunichar uc = g_utf8_get_char(c);
567 GUnicodeBreakType bt = g_unichar_break_type(uc);
568 if ((bt == G_UNICODE_BREAK_ALPHABETIC ||
569 bt == G_UNICODE_BREAK_HEBREW_LETTER || bt == G_UNICODE_BREAK_NUMERIC ||
570 bt == G_UNICODE_BREAK_QUOTATION)) {
574 if (c == NULL || *c ==
'\0') {
577 while ((c = g_utf8_next_char(c))) {
578 gunichar uc = g_utf8_get_char(c);
579 GUnicodeBreakType bt = g_unichar_break_type(uc);
580 if (!(bt == G_UNICODE_BREAK_ALPHABETIC ||
581 bt == G_UNICODE_BREAK_HEBREW_LETTER ||
582 bt == G_UNICODE_BREAK_NUMERIC || bt == G_UNICODE_BREAK_QUOTATION)) {
586 int index = g_utf8_pointer_to_offset(tb->
text, c);
593 gchar *c = g_utf8_offset_to_pointer(tb->
text, tb->
cursor);
594 while ((c = g_utf8_prev_char(c)) && c != tb->
text) {
595 gunichar uc = g_utf8_get_char(c);
596 GUnicodeBreakType bt = g_unichar_break_type(uc);
597 if ((bt == G_UNICODE_BREAK_ALPHABETIC ||
598 bt == G_UNICODE_BREAK_HEBREW_LETTER || bt == G_UNICODE_BREAK_NUMERIC ||
599 bt == G_UNICODE_BREAK_QUOTATION)) {
604 while ((n = g_utf8_prev_char(c))) {
605 gunichar uc = g_utf8_get_char(n);
606 GUnicodeBreakType bt = g_unichar_break_type(uc);
607 if (!(bt == G_UNICODE_BREAK_ALPHABETIC ||
608 bt == G_UNICODE_BREAK_HEBREW_LETTER ||
609 bt == G_UNICODE_BREAK_NUMERIC || bt == G_UNICODE_BREAK_QUOTATION)) {
618 int index = g_utf8_pointer_to_offset(tb->
text, c);
624 if (tb->
text == NULL) {
629 tb->
cursor = (int)g_utf8_strlen(tb->
text, -1);
641 char *c = g_utf8_offset_to_pointer(tb->
text, char_pos);
642 int pos = c - tb->
text;
643 int len = (int)strlen(tb->
text);
644 pos = MAX(0, MIN(len, pos));
646 tb->
text = g_realloc(tb->
text, len + slen + 1);
648 char *at = tb->
text + pos;
649 memmove(at + slen, at, len - pos + 1);
651 memmove(at, str, slen);
664 int len = g_utf8_strlen(tb->
text, -1);
668 pos = MAX(0, MIN(len, pos));
669 if ((pos + dlen) > len) {
673 char *start = g_utf8_offset_to_pointer(tb->
text, pos);
674 char *end = g_utf8_offset_to_pointer(tb->
text, pos + dlen);
676 memmove(start, end, (tb->
text + strlen(tb->
text)) - end + 1);
679 }
else if (tb->
cursor >= (pos + dlen)) {
694 if (tb == NULL || tb->
text == NULL) {
706 if (tb && tb->
cursor > 0) {
712 if (tb && tb->
cursor > 0) {
715 if (cursor > tb->
cursor) {
721 if (tb && tb->
cursor >= 0) {
722 int length = g_utf8_strlen(tb->
text, -1) - tb->
cursor;
729 if (tb && tb->
cursor >= 0) {
737 if (tb && tb->
cursor >= 0) {
740 if (cursor < tb->cursor) {
809 g_return_val_if_reached(0);
823 gboolean used_something = FALSE;
824 const gchar *w, *n, *e;
825 for (w = pad, n = g_utf8_next_char(w), e = w + pad_len; w < e;
826 w = n, n = g_utf8_next_char(n)) {
827 if (g_unichar_iscntrl(g_utf8_get_char(w))) {
832 used_something = TRUE;
834 return used_something;
838 pango_font_metrics_unref(tbfc->
metrics);
840 pango_font_description_free(tbfc->
pfd);
845 tbfc_cache = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
858 PangoLayout *layout = pango_layout_new(
p_context);
859 pango_layout_set_text(layout,
"aAjb", -1);
861 pango_layout_get_pixel_extents(layout, NULL, &rect);
862 tbfc->
height = rect.y + rect.height;
863 g_object_unref(layout);
892 tb, pango_layout_get_line_count(tb->
layout));
903 pango_layout_get_pixel_extents(tb->
layout, NULL, &rect);
904 return rect.height + rect.y;
909 pango_layout_get_pixel_extents(tb->
layout, NULL, &rect);
910 return rect.width + rect.x;
920 int width = pango_font_metrics_get_approximate_char_width(
p_metrics);
930 int width = pango_font_metrics_get_approximate_digit_width(
p_metrics);
931 ch_width = (width) / (
double)PANGO_SCALE;
957 int old_width = pango_layout_get_width(tb->
layout);
958 pango_layout_set_width(tb->
layout, -1);
961 pango_layout_set_width(tb->
layout, old_width);
962 return width + padding + offset;
gboolean helper_validate_font(PangoFontDescription *pfd, const char *font)
MouseBindingMouseDefaultAction
int textbox_get_height(const textbox *tb)
void textbox_insert(textbox *tb, const int char_pos, const char *str, const int slen)
void textbox_font(textbox *tb, TextBoxFontType tbft)
void textbox_delete(textbox *tb, int pos, int dlen)
int textbox_keybinding(textbox *tb, KeyBindingAction action)
void textbox_cleanup(void)
double textbox_get_estimated_char_width(void)
int textbox_get_font_height(const textbox *tb)
void textbox_set_pango_attributes(textbox *tb, PangoAttrList *list)
void textbox_set_ellipsize(textbox *tb, PangoEllipsizeMode mode)
const char * textbox_get_visible_text(const textbox *tb)
double textbox_get_estimated_char_height(void)
PangoAttrList * textbox_get_pango_attributes(textbox *tb)
textbox * textbox_create(widget *parent, WidgetType type, const char *name, TextboxFlags flags, TextBoxFontType tbft, const char *text, double xalign, double yalign)
int textbox_get_estimated_height(const textbox *tb, int eh)
void textbox_cursor(textbox *tb, int pos)
void textbox_set_pango_context(const char *font, PangoContext *p)
int textbox_get_font_width(const textbox *tb)
void textbox_cursor_end(textbox *tb)
gboolean textbox_append_text(textbox *tb, const char *pad, const int pad_len)
void textbox_moveresize(textbox *tb, int x, int y, int w, int h)
void textbox_text(textbox *tb, const char *text)
double textbox_get_estimated_ch(void)
void rofi_view_queue_redraw(void)
@ ROFI_ORIENTATION_HORIZONTAL
PangoFontMetrics * metrics
PangoFontDescription * pfd
static TBFontConfig * tbfc_default
static PangoContext * p_context
static int textbox_get_width(widget *)
static void textbox_cursor_dec_word(textbox *tb)
static void textbox_cursor_inc_word(textbox *tb)
static gboolean textbox_blink(gpointer data)
static WidgetTriggerActionResult textbox_editable_trigger_action(widget *wid, MouseBindingMouseDefaultAction action, gint x, gint y, G_GNUC_UNUSED void *user_data)
const char *const theme_prop_names[][3]
const char * default_font_name
static int textbox_get_desired_height(widget *wid, const int width)
static int textbox_cursor_inc(textbox *tb)
static void textbox_free(widget *)
int textbox_get_desired_width(widget *wid, G_GNUC_UNUSED const int height)
static void textbox_initialize_font(textbox *tb)
static void textbox_resize(widget *wid, short w, short h)
static void textbox_cursor_del_sol(textbox *tb)
static void textbox_tab_stops(textbox *tb)
static void textbox_cursor_bkspc(textbox *tb)
static void textbox_cursor_bkspc_word(textbox *tb)
static void textbox_draw(widget *, cairo_t *)
static void textbox_cursor_del_word(textbox *tb)
static PangoFontMetrics * p_metrics
static void textbox_cursor_del(textbox *tb)
static void __textbox_update_pango_text(textbox *tb)
static int _textbox_get_height(widget *)
static void textbox_cursor_del_eol(textbox *tb)
static int textbox_cursor_dec(textbox *tb)
static void tbfc_entry_free(TBFontConfig *tbfc)
static GHashTable * tbfc_cache
GList * rofi_theme_get_list_distance(const widget *widget, const char *property)
RofiDistance rofi_theme_get_distance(const widget *widget, const char *property, int def)
int rofi_theme_get_boolean(const widget *widget, const char *property, int def)
int distance_get_pixel(RofiDistance d, RofiOrientation ori)
void rofi_theme_get_color(const widget *widget, const char *property, cairo_t *d)
double rofi_theme_get_double(const widget *widget, const char *property, double def)
const char * rofi_theme_get_string(const widget *widget, const char *property, const char *def)