95 gint y, G_GNUC_UNUSED
void *user_data) {
108 pango_layout_xy_to_index(tb->
layout, x * PANGO_SCALE, y * PANGO_SCALE, &i,
129 tbfc->
pfd = pango_font_description_from_string(font);
133 PangoLayout *layout = pango_layout_new(
p_context);
134 pango_layout_set_font_description(layout, tbfc->
pfd);
135 pango_layout_set_text(layout,
"aAjb", -1);
137 pango_layout_get_pixel_extents(layout, NULL, &rect);
138 tbfc->
height = rect.y + rect.height;
139 g_object_unref(layout);
143 g_hash_table_insert(
tbfc_cache, (
char *)font, tbfc);
145 pango_font_description_free(tbfc->
pfd);
152 pango_layout_set_font_description(tb->
layout, tbfc->
pfd);
160 const char *text,
double xalign,
double yalign) {
173 tb->
emode = PANGO_ELLIPSIZE_END;
183 pango_layout_set_wrap(tb->
layout, PANGO_WRAP_WORD_CHAR);
195 if (txt == NULL || (*txt) ==
'\0') {
198 const char *placeholder =
232 {
"normal.normal",
"selected.normal",
"alternate.normal"},
234 {
"normal.urgent",
"selected.urgent",
"alternate.urgent"},
236 {
"normal.active",
"selected.active",
"alternate.active"},
272 pango_layout_set_attributes(tb->
layout, NULL);
280 size_t l = g_utf8_strlen(tb->
text, -1);
282 memset(
string,
'*', l);
284 pango_layout_set_text(tb->
layout,
string, l);
286 pango_layout_set_markup(tb->
layout, tb->
text, -1);
288 pango_layout_set_text(tb->
layout, tb->
text, -1);
295 return pango_layout_get_text(tb->
layout);
301 return pango_layout_get_attributes(tb->
layout);
307 pango_layout_set_attributes(tb->
layout, list);
316 const gchar *last_pointer = NULL;
318 if (g_utf8_validate(text, -1, &last_pointer)) {
319 tb->
text = g_strdup(text);
321 if (last_pointer != NULL) {
323 tb->
text = g_strndup(text, (last_pointer - text));
325 tb->
text = g_strdup(
"Invalid UTF-8 string.");
345 pango_layout_set_width(tb->
layout, -1);
351 pango_layout_set_ellipsize(tb->
layout, PANGO_ELLIPSIZE_MIDDLE);
355 pango_layout_set_ellipsize(tb->
layout, PANGO_ELLIPSIZE_NONE);
362 pango_layout_set_width(
379 pango_layout_set_width(
399 g_object_unref(tb->
layout);
419 int y = (pango_font_metrics_get_ascent(tb->
tbfc->
metrics) -
420 pango_layout_get_baseline(tb->
layout)) /
422 int line_width = 0, line_height = 0;
424 pango_layout_get_pixel_size(tb->
layout, &line_width, &line_height);
428 top = (tb->
widget.
h - bottom - line_height - top) * tb->
yalign + top;
441 cairo_set_operator(draw, CAIRO_OPERATOR_OVER);
442 cairo_set_source_rgb(draw, 0.0, 0.0, 0.0);
450 cairo_move_to(draw, x, top);
452 cairo_reset_clip(draw);
453 pango_cairo_show_layout(draw, tb->
layout);
460 const char *text = pango_layout_get_text(tb->
layout);
462 int cursor_offset = MIN(tb->
cursor, g_utf8_strlen(text, -1));
465 char *offset = g_utf8_offset_to_pointer(text, cursor_offset);
466 pango_layout_get_cursor_pos(tb->
layout, offset - text, &pos, NULL);
467 int cursor_x = pos.x / PANGO_SCALE;
468 int cursor_y = pos.y / PANGO_SCALE;
469 int cursor_height = pos.height / PANGO_SCALE;
470 int cursor_width = 2;
471 cairo_rectangle(draw, x + cursor_x, y + cursor_y, cursor_width,
487 int length = (tb->
text == NULL) ? 0 : g_utf8_strlen(tb->
text, -1);
488 tb->
cursor = MAX(0, MIN(length, pos));
522 if (tb->
text == NULL) {
526 gchar *c = g_utf8_offset_to_pointer(tb->
text, tb->
cursor);
527 while ((c = g_utf8_next_char(c))) {
528 gunichar uc = g_utf8_get_char(c);
529 GUnicodeBreakType bt = g_unichar_break_type(uc);
530 if ((bt == G_UNICODE_BREAK_ALPHABETIC ||
531 bt == G_UNICODE_BREAK_HEBREW_LETTER || bt == G_UNICODE_BREAK_NUMERIC ||
532 bt == G_UNICODE_BREAK_QUOTATION)) {
536 if (c == NULL || *c ==
'\0') {
539 while ((c = g_utf8_next_char(c))) {
540 gunichar uc = g_utf8_get_char(c);
541 GUnicodeBreakType bt = g_unichar_break_type(uc);
542 if (!(bt == G_UNICODE_BREAK_ALPHABETIC ||
543 bt == G_UNICODE_BREAK_HEBREW_LETTER ||
544 bt == G_UNICODE_BREAK_NUMERIC || bt == G_UNICODE_BREAK_QUOTATION)) {
548 int index = g_utf8_pointer_to_offset(tb->
text, c);
555 gchar *c = g_utf8_offset_to_pointer(tb->
text, tb->
cursor);
556 while ((c = g_utf8_prev_char(c)) && c != tb->
text) {
557 gunichar uc = g_utf8_get_char(c);
558 GUnicodeBreakType bt = g_unichar_break_type(uc);
559 if ((bt == G_UNICODE_BREAK_ALPHABETIC ||
560 bt == G_UNICODE_BREAK_HEBREW_LETTER || bt == G_UNICODE_BREAK_NUMERIC ||
561 bt == G_UNICODE_BREAK_QUOTATION)) {
566 while ((n = g_utf8_prev_char(c))) {
567 gunichar uc = g_utf8_get_char(n);
568 GUnicodeBreakType bt = g_unichar_break_type(uc);
569 if (!(bt == G_UNICODE_BREAK_ALPHABETIC ||
570 bt == G_UNICODE_BREAK_HEBREW_LETTER ||
571 bt == G_UNICODE_BREAK_NUMERIC || bt == G_UNICODE_BREAK_QUOTATION)) {
580 int index = g_utf8_pointer_to_offset(tb->
text, c);
586 if (tb->
text == NULL) {
591 tb->
cursor = (int)g_utf8_strlen(tb->
text, -1);
603 char *c = g_utf8_offset_to_pointer(tb->
text, char_pos);
604 int pos = c - tb->
text;
605 int len = (int)strlen(tb->
text);
606 pos = MAX(0, MIN(len, pos));
608 tb->
text = g_realloc(tb->
text, len + slen + 1);
610 char *at = tb->
text + pos;
611 memmove(at + slen, at, len - pos + 1);
613 memmove(at, str, slen);
626 int len = g_utf8_strlen(tb->
text, -1);
630 pos = MAX(0, MIN(len, pos));
631 if ((pos + dlen) > len) {
635 char *start = g_utf8_offset_to_pointer(tb->
text, pos);
636 char *end = g_utf8_offset_to_pointer(tb->
text, pos + dlen);
638 memmove(start, end, (tb->
text + strlen(tb->
text)) - end + 1);
641 }
else if (tb->
cursor >= (pos + dlen)) {
656 if (tb == NULL || tb->
text == NULL) {
668 if (tb && tb->
cursor > 0) {
674 if (tb && tb->
cursor > 0) {
677 if (cursor > tb->
cursor) {
683 if (tb && tb->
cursor >= 0) {
684 int length = g_utf8_strlen(tb->
text, -1) - tb->
cursor;
691 if (tb && tb->
cursor >= 0) {
699 if (tb && tb->
cursor >= 0) {
702 if (cursor < tb->cursor) {
771 g_return_val_if_reached(0);
785 gboolean used_something = FALSE;
786 const gchar *w, *n, *e;
787 for (w = pad, n = g_utf8_next_char(w), e = w + pad_len; w < e;
788 w = n, n = g_utf8_next_char(n)) {
789 if (g_unichar_iscntrl(g_utf8_get_char(w))) {
794 used_something = TRUE;
796 return used_something;
800 pango_font_metrics_unref(tbfc->
metrics);
802 pango_font_description_free(tbfc->
pfd);
807 tbfc_cache = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
820 PangoLayout *layout = pango_layout_new(
p_context);
821 pango_layout_set_text(layout,
"aAjb", -1);
823 pango_layout_get_pixel_extents(layout, NULL, &rect);
824 tbfc->
height = rect.y + rect.height;
825 g_object_unref(layout);
854 tb, pango_layout_get_line_count(tb->
layout));
865 pango_layout_get_pixel_extents(tb->
layout, NULL, &rect);
866 return rect.height + rect.y;
871 pango_layout_get_pixel_extents(tb->
layout, NULL, &rect);
872 return rect.width + rect.x;
882 int width = pango_font_metrics_get_approximate_char_width(
p_metrics);
892 int width = pango_font_metrics_get_approximate_digit_width(
p_metrics);
893 ch_width = (width) / (
double)PANGO_SCALE;
919 int old_width = pango_layout_get_width(tb->
layout);
920 pango_layout_set_width(tb->
layout, -1);
923 pango_layout_set_width(tb->
layout, old_width);
924 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)
int textbox_get_desired_width(widget *wid)
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 int textbox_get_desired_height(widget *wid)
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_cursor_inc(textbox *tb)
static void textbox_free(widget *)
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_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
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)