Ejemplo n.º 1
0
wxSize wxCollapsiblePane::DoGetBestSize() const
{
    wxASSERT_MSG( m_widget, wxT("DoGetBestSize called before creation") );

    wxSize sz = m_szCollapsed;
    if ( IsExpanded() )
    {
        wxSize panesz = GetPane()->GetBestSize();
        sz.x = wxMax(sz.x, panesz.x);
        sz.y += gtk_expander_get_spacing(GTK_EXPANDER(m_widget)) + panesz.y;
    }
    
    return sz;
}
Ejemplo n.º 2
0
static void
gtk_collapsiblepane_expanded_callback(GObject * WXUNUSED(object),
                                      GParamSpec * WXUNUSED(param_spec),
                                      wxCollapsiblePane *p)
{
    // NB: unlike for the "activate" signal, when this callback is called, if
    //     we try to query the "collapsed" status through p->IsCollapsed(), we
    //     get the right value. I.e. here p->IsCollapsed() will return false if
    //     this callback has been called at the end of a collapsed->expanded
    //     transition and viceversa. Inside the "activate" signal callback
    //     p->IsCollapsed() would return the wrong value!

    wxSize sz;
    if ( p->IsExpanded() )
    {
        // NB: we cannot use the p->GetBestSize() or p->GetMinSize() functions
        //     here as they would return the size for the collapsed expander
        //     even if the collapsed->expanded transition has already been
        //     completed; we solve this problem doing:

        sz = p->m_szCollapsed;

        wxSize panesz = p->GetPane()->GetBestSize();
        sz.x = wxMax(sz.x, panesz.x);
        sz.y += gtk_expander_get_spacing(GTK_EXPANDER(p->m_widget)) + panesz.y;
    }
    else // collapsed
    {
        // same problem described above: using p->Get[Best|Min]Size() here we
        // would get the size of the control when it is expanded even if the
        // expanded->collapsed transition should be complete now...
        // So, we use the size cached at control-creation time...
        sz = p->m_szCollapsed;
    }

    // VERY IMPORTANT:
    // just calling
    //          p->OnStateChange(sz);
    // here would work work BUT:
    //     1) in the expanded->collapsed transition it provokes a lot of flickering
    //     2) in the collapsed->expanded transition using the "Change status" wxButton
    //        in samples/collpane application some strange warnings would be generated
    //        by the "clearlooks" theme, if that's your theme.
    //
    // So we prefer to use some GTK+ native optimized calls, which prevent too many resize
    // calculations to happen. Note that the following code has been very carefully designed
    // and tested - be VERY careful when changing it!

    // 1) need to update our size hints
    // NB: this function call won't actually do any long operation
    //     (redraw/relayout/resize) so that it's flicker-free
    p->SetMinSize(sz);

    if (p->HasFlag(wxCP_NO_TLW_RESIZE))
    {
        // fire an event
        wxCollapsiblePaneEvent ev(p, p->GetId(), p->IsCollapsed());
        p->HandleWindowEvent(ev);

        // the user asked to explicitly handle the resizing itself...
        return;
    }

    wxTopLevelWindow *
        top = wxDynamicCast(wxGetTopLevelParent(p), wxTopLevelWindow);
    if ( top && top->GetSizer() )
    {
        // 2) recalculate minimal size of the top window
        sz = top->GetSizer()->CalcMin();

        if (top->m_mainWidget)
        {
            // 3) MAGIC HACK: if you ever used GtkExpander in a GTK+ program
            //    you know that this magic call is required to make it possible
            //    to shrink the top level window in the expanded->collapsed
            //    transition.  This may be sometimes undesired but *is*
            //    necessary and if you look carefully, all GTK+ programs using
            //    GtkExpander perform this trick (e.g. the standard "open file"
            //    dialog of GTK+>=2.4 is not resizable when the expander is
            //    collapsed!)
            gtk_window_set_resizable (GTK_WINDOW (top->m_widget), p->IsExpanded());

            // 4) set size hints
            top->SetMinClientSize(sz);

            // 5) set size
            top->SetClientSize(sz);
        }
    }

    if ( p->m_bIgnoreNextChange )
    {
        // change generated programmatically - do not send an event!
        p->m_bIgnoreNextChange = false;
        return;
    }

    // fire an event
    wxCollapsiblePaneEvent ev(p, p->GetId(), p->IsCollapsed());
    p->HandleWindowEvent(ev);
}