-
Notifications
You must be signed in to change notification settings - Fork 31
Widget Rectangles and Matrices
What makes it very complex is that nuiWidget methods use different origins: some are local (0,0 means the top left of the widget's contents), some are relative to the widget's parent (0,0 is the top left of the parents contents). some are global (0,0 is the top left of the top level container).
- X and Y in Mouse events (and Drag and Drop events).
- Draw operations.
- Set/GetVisibleRect
- Set/GetHotRect
- InvalidateRect
- LocalToLocal -> from this widget's local origin to the referenced widget local origin.
- GlobalToLocal -> from global origin (the nuiTopLevel that is the root of the tree) to local.
- LocalToGlobal -> the opposite of GlobalToLocal.
- GetIdealRect
- SetLayout
- SetRect
- GetRect
- GetBorderedRect
- Set/GetUser[Width|Height|Top|LeftRight|Bottom|Rect|Pos] (yeah, quite a mouthfull...)
The matrix operations always work on strictly local coordinates. This means that if you feed them the result of GetRect without first doing a LocalToLocal(GetParent(), rect); the result will be wrong, unless the widget is placed on the top left corner of its parent.
Moreover, you have to pay special attention to GetIdealRect: usually returns a rectangle that looks like {0, 0, idealwidth, idealheight} which would be a fine rectangle to pass to the matrix operations. BUT, as soon as you give your widget a User defined position, GetIdealRect returns { UserX, UserY, IdealWidth, IdealHeight }, that's the way the parent knows there is something special to do for this widget. You should always consider the return value of GetIdealRect to be local to the parent, and possibly not laying down on it 0,0 (top left) corner. That is even more true if the parent is an nuiFixed.
Last but not least, the pivot and rotation matrices will mess up your rects and it has two consequences:
- it breaks clipping as we don't support clipping rects that are not parallels to the OpenGL context's borders (we use glScissor). It is manageable by disabling clipping on the widget you want to rotate and is should stay manageable once you know about it. - to calculate your bounding rect you will have to transform all four corners of the original rect as the rotated rect will not be parallel to the axes. Once more this is easy to do, however there is no method in nui to do it for you.