[textbox] Implement text-transform add upper/lower/capitalize transform

fixes: #1010
This commit is contained in:
Dave Davenport 2022-07-30 14:50:05 +02:00
parent 01908d8dc0
commit 77af850200
10 changed files with 140 additions and 66 deletions

View File

@ -773,9 +773,15 @@ should be applied.
.IP \(bu 2 .IP \(bu 2
\fB\fCitalic\fR: put the highlighted text in script type (slanted). \fB\fCitalic\fR: put the highlighted text in script type (slanted).
.IP \(bu 2 .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 .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 .RE
@ -1468,6 +1474,8 @@ The offset of the window to the anchor point, allowing you to push the window le
.IP \(bu 2 .IP \(bu 2
\fBtext-color\fP: the text color to use. \fBtext-color\fP: the text color to use.
.IP \(bu 2 .IP \(bu 2
\fBtext-transform\fP: text style {color} for the whole text.
.IP \(bu 2
\fBhighlight\fP: text style {color}. \fBhighlight\fP: text style {color}.
color is optional, multiple highlight styles can be added like: bold underline italic #000000; 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. This option is only available on the \fB\fCelement-text\fR widget.

View File

@ -498,8 +498,11 @@ should be applied.
* `bold`: make the text thicker then the surrounding text. * `bold`: make the text thicker then the surrounding text.
* `italic`: put the highlighted text in script type (slanted). * `italic`: put the highlighted text in script type (slanted).
* `underline`: put a line under the highlighted text. * `underline`: put a line under the text.
* `strikethrough`: put a line through the highlighted text. * `strikethrough`: put a line through the text.
* `uppercase`: Uppercase the text.
* `lowercase`: Lowercase the text.
* `capitalize`: Capitalize the text.
## Line style ## 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). * **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). * **horizontal-align**: Horizontal alignment of the text. A number between 0 (left) and 1 (right).
* **text-color**: the text color to use. * **text-color**: the text color to use.
* **text-transform**: text style {color} for the whole text.
* **highlight**: text style {color}. * **highlight**: text style {color}.
color is optional, multiple highlight styles can be added like: bold underline italic #000000; color is optional, multiple highlight styles can be added like: bold underline italic #000000;
This option is only available on the `element-text` widget. This option is only available on the `element-text` widget.

View File

@ -49,6 +49,19 @@ PangoAttrList *helper_token_match_get_pango_attr(RofiHighlightColorStyle th,
const char *input, const char *input,
PangoAttrList *retv); 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 pfd Pango font description to validate.
* @param font The name of the font to check. * @param font The name of the font to check.

View File

@ -58,12 +58,16 @@ typedef enum {
ROFI_HL_UNDERLINE = 2, ROFI_HL_UNDERLINE = 2,
/** strikethrough */ /** strikethrough */
ROFI_HL_STRIKETHROUGH = 16, ROFI_HL_STRIKETHROUGH = 16,
/** small caps */
ROFI_HL_SMALL_CAPS = 32,
/** italic */ /** italic */
ROFI_HL_ITALIC = 4, ROFI_HL_ITALIC = 4,
/** color */ /** 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; } RofiHighlightStyle;
/** Style of line */ /** Style of line */

View File

@ -219,7 +219,9 @@ BOLD (?i:bold)
UNDERLINE (?i:underline) UNDERLINE (?i:underline)
ITALIC (?i:italic) ITALIC (?i:italic)
STRIKETHROUGH (?i:strikethrough) STRIKETHROUGH (?i:strikethrough)
SMALLCAPS (?i:small\ caps) UPPERCASE (?i:uppercase)
LOWERCASE (?i:lowercase)
CAPITALIZE (?i:capitalize)
/* ANGLES */ /* ANGLES */
@ -729,7 +731,9 @@ if ( queue == NULL ) {
<PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{ITALIC} { return T_ITALIC; } <PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{ITALIC} { return T_ITALIC; }
<PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{UNDERLINE} { return T_UNDERLINE; } <PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{UNDERLINE} { return T_UNDERLINE; }
<PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{STRIKETHROUGH} { return T_STRIKETHROUGH; } <PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{STRIKETHROUGH} { return T_STRIKETHROUGH; }
<PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{SMALLCAPS} { return T_SMALLCAPS; } <PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{UPPERCASE} { return T_UPPERCASE; }
<PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{LOWERCASE} { return T_LOWERCASE; }
<PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{CAPITALIZE} { return T_CAPITALIZE; }
<PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{ANGLE_DEG} { return T_ANGLE_DEG; } <PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{ANGLE_DEG} { return T_ANGLE_DEG; }
<PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{ANGLE_RAD} { return T_ANGLE_RAD; } <PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{ANGLE_RAD} { return T_ANGLE_RAD; }

View File

@ -185,9 +185,11 @@ static ThemeColor hwb_to_rgb ( double h, double w, double b )
%token T_ITALIC "Italic" %token T_ITALIC "Italic"
%token T_UNDERLINE "Underline" %token T_UNDERLINE "Underline"
%token T_STRIKETHROUGH "Strikethrough" %token T_STRIKETHROUGH "Strikethrough"
%token T_SMALLCAPS "Small CAPS"
%token T_DASH "Dash" %token T_DASH "Dash"
%token T_SOLID "Solid" %token T_SOLID "Solid"
%token T_UPPERCASE "Uppercase"
%token T_CAPITALIZE "Capitalize"
%token T_LOWERCASE "Lowercase"
%token T_UNIT_PX "pixels" %token T_UNIT_PX "pixels"
%token T_UNIT_MM "mm" %token T_UNIT_MM "mm"
@ -762,7 +764,9 @@ t_property_highlight_style
| T_UNDERLINE { $$ = ROFI_HL_UNDERLINE; } | T_UNDERLINE { $$ = ROFI_HL_UNDERLINE; }
| T_STRIKETHROUGH { $$ = ROFI_HL_STRIKETHROUGH; } | T_STRIKETHROUGH { $$ = ROFI_HL_STRIKETHROUGH; }
| T_ITALIC { $$ = ROFI_HL_ITALIC; } | 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; }
; ;

View File

@ -415,6 +415,70 @@ int find_arg_char(const char *const key, char *val) {
return FALSE; 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, PangoAttrList *helper_token_match_get_pango_attr(RofiHighlightColorStyle th,
rofi_int_matcher **tokens, rofi_int_matcher **tokens,
const char *input, 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++) { for (int index = (count > 1) ? 1 : 0; index < count; index++) {
int start, end; int start, end;
g_match_info_fetch_pos(gmi, index, &start, &end); g_match_info_fetch_pos(gmi, index, &start, &end);
if (th.style & ROFI_HL_BOLD) { helper_token_match_set_pango_attr_on_style(retv, start, end, th);
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);
}
}
} }
g_match_info_next(gmi, NULL); g_match_info_next(gmi, NULL);
} }

View File

@ -386,6 +386,15 @@ static void int_rofi_theme_print_property(Property *p) {
if (p->value.highlight.style & ROFI_HL_ITALIC) { if (p->value.highlight.style & ROFI_HL_ITALIC) {
printf("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) { if (p->value.highlight.style & ROFI_HL_COLOR) {
rofi_theme_print_color(p->value.highlight.color); rofi_theme_print_color(p->value.highlight.color);
} }

View File

@ -736,6 +736,7 @@ listview *listview_create(widget *parent, const char *name,
buff[i * 2] = 'a'; buff[i * 2] = 'a';
buff[i * 2 + 1] = '\n'; buff[i * 2 + 1] = '\n';
}; };
textbox_moveresize(row.textbox, 0, 0, 100000000, -1);
textbox_text(row.textbox, buff); textbox_text(row.textbox, buff);
} }
// Make textbox very wide. // Make textbox very wide.

View File

@ -232,10 +232,6 @@ textbox *textbox_create(widget *parent, WidgetType type, const char *name,
textbox_text(tb, txt ? txt : ""); textbox_text(tb, txt ? txt : "");
textbox_cursor_end(tb); 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_timeout = 0;
tb->blink = 1; tb->blink = 1;
if ((tb->flags & TB_EDITABLE) == TB_EDITABLE) { if ((tb->flags & TB_EDITABLE) == TB_EDITABLE) {
@ -257,6 +253,11 @@ textbox *textbox_create(widget *parent, WidgetType type, const char *name,
} else { } else {
pango_layout_set_alignment(tb->layout, PANGO_ALIGN_RIGHT); 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; return tb;
} }
@ -324,6 +325,15 @@ static void __textbox_update_pango_text(textbox *tb) {
} else { } else {
pango_layout_set_text(tb->layout, tb->text, -1); 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) { const char *textbox_get_visible_text(const textbox *tb) {
if (tb == NULL) { 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) { if (tb->flags & TB_AUTOHEIGHT) {
// Width determines height! // Width determines height!
int tw = MAX(1, w); int padding = widget_padding_get_padding_width(WIDGET(tb));
pango_layout_set_width( int tw = MAX(1 + padding, w);
tb->layout, pango_layout_set_width(tb->layout, PANGO_SCALE * (tw - padding));
PANGO_SCALE * (tw - widget_padding_get_padding_width(WIDGET(tb))));
int hd = textbox_get_height(tb); int hd = textbox_get_height(tb);
h = MAX(hd, h); h = MAX(hd, h);
} }