@@ -32,6 +32,17 @@ public final class WaypointsScreen extends Screen
3232 private int scroll ; // 0 at top, grows when scrolling down
3333 private int viewportTop ;
3434 private int viewportBottom ;
35+ // Scrollbar interaction
36+ private boolean draggingScrollbar = false ;
37+ private double scrollbarDragStartY = 0.0 ;
38+ private double scrollbarStartScroll = 0.0 ;
39+ private int scrollTrackTop = 0 ;
40+ private int scrollTrackBottom = 0 ;
41+ private int scrollTrackX = 0 ;
42+ private int scrollTrackWidth = 0 ;
43+ private int scrollThumbTop = 0 ;
44+ private int scrollThumbHeight = 0 ;
45+ private int scrollMax = 0 ;
3546
3647 // Dimension filter (null = show all)
3748 private net .wurstclient .waypoints .WaypointDimension filterDim = null ;
@@ -237,7 +248,7 @@ protected void init()
237248 // "Top" button above the up-arrow that jumps directly to the top
238249 addDrawableChild (ButtonWidget .builder (Text .literal ("▲▲" ), b -> {
239250 scrollToTop ();
240- }).dimensions (arrowX + 20 , Math .max (0 , viewportTop - 24 ), 20 , 20 )
251+ }).dimensions (arrowX + 20 , Math .max (0 , viewportTop - 20 ), 20 , 20 )
241252 .build ());
242253 // Up arrow (move up by a few rows)
243254 addDrawableChild (ButtonWidget .builder (Text .literal ("▲" ), b -> {
@@ -280,6 +291,92 @@ public boolean mouseScrolled(double mouseX, double mouseY,
280291 verticalAmount );
281292 }
282293
294+ @ Override
295+ public boolean mouseClicked (net .minecraft .client .gui .Click context ,
296+ boolean doubleClick )
297+ {
298+ double mouseX = context .x ();
299+ double mouseY = context .y ();
300+ int button = context .button ();
301+ if (button == 0 && scrollMax > 0 )
302+ {
303+ if (isOverScrollbarThumb (mouseX , mouseY ))
304+ {
305+ draggingScrollbar = true ;
306+ scrollbarDragStartY = mouseY ;
307+ scrollbarStartScroll = scroll ;
308+ return true ;
309+ }
310+ if (isOverScrollbarTrack (mouseX , mouseY ))
311+ {
312+ int trackRange =
313+ (scrollTrackBottom - scrollTrackTop ) - scrollThumbHeight ;
314+ if (trackRange > 0 )
315+ {
316+ double ratio =
317+ (mouseY - scrollTrackTop - scrollThumbHeight / 2.0 )
318+ / (double )trackRange ;
319+ scroll = (int )Math .max (0 ,
320+ Math .min (scrollMax , Math .round (ratio * scrollMax )));
321+ saveScrollState ();
322+ return true ;
323+ }
324+ return true ;
325+ }
326+ }
327+ return super .mouseClicked (context , doubleClick );
328+ }
329+
330+ @ Override
331+ public boolean mouseDragged (net .minecraft .client .gui .Click context ,
332+ double deltaX , double deltaY )
333+ {
334+ double mouseY = context .y ();
335+ int button = context .button ();
336+ if (draggingScrollbar && button == 0 && scrollMax > 0 )
337+ {
338+ int trackRange =
339+ (scrollTrackBottom - scrollTrackTop ) - scrollThumbHeight ;
340+ if (trackRange > 0 )
341+ {
342+ double delta = mouseY - scrollbarDragStartY ;
343+ double ratio = delta / (double )trackRange ;
344+ scroll = (int )Math .max (0 , Math .min (scrollMax ,
345+ Math .round (scrollbarStartScroll + ratio * scrollMax )));
346+ saveScrollState ();
347+ return true ;
348+ }
349+ return true ;
350+ }
351+ return super .mouseDragged (context , deltaX , deltaY );
352+ }
353+
354+ @ Override
355+ public boolean mouseReleased (net .minecraft .client .gui .Click context )
356+ {
357+ if (context .button () == 0 && draggingScrollbar )
358+ {
359+ draggingScrollbar = false ;
360+ return true ;
361+ }
362+ return super .mouseReleased (context );
363+ }
364+
365+ private boolean isOverScrollbarThumb (double mouseX , double mouseY )
366+ {
367+ return scrollMax > 0 && mouseX >= scrollTrackX
368+ && mouseX <= scrollTrackX + scrollTrackWidth
369+ && mouseY >= scrollThumbTop
370+ && mouseY <= scrollThumbTop + scrollThumbHeight ;
371+ }
372+
373+ private boolean isOverScrollbarTrack (double mouseX , double mouseY )
374+ {
375+ return scrollMax > 0 && mouseX >= scrollTrackX
376+ && mouseX <= scrollTrackX + scrollTrackWidth
377+ && mouseY >= scrollTrackTop && mouseY <= scrollTrackBottom ;
378+ }
379+
283380 @ Override
284381 public void render (DrawContext context , int mouseX , int mouseY , float delta )
285382 {
@@ -361,6 +458,49 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta)
361458 }
362459
363460 context .disableScissor ();
461+
462+ // Draw scrollbar track & thumb (to the right of the list area)
463+ int contentHeight = rows .size () * ROW_HEIGHT ;
464+ int trackWidth = 8 ;
465+ // position scrollbar centered with the arrow buttons (they are
466+ // placed at arrowX + 20 in init(), where arrowX = x + 305)
467+ int arrowX = x + 305 ;
468+ int buttonX = arrowX + 20 ;
469+ int buttonWidth = 20 ;
470+ int trackX = buttonX + (buttonWidth - trackWidth ) / 2 ;
471+ // leave space for the ▲▲ and ▼▼ buttons above/below the track
472+ int trackTop = viewportTop + 24 ; // push down past the top arrow
473+ int trackBottom = viewportBottom - 24 ; // leave room for bottom arrow
474+ scrollMax = Math .max (0 , contentHeight - (viewportBottom - viewportTop ));
475+ if (scrollMax > 0 && trackBottom > trackTop + 1 )
476+ {
477+ scrollTrackTop = trackTop ;
478+ scrollTrackBottom = trackBottom ;
479+ scrollTrackX = trackX ;
480+ scrollTrackWidth = trackWidth ;
481+ int trackHeight = trackBottom - trackTop ;
482+ int thumbHeight =
483+ (int )Math .round (((double )(viewportBottom - viewportTop )
484+ / Math .max (1.0 , (double )contentHeight )) * trackHeight );
485+ scrollThumbHeight =
486+ Math .max (12 , Math .min (trackHeight , thumbHeight ));
487+ int thumbTravel = trackHeight - scrollThumbHeight ;
488+ int thumbOffset = thumbTravel > 0
489+ ? (int )Math
490+ .round (((double )scroll / (double )scrollMax ) * thumbTravel )
491+ : 0 ;
492+ scrollThumbTop = trackTop + thumbOffset ;
493+ context .fill (trackX , trackTop , trackX + trackWidth , trackBottom ,
494+ 0x55222222 );
495+ context .fill (trackX , scrollThumbTop , trackX + trackWidth ,
496+ scrollThumbTop + scrollThumbHeight , 0xFFAAAAAA );
497+ }else
498+ {
499+ scrollTrackTop = trackTop ;
500+ scrollTrackBottom = trackTop ;
501+ scrollThumbTop = trackTop ;
502+ scrollThumbHeight = 0 ;
503+ }
364504 }
365505
366506 private WaypointDimension currentDim ()
0 commit comments