Skip to content

Commit ff8b246

Browse files
committed
Resize Mode Fill and Better Handling for Min Extent in Frame Set
This update adds a new experimental resize mode called "Fill" which attempts to always keep a control at position 0, 0 and make it's extent match the parent's content area. You're results may vary. I'm sure I'll be revisiting this to handle various cases in the future. This code also greatly improves how Min Extent is handled by the Frame Set. Instead of modifying the Min Extent of children, the Frame Set now safely clips the children if they can't fit inside their frame.
1 parent 359c92a commit ff8b246

12 files changed

+167
-49
lines changed

editor/AssetAdmin/AssetAdmin.cs

+5-8
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@
8888
VertSizing = "bottom";
8989
Position = "0 0";
9090
Extent = "330 380";
91-
MinExtent = "100 100";
91+
MinExtent = "200 100";
9292
text = "Asset Library";
9393
canMove = true;
9494
canClose = false;
@@ -168,10 +168,9 @@
168168
{
169169
HorizSizing = "right";
170170
VertSizing = "bottom";
171-
Position = "0 0";
172-
Extent = "706 380";
173-
MinExtent = "100 100";
174171
text = "Asset Inspector";
172+
Extent = "706 380";
173+
MinExtent = "500 250";
175174
canMove = true;
176175
canClose = false;
177176
canMinimize = true;
@@ -189,11 +188,9 @@
189188
%this.inspector = new GuiControl()
190189
{
191190
class = "AssetInspector";
192-
HorizSizing = "width";
193-
VertSizing = "height";
194-
Position="0 0";
195191
Extent="700 370";
196-
MinExtent="350 222";
192+
HorizSizing = "fill";
193+
VertSizing = "fill";
197194
};
198195
ThemeManager.setProfile(%this.inspector, "overlayProfile");
199196

editor/AssetAdmin/AssetInspector.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@
8888
HorizSizing = width;
8989
VertSizing = height;
9090
Position = "0 34";
91-
Extent = "700 320";
91+
Extent = "700 336";
9292
TabPosition = top;
9393
Visible = false;
9494
};

editor/EditorCore/scripts/EditorProjectCard.cs

+2
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ class = EditorProjectCardScroller;
5252
Extent="200 120";
5353
hScrollBar="alwaysOff";
5454
vScrollBar="alwaysOn";
55+
HorizSizing = "right";
56+
VertSizing = "bottom";
5557
constantThumbHeight="0";
5658
showArrowButtons="0";
5759
scrollBarThickness="6";

engine/source/gui/buttons/guiDropDownCtrl.cc

+2
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ GuiDropDownCtrl::GuiDropDownCtrl()
9494
mScroll = new GuiScrollCtrl();
9595
AssertFatal(mScroll, "GuiDropDownCtrl: Failed to initialize GuiScrollCtrl!");
9696
mScroll->setField("profile", "GuiScrollProfile");
97+
mScroll->setField("horizSizing","right");
98+
mScroll->setField("vertSizing","bottom");
9799
mScrollProfile = mScroll->mProfile;
98100
mScrollProfile->incRefCount();
99101

engine/source/gui/containers/guiFrameSetCtrl.cc

+46-4
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,6 @@ void GuiFrameSetCtrl::Frame::resize(const Point2I& newPosition, const Point2I& n
5656
sizeInsertButtons(newPosition, newExtent);
5757
if (control)
5858
{
59-
if (control->mMinExtent.x > minSize || control->mMinExtent.y > minSize)
60-
{
61-
control->mMinExtent.set(minSize, minSize);
62-
}
6359
control->resize(newPosition, newExtent);
6460
}
6561
if (!child1 && !child2 && owner->isEditMode())
@@ -1133,6 +1129,52 @@ void GuiFrameSetCtrl::undockWindowFromBook(GuiWindowCtrl* window, GuiTabBookCtrl
11331129
}
11341130
}
11351131

