Rect ResizeRect(Rect window, float detectionRange) { Rect CalcDraggableRect(Rect r, float d) { r.xMin -= d; r.yMin -= d; r.xMax += d; r.yMax += d; return(r); } var evt = Event.current; var id = GUIUtility.GetControlID(FocusType.Passive); switch (evt.type) { case EventType.MouseUp: { draggingLR = draggingTB = 0; if (GUIUtility.hotControl == id) { GUIUtility.hotControl = 0; } } break; case EventType.MouseDown: { if (GUIUtility.hotControl == 0) { var pos = evt.mousePosition; var rect = CalcDraggableRect(window, detectionRange); if (rect.Contains(pos)) { draggingLR = (pos.x < window.xMin) ? -1 : ((window.xMax < pos.x) ? 1 : 0); draggingTB = (pos.y < window.yMin) ? -1 : ((window.yMax < pos.y) ? 1 : 0); GUIUtility.hotControl = id; } } } break; case EventType.MouseDrag: if ((GUIUtility.hotControl == id) && (evt.button == 0)) { var pos = evt.mousePosition; if (draggingLR == -1) { window.xMin = pos.x; } if (draggingLR == 1) { window.xMax = pos.x; } if (draggingTB == -1) { window.yMin = pos.y; } if (draggingTB == 1) { window.yMax = pos.y; } } break; case EventType.Repaint: { var cursor = MouseCursor.Default; if (GUIUtility.hotControl == 0) { var pos = evt.mousePosition; var rect = CalcDraggableRect(window, detectionRange); if (rect.Contains(pos) && !window.Contains(pos)) { var h = (pos.x < window.xMin) || (window.xMax < pos.x); var v = (pos.y < window.yMin) || (window.yMax < pos.y); cursor = h ? (v ? MouseCursor.ResizeUpLeft : MouseCursor.ResizeHorizontal) : (v ? MouseCursor.ResizeVertical : MouseCursor.Default); } } else { cursor = (draggingLR != 0) ? ((draggingTB != 0) ? MouseCursor.ResizeUpLeft : MouseCursor.ResizeHorizontal) : ((draggingTB != 0) ? MouseCursor.ResizeVertical : MouseCursor.Default); } if (cursor != MouseCursor.Default) { RGUIUtility.SetCursor(cursor); } } break; } return(window); }
static object DoDrag(object obj, Type type) { var controlId = GUIUtility.GetControlID(DoDragHash, FocusType.Passive); var rect = GUILayoutUtility.GetLastRect(); var ev = Event.current; var evType = ev.GetTypeForControl(controlId); switch (evType) { case EventType.MouseDown: { if ((ev.button == RapidGUIBehaviour.Instance.prefixLabelSlideButton) && rect.Contains(ev.mousePosition)) { GUIUtility.hotControl = controlId; lastMousePos = ev.mousePosition; RGUIUtility.SetCursor(MouseCursor.ResizeHorizontal); ev.Use(); } } break; case EventType.MouseUp: { if (GUIUtility.hotControl == controlId) { GUIUtility.hotControl = 0; ev.Use(); } } break; case EventType.MouseDrag: { if ((ev.button == RapidGUIBehaviour.Instance.prefixLabelSlideButton) && (GUIUtility.hotControl == controlId)) { var diff = ev.mousePosition - lastMousePos; var add = (Mathf.Abs(diff.x) > Mathf.Abs(diff.y)) ? diff.x : diff.y; add = Math.Sign(add); lastMousePos = ev.mousePosition; if (typeof(int) == type) { var v = (int)obj; v += (int)(add); obj = v; } else if (typeof(float) == type) { var scale = 0.03f; var v = (float)obj; v += add * scale; v = Mathf.Floor(v * 100f) * 0.01f; // chop obj = v; } ev.Use(); } } break; case EventType.Repaint: { if (GUIUtility.hotControl == controlId) { RGUIUtility.SetCursor(MouseCursor.ResizeHorizontal); } } break; } return(obj); }
internal static void DoMinMaxSlider(Rect position, int id, ref float value, ref float size, float visualStart, float visualEnd, float startLimit, float endLimit, GUIStyle slider, GUIStyle thumb, bool horiz) { Event evt = Event.current; bool usePageScrollbars = size == 0; float minVisual = Mathf.Min(visualStart, visualEnd); float maxVisual = Mathf.Max(visualStart, visualEnd); float minLimit = Mathf.Min(startLimit, endLimit); float maxLimit = Mathf.Max(startLimit, endLimit); MinMaxSliderState state = s_MinMaxSliderState; if (GUIUtility.hotControl == id && state != null) { minVisual = state.dragStartLimit; minLimit = state.dragStartLimit; maxVisual = state.dragEndLimit; maxLimit = state.dragEndLimit; } float minSize = 0; float displayValue = Mathf.Clamp(value, minVisual, maxVisual); float displaySize = Mathf.Clamp(value + size, minVisual, maxVisual) - displayValue; float sign = visualStart > visualEnd ? -1 : 1; if (slider == null || thumb == null) { return; } // Figure out the rects float pixelsPerValue; float mousePosition; Rect thumbRect; Rect thumbMinRect, thumbMaxRect; if (horiz) { float thumbSize = thumb.fixedWidth != 0 ? thumb.fixedWidth : thumb.padding.horizontal; pixelsPerValue = (position.width - slider.padding.horizontal - thumbSize) / (maxVisual - minVisual); thumbRect = new Rect( (displayValue - minVisual) * pixelsPerValue + position.x + slider.padding.left, position.y + slider.padding.top, displaySize * pixelsPerValue + thumbSize, position.height - slider.padding.vertical); thumbMinRect = new Rect(thumbRect.x, thumbRect.y, thumb.padding.left, thumbRect.height); thumbMaxRect = new Rect(thumbRect.xMax - thumb.padding.right, thumbRect.y, thumb.padding.right, thumbRect.height); mousePosition = evt.mousePosition.x - position.x; } else { float thumbSize = thumb.fixedHeight != 0 ? thumb.fixedHeight : thumb.padding.vertical; pixelsPerValue = (position.height - slider.padding.vertical - thumbSize) / (maxVisual - minVisual); thumbRect = new Rect( position.x + slider.padding.left, (displayValue - minVisual) * pixelsPerValue + position.y + slider.padding.top, position.width - slider.padding.horizontal, displaySize * pixelsPerValue + thumbSize); thumbMinRect = new Rect(thumbRect.x, thumbRect.y, thumbRect.width, thumb.padding.top); thumbMaxRect = new Rect(thumbRect.x, thumbRect.yMax - thumb.padding.bottom, thumbRect.width, thumb.padding.bottom); mousePosition = evt.mousePosition.y - position.y; } float mousePos; float thumbPos; switch (evt.GetTypeForControl(id)) { case EventType.MouseDown: // if the click is outside this control, just bail out... if (evt.button != 0 || !position.Contains(evt.mousePosition) || minVisual - maxVisual == 0) { return; } if (state == null) { state = s_MinMaxSliderState = new MinMaxSliderState(); } // These are required to be set whenever we grab hotcontrol, regardless of if we actually drag or not. (case 585577) state.dragStartLimit = startLimit; state.dragEndLimit = endLimit; if (thumbRect.Contains(evt.mousePosition)) { // We have a mousedown on the thumb // Record where we're draging from, so the user can get back. state.dragStartPos = mousePosition; state.dragStartValue = value; state.dragStartSize = size; state.dragStartValuesPerPixel = pixelsPerValue; if (thumbMinRect.Contains(evt.mousePosition)) { state.whereWeDrag = 1; } else if (thumbMaxRect.Contains(evt.mousePosition)) { state.whereWeDrag = 2; } else { state.whereWeDrag = 0; } GUIUtility.hotControl = id; evt.Use(); return; } else { // We're outside the thumb, but inside the trough. // If we have no background, we just bail out. if (slider == GUIStyle.none) { return; } // If we have a scrollSize, we do pgup/pgdn style movements // if not, we just snap to the current position and begin tracking if (size != 0 && usePageScrollbars) { if (horiz) { if (mousePosition > thumbRect.xMax - position.x) { value += size * sign * .9f; } else { value -= size * sign * .9f; } } else { if (mousePosition > thumbRect.yMax - position.y) { value += size * sign * .9f; } else { value -= size * sign * .9f; } } state.whereWeDrag = 0; GUI.changed = true; s_NextScrollStepTime = System.DateTime.Now.AddMilliseconds(kFirstScrollWait); mousePos = horiz ? evt.mousePosition.x : evt.mousePosition.y; thumbPos = horiz ? thumbRect.x : thumbRect.y; state.whereWeDrag = mousePos > thumbPos ? 4 : 3; } else { if (horiz) { value = ((float)mousePosition - thumbRect.width * .5f) / pixelsPerValue + minVisual - size * .5f; } else { value = ((float)mousePosition - thumbRect.height * .5f) / pixelsPerValue + minVisual - size * .5f; } state.dragStartPos = mousePosition; state.dragStartValue = value; state.dragStartSize = size; state.dragStartValuesPerPixel = pixelsPerValue; state.whereWeDrag = 0; GUI.changed = true; } GUIUtility.hotControl = id; value = Mathf.Clamp(value, minLimit, maxLimit - size); evt.Use(); return; } case EventType.MouseDrag: if (GUIUtility.hotControl != id) { return; } // Recalculate the value from the mouse position. this has the side effect that values are relative to the // click point - no matter where inside the trough the original value was. Also means user can get back original value // if he drags back to start position. float deltaVal = (mousePosition - state.dragStartPos) / state.dragStartValuesPerPixel; switch (state.whereWeDrag) { case 0: // normal drag value = Mathf.Clamp(state.dragStartValue + deltaVal, minLimit, maxLimit - size); break; case 1: // min size drag value = state.dragStartValue + deltaVal; size = state.dragStartSize - deltaVal; if (value < minLimit) { size -= minLimit - value; value = minLimit; } if (size < minSize) { value -= minSize - size; size = minSize; } break; case 2: // max size drag size = state.dragStartSize + deltaVal; if (value + size > maxLimit) { size = maxLimit - value; } if (size < minSize) { size = minSize; } break; } GUI.changed = true; evt.Use(); break; case EventType.MouseUp: if (GUIUtility.hotControl == id) { evt.Use(); GUIUtility.hotControl = 0; } break; case EventType.Repaint: slider.Draw(position, GUIContent.none, id); thumb.Draw(thumbRect, GUIContent.none, id); #if false EditorGUIUtility.AddCursorRect(thumbMinRect, horiz ? MouseCursor.ResizeHorizontal : MouseCursor.ResizeVertical, state != null && state.whereWeDrag == 1 ? id : -1); EditorGUIUtility.AddCursorRect(thumbMaxRect, horiz ? MouseCursor.ResizeHorizontal : MouseCursor.ResizeVertical, state != null && state.whereWeDrag == 2 ? id : -1); #else var hasControl = (GUIUtility.hotControl == id) && (state != null); var draggingThumb = hasControl && (state.whereWeDrag == 1 || state.whereWeDrag == 2); if (draggingThumb || (!hasControl && (thumbMinRect.Contains(evt.mousePosition) || thumbMaxRect.Contains(evt.mousePosition))) ) { RGUIUtility.SetCursor(horiz ? MouseCursor.ResizeHorizontal : MouseCursor.ResizeVertical); } #endif // if the mouse is outside this control, just bail out... if (GUIUtility.hotControl != id || !position.Contains(evt.mousePosition) || minVisual - maxVisual == 0) { return; } if (thumbRect.Contains(evt.mousePosition)) { if (state != null && (state.whereWeDrag == 3 || state.whereWeDrag == 4)) // if was scrolling with "through" and the thumb reached mouse - sliding action over { GUIUtility.hotControl = 0; } return; } if (System.DateTime.Now < s_NextScrollStepTime) { return; } mousePos = horiz ? evt.mousePosition.x : evt.mousePosition.y; thumbPos = horiz ? thumbRect.x : thumbRect.y; int currentSide = mousePos > thumbPos ? 4 : 3; if (state != null && currentSide != state.whereWeDrag) { return; } // If we have a scrollSize, we do pgup/pgdn style movements if (size != 0 && usePageScrollbars) { if (horiz) { if (mousePosition > thumbRect.xMax - position.x) { value += size * sign * .9f; } else { value -= size * sign * .9f; } } else { if (mousePosition > thumbRect.yMax - position.y) { value += size * sign * .9f; } else { value -= size * sign * .9f; } } if (state != null) { state.whereWeDrag = -1; } GUI.changed = true; } value = Mathf.Clamp(value, minLimit, maxLimit - size); s_NextScrollStepTime = System.DateTime.Now.AddMilliseconds(kScrollWait); break; } }