Add support for setting tabs stops on textboxes (#1571)

* Document new array of values type

* Move WIDGET_PADDING_INIT from widget.c to widget-internal.h

* Refactor WIDGET_PADDING_INIT macro

* Add support for setting tab stops on textbox

This allows to emulate a multi-column layout inside the text boxes.

The implementation is kinda hackish due to the limitations of the theme
parser. The only property type that can contain multiple distance values
is Padding, so I used that.

* Use new array syntax for tab-stops
This commit is contained in:
Jakub Jirutka 2022-01-24 22:20:41 +01:00 committed by GitHub
parent 33643d0642
commit 6e3feee179
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 64 additions and 19 deletions

View File

@ -216,6 +216,7 @@ The current theme format supports different types:
* an orientation
* a cursor
* a list of keywords
* an array of values
* an environment variable
* Inherit
@ -450,6 +451,7 @@ style property.
> When no unit is specified, pixels are assumed.
## Position
Indicate a place on the window/monitor.
@ -533,6 +535,13 @@ Specify the type of mouse cursor that is set when the mouse pointer is over the
A list starts with a '[' and ends with a ']'. The entries in the list are comma-separated.
The `keyword` in the list refers to an widget name.
## Array of values
* Format: `{ value, value, ... }`
An array starts with a '{' and ends with a '}'. The entries in the array are comma-separated.
Currently, only the integer and distance types are supported as array values.
## Environment variable
* Format: `${:alnum:}`
@ -760,6 +769,10 @@ The following properties are currently supported:
* **placeholder-color**: Color of the placeholder text.
* **blink**: Enable/Disable blinking on an input textbox (Boolean).
* **markup**: Force markup on, beware that only valid pango markup strings are shown.
* **tab-stops**: array of distances
Set the location of tab stops by their distance from the beginning of the line.
Each distance should be greater than the previous one.
The text appears to the right of the tab stop position (other alignments are not supported yet).
### listview:
* **columns**: integer

View File

@ -29,6 +29,28 @@
#define WIDGET_INTERNAL_H
#include "theme.h"
/** Macro for initializing the RofiDistance struct. */
#define WIDGET_DISTANCE_INIT \
(RofiDistance){ \
.base = { \
.distance = 0, \
.type = ROFI_PU_PX, \
.modtype = ROFI_DISTANCE_MODIFIER_NONE, \
.left = NULL, \
.right = NULL, \
}, \
.style = ROFI_HL_SOLID, \
}
/* Macro for initializing the RofiPadding struct. */
#define WIDGET_PADDING_INIT \
(RofiPadding){ \
.top = WIDGET_DISTANCE_INIT, \
.right = WIDGET_DISTANCE_INIT, \
.bottom = WIDGET_DISTANCE_INIT, \
.left = WIDGET_DISTANCE_INIT, \
}
/**
* Data structure holding the internal state of the Widget
*/

View File

@ -163,6 +163,30 @@ static void textbox_initialize_font(textbox *tb) {
}
}
static void textbox_tab_stops(textbox *tb) {
GList *dists = rofi_theme_get_array_distance(WIDGET(tb), "tab-stops");
if (dists != NULL) {
PangoTabArray *tabs = pango_tab_array_new(g_list_length(dists), TRUE);
int i = 0, ppx = 0;
for (const GList *iter = g_list_first(dists); iter != NULL; iter = g_list_next(iter), i++) {
const RofiDistance *dist = iter->data;
int px = distance_get_pixel(*dist, ROFI_ORIENTATION_HORIZONTAL);
if (px <= ppx) {
continue;
}
pango_tab_array_set_tab(tabs, i, PANGO_TAB_LEFT, px);
ppx = px;
}
pango_layout_set_tabs(tb->layout, tabs);
pango_tab_array_free(tabs);
g_list_free_full(dists, g_free);
}
}
textbox *textbox_create(widget *parent, WidgetType type, const char *name,
TextboxFlags flags, TextBoxFontType tbft,
const char *text, double xalign, double yalign) {
@ -186,6 +210,7 @@ textbox *textbox_create(widget *parent, WidgetType type, const char *name,
textbox_font(tb, tbft);
textbox_initialize_font(tb);
textbox_tab_stops(tb);
if ((tb->flags & TB_WRAP) == TB_WRAP) {
pango_layout_set_wrap(tb->layout, PANGO_WRAP_WORD_CHAR);

View File

@ -31,30 +31,15 @@
#include <glib.h>
#include <math.h>
/** Default padding. */
#define WIDGET_DEFAULT_PADDING 0
/** macro for initializing the padding struction. */
#define WIDGET_PADDING_INIT \
{ \
{WIDGET_DEFAULT_PADDING, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE, NULL, \
NULL}, \
ROFI_HL_SOLID \
}
void widget_init(widget *wid, widget *parent, WidgetType type,
const char *name) {
wid->type = type;
wid->parent = parent;
wid->name = g_strdup(name);
wid->def_padding = (RofiPadding){WIDGET_PADDING_INIT, WIDGET_PADDING_INIT,
WIDGET_PADDING_INIT, WIDGET_PADDING_INIT};
wid->def_border = (RofiPadding){WIDGET_PADDING_INIT, WIDGET_PADDING_INIT,
WIDGET_PADDING_INIT, WIDGET_PADDING_INIT};
wid->def_border_radius =
(RofiPadding){WIDGET_PADDING_INIT, WIDGET_PADDING_INIT,
WIDGET_PADDING_INIT, WIDGET_PADDING_INIT};
wid->def_margin = (RofiPadding){WIDGET_PADDING_INIT, WIDGET_PADDING_INIT,
WIDGET_PADDING_INIT, WIDGET_PADDING_INIT};
wid->def_padding = WIDGET_PADDING_INIT;
wid->def_border = WIDGET_PADDING_INIT;
wid->def_border_radius = WIDGET_PADDING_INIT;
wid->def_margin = WIDGET_PADDING_INIT;
wid->padding = rofi_theme_get_padding(wid, "padding", wid->def_padding);
wid->border = rofi_theme_get_padding(wid, "border", wid->def_border);