void WindowArea::DoGroupLayout() { SATWindow* parentWindow = fWindowLayerOrder.ItemAt(0); if (parentWindow == NULL) return; BRect frame = parentWindow->CompleteWindowFrame(); // Make it also work for solver which don't support negative variables frame.OffsetBy(kMakePositiveOffset, kMakePositiveOffset); // adjust window size soft constraints fWidthConstraint->SetRightSide(frame.Width()); fHeightConstraint->SetRightSide(frame.Height()); LinearSpec* linearSpec = fGroup->GetLinearSpec(); Constraint* leftConstraint = linearSpec->AddConstraint(1.0, LeftVar(), kEQ, frame.left); Constraint* topConstraint = linearSpec->AddConstraint(1.0, TopVar(), kEQ, frame.top); // give soft constraints a high penalty fWidthConstraint->SetPenaltyNeg(kHighPenalty); fWidthConstraint->SetPenaltyPos(kHighPenalty); fHeightConstraint->SetPenaltyNeg(kHighPenalty); fHeightConstraint->SetPenaltyPos(kHighPenalty); // After we set the new parameter solve and apply the new layout. ResultType result; for (int32 tries = 0; tries < 15; tries++) { result = fGroup->GetLinearSpec()->Solve(); if (result == kInfeasible) { debug_printf("can't solve constraints!\n"); break; } if (result == kOptimal) { const WindowAreaList& areas = fGroup->GetAreaList(); for (int32 i = 0; i < areas.CountItems(); i++) { WindowArea* area = areas.ItemAt(i); area->_MoveToSAT(parentWindow); } break; } } // set penalties back to normal fWidthConstraint->SetPenaltyNeg(kExtentPenalty); fWidthConstraint->SetPenaltyPos(kExtentPenalty); fHeightConstraint->SetPenaltyNeg(kExtentPenalty); fHeightConstraint->SetPenaltyPos(kExtentPenalty); linearSpec->RemoveConstraint(leftConstraint); linearSpec->RemoveConstraint(topConstraint); }
void GroupCookie::DoGroupLayout(SATWindow* triggerWindow) { if (!fSATGroup.Get()) return; BRect frame = triggerWindow->CompleteWindowFrame(); // Make it also work for solver which don't support negative variables frame.OffsetBy(kMakePositiveOffset, kMakePositiveOffset); // adjust window size soft constraints fWidthConstraint->SetRightSide(frame.Width()); fHeightConstraint->SetRightSide(frame.Height()); LinearSpec* linearSpec = fSATGroup->GetLinearSpec(); fLeftConstraint = linearSpec->AddConstraint(1.0, fLeftBorder, kEQ, frame.left); fTopConstraint = linearSpec->AddConstraint(1.0, fTopBorder, kEQ, frame.top); // adjust window position soft constraints // (a bit more penalty for them so they take precedence) fWidthConstraint->SetPenaltyNeg(-1); fWidthConstraint->SetPenaltyPos(-1); fHeightConstraint->SetPenaltyNeg(-1); fHeightConstraint->SetPenaltyPos(-1); // After we set the new parameter solve and apply the new layout. ResultType result; for (int32 tries = 0; tries < 15; tries++) { result = fSATGroup->GetLinearSpec()->Solve(); if (result == kInfeasible) { debug_printf("can't solve constraints!\n"); break; } if (result == kOptimal) { fSATGroup->AdjustWindows(triggerWindow); _UpdateWindowSize(frame); break; } } // set penalties back to normal fWidthConstraint->SetPenaltyNeg(kExtentPenalty); fWidthConstraint->SetPenaltyPos(kExtentPenalty); fHeightConstraint->SetPenaltyNeg(kExtentPenalty); fHeightConstraint->SetPenaltyPos(kExtentPenalty); linearSpec->RemoveConstraint(fLeftConstraint); fLeftConstraint = NULL; linearSpec->RemoveConstraint(fTopConstraint); fTopConstraint = NULL; }
void WindowArea::_UninitConstraints() { LinearSpec* linearSpec = fGroup->GetLinearSpec(); linearSpec->RemoveConstraint(fMinWidthConstraint, true); linearSpec->RemoveConstraint(fMinHeightConstraint, true); linearSpec->RemoveConstraint(fMaxWidthConstraint, true); linearSpec->RemoveConstraint(fMaxHeightConstraint, true); linearSpec->RemoveConstraint(fWidthConstraint, true); linearSpec->RemoveConstraint(fHeightConstraint, true); fMinWidthConstraint = NULL; fMinHeightConstraint = NULL; fMaxWidthConstraint = NULL; fMaxHeightConstraint = NULL; fWidthConstraint = NULL; fHeightConstraint = NULL; }
bool WindowArea::Init(SATGroup* group) { _UninitConstraints(); if (group != NULL && group->fWindowAreaList.AddItem(this) == false) return false; fGroup = group; LinearSpec* linearSpec = fGroup->GetLinearSpec(); fMinWidthConstraint = linearSpec->AddConstraint(1.0, RightVar(), -1.0, LeftVar(), kGE, 0); fMinHeightConstraint = linearSpec->AddConstraint(1.0, BottomVar(), -1.0, TopVar(), kGE, 0); fMaxWidthConstraint = linearSpec->AddConstraint(1.0, RightVar(), -1.0, LeftVar(), kLE, 0, kInequalityPenalty, kInequalityPenalty); fMaxHeightConstraint = linearSpec->AddConstraint(1.0, BottomVar(), -1.0, TopVar(), kLE, 0, kInequalityPenalty, kInequalityPenalty); // Width and height have soft constraints fWidthConstraint = linearSpec->AddConstraint(1.0, RightVar(), -1.0, LeftVar(), kEQ, 0, kExtentPenalty, kExtentPenalty); fHeightConstraint = linearSpec->AddConstraint(-1.0, TopVar(), 1.0, BottomVar(), kEQ, 0, kExtentPenalty, kExtentPenalty); if (!fMinWidthConstraint || !fMinHeightConstraint || !fWidthConstraint || !fHeightConstraint || !fMaxWidthConstraint || !fMaxHeightConstraint) return false; return true; }
bool GroupCookie::Init(SATGroup* group, WindowArea* area) { ASSERT(fSATGroup.Get() == NULL); fSATGroup.SetTo(group); fWindowArea = area; LinearSpec* linearSpec = group->GetLinearSpec(); // create variables fLeftBorder = linearSpec->AddVariable(); fTopBorder = linearSpec->AddVariable(); fRightBorder = linearSpec->AddVariable(); fBottomBorder = linearSpec->AddVariable(); if (!fLeftBorder || !fTopBorder || !fRightBorder || !fBottomBorder) { // clean up Uninit(); return false; } // create constraints BRect frame = fSATWindow->CompleteWindowFrame(); int32 minWidth, maxWidth, minHeight, maxHeight; fSATWindow->GetSizeLimits(&minWidth, &maxWidth, &minHeight, &maxHeight); fMinWidthConstraint = linearSpec->AddConstraint(1.0, fRightBorder, -1.0, fLeftBorder, kGE, minWidth); fMinHeightConstraint = linearSpec->AddConstraint(1.0, fBottomBorder, -1.0, fTopBorder, kGE, minHeight); // The width and height constraints have higher penalties than the // position constraints (left, top), so a window will keep its size // unless explicitly resized. fWidthConstraint = linearSpec->AddConstraint(-1.0, fLeftBorder, 1.0, fRightBorder, kEQ, frame.Width(), kExtentPenalty, kExtentPenalty); fHeightConstraint = linearSpec->AddConstraint(-1.0, fTopBorder, 1.0, fBottomBorder, kEQ, frame.Height(), kExtentPenalty, kExtentPenalty); if (!fMinWidthConstraint || !fMinHeightConstraint || !fWidthConstraint || !fHeightConstraint) { // clean up Uninit(); return false; } fLeftBorderConstraint = area->LeftTab()->Connect(fLeftBorder); fTopBorderConstraint = area->TopTab()->Connect(fTopBorder); fRightBorderConstraint = area->RightTab()->Connect(fRightBorder); fBottomBorderConstraint = area->BottomTab()->Connect(fBottomBorder); if (!fLeftBorderConstraint || !fTopBorderConstraint || !fRightBorderConstraint || !fBottomBorderConstraint) { Uninit(); return false; } return true; }