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