static void ComputeRectsForInsetBoxShadow(gfxIntSize aBlurRadius, gfxIntSize aSpreadRadius, const Rect& aDestRect, const Rect& aShadowClipRect, Rect& aOutOuterRect, Rect& aOutInnerRect, Margin& aOutPathMargins) { gfxIntSize marginSize = aBlurRadius + aSpreadRadius; // The sizes we're given for aBlurRadius/aSpreadRadius are radius'. // We actually want to paint the whole blur, so we need the diameter. // We render both the outer / inner blur portions of a blur, // Then we clip out the outer portion later. aOutPathMargins.SizeTo(marginSize.height, marginSize.width, marginSize.height, marginSize.width); aOutPathMargins += aOutPathMargins; aOutOuterRect.x = 0; aOutInnerRect.x = marginSize.width; aOutOuterRect.y = 0; aOutInnerRect.y = marginSize.height; // + 1 for the middle edges so we can sample them aOutInnerRect.width = aOutPathMargins.LeftRight() + 1; aOutInnerRect.height = aOutPathMargins.TopBottom() + 1; // The outer path rect needs to be 1 blur radius past the inner edges aOutOuterRect.width = aOutInnerRect.XMost() + marginSize.width; aOutOuterRect.height = aOutInnerRect.YMost() + marginSize.height; if ((aOutOuterRect.width >= aDestRect.width) || (aOutOuterRect.height >= aDestRect.height) || (aOutInnerRect.width >= aShadowClipRect.width) || (aOutInnerRect.height >= aShadowClipRect.height)) { aOutOuterRect.width = aDestRect.width; aOutOuterRect.height = aDestRect.height; aOutInnerRect.width = aShadowClipRect.width; aOutInnerRect.height = aShadowClipRect.height; aOutPathMargins.SizeTo(0, 0, 0, 0); } }
/*** * We create our minimal rect with 2 rects. * The first is the inside whitespace rect, that is "cut out" * from the box. This is (1). This must be the size * of the blur radius + corner radius so we can have a big enough * inside cut. * * The second (2) is one blur radius surrounding the inner * frame of (1). This is the amount of blur space required * to get a proper blend. * * B = one blur size * W = one blur + corner radii - known as inner margin * ___________________________________ * | | * | | | | * | (2) | (1) | (2) | * | B | W | B | * | | | | * | | | | * | | | * |________________________________| */ static void GetBlurMargins(const RectCornerRadii* aInnerClipRadii, const IntSize& aBlurRadius, Margin& aOutBlurMargin, Margin& aOutInnerMargin) { Size cornerSize(0, 0); if (aInnerClipRadii) { const RectCornerRadii& corners = *aInnerClipRadii; NS_FOR_CSS_FULL_CORNERS(i) { cornerSize.width = std::max(cornerSize.width, corners[i].width); cornerSize.height = std::max(cornerSize.height, corners[i].height); } } // Only the inside whitespace size cares about the border radius size. // Outer sizes only care about blur. IntSize margin = IntSize::Ceil(cornerSize) + aBlurRadius; aOutInnerMargin.SizeTo(margin.height, margin.width, margin.height, margin.width); aOutBlurMargin.SizeTo(aBlurRadius.height, aBlurRadius.width, aBlurRadius.height, aBlurRadius.width); }
static bool GetInsetBoxShadowRects(const Margin& aBlurMargin, const Margin& aInnerMargin, const Rect& aShadowClipRect, const Rect& aDestinationRect, Rect& aOutWhitespaceRect, Rect& aOutOuterRect) { // We always copy (2 * blur radius) + corner radius worth of data to the destination rect // This covers the blend of the path + the actual blur // Need +1 so that we copy the edges correctly as we'll copy // over the min box shadow corners then the +1 for the edges between // Note, the (x,y) coordinates are from the blur margin // since the frame outside the whitespace rect is 1 blur radius extra space. Rect insideWhiteSpace(aBlurMargin.left, aBlurMargin.top, aInnerMargin.LeftRight() + 1, aInnerMargin.TopBottom() + 1); // If the inner white space rect is larger than the shadow clip rect // our approach does not work as we'll just copy one corner // and cover the destination. In those cases, fallback to the destination rect bool useDestRect = (aShadowClipRect.width <= aInnerMargin.LeftRight()) || (aShadowClipRect.height <= aInnerMargin.TopBottom()); if (useDestRect) { aOutWhitespaceRect = aShadowClipRect; aOutOuterRect = aDestinationRect; } else { aOutWhitespaceRect = insideWhiteSpace; aOutOuterRect = aOutWhitespaceRect; aOutOuterRect.Inflate(aBlurMargin); } return useDestRect; }
void CrustaApp:: produceDataDialog() { dataDialog = new PopupWindow( "DataDialog", Vrui::getWidgetManager(), "Load Crusta Data"); RowColumn* root = new RowColumn("DataRoot", dataDialog, false); RowColumn* top = new RowColumn("DataTop", root, false); top->setOrientation(RowColumn::HORIZONTAL); top->setColumnWeight(0, 1.0f); ScrolledListBox* box = new ScrolledListBox("DataListBox", top, ListBox::MULTIPLE, DATALISTBOX_SIZE[0], DATALISTBOX_SIZE[1]); dataListBox = box->getListBox(); dataListBox->setAutoResize(true); Margin* addRemoveMargin = new Margin("DataAddRemoveMargin", top, false); addRemoveMargin->setAlignment(Alignment::VCENTER); RowColumn* addRemoveRoot = new RowColumn("DataAddRemoveRoot", addRemoveMargin, false); Button* button = new Button("DataAddButton", addRemoveRoot, "Add"); button->getSelectCallbacks().add(this, &CrustaApp::addDataCallback); button = new Button("DataRemoveButton", addRemoveRoot, "Remove"); button->getSelectCallbacks().add(this, &CrustaApp::removeDataCallback); button = new Button("DataClearButton", addRemoveRoot, "Clear"); button->getSelectCallbacks().add(this, &CrustaApp::clearDataCallback); addRemoveRoot->manageChild(); addRemoveMargin->manageChild(); top->manageChild(); Margin* actionMargin = new Margin("DataActionMargin", root, false); actionMargin->setAlignment(Alignment::RIGHT); RowColumn* actionRoot = new RowColumn("DataActionRoot",actionMargin,false); actionRoot->setOrientation(RowColumn::HORIZONTAL); button = new Button("DataCancelButton", actionRoot, "Cancel"); button->getSelectCallbacks().add(this, &CrustaApp::loadDataCancelCallback); button = new Button("DataOkButton", actionRoot, "Load"); button->getSelectCallbacks().add(this, &CrustaApp::loadDataOkCallback); actionRoot->manageChild(); actionMargin->manageChild(); root->manageChild(); }
RangeEditor:: RangeEditor(const char* name, Container* parent, bool childManaged) : RowColumn(name, parent, false) { ///\todo allow changing the preferred size through API const Vector preferredSize(4.0f, 0.0f, 0.0f); const StyleSheet* style = getManager()->getStyleSheet(); setNumMinorWidgets(1); //- create the min max labels group RowColumn* labels = new RowColumn("Rlabels", this, false); labels->setNumMinorWidgets(5); labels->setColumnWeight(2, 1.0f); new Label("RminLabelName", labels, "Min:"); rangeLabels[0] = new TextField("RminLabel", labels, 9); rangeLabels[0]->setFloatFormat(TextField::FIXED); rangeLabels[0]->setFieldWidth(9); rangeLabels[0]->setPrecision(2); Margin* centerMargin = new Margin("RcenterMargin", labels, false); centerMargin->setAlignment(Alignment::HCENTER); rangeLabels[1] = new TextField("RcenterLabel", centerMargin, 9); rangeLabels[1]->setFloatFormat(TextField::FIXED); rangeLabels[1]->setFieldWidth(9); rangeLabels[1]->setPrecision(2); centerMargin->manageChild(); rangeLabels[2] = new TextField("RmaxLabel", labels, 9); rangeLabels[2]->setHAlignment(GLFont::Left); rangeLabels[2]->setFloatFormat(TextField::FIXED); rangeLabels[2]->setFieldWidth(9); rangeLabels[2]->setPrecision(2); new Label("RmaxLabelName", labels, ":Max"); labels->manageChild(); //- create the min/max sliders group RowColumn* minmax = new RowColumn("Rminmax", this, false); minmax->setNumMinorWidgets(2); minmax->setPacking(RowColumn::PACK_GRID); RelativeSlider* slider; slider = new RelativeSlider("RminSlider", minmax, RelativeSlider::HORIZONTAL, style->fontHeight*preferredSize[0]); slider->setValue(0.0); slider->setValueRange(-2.0, 2.0, 1.0); slider->getValueCallbacks().add(this, &RangeEditor::sliderCallback); slider = new RelativeSlider("RmaxSlider", minmax, RelativeSlider::HORIZONTAL, style->fontHeight*preferredSize[0]); slider->setValue(0.0); slider->setValueRange(-2.0, 2.0, 1.0); slider->getValueCallbacks().add(this, &RangeEditor::sliderCallback); minmax->manageChild(); //- create the shift slider group RowColumn* shift = new RowColumn("Rshift", this, false); shift->setNumMinorWidgets(1); slider = new RelativeSlider("RshiftSlider", shift, RelativeSlider::HORIZONTAL, style->fontHeight*2.0f*preferredSize[0]); slider->setValue(0.0); slider->setValueRange(-2.0, 2.0, 1.0); slider->getValueCallbacks().add(this, &RangeEditor::sliderCallback); shift->manageChild(); //- finalize if(childManaged) manageChild(); }
static const Margin max(const Margin &a, const Margin &b) { return Margin(max(a.lt(), b.lt()), max(a.rb(), b.rb())); }