diff --git a/doc/rofi-theme.5 b/doc/rofi-theme.5 index 17d2a645..30ebfea3 100644 --- a/doc/rofi-theme.5 +++ b/doc/rofi-theme.5 @@ -773,9 +773,15 @@ should be applied. .IP \(bu 2 \fB\fCitalic\fR: put the highlighted text in script type (slanted). .IP \(bu 2 -\fB\fCunderline\fR: put a line under the highlighted text. +\fB\fCunderline\fR: put a line under the text. .IP \(bu 2 -\fB\fCstrikethrough\fR: put a line through the highlighted text. +\fB\fCstrikethrough\fR: put a line through the text. +.IP \(bu 2 +\fB\fCuppercase\fR: Uppercase the text. +.IP \(bu 2 +\fB\fClowercase\fR: Lowercase the text. +.IP \(bu 2 +\fB\fCcapitalize\fR: Capitalize the text. .RE @@ -1468,6 +1474,8 @@ The offset of the window to the anchor point, allowing you to push the window le .IP \(bu 2 \fBtext-color\fP: the text color to use. .IP \(bu 2 +\fBtext-transform\fP: text style {color} for the whole text. +.IP \(bu 2 \fBhighlight\fP: text style {color}. color is optional, multiple highlight styles can be added like: bold underline italic #000000; This option is only available on the \fB\fCelement-text\fR widget. diff --git a/doc/rofi-theme.5.markdown b/doc/rofi-theme.5.markdown index 6c7f30de..1a9716d3 100644 --- a/doc/rofi-theme.5.markdown +++ b/doc/rofi-theme.5.markdown @@ -498,8 +498,11 @@ should be applied. * `bold`: make the text thicker then the surrounding text. * `italic`: put the highlighted text in script type (slanted). - * `underline`: put a line under the highlighted text. - * `strikethrough`: put a line through the highlighted text. + * `underline`: put a line under the text. + * `strikethrough`: put a line through the text. + * `uppercase`: Uppercase the text. + * `lowercase`: Lowercase the text. + * `capitalize`: Capitalize the text. ## Line style @@ -912,6 +915,7 @@ The following properties are currently supported: * **vertical-align**: Vertical alignment of the text. A number between 0 (top) and 1 (bottom). * **horizontal-align**: Horizontal alignment of the text. A number between 0 (left) and 1 (right). * **text-color**: the text color to use. +* **text-transform**: text style {color} for the whole text. * **highlight**: text style {color}. color is optional, multiple highlight styles can be added like: bold underline italic #000000; This option is only available on the `element-text` widget. diff --git a/include/helper-theme.h b/include/helper-theme.h index 6776384d..f8fd2aa7 100644 --- a/include/helper-theme.h +++ b/include/helper-theme.h @@ -49,6 +49,19 @@ PangoAttrList *helper_token_match_get_pango_attr(RofiHighlightColorStyle th, const char *input, PangoAttrList *retv); +/** + * @param th The RofiHighlightColorStyle + * @param start The start to highlighting. + * @param stop The stop point for the highlight + * @param retv The Attribute list to update with matches + * + * Creates a set of pango attributes highlighting the matches found in the input + * style. + * + */ +void helper_token_match_set_pango_attr_on_style(PangoAttrList *retv, int start, + int end, + RofiHighlightColorStyle th); /** * @param pfd Pango font description to validate. * @param font The name of the font to check. diff --git a/include/rofi-types.h b/include/rofi-types.h index 48de8f78..807a2556 100644 --- a/include/rofi-types.h +++ b/include/rofi-types.h @@ -58,12 +58,16 @@ typedef enum { ROFI_HL_UNDERLINE = 2, /** strikethrough */ ROFI_HL_STRIKETHROUGH = 16, - /** small caps */ - ROFI_HL_SMALL_CAPS = 32, /** italic */ ROFI_HL_ITALIC = 4, /** color */ - ROFI_HL_COLOR = 8 + ROFI_HL_COLOR = 8, + /** uppercase */ + ROFI_HL_UPPERCASE = 32, + /** lowercase */ + ROFI_HL_LOWERCASE = 64, + /** capitalize */ + ROFI_HL_CAPITALIZE = 128 } RofiHighlightStyle; /** Style of line */ diff --git a/lexer/theme-lexer.l b/lexer/theme-lexer.l index 8edf5eea..96407443 100644 --- a/lexer/theme-lexer.l +++ b/lexer/theme-lexer.l @@ -219,7 +219,9 @@ BOLD (?i:bold) UNDERLINE (?i:underline) ITALIC (?i:italic) STRIKETHROUGH (?i:strikethrough) -SMALLCAPS (?i:small\ caps) +UPPERCASE (?i:uppercase) +LOWERCASE (?i:lowercase) +CAPITALIZE (?i:capitalize) /* ANGLES */ @@ -729,7 +731,9 @@ if ( queue == NULL ) { {ITALIC} { return T_ITALIC; } {UNDERLINE} { return T_UNDERLINE; } {STRIKETHROUGH} { return T_STRIKETHROUGH; } -{SMALLCAPS} { return T_SMALLCAPS; } +{UPPERCASE} { return T_UPPERCASE; } +{LOWERCASE} { return T_LOWERCASE; } +{CAPITALIZE} { return T_CAPITALIZE; } {ANGLE_DEG} { return T_ANGLE_DEG; } {ANGLE_RAD} { return T_ANGLE_RAD; } diff --git a/lexer/theme-parser.y b/lexer/theme-parser.y index 494ad368..4e23a7e3 100644 --- a/lexer/theme-parser.y +++ b/lexer/theme-parser.y @@ -185,9 +185,11 @@ static ThemeColor hwb_to_rgb ( double h, double w, double b ) %token T_ITALIC "Italic" %token T_UNDERLINE "Underline" %token T_STRIKETHROUGH "Strikethrough" -%token T_SMALLCAPS "Small CAPS" %token T_DASH "Dash" %token T_SOLID "Solid" +%token T_UPPERCASE "Uppercase" +%token T_CAPITALIZE "Capitalize" +%token T_LOWERCASE "Lowercase" %token T_UNIT_PX "pixels" %token T_UNIT_MM "mm" @@ -762,7 +764,9 @@ t_property_highlight_style | T_UNDERLINE { $$ = ROFI_HL_UNDERLINE; } | T_STRIKETHROUGH { $$ = ROFI_HL_STRIKETHROUGH; } | T_ITALIC { $$ = ROFI_HL_ITALIC; } -| T_SMALLCAPS { $$ = ROFI_HL_SMALL_CAPS; } +| T_UPPERCASE { $$ = ROFI_HL_UPPERCASE; } +| T_LOWERCASE { $$ = ROFI_HL_LOWERCASE; } +| T_CAPITALIZE { $$ = ROFI_HL_CAPITALIZE; } ; diff --git a/source/helper.c b/source/helper.c index 5de0c82f..2662b2b2 100644 --- a/source/helper.c +++ b/source/helper.c @@ -415,6 +415,70 @@ int find_arg_char(const char *const key, char *val) { return FALSE; } +void helper_token_match_set_pango_attr_on_style(PangoAttrList *retv, int start, + int end, + RofiHighlightColorStyle th) { + if (th.style & ROFI_HL_BOLD) { + PangoAttribute *pa = pango_attr_weight_new(PANGO_WEIGHT_BOLD); + pa->start_index = start; + pa->end_index = end; + pango_attr_list_insert(retv, pa); + } + if (th.style & ROFI_HL_UPPERCASE) { + PangoAttribute *pa = + pango_attr_text_transform_new(PANGO_TEXT_TRANSFORM_UPPERCASE); + pa->start_index = start; + pa->end_index = end; + pango_attr_list_insert(retv, pa); + } + if (th.style & ROFI_HL_LOWERCASE) { + PangoAttribute *pa = + pango_attr_text_transform_new(PANGO_TEXT_TRANSFORM_LOWERCASE); + pa->start_index = start; + pa->end_index = end; + pango_attr_list_insert(retv, pa); + } + if (th.style & ROFI_HL_CAPITALIZE) { + PangoAttribute *pa = + pango_attr_text_transform_new(PANGO_TEXT_TRANSFORM_CAPITALIZE); + pa->start_index = start; + pa->end_index = end; + pango_attr_list_insert(retv, pa); + } + if (th.style & ROFI_HL_UNDERLINE) { + PangoAttribute *pa = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE); + pa->start_index = start; + pa->end_index = end; + pango_attr_list_insert(retv, pa); + } + if (th.style & ROFI_HL_STRIKETHROUGH) { + PangoAttribute *pa = pango_attr_strikethrough_new(TRUE); + pa->start_index = start; + pa->end_index = end; + pango_attr_list_insert(retv, pa); + } + if (th.style & ROFI_HL_ITALIC) { + PangoAttribute *pa = pango_attr_style_new(PANGO_STYLE_ITALIC); + pa->start_index = start; + pa->end_index = end; + pango_attr_list_insert(retv, pa); + } + if (th.style & ROFI_HL_COLOR) { + PangoAttribute *pa = pango_attr_foreground_new( + th.color.red * 65535, th.color.green * 65535, th.color.blue * 65535); + pa->start_index = start; + pa->end_index = end; + pango_attr_list_insert(retv, pa); + + if (th.color.alpha < 1.0) { + pa = pango_attr_foreground_alpha_new(th.color.alpha * 65535); + pa->start_index = start; + pa->end_index = end; + pango_attr_list_insert(retv, pa); + } + } +} + PangoAttrList *helper_token_match_get_pango_attr(RofiHighlightColorStyle th, rofi_int_matcher **tokens, const char *input, @@ -436,53 +500,7 @@ PangoAttrList *helper_token_match_get_pango_attr(RofiHighlightColorStyle th, for (int index = (count > 1) ? 1 : 0; index < count; index++) { int start, end; g_match_info_fetch_pos(gmi, index, &start, &end); - if (th.style & ROFI_HL_BOLD) { - PangoAttribute *pa = pango_attr_weight_new(PANGO_WEIGHT_BOLD); - pa->start_index = start; - pa->end_index = end; - pango_attr_list_insert(retv, pa); - } - if (th.style & ROFI_HL_UNDERLINE) { - PangoAttribute *pa = - pango_attr_underline_new(PANGO_UNDERLINE_SINGLE); - pa->start_index = start; - pa->end_index = end; - pango_attr_list_insert(retv, pa); - } - if (th.style & ROFI_HL_STRIKETHROUGH) { - PangoAttribute *pa = pango_attr_strikethrough_new(TRUE); - pa->start_index = start; - pa->end_index = end; - pango_attr_list_insert(retv, pa); - } - if (th.style & ROFI_HL_SMALL_CAPS) { - PangoAttribute *pa = - pango_attr_variant_new(PANGO_VARIANT_SMALL_CAPS); - pa->start_index = start; - pa->end_index = end; - pango_attr_list_insert(retv, pa); - } - if (th.style & ROFI_HL_ITALIC) { - PangoAttribute *pa = pango_attr_style_new(PANGO_STYLE_ITALIC); - pa->start_index = start; - pa->end_index = end; - pango_attr_list_insert(retv, pa); - } - if (th.style & ROFI_HL_COLOR) { - PangoAttribute *pa = pango_attr_foreground_new( - th.color.red * 65535, th.color.green * 65535, - th.color.blue * 65535); - pa->start_index = start; - pa->end_index = end; - pango_attr_list_insert(retv, pa); - - if (th.color.alpha < 1.0) { - pa = pango_attr_foreground_alpha_new(th.color.alpha * 65535); - pa->start_index = start; - pa->end_index = end; - pango_attr_list_insert(retv, pa); - } - } + helper_token_match_set_pango_attr_on_style(retv, start, end, th); } g_match_info_next(gmi, NULL); } diff --git a/source/theme.c b/source/theme.c index 0319b18d..774298c0 100644 --- a/source/theme.c +++ b/source/theme.c @@ -386,6 +386,15 @@ static void int_rofi_theme_print_property(Property *p) { if (p->value.highlight.style & ROFI_HL_ITALIC) { printf("italic "); } + if (p->value.highlight.style & ROFI_HL_UPPERCASE) { + printf("uppercase "); + } + if (p->value.highlight.style & ROFI_HL_LOWERCASE) { + printf("lowercase "); + } + if (p->value.highlight.style & ROFI_HL_CAPITALIZE) { + printf("capitalize "); + } if (p->value.highlight.style & ROFI_HL_COLOR) { rofi_theme_print_color(p->value.highlight.color); } diff --git a/source/widgets/listview.c b/source/widgets/listview.c index 55e61fd8..2b8f5d81 100644 --- a/source/widgets/listview.c +++ b/source/widgets/listview.c @@ -736,6 +736,7 @@ listview *listview_create(widget *parent, const char *name, buff[i * 2] = 'a'; buff[i * 2 + 1] = '\n'; }; + textbox_moveresize(row.textbox, 0, 0, 100000000, -1); textbox_text(row.textbox, buff); } // Make textbox very wide. diff --git a/source/widgets/textbox.c b/source/widgets/textbox.c index e4f28915..00ab1ac1 100644 --- a/source/widgets/textbox.c +++ b/source/widgets/textbox.c @@ -232,10 +232,6 @@ textbox *textbox_create(widget *parent, WidgetType type, const char *name, textbox_text(tb, txt ? txt : ""); textbox_cursor_end(tb); - // auto height/width modes get handled here - textbox_moveresize(tb, tb->widget.x, tb->widget.y, tb->widget.w, - tb->widget.h); - tb->blink_timeout = 0; tb->blink = 1; if ((tb->flags & TB_EDITABLE) == TB_EDITABLE) { @@ -257,6 +253,11 @@ textbox *textbox_create(widget *parent, WidgetType type, const char *name, } else { pango_layout_set_alignment(tb->layout, PANGO_ALIGN_RIGHT); } + // auto height/width modes get handled here + // UPDATE: don't autoheight here, as there is no width set. + // so no height can be determined and might result into crash. + // textbox_moveresize(tb, tb->widget.x, tb->widget.y, tb->widget.w, + // tb->widget.h); return tb; } @@ -324,6 +325,15 @@ static void __textbox_update_pango_text(textbox *tb) { } else { pango_layout_set_text(tb->layout, tb->text, -1); } + if (tb->text) { + RofiHighlightColorStyle th = {0, {0.0, 0.0, 0.0, 0.0}}; + th = rofi_theme_get_highlight(WIDGET(tb), "text-transform", th); + if (th.style != 0) { + PangoAttrList *list = pango_attr_list_new(); + helper_token_match_set_pango_attr_on_style(list, 0, G_MAXUINT, th); + pango_layout_set_attributes(tb->layout, list); + } + } } const char *textbox_get_visible_text(const textbox *tb) { if (tb == NULL) { @@ -398,10 +408,9 @@ void textbox_moveresize(textbox *tb, int x, int y, int w, int h) { if (tb->flags & TB_AUTOHEIGHT) { // Width determines height! - int tw = MAX(1, w); - pango_layout_set_width( - tb->layout, - PANGO_SCALE * (tw - widget_padding_get_padding_width(WIDGET(tb)))); + int padding = widget_padding_get_padding_width(WIDGET(tb)); + int tw = MAX(1 + padding, w); + pango_layout_set_width(tb->layout, PANGO_SCALE * (tw - padding)); int hd = textbox_get_height(tb); h = MAX(hd, h); }