domingo, 15 de julho de 2007

Sliding separator news

First version of the sliding separator has a major flaw: if the windows are inside a sizer, item's proportion must be changed at motion or mouse up (I think mouse up is enough). For that wxWindow:­:GetContainingSizer, wxSizer:­:GetItem and wxSizerItem:­:SetProportion may be used. Other windows in the sizer can't be disturbed, so the sum of the two proportions must be constant. There is a list of problems to solve:

- both windows should be proportional, or not: resizing a proportional window with a not proportional window is likely to afect other items.
- a proportional window with minimum size can't get proportion = 0.
- windows with size = 0 and proportion = 0 must be accepted as proportional, in case a window is completely hidden using the slider.

Now the problem is that on mouse up I don't know if the window has proportion = 0 because it was hidden or because it is not proportional, so I have to check on mouse down if the slide can be done and capture the mouse only when all is ok:
void SlideSep::OnLeftDown(wxMouseEvent& event) {
wxSizer* sz = m_windowTL->GetContainingSizer();
if (sz != m_windowBR->GetContainingSizer()) {
wxLogDebug(_T("Adjacent windows should have the same sizer!"));
event.Skip();
return;
}
if (sz) {
wxSizerItem* i1 = sz->GetItem(m_windowTL);
wxSizerItem* i2 = sz->GetItem(m_windowBR);
wxSize s1 = m_windowTL->GetSize();
wxSize s2 = m_windowBR->GetSize();
int p1 = i1->GetProportion();
int p2 = i2->GetProportion();
if ( (p1 || !s1.x) != (p2 || !s2.x) ) {
wxLogDebug(_T("Both items should be proportional, or not!"));
event.Skip();
return;
}
}
m_startPoint = event.GetPosition();
this->CaptureMouse();
event.Skip();
}

Mouse motion has no changes, all proportional stuff is done in mouse up. If capture is lost same changes apply:
void SlideSep::OnLeftUp(wxMouseEvent& event) {
if (HasCapture()) {
this->ReleaseMouse();
OnReleaseMouse();
}
event.Skip();
}

void SlideSep::OnCaptureLost(wxMouseCaptureLostEvent& WXUNUSED(event)) {
OnReleaseMouse();
}

When the mouse is released proportions are changed. If proportions are small numbers a Layout is needed to fix: if I have three windows with proportions 2,5,3 then each window has to be a multiple of 1/10 of the space available; to have a "continuous sliding" proportions must be big numbers like 2000,etc.
void SlideSep::OnReleaseMouse() {
wxSizer* sz = m_windowTL->GetContainingSizer();
if (sz && sz == m_windowBR->GetContainingSizer()) {
wxSizerItem* i1 = sz->GetItem(m_windowTL);
wxSizerItem* i2 = sz->GetItem(m_windowBR);
int p1 = i1->GetProportion();
int p2 = i2->GetProportion();
if (p1 || p2) {
wxSize m1 = m_windowTL->GetMinSize();
wxSize m2 = m_windowBR->GetMinSize();
wxSize s1 = m_windowTL->GetSize();
wxSize s2 = m_windowBR->GetSize();
int ss = s1.x + s2.x;
int pp = p1 + p2;
p1 = (int)((double)pp * s1.x / ss + 0.5);
if (p1 == pp && m2.x != 0) p1--;
if (p1 == 0 && m1.x != 0) p1++;
p2 = pp - p1;
i1->SetProportion(p1);
i2->SetProportion(p2);
sz->Layout();
}
}
}


Source files are here. I'm going back to main project now.

Etiquetas: ,

0 Comentários:

Enviar um comentário

Subscrever Enviar feedback [Atom]

<< Página inicial