Implement bold, dim, italic, inverse, underline

Didn't get everything the last time.
This commit is contained in:
Ray Chason
2026-08-14 11:08:26 +03:00
committed by Pasi Kallinen
parent 8d7d609a56
commit 514669823b
3 changed files with 59 additions and 82 deletions
+45 -11
View File
@@ -25,6 +25,7 @@ typedef struct WidgetData {
/* Attributes */ /* Attributes */
unsigned attrs; unsigned attrs;
boolean highlight;
/* Fonts for italic, bold and bold-italic */ /* Fonts for italic, bold and bold-italic */
XFontStruct *font[4]; /* To use the fonts */ XFontStruct *font[4]; /* To use the fonts */
@@ -138,6 +139,16 @@ X11_set_attrs(Widget w, unsigned attrs)
} }
} }
void
X11_set_highlight(Widget w, boolean highlight)
{
WidgetData *data = get_widget_data(w);
if (data != NULL) {
data->highlight = highlight;
update_label(w, data);
}
}
void void
X11_set_percent(Widget w, unsigned percent, Pixel color) X11_set_percent(Widget w, unsigned percent, Pixel color)
{ {
@@ -232,16 +243,23 @@ update_label(Widget w, WidgetData *data)
XtSetArg(args[num_args], XtNheight, &height); num_args++; XtSetArg(args[num_args], XtNheight, &height); num_args++;
XtGetValues(w, args, num_args); XtGetValues(w, args, num_args);
} }
width = max(width, 1); if (width < 2 || height < 2) {
height = max(height, 1); /* Pixmap must not have zero size, or a crash will ensue;
minimum size 2 simplifies border logic */
width = max(width, 2);
height = max(height, 2);
fgpixel = bgpixel;
}
/* Use the full width of the widget if a percentage bar is set */ /* Use the full width of the widget if a percentage bar is set or inverse
if (data->percent != 0) { is in effect */
Dimension wwidth; if (data->percent != 0 || (attrs & HL_INVERSE) != 0 || data->highlight) {
Dimension wwidth, iwidth;
num_args = 0; num_args = 0;
XtSetArg(args[num_args], XtNwidth, &wwidth); num_args++; XtSetArg(args[num_args], XtNwidth, &wwidth); num_args++;
XtSetArg(args[num_args], XtNinternalWidth, &iwidth); num_args++;
XtGetValues(w, args, num_args); XtGetValues(w, args, num_args);
width = max(width, wwidth); width = max(width, wwidth - iwidth*2);
} }
/* Create the pixmap */ /* Create the pixmap */
@@ -253,7 +271,7 @@ update_label(Widget w, WidgetData *data)
for (unsigned pass = 0; pass < 2; ++pass) { for (unsigned pass = 0; pass < 2; ++pass) {
XGCValues values; XGCValues values;
if (attrs & HL_INVERSE) { if (!!(attrs & HL_INVERSE) ^ !!data->highlight) {
values.foreground = bgpixel; values.foreground = bgpixel;
values.background = fgpixel; values.background = fgpixel;
} else { } else {
@@ -280,7 +298,11 @@ update_label(Widget w, WidgetData *data)
XSetClipRectangles(display, ggc, 0, 0, &clip, 1, Unsorted); XSetClipRectangles(display, ggc, 0, 0, &clip, 1, Unsorted);
} }
XSetForeground(display, ggc, values.background); /* Draw a border for inverse and highlight together */
/* Otherwise, fill with the background color */
if (!((attrs & HL_INVERSE) && data->highlight)) {
XSetForeground(display, ggc, values.background);
}
XFillRectangle(display, new_pixmap, ggc, 0, 0, width, height); XFillRectangle(display, new_pixmap, ggc, 0, 0, width, height);
XSetForeground(display, ggc, values.foreground); XSetForeground(display, ggc, values.foreground);
@@ -314,9 +336,16 @@ update_label(Widget w, WidgetData *data)
} }
/* Render the line */ /* Render the line */
XDrawString(display, new_pixmap, ggc, XDrawImageString(display, new_pixmap, ggc,
x, y, x, y,
label + i, line2); label + i, line2);
/* Draw the underline if requested */
if (attrs & HL_ULINE) {
XDrawLine(display, new_pixmap, ggc,
x, y,
x + lwidth - 1, y);
}
y += font->ascent + font->descent; y += font->ascent + font->descent;
@@ -327,6 +356,11 @@ update_label(Widget w, WidgetData *data)
} }
} }
/* Ensure a one-pixel border if both inverse and highlight */
if ((attrs & HL_INVERSE) && data->highlight) {
XDrawRectangle(display, new_pixmap, ggc, 0, 0, width-1, height-1);
}
XtReleaseGC(w, ggc); XtReleaseGC(w, ggc);
/* Set up to display the percent bar on the second pass */ /* Set up to display the percent bar on the second pass */
+14 -63
View File
@@ -1223,12 +1223,10 @@ struct f_overload {
static const struct f_overload *ff_ovld_from_mask(unsigned long); static const struct f_overload *ff_ovld_from_mask(unsigned long);
static const struct f_overload *ff_ovld_from_indx(int); static const struct f_overload *ff_ovld_from_indx(int);
static void hilight_label(Widget);
static void update_val(struct X_status_value *, long); static void update_val(struct X_status_value *, long);
static void skip_cond_val(struct X_status_value *); static void skip_cond_val(struct X_status_value *);
static void update_color(struct X_status_value *, int); static void update_color(struct X_status_value *, int);
static Pixel color_to_pixel(Widget, int); static Pixel color_to_pixel(Widget, int);
static boolean name_widget_has_label(struct X_status_value *);
static void apply_hilite_attributes(struct X_status_value *, int); static void apply_hilite_attributes(struct X_status_value *, int);
static const char *width_string(int); static const char *width_string(int);
static void create_widget(Widget, struct X_status_value *, int); static void create_widget(Widget, struct X_status_value *, int);
@@ -1415,18 +1413,6 @@ null_out_status(void)
} }
} }
/* this is almost an exact duplicate of hilight_value() */
static void
hilight_label(Widget w) /* label widget */
{
/*
* This predates STATUS_HILITES.
* It is used to show any changed item in inverse and gets
* reset on the next turn.
*/
swap_fg_bg(w);
}
DISABLE_WARNING_FORMAT_NONLITERAL DISABLE_WARNING_FORMAT_NONLITERAL
static void static void
@@ -1631,14 +1617,10 @@ update_val(struct X_status_value *attr_rec, long new_value)
if (attr_rec != &shown_stats[F_TIME] if (attr_rec != &shown_stats[F_TIME]
&& attr_rec != &shown_stats[F_VERS] && attr_rec != &shown_stats[F_VERS]
&& !attr_rec->set ^ !*buf) { && !attr_rec->set ^ !*buf) {
/* But don't hilite if inverted from status_hilite since if (attr_rec->type == SV_VALUE)
it will already be hilited by apply_hilite_attributes(). */ X11_set_highlight(get_value_widget(attr_rec->w), TRUE);
if (!attr_rec->inverted_hilite) { else
if (attr_rec->type == SV_VALUE) X11_set_highlight(attr_rec->w, TRUE);
hilight_value(attr_rec->w);
else
hilight_label(attr_rec->w);
}
attr_rec->set = !attr_rec->set; attr_rec->set = !attr_rec->set;
} }
attr_rec->turn_count = 0; attr_rec->turn_count = 0;
@@ -1664,7 +1646,7 @@ skip_cond_val(struct X_status_value *sv)
also requested to be highlighted, it used its own copy of also requested to be highlighted, it used its own copy of
'set' but the same widget so the highlighting got toggled 'set' but the same widget so the highlighting got toggled
off; this will turn in back on in that exceptional case */ off; this will turn in back on in that exceptional case */
hilight_label(sv->w); X11_set_highlight(sv->w, FALSE);
sv->set = FALSE; sv->set = FALSE;
} }
} }
@@ -1686,10 +1668,7 @@ update_color(struct X_status_value *sv, int color)
sv->colr = color; sv->colr = color;
} }
if (pixel != 0) { if (pixel != 0) {
char *arg_name = (sv->set || sv->inverted_hilite) ? XtNbackground XtSetArg(args[0], XtNforeground, pixel);
: XtNforeground;
XtSetArg(args[0], arg_name, pixel);
XtSetValues(w, args, ONE); XtSetValues(w, args, ONE);
X11_update_label(w); X11_update_label(w);
} }
@@ -1719,38 +1698,14 @@ color_to_pixel(Widget w, int color)
return pixel; return pixel;
} }
static boolean
name_widget_has_label(struct X_status_value *sv)
{
Arg args[1];
const char *label;
XtSetArg(args[0], XtNlabel, &label);
XtGetValues(sv->w, args, ONE);
return (*label != '\0');
}
static void static void
apply_hilite_attributes(struct X_status_value *sv, int attributes) apply_hilite_attributes(struct X_status_value *sv, int attributes)
{ {
boolean attr_inversion = ((HL_INVERSE & attributes) Widget w = sv->w;
&& (sv->type != SV_NAME if (sv->type == SV_VALUE) {
|| name_widget_has_label(sv))); w = get_value_widget(w);
if (sv->inverted_hilite != attr_inversion) {
sv->inverted_hilite = attr_inversion;
if (!sv->set) {
if (sv->type == SV_VALUE)
hilight_value(sv->w);
else
hilight_label(sv->w);
}
} }
sv->attr = attributes; X11_set_attrs(w, attributes);
/* Could possibly add more attributes here: HL_ATTCLR_DIM,
HL_ATTCLR_BLINK, HL_ATTCLR_ULINE, and HL_ATTCLR_BOLD. If so,
extract the above into its own function apply_hilite_inverse()
and each other attribute into its own to keep the code clean. */
} }
static void static void
@@ -2021,14 +1976,10 @@ check_turn_events(void)
continue; continue;
if (sv->turn_count++ >= hilight_time) { if (sv->turn_count++ >= hilight_time) {
/* unhighlights by toggling a highlighted item back off again, if (sv->type == SV_VALUE)
unless forced inverted by a status_hilite rule */ X11_set_highlight(get_value_widget(sv->w), FALSE);
if (!sv->inverted_hilite) { else
if (sv->type == SV_VALUE) X11_set_highlight(sv->w, FALSE);
hilight_value(sv->w);
else
hilight_label(sv->w);
}
sv->set = FALSE; sv->set = FALSE;
} }
} }
-8
View File
@@ -152,14 +152,6 @@ get_value_width(Widget w)
return (int) width; return (int) width;
} }
/* Swap foreground and background colors (this is the best I can do with */
/* a label widget, unless I can get some init hook in there). */
void
hilight_value(Widget w)
{
swap_fg_bg(get_value_widget(w));
}
/* Swap the foreground and background colors of the given widget */ /* Swap the foreground and background colors of the given widget */
void void
swap_fg_bg(Widget w) swap_fg_bg(Widget w)