1132+
void GuiFrameSetCtrl::renderChild(GuiControl* ctrl, const Point2I& offset, const RectI& content, const RectI& clipRect)
1133+
{
1134+
RectI clip = RectI(clipRect);
1135+
Frame* frame = mRootFrame.findFrameWithCtrl(ctrl);
1136+
if (frame)
1137+
{
1138+
Point2I framePos = localToGlobalCoord(frame->localPosition);
1139+
RectI area(framePos, frame->extent);
1140+
clip.intersect(area);
1141+
}
1142+
1143+
Parent::renderChild(ctrl, offset, content, clip);
1144+
}
1145+
1146+
GuiControl* GuiFrameSetCtrl::findHitControl(const Point2I& pt, S32 initialLayer)
1147+
{
1148+
iterator i = end(); // find in z order (last to first)
1149+
while (i != begin())
1150+
{
1151+
i--;
1152+
GuiControl* ctrl = static_cast<GuiControl*>(*i);
1153+
RectI ctrlRect = RectI(localToGlobalCoord(ctrl->getPosition()), ctrl->getExtent());
1154+
Frame* frame = mRootFrame.findFrameWithCtrl(ctrl);
1155+
if (frame)
1156+
{
1157+
Point2I framePos = localToGlobalCoord(frame->localPosition);
1158+
RectI area(framePos, frame->extent);
1159+
ctrlRect.intersect(area);
1160+
}
1161+
Point2I globalPoint = localToGlobalCoord(pt);
1162+
if (initialLayer >= 0 && ctrl->mLayer > initialLayer)
1163+
{
1164+
continue;
1165+
}
1166+
else if (ctrl->mVisible && ctrl->pointInControl(pt - ctrl->mRenderInsetLT) && ctrl->mUseInput && ctrlRect.pointInRect(globalPoint))
1167+
{
1168+
Point2I ptemp = pt - (ctrl->mBounds.point + ctrl->mRenderInsetLT);
1169+
GuiControl* hitCtrl = ctrl->findHitControl(ptemp);
1170+
1171+
if (hitCtrl->mUseInput)
1172+
return hitCtrl;
1173+
}
1174+
}
1175+
return this;
1176+
}
1177+
11361178
void GuiFrameSetCtrl::setDropButtonProfile(GuiControlProfile* prof)
11371179
{
11381180
AssertFatal(prof, "GuiFrameSetCtrl::setDropButtonProfile: invalid content profile");

engine/source/gui/containers/guiFrameSetCtrl.h

+2
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ class GuiFrameSetCtrl : public GuiEasingSupport
120120
void renderDropButton(const GuiFrameSetCtrl::Frame* frame, const RectI& buttonRect, const Point2I& cursorPt, const Point2I& fillPos, const Point2I& fillExt, GuiDirection direction);
121121
void handleDropButtons(GuiWindowCtrl* window);
122122
void undockWindowFromBook(GuiWindowCtrl* window, GuiTabBookCtrl* book, GuiTabPageCtrl* page);
123+
void renderChild(GuiControl* ctrl, const Point2I& offset, const RectI& content, const RectI& clipRect);
124+
GuiControl* findHitControl(const Point2I& pt, S32 initialLayer = -1);
123125

124126
Point2I splitFrame(S32 frameID, bool isVertical);
125127
void splitFrame(GuiFrameSetCtrl::Frame* frame, GuiDirection direction);

engine/source/gui/containers/guiGridCtrl.cc

+2-8
Original file line numberDiff line numberDiff line change
@@ -333,14 +333,8 @@ Point2F GuiGridCtrl::GetGridItemHeight(const S32 totalArea, const S32 maxChainLe
333333
void GuiGridCtrl::onChildAdded(GuiControl* child)
334334
{
335335
//Ensure the child isn't positioned to the center
336-
if (child->getHorizSizing() == horizResizeCenter)
337-
{
338-
child->setHorizSizing(horizResizeLeft);
339-
}
340-
if (child->getVertSizing() == vertResizeCenter)
341-
{
342-
child->setVertSizing(vertResizeTop);
343-
}
336+
child->preventResizeModeCenter();
337+
child->preventResizeModeFill();
344338
resize(getPosition(), getExtent());
345339

346340
Parent::onChildAdded(child);

engine/source/gui/containers/guiScrollCtrl.cc

+16-2
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ IMPLEMENT_CONOBJECT(GuiScrollCtrl);
4949
GuiScrollCtrl::GuiScrollCtrl()
5050
{
5151
mBounds.extent.set(200,200);
52-
mScrollBarThickness = 16;
52+
mScrollBarThickness = 14;
5353
mScrollBarDragTolerance = 130;
5454
mDepressed = false;
5555
curHitRegion = Content;
@@ -70,6 +70,9 @@ GuiScrollCtrl::GuiScrollCtrl()
7070
mScrollOffset.set(0, 0);
7171
mContentExt.set(200,200);
7272

73+
mHorizSizing = horizResizeFill;
74+
mVertSizing = vertResizeFill;
75+
7376
setField("thumbProfile", "GuiScrollThumbProfile");
7477
setField("arrowProfile", "GuiScrollArrowProfile");
7578
setField("trackProfile", "GuiScrollTrackProfile");
@@ -117,10 +120,14 @@ void GuiScrollCtrl::resize(const Point2I &newPos, const Point2I &newExt)
117120
{
118121
GuiControl* ctrl = static_cast<GuiControl*>(*i);
119122
ctrl->mRenderInsetRB = Point2I(ctrl->mRenderInsetRB.x + deltaX, ctrl->mRenderInsetRB.y + deltaY);
123+
ctrl->preventResizeModeFill();
124+
ctrl->preventResizeModeCenter();
120125
ctrl->parentResized(mBounds.extent - (ctrl->mRenderInsetLT + ctrl->mRenderInsetRB), mBounds.extent - (ctrl->mRenderInsetLT + ctrl->mRenderInsetRB));
121126
}
122127

128+
mCalcGuard = true;
123129
Parent::resize(newPos, newExt);
130+
mCalcGuard = false;
124131
computeSizes();
125132
}
126133
mResizeGuard = false;
@@ -135,6 +142,13 @@ void GuiScrollCtrl::childResized(GuiControl *child)
135142

136143
void GuiScrollCtrl::addObject(SimObject* object)
137144
{
145+
//Fill is not supported inside a scroll control
146+
GuiControl* child = dynamic_cast<GuiControl*>(object);
147+
if (child)
148+
{
149+
child->preventResizeModeFill();
150+
child->preventResizeModeCenter();
151+
}
138152
Parent::addObject(object);
139153
computeSizes();
140154
}
@@ -1088,7 +1102,7 @@ void GuiScrollCtrl::renderHScrollBar(const Point2I& offset)
10881102
}
10891103
}
10901104

1091-
void GuiScrollCtrl::renderChildControls(Point2I offset, RectI content, const RectI& updateRect)
1105+
void GuiScrollCtrl::renderChildControls(const Point2I& offset, const RectI& content, const RectI& updateRect)
10921106
{
10931107
// offset is the upper-left corner of this control in screen coordinates. It should almost always be the same offset passed into the onRender method.
10941108
// updateRect is the area that this control was allowed to draw in. It should almost always be the same as the value in onRender.

engine/source/gui/containers/guiScrollCtrl.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ class GuiScrollCtrl : public GuiControl
178178
virtual void renderVScrollBar(const Point2I& offset);
179179
virtual void renderHScrollBar(const Point2I& offset);
180180
virtual GuiControl* findHitControl(const Point2I &pt, S32 initialLayer = -1);
181-
virtual void renderChildControls(Point2I offset, RectI content, const RectI& updateRect);
181+
virtual void renderChildControls(const Point2I& offset, const RectI& content, const RectI& updateRect);
182182
};
183183

184184
#endif //_GUI_SCROLL_CTRL_H

engine/source/gui/editor/guiMenuBarCtrl.cc

+2
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,8 @@ void GuiMenuItemCtrl::onChildAdded(GuiControl *child)
718718
if(mScroll == NULL)
719719
{
720720
mScroll = new GuiScrollCtrl();
721+
mScroll->setField("horizSizing","right");
722+
mScroll->setField("vertSizing","bottom");
721723
AssertFatal(mScroll, "GuiMenuItemCtrl::onChildAdded Failed to initialize GuiScrollCtrl!");
722724
}
723725

engine/source/gui/guiControl.cc

+73-21
Original file line numberDiff line numberDiff line change
@@ -185,20 +185,22 @@ static EnumTable::Enums horzEnums[] =
185185
{ GuiControl::horizResizeRight, "right" },
186186
{ GuiControl::horizResizeWidth, "width" },
187187
{ GuiControl::horizResizeLeft, "left" },
188-
{ GuiControl::horizResizeCenter, "center" },
189-
{ GuiControl::horizResizeRelative, "relative" }
188+
{ GuiControl::horizResizeCenter, "center" },
189+
{ GuiControl::horizResizeRelative, "relative" },
190+
{ GuiControl::horizResizeFill, "fill" }
190191
};
191-
static EnumTable gHorizSizingTable(5, &horzEnums[0]);
192+
static EnumTable gHorizSizingTable(6, &horzEnums[0]);
192193

