public static double ScrollBehavior( Rect bgRect, double contentSize, double viewSize, double viewPosition, int id, bool horizontal, out Rect gripRect, out bool hovered, out bool held) { GUIContext g = Form.current.uiContext; //grip size var trackSize = horizontal ? bgRect.Width : bgRect.Height; var contentRatio = viewSize / contentSize; var gripSize = trackSize * contentRatio; const double minGripSize = 20.0; if (gripSize < minGripSize) { gripSize = minGripSize; } if (gripSize > trackSize) { gripSize = trackSize; } //grip position var viewScrollAreaSize = contentSize - viewSize; var viewPositionRatio = viewPosition / viewScrollAreaSize; var trackScrollAreaSize = trackSize - gripSize; var gripPositionOnTrack = trackScrollAreaSize * viewPositionRatio; hovered = false; held = false; hovered = g.IsMouseHoveringRect(bgRect); g.KeepAliveID(id); if (hovered) { g.SetHoverID(id); if (Mouse.Instance.LeftButtonPressed) //start track { g.SetActiveID(id); } } if (g.ActiveId == id) { if (Mouse.Instance.LeftButtonState == KeyState.Down) { var v = Mouse.Instance.MouseDelta; var mousePositionDelta = horizontal ? v.X : v.Y; var newGripPosition = gripPositionOnTrack + mousePositionDelta; newGripPosition = Math.Clamp(newGripPosition, 0, trackScrollAreaSize); var newGripPositonRatio = newGripPosition / trackScrollAreaSize; viewPosition = newGripPositonRatio * viewScrollAreaSize; } else //end track { g.SetActiveID(0); } } if (g.ActiveId == id) { held = true; } if (horizontal) { gripRect = new Rect(bgRect.X + gripPositionOnTrack, bgRect.Y, gripSize, bgRect.Height); } else { gripRect = new Rect(bgRect.X, bgRect.Y + gripPositionOnTrack, bgRect.Width, gripSize); } return(viewPosition); }