summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas E. Dickey <dickey@invisible-island.net>2025-05-20 04:23:41 -0400
committerThomas E. Dickey <dickey@invisible-island.net>2025-05-20 04:28:47 -0400
commit7a97e12d435e05fbb9ca2f20f1a116c4a23eb194 (patch)
tree33edf82b27d34559719bd5fdd662c4cd9e57dc94
parent942b868e73e86287995ba8eefb6348ac4fb57954 (diff)
issue 8: Scrollbar not shown in text widgetHEADmaster
Creating a text widget with a string that does not fit into the allocated width does not show a scrollbar. The same code when linked to Xaw3d does show a scrollbar. Investigation shows this difference came from Author: dawes <dawes> Date: Sun Jun 28 12:56:14 1998 +0000 #1738 and probably was done to improve performance (by eliminating the use of floating point). Signed-off-by: Thomas E. Dickey <dickey@invisible-island.net>
-rw-r--r--src/Text.c120
1 files changed, 89 insertions, 31 deletions
diff --git a/src/Text.c b/src/Text.c
index 14cf0c3..0f7e831 100644
--- a/src/Text.c
+++ b/src/Text.c
@@ -1476,6 +1476,58 @@ GetWidestLine(TextWidget ctx)
return (widest);
}
+static void
+CheckVBarScrolling(TextWidget ctx)
+{
+ float first, last;
+ Boolean temp = (ctx->text.vbar == NULL);
+
+ if (ctx->text.scroll_vert == XawtextScrollNever) return;
+
+ if ( (ctx->text.lastPos > 0) && (ctx->text.lt.lines > 0)) {
+ first = (float) ctx->text.lt.top;
+ first /= (float) ctx->text.lastPos;
+ last = (float) ctx->text.lt.info[ctx->text.lt.lines].position;
+ if ( ctx->text.lt.info[ctx->text.lt.lines].position < ctx->text.lastPos )
+ last /= (float) ctx->text.lastPos;
+ else
+ last = 1.0;
+
+ if (ctx->text.scroll_vert == XawtextScrollWhenNeeded) {
+ int line;
+ XawTextPosition last_pos;
+ Position y = (Position) (ctx->core.height - ctx->text.margin.bottom);
+
+ if (ctx->text.hbar != NULL)
+ y -= (Position) (ctx->text.hbar->core.height +
+ 2 * ctx->text.hbar->core.border_width);
+
+ last_pos = PositionForXY(ctx, (Position) ctx->core.width, y);
+ line = LineForPosition(ctx, last_pos);
+
+ if ( (y < ctx->text.lt.info[line + 1].y) || ((last - first) < 1.0) )
+ CreateVScrollBar(ctx);
+ else
+ DestroyVScrollBar(ctx);
+ }
+
+ if (ctx->text.vbar != NULL)
+ XawScrollbarSetThumb(ctx->text.vbar, first, last - first);
+
+ if ( (ctx->text.vbar == NULL) != temp) {
+ _XawTextNeedsUpdating(ctx, zeroPosition, ctx->text.lastPos);
+ if (ctx->text.vbar == NULL)
+ _XawTextBuildLineTable (ctx, zeroPosition, FALSE);
+ }
+ }
+ else if (ctx->text.vbar != NULL) {
+ if (ctx->text.scroll_vert == XawtextScrollWhenNeeded)
+ DestroyVScrollBar(ctx);
+ else if (ctx->text.scroll_vert == XawtextScrollAlways)
+ XawScrollbarSetThumb(ctx->text.vbar, 0.0, 1.0);
+ }
+}
+
/*
* This routine is used by Text to notify an associated scrollbar of the
* correct metrics (position and shown fraction) for the text being currently
@@ -1484,40 +1536,46 @@ GetWidestLine(TextWidget ctx)
void
_XawTextSetScrollBars(TextWidget ctx)
{
- float first;
-
- if (ctx->text.scroll_vert == XawtextScrollAlways) {
- float last;
-
- if (ctx->text.lastPos == 0)
- first = 0.0;
- else
- first = (float)ctx->text.lt.top / (float)ctx->text.lastPos;
-
- if (ctx->text.lt.info[ctx->text.lt.lines].position < ctx->text.lastPos)
- last = (float)ctx->text.lt.info[ctx->text.lt.lines].position /
- (float)ctx->text.lastPos;
- else
- last = 1.0;
-
- XawScrollbarSetThumb(ctx->text.vbar, first, last - first);
- }
+ float first, last, widest;
+ Boolean temp = (ctx->text.hbar == NULL);
+ Boolean vtemp = (ctx->text.vbar == NULL);
+
+ CheckVBarScrolling(ctx);
+
+ if (ctx->text.scroll_horiz == XawtextScrollNever) return;
+
+ if (ctx->text.vbar != NULL)
+ widest = (float)(int)(ctx->core.width - ctx->text.vbar->core.width);
+ else
+ widest = (float) (ctx->core.width);
+ widest /= (last = GetWidestLine(ctx));
+ if (ctx->text.scroll_horiz == XawtextScrollWhenNeeded) {
+ if (widest < 1.0)
+ CreateHScrollBar(ctx);
+ else
+ DestroyHScrollBar(ctx);
+ }
- if (ctx->text.scroll_horiz == XawtextScrollAlways) {
- unsigned value = GetWidestLine(ctx);
- float denom = (float)value;
- float widest;
+ if ( (ctx->text.hbar == NULL) != temp ) {
+ _XawTextBuildLineTable (ctx, ctx->text.lt.top, TRUE);
+ CheckVBarScrolling(ctx); /* Recheck need for vbar, now that we added
+ or removed the hbar.*/
+ }
- if (denom <= 0)
- denom = (float)((int)XtWidth(ctx) - RHMargins(ctx));
- if (denom <= 0)
- denom = 1;
- widest = (float)((int)XtWidth(ctx) - RHMargins(ctx)) / denom;
- first = (float)(ctx->text.r_margin.left - ctx->text.left_margin);
- first /= denom;
+ if (ctx->text.hbar != NULL) {
+ first = ctx->text.r_margin.left - ctx->text.margin.left;
+ first /= last;
+ XawScrollbarSetThumb(ctx->text.hbar, first, widest);
+ }
- XawScrollbarSetThumb(ctx->text.hbar, first, widest);
- }
+ if (((ctx->text.hbar == NULL) && (ctx->text.margin.left !=
+ ctx->text.r_margin.left)) ||
+ (ctx->text.vbar == NULL) != vtemp)
+ {
+ ctx->text.margin.left = ctx->text.r_margin.left;
+ _XawTextNeedsUpdating(ctx, zeroPosition, ctx->text.lastPos);
+ FlushUpdate(ctx);
+ }
}
static void