193194
static EnumTable::Enums vertEnums[] =
194195
{
195196
{ GuiControl::vertResizeBottom, "bottom" },
196197
{ GuiControl::vertResizeHeight, "height" },
197198
{ GuiControl::vertResizeTop, "top" },
198-
{ GuiControl::vertResizeCenter, "center" },
199-
{ GuiControl::vertResizeRelative, "relative" }
199+
{ GuiControl::vertResizeCenter, "center" },
200+
{ GuiControl::vertResizeRelative, "relative" },
201+
{ GuiControl::vertResizeFill, "fill" }
200202
};
201-
static EnumTable gVertSizingTable(5, &vertEnums[0]);
203+
static EnumTable gVertSizingTable(6, &vertEnums[0]);
202204

203205
void GuiControl::initPersistFields()
204206
{
@@ -423,10 +425,20 @@ void GuiControl::resize(const Point2I &newPosition, const Point2I &newExtent)
423425
{
424426
actualNewPosition.x = (parentInnerExtent.x - actualNewExtent.x) / 2;
425427
}
428+
else if (mHorizSizing == horizResizeFill)
429+
{
430+
actualNewPosition.x = 0;
431+
actualNewExtent.x = parentInnerExtent.x;
432+
}
426433
if (mVertSizing == vertResizeCenter)
427434
{
428435
actualNewPosition.y = (parentInnerExtent.y - actualNewExtent.y) / 2;
429436
}
437+
else if (mVertSizing == vertResizeFill)
438+
{
439+
actualNewPosition.y = 0;
440+
actualNewExtent.y = parentInnerExtent.y;
441+
}
430442
}
431443

