Esempio n. 1
0
// Finds the best width and height given the parents' width and height
wxSize wxRibbonToolBar::GetBestSizeForParentSize(const wxSize& parentSize) const
{
    if (!m_sizes)
        return GetMinSize();

    // Choose row count with largest possible area
    wxSize size = parentSize;

    // A toolbar should maximize its width whether vertical or horizontal, so
    // force the major axis to be horizontal. Without this, there will be
    // redundant horizontal space.
    wxOrientation major_axis = wxHORIZONTAL;
    wxSize bestSize = m_sizes[0];

    if(m_nrows_max != m_nrows_min)
    {
        int area = 0;
        for(int i = 0; i <= m_nrows_max - m_nrows_min; ++i)
        {
            if(m_sizes[i].x <= size.x && m_sizes[i].y <= size.y &&
                GetSizeInOrientation(m_sizes[i], major_axis) > area)
            {
                area = GetSizeInOrientation(m_sizes[i], major_axis);
                bestSize = m_sizes[i];
            }
        }
    }
    return bestSize;
}
Esempio n. 2
0
wxSize wxRibbonToolBar::DoGetNextLargerSize(wxOrientation direction,
                                 wxSize relative_to) const
{
    // Pick the smallest of our sizes which are larger than the given size
    wxSize result(relative_to);
    int area = INT_MAX;
    int nrows;
    for(nrows = m_nrows_min; nrows <= m_nrows_max; ++nrows)
    {
        wxSize size(m_sizes[nrows - m_nrows_min]);
        wxSize original(size);
        switch(direction)
        {
        case wxHORIZONTAL:
            if(size.GetWidth() > relative_to.GetWidth()
                && size.GetHeight() <= relative_to.GetHeight())
            {
                size.SetHeight(relative_to.GetHeight());
                break;
            }
            continue;
        case wxVERTICAL:
            if(size.GetWidth() <= relative_to.GetWidth()
                && size.GetHeight() > relative_to.GetHeight())
            {
                size.SetWidth(relative_to.GetWidth());
                break;
            }
            continue;
        case wxBOTH:
            if(size.GetWidth() > relative_to.GetWidth()
                && size.GetHeight() > relative_to.GetHeight())
            {
                break;
            }
            continue;
        }
        if(GetSizeInOrientation(original, direction) < area)
        {
            result = size;
            area = GetSizeInOrientation(original, direction);
        }
    }

    return result;
}
Esempio n. 3
0
void wxRibbonToolBar::OnSize(wxSizeEvent& evt)
{
    if(m_art == NULL)
        return;

    // Choose row count with largest possible area
    wxSize size = evt.GetSize();
    int row_count = m_nrows_max;
    wxOrientation major_axis = m_art->GetFlags() & wxRIBBON_BAR_FLOW_VERTICAL ?
        wxVERTICAL : wxHORIZONTAL;
    if(m_nrows_max != m_nrows_min)
    {
        int area = 0;
        for(int i = 0; i <= m_nrows_max - m_nrows_min; ++i)
        {
            if(m_sizes[i].x <= size.x && m_sizes[i].y <= size.y &&
                GetSizeInOrientation(m_sizes[i], major_axis) > area)
            {
                area = GetSizeInOrientation(m_sizes[i], major_axis);
                row_count = m_nrows_min + i;
            }
        }
    }

    // Assign groups to rows and calculate row widths
    wxSize* row_sizes = new wxSize[row_count];
    int sep = m_art->GetMetric(wxRIBBON_ART_TOOL_GROUP_SEPARATION_SIZE);

    int r;
    for(r = 0; r < row_count; ++r)
        row_sizes[r] = wxSize(0, 0);
    size_t g;
    size_t group_count = m_groups.GetCount();
    for(g = 0; g < group_count; ++g)
    {
        wxRibbonToolBarToolGroup* group = m_groups.Item(g);
        int shortest_row = 0;
        for(r = 1; r < row_count; ++r)
        {
            if(row_sizes[r].GetWidth() < row_sizes[shortest_row].GetWidth())
                shortest_row = r;
        }
        group->position = wxPoint(row_sizes[shortest_row].x, shortest_row);
        row_sizes[shortest_row].x += group->size.x + sep;
        if(group->size.y > row_sizes[shortest_row].y)
            row_sizes[shortest_row].y = group->size.y;
    }

    // Calculate row positions
    int total_height = 0;
    for(r = 0; r < row_count; ++r)
        total_height += row_sizes[r].GetHeight();
    int rowsep = (size.GetHeight() - total_height) / (row_count + 1);
    int* rowypos = new int[row_count];
    rowypos[0] = rowsep;
    for(r = 1; r < row_count; ++r)
    {
        rowypos[r] = rowypos[r - 1] + row_sizes[r - 1].GetHeight() + rowsep;
    }

    // Set group y positions
    for(g = 0; g < group_count; ++g)
    {
        wxRibbonToolBarToolGroup* group = m_groups.Item(g);
        group->position.y = rowypos[group->position.y];
    }

    delete[] rowypos;
    delete[] row_sizes;
}
Esempio n. 4
0
bool wxRibbonToolBar::Realize()
{
    if(m_art == NULL)
        return false;

    // Calculate the size of each group and the position/size of each tool
    wxMemoryDC temp_dc;
    size_t group_count = m_groups.GetCount();
    size_t g, t;
    for(g = 0; g < group_count; ++g)
    {
        wxRibbonToolBarToolBase* prev = NULL;
        wxRibbonToolBarToolGroup* group = m_groups.Item(g);
        size_t tool_count = group->tools.GetCount();
        int tallest = 0;
        for(t = 0; t < tool_count; ++t)
        {
            wxRibbonToolBarToolBase* tool = group->tools.Item(t);
            tool->size = m_art->GetToolSize(temp_dc, this,
                tool->bitmap.GetSize(), tool->kind, t == 0,
                t == (tool_count - 1), &tool->dropdown);
            if(t == 0)
                tool->state |= wxRIBBON_TOOLBAR_TOOL_FIRST;
            if(t == tool_count - 1)
                tool->state |= wxRIBBON_TOOLBAR_TOOL_LAST;
            if(tool->size.GetHeight() > tallest)
                tallest = tool->size.GetHeight();
            if(prev)
            {
                tool->position = prev->position;
                tool->position.x += prev->size.x;
            }
            else
            {
                tool->position = wxPoint(0, 0);
            }
            prev = tool;
        }
        if(tool_count == 0)
            group->size = wxSize(0, 0);
        else
        {
            group->size = wxSize(prev->position.x + prev->size.x, tallest);
            for(t = 0; t < tool_count; ++t)
                group->tools.Item(t)->size.SetHeight(tallest);
        }
    }

    // Calculate the minimum size for each possible number of rows
    int nrows, r;
    int sep = m_art->GetMetric(wxRIBBON_ART_TOOL_GROUP_SEPARATION_SIZE);
    int smallest_area = INT_MAX;
    wxSize* row_sizes = new wxSize[m_nrows_max];
    wxOrientation major_axis = m_art->GetFlags() & wxRIBBON_BAR_FLOW_VERTICAL ?
        wxVERTICAL : wxHORIZONTAL;
    SetMinSize(wxSize(0, 0));
    for(nrows = m_nrows_min; nrows <= m_nrows_max; ++nrows)
    {
        for(r = 0; r < nrows; ++r)
            row_sizes[r] = wxSize(0, 0);
        for(g = 0; g < group_count; ++g)
        {
            wxRibbonToolBarToolGroup* group = m_groups.Item(g);
            int shortest_row = 0;
            for(r = 1; r < nrows; ++r)
            {
                if(row_sizes[r].GetWidth() < row_sizes[shortest_row].GetWidth())
                    shortest_row = r;
            }
            row_sizes[shortest_row].x += group->size.x + sep;
            if(group->size.y > row_sizes[shortest_row].y)
                row_sizes[shortest_row].y = group->size.y;
        }
        wxSize size(0, 0);
        for(r = 0; r < nrows; ++r)
        {
            if(row_sizes[r].GetWidth() != 0)
                row_sizes[r].DecBy(sep, 0);
            if(row_sizes[r].GetWidth() > size.GetWidth())
                size.SetWidth(row_sizes[r].GetWidth());
            size.IncBy(0, row_sizes[r].y);
        }
        m_sizes[nrows - m_nrows_min] = size;
        if(GetSizeInOrientation(size, major_axis) < smallest_area)
        {
            SetMinSize(size);
            smallest_area = GetSizeInOrientation(size, major_axis);
        }
    }
    delete[] row_sizes;

    // Position the groups
    wxSizeEvent dummy_event(GetSize());
    OnSize(dummy_event);

    return true;
}
Esempio n. 5
0
void wxRibbonToolBar::OnSize(wxSizeEvent& evt)
{
    if(m_art == NULL)
        return;

    // Choose row count with largest possible area
    wxSize size = evt.GetSize();
    int row_count = m_nrows_max;
    wxOrientation major_axis = m_art->GetFlags() & wxRIBBON_BAR_FLOW_VERTICAL ?
        wxVERTICAL : wxHORIZONTAL;

    // See if we're sizing flexibly, and set min size differently
    bool sizingFlexibly = false;
    wxRibbonPanel* panel = wxDynamicCast(GetParent(), wxRibbonPanel);
    if (panel && (panel->GetFlags() & wxRIBBON_PANEL_FLEXIBLE))
        sizingFlexibly = true;

    // Without this, there will be redundant horizontal space because SetMinSize will
    // use the smallest possible height (and therefore largest width).
    if (sizingFlexibly)
        major_axis = wxHORIZONTAL;

    wxSize bestSize = m_sizes[0];

    if(m_nrows_max != m_nrows_min)
    {
        int area = 0;
        for(int i = 0; i <= m_nrows_max - m_nrows_min; ++i)
        {
            if(m_sizes[i].x <= size.x && m_sizes[i].y <= size.y &&
                GetSizeInOrientation(m_sizes[i], major_axis) > area)
            {
                area = GetSizeInOrientation(m_sizes[i], major_axis);
                row_count = m_nrows_min + i;
                bestSize = m_sizes[i];
            }
        }
    }

    // Assign groups to rows and calculate row widths
    wxSize* row_sizes = new wxSize[row_count];
    int sep = m_art->GetMetric(wxRIBBON_ART_TOOL_GROUP_SEPARATION_SIZE);

    int r;
    for(r = 0; r < row_count; ++r)
        row_sizes[r] = wxSize(0, 0);
    size_t g;
    size_t group_count = m_groups.GetCount();
    for(g = 0; g < group_count; ++g)
    {
        wxRibbonToolBarToolGroup* group = m_groups.Item(g);
        int shortest_row = 0;
        for(r = 1; r < row_count; ++r)
        {
            if(row_sizes[r].GetWidth() < row_sizes[shortest_row].GetWidth())
                shortest_row = r;
        }
        group->position = wxPoint(row_sizes[shortest_row].x, shortest_row);
        row_sizes[shortest_row].x += group->size.x + sep;
        if(group->size.y > row_sizes[shortest_row].y)
            row_sizes[shortest_row].y = group->size.y;
    }

    // Calculate row positions
    int total_height = 0;
    for(r = 0; r < row_count; ++r)
        total_height += row_sizes[r].GetHeight();
    int rowsep = (size.GetHeight() - total_height) / (row_count + 1);
    int* rowypos = new int[row_count];
    rowypos[0] = rowsep;
    for(r = 1; r < row_count; ++r)
    {
        rowypos[r] = rowypos[r - 1] + row_sizes[r - 1].GetHeight() + rowsep;
    }

    // Set group y positions
    for(g = 0; g < group_count; ++g)
    {
        wxRibbonToolBarToolGroup* group = m_groups.Item(g);
        group->position.y = rowypos[group->position.y];
    }

    delete[] rowypos;
    delete[] row_sizes;
}
Esempio n. 6
0
bool wxRibbonToolBar::Realize()
{
    if(m_art == NULL)
        return false;

    // Calculate the size of each group and the position/size of each tool
    wxMemoryDC temp_dc;
    size_t group_count = m_groups.GetCount();
    size_t g, t;
    for(g = 0; g < group_count; ++g)
    {
        wxRibbonToolBarToolBase* prev = NULL;
        wxRibbonToolBarToolGroup* group = m_groups.Item(g);
        size_t tool_count = group->tools.GetCount();
        int tallest = 0;
        for(t = 0; t < tool_count; ++t)
        {
            wxRibbonToolBarToolBase* tool = group->tools.Item(t);
            tool->size = m_art->GetToolSize(temp_dc, this,
                tool->bitmap.GetSize(), tool->kind, t == 0,
                t == (tool_count - 1), &tool->dropdown);
            if(t == 0)
                tool->state |= wxRIBBON_TOOLBAR_TOOL_FIRST;
            if(t == tool_count - 1)
                tool->state |= wxRIBBON_TOOLBAR_TOOL_LAST;
            if(tool->size.GetHeight() > tallest)
                tallest = tool->size.GetHeight();
            if(prev)
            {
                tool->position = prev->position;
                tool->position.x += prev->size.x;
            }
            else
            {
                tool->position = wxPoint(0, 0);
            }
            prev = tool;
        }
        if(tool_count == 0)
            group->size = wxSize(0, 0);
        else
        {
            group->size = wxSize(prev->position.x + prev->size.x, tallest);
            for(t = 0; t < tool_count; ++t)
                group->tools.Item(t)->size.SetHeight(tallest);
        }
    }

    // Calculate the minimum size for each possible number of rows
    int nrows, r;
    int sep = m_art->GetMetric(wxRIBBON_ART_TOOL_GROUP_SEPARATION_SIZE);
    int smallest_area = INT_MAX;
    wxSize* row_sizes = new wxSize[m_nrows_max];
    wxOrientation major_axis = m_art->GetFlags() & wxRIBBON_BAR_FLOW_VERTICAL ?
        wxVERTICAL : wxHORIZONTAL;

    SetMinSize(wxSize(0, 0));
    wxSize minSize(INT_MAX, INT_MAX);

    // See if we're sizing flexibly (i.e. wrapping), and set min size differently
    bool sizingFlexibly = false;
    wxRibbonPanel* panel = wxDynamicCast(GetParent(), wxRibbonPanel);
    if (panel && (panel->GetFlags() & wxRIBBON_PANEL_FLEXIBLE))
        sizingFlexibly = true;

    // Without this, there will be redundant horizontal space because SetMinSize will
    // use the smallest possible height (and therefore largest width).
    if (sizingFlexibly)
        major_axis = wxHORIZONTAL;

    for(nrows = m_nrows_min; nrows <= m_nrows_max; ++nrows)
    {
        for(r = 0; r < nrows; ++r)
            row_sizes[r] = wxSize(0, 0);
        for(g = 0; g < group_count; ++g)
        {
            wxRibbonToolBarToolGroup* group = m_groups.Item(g);
            int shortest_row = 0;
            for(r = 1; r < nrows; ++r)
            {
                if(row_sizes[r].GetWidth() < row_sizes[shortest_row].GetWidth())
                    shortest_row = r;
            }
            row_sizes[shortest_row].x += group->size.x + sep;
            if(group->size.y > row_sizes[shortest_row].y)
                row_sizes[shortest_row].y = group->size.y;
        }
        wxSize size(0, 0);
        for(r = 0; r < nrows; ++r)
        {
            if(row_sizes[r].GetWidth() != 0)
                row_sizes[r].DecBy(sep, 0);
            if(row_sizes[r].GetWidth() > size.GetWidth())
                size.SetWidth(row_sizes[r].GetWidth());
            size.IncBy(0, row_sizes[r].y);
        }
        m_sizes[nrows - m_nrows_min] = size;

        if(GetSizeInOrientation(size, major_axis) < smallest_area)
        {
            smallest_area = GetSizeInOrientation(size, major_axis);
            SetMinSize(size);
        }

        if (sizingFlexibly)
        {
            if (size.x < minSize.x)
                minSize.x = size.x;
            if (size.y < minSize.y)
                minSize.y = size.y;
        }
    }

    if (sizingFlexibly)
    {
        // Give it the min size in either direction regardless of row,
        // so that we're able to vary the size of the panel according to
        // the space the toolbar takes up.
        SetMinSize(minSize);
    }
    delete[] row_sizes;

    // Position the groups
    wxSizeEvent dummy_event(GetSize());
    OnSize(dummy_event);

    return true;
}