432444
// only do the child control resizing stuff if you really need to.
@@ -541,7 +553,8 @@ void GuiControl::parentResized(const Point2I &oldParentExtent, const Point2I &ne
541553
//In the case of centering, we want to make doubly sure we are using the inner rect.
542554
GuiControl* parent = getParent();
543555
Point2I parentInnerExt = Point2I(newParentExtent);
544-
if(mHorizSizing == horizResizeCenter || mVertSizing == vertResizeCenter)
556+
if(mHorizSizing == horizResizeCenter || mVertSizing == vertResizeCenter ||
557+
mHorizSizing == horizResizeFill || mVertSizing == vertResizeFill)
545558
{
546559
//This is based on the "new" outer extent of the parent.
547560
parentInnerExt = parent->getInnerRect().extent;
@@ -553,6 +566,11 @@ void GuiControl::parentResized(const Point2I &oldParentExtent, const Point2I &ne
553566
newExtent.x += deltaX;
554567
else if (mHorizSizing == horizResizeLeft)
555568
newPosition.x += deltaX;
569+
else if (mHorizSizing == horizResizeFill)
570+
{
571+
newPosition.x = 0;
572+
newExtent.x = parentInnerExt.x;
573+
}
556574
else if (mHorizSizing == horizResizeRelative && oldParentExtent.x != 0)
557575
{
558576
Point2F percent = relPosBatteryH(newPosition.x, newExtent.x, oldParentExtent.x);
@@ -569,6 +587,11 @@ void GuiControl::parentResized(const Point2I &oldParentExtent, const Point2I &ne
569587
newExtent.y += deltaY;
570588
else if (mVertSizing == vertResizeTop)
571589
newPosition.y += deltaY;
590+
else if (mVertSizing == vertResizeFill)
591+
{
592+
newPosition.y = 0;
593+
newExtent.y = parentInnerExt.y;
594+
}
572595
else if(mVertSizing == vertResizeRelative && oldParentExtent.y != 0)
573596
{
574597
Point2F percent = relPosBatteryV(newPosition.y, newExtent.y, oldParentExtent.y);
@@ -584,6 +607,30 @@ void GuiControl::parentResized(const Point2I &oldParentExtent, const Point2I &ne
584607
resize(newPosition, newExtent);
585608
}
586609

610+
void GuiControl::preventResizeModeFill()
611+
{
612+
if (getHorizSizing() == horizResizeFill)
613+
{
614+
setHorizSizing(horizResizeRight);
615+
}
616+
if (getVertSizing() == vertResizeFill)
617+
{
618+
setVertSizing(vertResizeBottom);
619+
}
620+
}
621+
622+
void GuiControl::preventResizeModeCenter()
623+
{
624+
if (getHorizSizing() == horizResizeCenter)
625+
{
626+
setHorizSizing(horizResizeRight);
627+
}
628+
if (getVertSizing() == vertResizeCenter)
629+
{
630+
setVertSizing(vertResizeBottom);
631+
}
632+
}
633+
587634
Point2I GuiControl::extentBattery(Point2I &newExtent)
588635
{
589636
if (mMinExtent.x == 0 && mMinExtent.y == 0)
@@ -936,7 +983,7 @@ bool GuiControl::renderTooltip(Point2I &cursorPos, const char* tipText )
936983
return true;
937984
}
938985

939-
void GuiControl::renderChildControls(Point2I offset, RectI content, const RectI &updateRect)
986+
void GuiControl::renderChildControls(const Point2I& offset, const RectI& content, const RectI& updateRect)
940987
{
941988
// offset is the upper-left corner of this control in screen coordinates. It should almost always be the same offset passed into the onRender method.
942989
// updateRect is the area that this control was allowed to draw in. It should almost always be the same as the value in onRender.
@@ -957,19 +1004,7 @@ void GuiControl::renderChildControls(Point2I offset, RectI content, const RectI
9571004
}
9581005
if (ctrl->mVisible)
9591006
{
960-
ctrl->mRenderInsetLT = content.point - offset;
961-
ctrl->mRenderInsetRB = mBounds.extent - (ctrl->mRenderInsetLT + content.extent);
962-
Point2I childPosition = content.point + ctrl->getPosition();
963-
RectI childClip(childPosition, ctrl->getExtent());
964-
965-
if (childClip.intersect(clipRect))
966-
{
967-
RectI old = dglGetClipRect();
968-
dglSetClipRect(clipRect);
969-
glDisable(GL_CULL_FACE);
970-
ctrl->onRender(childPosition, RectI(childPosition, ctrl->getExtent()));
971-
dglSetClipRect(old);
972-
}
1007+
renderChild(ctrl, offset, content, clipRect);
9731008
}
9741009
size_cpy = objectList.size(); // CHRIS: i know its wierd but the size of the list changes sometimes during execution of this loop
9751010
if(size != size_cpy)
@@ -981,6 +1016,23 @@ void GuiControl::renderChildControls(Point2I offset, RectI content, const RectI
9811016
}
9821017
}
9831018

1019+
void GuiControl::renderChild(GuiControl* ctrl, const Point2I& offset, const RectI& content, const RectI& clipRect)
1020+
{
1021+
ctrl->mRenderInsetLT = content.point - offset;
1022+
ctrl->mRenderInsetRB = mBounds.extent - (ctrl->mRenderInsetLT + content.extent);
1023+
Point2I childPosition = content.point + ctrl->getPosition();
1024+
RectI childClip(childPosition, ctrl->getExtent());
1025+
1026+
if (childClip.intersect(clipRect))
1027+
{
1028+
RectI old = dglGetClipRect();
1029+
dglSetClipRect(clipRect);
1030+
glDisable(GL_CULL_FACE);
1031+
ctrl->onRender(childPosition, RectI(childPosition, ctrl->getExtent()));
1032+
dglSetClipRect(old);
1033+
}
1034+
}
1035+
9841036
void GuiControl::setUpdateRegion(Point2I pos, Point2I ext)
9851037
{
9861038
Point2I upos = localToGlobalCoord(pos);

0 commit comments

Comments
 (0)