mirror of
https://github.com/aseprite/aseprite.git
synced 2025-04-17 08:43:11 +00:00
Convert jgrid widget to C++ Grid class (avoid reallocs, use std::vector for internals instead).
This commit is contained in:
parent
d8a3d27c0f
commit
8b67fd0bf3
@ -50,7 +50,7 @@ void AboutCommand::onExecute(Context* context)
|
||||
{
|
||||
FramePtr frame(new Frame(false, "About " PACKAGE));
|
||||
Box* box1 = new Box(JI_VERTICAL);
|
||||
Widget* grid = jgrid_new(2, false);
|
||||
Grid* grid = new Grid(2, false);
|
||||
Label* title = new Label(PACKAGE " v" VERSION);
|
||||
Label* subtitle = new Label("Animated sprites editor && pixel art tool");
|
||||
Widget* authors_separator1 = ji_separator_new("Authors:", JI_HORIZONTAL | JI_TOP);
|
||||
@ -68,19 +68,19 @@ void AboutCommand::onExecute(Context* context)
|
||||
Label* website = new LinkLabel(WEBSITE);
|
||||
Button* close_button = new Button("&Close");
|
||||
|
||||
jgrid_add_child(grid, title, 2, 1, 0);
|
||||
jgrid_add_child(grid, subtitle, 2, 1, 0);
|
||||
jgrid_add_child(grid, authors_separator1, 2, 1, 0);
|
||||
jgrid_add_child(grid, author1, 1, 1, 0);
|
||||
jgrid_add_child(grid, author1_desc, 1, 1, 0);
|
||||
jgrid_add_child(grid, author2, 1, 1, 0);
|
||||
jgrid_add_child(grid, author2_desc, 1, 1, 0);
|
||||
jgrid_add_child(grid, author3, 1, 1, 0);
|
||||
jgrid_add_child(grid, author3_desc, 1, 1, 0);
|
||||
jgrid_add_child(grid, authors_separator2, 2, 1, 0);
|
||||
jgrid_add_child(grid, copyright, 2, 1, 0);
|
||||
jgrid_add_child(grid, website, 2, 1, 0);
|
||||
jgrid_add_child(grid, bottom_box1, 2, 1, 0);
|
||||
grid->addChildInCell(title, 2, 1, 0);
|
||||
grid->addChildInCell(subtitle, 2, 1, 0);
|
||||
grid->addChildInCell(authors_separator1, 2, 1, 0);
|
||||
grid->addChildInCell(author1, 1, 1, 0);
|
||||
grid->addChildInCell(author1_desc, 1, 1, 0);
|
||||
grid->addChildInCell(author2, 1, 1, 0);
|
||||
grid->addChildInCell(author2_desc, 1, 1, 0);
|
||||
grid->addChildInCell(author3, 1, 1, 0);
|
||||
grid->addChildInCell(author3_desc, 1, 1, 0);
|
||||
grid->addChildInCell(authors_separator2, 2, 1, 0);
|
||||
grid->addChildInCell(copyright, 2, 1, 0);
|
||||
grid->addChildInCell(website, 2, 1, 0);
|
||||
grid->addChildInCell(bottom_box1, 2, 1, 0);
|
||||
|
||||
jwidget_magnetic(close_button, true);
|
||||
|
||||
|
@ -50,7 +50,7 @@ Console::Console()
|
||||
return;
|
||||
else {
|
||||
Frame* window = new Frame(false, "Errors Console");
|
||||
Widget* grid = jgrid_new(1, false);
|
||||
Grid* grid = new Grid(1, false);
|
||||
Widget* view = jview_new();
|
||||
Widget* textbox = jtextbox_new(NULL, JI_WORDWRAP);
|
||||
Button* button = new Button("&Cancel");
|
||||
@ -65,8 +65,8 @@ Console::Console()
|
||||
|
||||
jwidget_set_min_size(button, 60, 0);
|
||||
|
||||
jgrid_add_child(grid, view, 1, 1, JI_HORIZONTAL | JI_VERTICAL);
|
||||
jgrid_add_child(grid, button, 1, 1, JI_CENTER);
|
||||
grid->addChildInCell(view, 1, 1, JI_HORIZONTAL | JI_VERTICAL);
|
||||
grid->addChildInCell(button, 1, 1, JI_CENTER);
|
||||
jwidget_add_child(window, grid);
|
||||
|
||||
view->setVisible(false);
|
||||
|
@ -8,6 +8,7 @@ add_library(gui-lib
|
||||
entry.cpp
|
||||
event.cpp
|
||||
frame.cpp
|
||||
grid.cpp
|
||||
jaccel.cpp
|
||||
jalert.cpp
|
||||
jclipboard.cpp
|
||||
@ -16,7 +17,6 @@ add_library(gui-lib
|
||||
jdraw.cpp
|
||||
jfont.cpp
|
||||
jfontbmp.cpp
|
||||
jgrid.cpp
|
||||
jhook.cpp
|
||||
jimage.cpp
|
||||
jinete.cpp
|
||||
|
565
src/gui/grid.cpp
Normal file
565
src/gui/grid.cpp
Normal file
@ -0,0 +1,565 @@
|
||||
// ASE gui library
|
||||
// Copyright (C) 2001-2011 David Capello
|
||||
//
|
||||
// This source file is ditributed under a BSD-like license, please
|
||||
// read LICENSE.txt for more information.
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "base/memory.h"
|
||||
#include "gfx/size.h"
|
||||
#include "gui/grid.h"
|
||||
#include "gui/jlist.h"
|
||||
#include "gui/jmessage.h"
|
||||
#include "gui/jrect.h"
|
||||
#include "gui/preferred_size_event.h"
|
||||
#include "gui/theme.h"
|
||||
#include "gui/widget.h"
|
||||
|
||||
using namespace gfx;
|
||||
|
||||
Grid::Cell::Cell()
|
||||
{
|
||||
parent = NULL;
|
||||
child = NULL;
|
||||
hspan = 0;
|
||||
vspan = 0;
|
||||
align = 0;
|
||||
w = 0;
|
||||
h = 0;
|
||||
}
|
||||
|
||||
Grid::Grid(int columns, bool same_width_columns)
|
||||
: Widget(JI_GRID)
|
||||
, m_colstrip(columns)
|
||||
{
|
||||
ASSERT(columns > 0);
|
||||
|
||||
m_same_width_columns = same_width_columns;
|
||||
|
||||
for (size_t col=0; col<m_colstrip.size(); ++col) {
|
||||
m_colstrip[col].size = 0;
|
||||
m_colstrip[col].expand_count = 0;
|
||||
}
|
||||
|
||||
jwidget_init_theme(this);
|
||||
}
|
||||
|
||||
Grid::~Grid()
|
||||
{
|
||||
// Delete all cells.
|
||||
for (size_t row=0; row<m_cells.size(); ++row)
|
||||
for (size_t col=0; col<m_cells[row].size(); ++col)
|
||||
delete m_cells[row][col];
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a child widget in the specified grid.
|
||||
*
|
||||
* @param widget The grid widget.
|
||||
* @param child The child widget.
|
||||
* @param hspan
|
||||
* @param vspan
|
||||
* @param align
|
||||
* It's a combination of the following values:
|
||||
*
|
||||
* - JI_HORIZONTAL: The widget'll get excess horizontal space.
|
||||
* - JI_VERTICAL: The widget'll get excess vertical space.
|
||||
*
|
||||
* - JI_LEFT: Sets horizontal alignment to the beginning of cell.
|
||||
* - JI_CENTER: Sets horizontal alignment to the center of cell.
|
||||
* - JI_RIGHT: Sets horizontal alignment to the end of cell.
|
||||
* - None: Uses the whole horizontal space of the cell.
|
||||
*
|
||||
* - JI_TOP: Sets vertical alignment to the beginning of the cell.
|
||||
* - JI_MIDDLE: Sets vertical alignment to the center of the cell.
|
||||
* - JI_BOTTOM: Sets vertical alignment to the end of the cell.
|
||||
* - None: Uses the whole vertical space of the cell.
|
||||
*/
|
||||
void Grid::addChildInCell(Widget* child, int hspan, int vspan, int align)
|
||||
{
|
||||
ASSERT(hspan > 0);
|
||||
ASSERT(vspan > 0);
|
||||
|
||||
jwidget_add_child(this, child);
|
||||
|
||||
if (!putWidgetInCell(child, hspan, vspan, align)) {
|
||||
expandRows(m_rowstrip.size()+1);
|
||||
putWidgetInCell(child, hspan, vspan, align);
|
||||
}
|
||||
}
|
||||
|
||||
bool Grid::onProcessMessage(JMessage msg)
|
||||
{
|
||||
switch (msg->type) {
|
||||
|
||||
case JM_SETPOS:
|
||||
setGridPosition(&msg->setpos.rect);
|
||||
return true;
|
||||
|
||||
case JM_DRAW:
|
||||
getTheme()->draw_grid(this, &msg->draw.rect);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
return Widget::onProcessMessage(msg);
|
||||
}
|
||||
|
||||
void Grid::onPreferredSize(PreferredSizeEvent& ev)
|
||||
{
|
||||
int w, h;
|
||||
|
||||
w = h = 0;
|
||||
|
||||
calculateSize();
|
||||
|
||||
// Calculate the total
|
||||
sumStripSize(m_colstrip, w);
|
||||
sumStripSize(m_rowstrip, h);
|
||||
|
||||
w += this->border_width.l + this->border_width.r;
|
||||
h += this->border_width.t + this->border_width.b;
|
||||
|
||||
ev.setPreferredSize(Size(w, h));
|
||||
}
|
||||
|
||||
void Grid::sumStripSize(const std::vector<Strip>& strip, int& size)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
size = 0;
|
||||
for (i=j=0; i<(int)strip.size(); ++i) {
|
||||
if (strip[i].size > 0) {
|
||||
size += strip[i].size;
|
||||
if (++j > 1)
|
||||
size += this->child_spacing;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Grid::setGridPosition(JRect rect)
|
||||
{
|
||||
JRect cpos = jrect_new(0, 0, 0, 0);
|
||||
int pos_x, pos_y;
|
||||
Size reqSize;
|
||||
int x, y, w, h;
|
||||
int col, row;
|
||||
|
||||
jrect_copy(this->rc, rect);
|
||||
|
||||
calculateSize();
|
||||
distributeSize(rect);
|
||||
|
||||
pos_y = rect->y1 + this->border_width.t;
|
||||
for (row=0; row<(int)m_rowstrip.size(); ++row) {
|
||||
pos_x = rect->x1 + this->border_width.l;
|
||||
|
||||
for (col=0; col<(int)m_colstrip.size(); ++col) {
|
||||
Cell* cell = m_cells[row][col];
|
||||
|
||||
if (cell->child != NULL &&
|
||||
cell->parent == NULL &&
|
||||
!(cell->child->flags & JI_HIDDEN)) {
|
||||
x = pos_x;
|
||||
y = pos_y;
|
||||
|
||||
calculateCellSize(col, cell->hspan, m_colstrip, w);
|
||||
calculateCellSize(row, cell->vspan, m_rowstrip, h);
|
||||
|
||||
reqSize = cell->child->getPreferredSize();
|
||||
|
||||
if (cell->align & JI_LEFT) {
|
||||
w = reqSize.w;
|
||||
}
|
||||
else if (cell->align & JI_CENTER) {
|
||||
x += w/2 - reqSize.w/2;
|
||||
w = reqSize.w;
|
||||
}
|
||||
else if (cell->align & JI_RIGHT) {
|
||||
x += w - reqSize.w;
|
||||
w = reqSize.w;
|
||||
}
|
||||
|
||||
if (cell->align & JI_TOP) {
|
||||
h = reqSize.h;
|
||||
}
|
||||
else if (cell->align & JI_MIDDLE) {
|
||||
y += h/2 - reqSize.h/2;
|
||||
h = reqSize.h;
|
||||
}
|
||||
else if (cell->align & JI_BOTTOM) {
|
||||
y += h - reqSize.h;
|
||||
h = reqSize.h;
|
||||
}
|
||||
|
||||
jrect_replace(cpos, x, y, x+w, y+h);
|
||||
jwidget_set_rect(cell->child, cpos);
|
||||
}
|
||||
|
||||
if (m_colstrip[col].size > 0)
|
||||
pos_x += m_colstrip[col].size + this->child_spacing;
|
||||
}
|
||||
|
||||
if (m_rowstrip[row].size > 0)
|
||||
pos_y += m_rowstrip[row].size + this->child_spacing;
|
||||
}
|
||||
|
||||
jrect_free(cpos);
|
||||
}
|
||||
|
||||
void Grid::calculateCellSize(int start, int span, const std::vector<Strip>& strip, int& size)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
size = 0;
|
||||
|
||||
for (i=start, j=0; i<start+span; ++i) {
|
||||
if (strip[i].size > 0) {
|
||||
size += strip[i].size;
|
||||
if (++j > 1)
|
||||
size += this->child_spacing;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Calculates the size of each strip (rows and columns) in the grid.
|
||||
void Grid::calculateSize()
|
||||
{
|
||||
if (m_rowstrip.size() == 0)
|
||||
return;
|
||||
|
||||
calculateStripSize(m_colstrip, m_rowstrip, JI_HORIZONTAL);
|
||||
calculateStripSize(m_rowstrip, m_colstrip, JI_VERTICAL);
|
||||
|
||||
expandStrip(m_colstrip, m_rowstrip, &Grid::incColSize);
|
||||
expandStrip(m_rowstrip, m_colstrip, &Grid::incRowSize);
|
||||
|
||||
// Same width in all columns
|
||||
if (m_same_width_columns) {
|
||||
int max_w = 0;
|
||||
for (int col=0; col<(int)m_colstrip.size(); ++col)
|
||||
max_w = MAX(max_w, m_colstrip[col].size);
|
||||
|
||||
for (int col=0; col<(int)m_colstrip.size(); ++col)
|
||||
m_colstrip[col].size = max_w;
|
||||
}
|
||||
}
|
||||
|
||||
void Grid::calculateStripSize(std::vector<Strip>& colstrip,
|
||||
std::vector<Strip>& rowstrip, int align)
|
||||
{
|
||||
Cell* cell;
|
||||
|
||||
// For each column
|
||||
for (int col=0; col<(int)colstrip.size(); ++col) {
|
||||
// A counter of widgets that want more space in this column
|
||||
int expand_count = 0;
|
||||
|
||||
// For each row
|
||||
for (int row=0; row<(int)rowstrip.size(); ++row) {
|
||||
// For each cell
|
||||
if (&colstrip == &m_colstrip)
|
||||
cell = m_cells[row][col];
|
||||
else
|
||||
cell = m_cells[col][row]; // Transposed
|
||||
|
||||
if (cell->child != NULL) {
|
||||
if (cell->parent == NULL) {
|
||||
// If the widget isn't hidden then we can request its size
|
||||
if (!(cell->child->flags & JI_HIDDEN)) {
|
||||
Size reqSize = cell->child->getPreferredSize();
|
||||
cell->w = reqSize.w - (cell->hspan-1) * this->child_spacing;
|
||||
cell->h = reqSize.h - (cell->vspan-1) * this->child_spacing;
|
||||
|
||||
if ((cell->align & align) == align)
|
||||
++expand_count;
|
||||
}
|
||||
else
|
||||
cell->w = cell->h = 0;
|
||||
}
|
||||
else {
|
||||
if (!(cell->child->flags & JI_HIDDEN)) {
|
||||
if ((cell->parent->align & align) == align)
|
||||
++expand_count;
|
||||
}
|
||||
}
|
||||
|
||||
if (&colstrip == &m_colstrip)
|
||||
row += cell->vspan-1;
|
||||
else
|
||||
row += cell->hspan-1; // Transposed
|
||||
}
|
||||
}
|
||||
|
||||
colstrip[col].size = 0;
|
||||
colstrip[col].expand_count = expand_count;
|
||||
}
|
||||
}
|
||||
|
||||
void Grid::expandStrip(std::vector<Strip>& colstrip,
|
||||
std::vector<Strip>& rowstrip,
|
||||
void (Grid::*incCol)(int, int))
|
||||
{
|
||||
bool more_span;
|
||||
int i, current_span = 1;
|
||||
|
||||
do {
|
||||
more_span = false;
|
||||
for (int col=0; col<(int)colstrip.size(); ++col) {
|
||||
for (int row=0; row<(int)rowstrip.size(); ++row) {
|
||||
int cell_size;
|
||||
int cell_span;
|
||||
Cell* cell;
|
||||
|
||||
// For each cell
|
||||
if (&colstrip == &m_colstrip) {
|
||||
cell = m_cells[row][col];
|
||||
cell_size = cell->w;
|
||||
cell_span = cell->hspan;
|
||||
}
|
||||
else {
|
||||
cell = m_cells[col][row]; // Transposed
|
||||
cell_size = cell->h;
|
||||
cell_span = cell->vspan;
|
||||
}
|
||||
|
||||
if (cell->child != NULL &&
|
||||
cell->parent == NULL &&
|
||||
cell_size > 0) {
|
||||
ASSERT(cell_span > 0);
|
||||
|
||||
if (cell_span == current_span) {
|
||||
// Calculate the maximum (expand_count) in cell's columns.
|
||||
int max_expand_count = 0;
|
||||
for (i=col; i<col+cell_span; ++i)
|
||||
max_expand_count = MAX(max_expand_count,
|
||||
colstrip[i].expand_count);
|
||||
|
||||
int expand = 0; // How many columns have the maximum value of "expand_count"
|
||||
int last_expand = 0; // This variable is used to add the remainder space to the last column
|
||||
for (i=col; i<col+cell_span; ++i) {
|
||||
if (colstrip[i].expand_count == max_expand_count) {
|
||||
++expand;
|
||||
last_expand = i;
|
||||
}
|
||||
}
|
||||
|
||||
// Divide the available size of the cell in the number of columns which are expandible
|
||||
int size = cell_size / expand;
|
||||
for (i=col; i<col+cell_span; ++i) {
|
||||
if (colstrip[i].expand_count == max_expand_count) {
|
||||
// For the last column, use all the available space in the column
|
||||
if (last_expand == i) {
|
||||
if (&colstrip == &m_colstrip)
|
||||
size = cell->w;
|
||||
else
|
||||
size = cell->h; // Transposed
|
||||
}
|
||||
|
||||
(this->*incCol)(i, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (cell_span > current_span) {
|
||||
more_span = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
++current_span;
|
||||
} while (more_span);
|
||||
}
|
||||
|
||||
void Grid::distributeSize(JRect rect)
|
||||
{
|
||||
if (m_rowstrip.size() == 0)
|
||||
return;
|
||||
|
||||
distributeStripSize(m_colstrip, jrect_w(rect), this->border_width.l + this->border_width.r, m_same_width_columns);
|
||||
distributeStripSize(m_rowstrip, jrect_h(rect), this->border_width.t + this->border_width.b, false);
|
||||
}
|
||||
|
||||
void Grid::distributeStripSize(std::vector<Strip>& colstrip,
|
||||
int rect_size, int border_size, bool same_width)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
int max_expand_count = 0;
|
||||
for (i=0; i<(int)colstrip.size(); ++i)
|
||||
max_expand_count = MAX(max_expand_count,
|
||||
colstrip[i].expand_count);
|
||||
|
||||
int total_req = 0;
|
||||
int wantmore_count = 0;
|
||||
for (i=j=0; i<(int)colstrip.size(); ++i) {
|
||||
if (colstrip[i].size > 0) {
|
||||
total_req += colstrip[i].size;
|
||||
if (++j > 1)
|
||||
total_req += this->child_spacing;
|
||||
}
|
||||
|
||||
if (colstrip[i].expand_count == max_expand_count || same_width) {
|
||||
++wantmore_count;
|
||||
}
|
||||
}
|
||||
total_req += border_size;
|
||||
|
||||
if (wantmore_count > 0) {
|
||||
int extra_total = rect_size - total_req;
|
||||
if (extra_total > 0) {
|
||||
// If a expandable column-strip was empty (size=0) then we have
|
||||
// to reduce the extra_total size because a new child-spacing is
|
||||
// added by this column
|
||||
for (i=0; i<(int)colstrip.size(); ++i) {
|
||||
if ((colstrip[i].size == 0) &&
|
||||
(colstrip[i].expand_count == max_expand_count || same_width)) {
|
||||
extra_total -= this->child_spacing;
|
||||
}
|
||||
}
|
||||
|
||||
int extra_foreach = extra_total / wantmore_count;
|
||||
|
||||
for (i=0; i<(int)colstrip.size(); ++i) {
|
||||
if (colstrip[i].expand_count == max_expand_count || same_width) {
|
||||
ASSERT(wantmore_count > 0);
|
||||
|
||||
colstrip[i].size += extra_foreach;
|
||||
extra_total -= extra_foreach;
|
||||
|
||||
if (--wantmore_count == 0) {
|
||||
colstrip[i].size += extra_total;
|
||||
extra_total = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(wantmore_count == 0);
|
||||
ASSERT(extra_total == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Grid::putWidgetInCell(Widget* child, int hspan, int vspan, int align)
|
||||
{
|
||||
int col, row, colbeg, colend, rowend;
|
||||
Cell *cell, *parentcell;
|
||||
|
||||
for (row=0; row<(int)m_rowstrip.size(); ++row) {
|
||||
for (col=0; col<(int)m_colstrip.size(); ++col) {
|
||||
cell = m_cells[row][col];
|
||||
|
||||
if (cell->child == NULL) {
|
||||
cell->child = child;
|
||||
cell->hspan = hspan;
|
||||
cell->vspan = vspan;
|
||||
cell->align = align;
|
||||
|
||||
parentcell = cell;
|
||||
colbeg = col;
|
||||
colend = MIN(col+hspan, (int)m_colstrip.size());
|
||||
rowend = row+vspan;
|
||||
|
||||
expandRows(row+vspan);
|
||||
|
||||
for (++col; col<colend; ++col) {
|
||||
cell = m_cells[row][col];
|
||||
|
||||
// If these asserts fails, it's really possible that you
|
||||
// specified bad values for hspan or vspan (they are
|
||||
// overlapping with other cells).
|
||||
ASSERT(cell->parent == NULL);
|
||||
ASSERT(cell->child == NULL);
|
||||
|
||||
cell->parent = parentcell;
|
||||
cell->child = child;
|
||||
cell->hspan = colend - col;
|
||||
cell->vspan = rowend - row;
|
||||
}
|
||||
|
||||
for (++row; row<rowend; ++row) {
|
||||
for (col=colbeg; col<colend; ++col) {
|
||||
cell = m_cells[row][col];
|
||||
|
||||
ASSERT(cell->parent == NULL);
|
||||
ASSERT(cell->child == NULL);
|
||||
|
||||
cell->parent = parentcell;
|
||||
cell->child = child;
|
||||
cell->hspan = colend - col;
|
||||
cell->vspan = rowend - row;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Expands the grid's rows to reach the specified quantity of rows in
|
||||
// the parameter.
|
||||
void Grid::expandRows(int rows)
|
||||
{
|
||||
if ((int)m_rowstrip.size() < rows) {
|
||||
int old_size = (int)m_rowstrip.size();
|
||||
|
||||
m_cells.resize(rows);
|
||||
m_rowstrip.resize(rows);
|
||||
|
||||
for (int row=old_size; row<rows; ++row) {
|
||||
m_cells[row].resize(m_colstrip.size());
|
||||
m_rowstrip[row].size = 0;
|
||||
m_rowstrip[row].expand_count = 0;
|
||||
|
||||
for (int col=0; col<(int)m_cells[row].size(); ++col) {
|
||||
m_cells[row][col] = new Cell;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Grid::incColSize(int col, int size)
|
||||
{
|
||||
m_colstrip[col].size += size;
|
||||
|
||||
for (int row=0; row<(int)m_rowstrip.size(); ) {
|
||||
Cell* cell = m_cells[row][col];
|
||||
|
||||
if (cell->child != NULL) {
|
||||
if (cell->parent != NULL)
|
||||
cell->parent->w -= size;
|
||||
else
|
||||
cell->w -= size;
|
||||
|
||||
row += cell->vspan;
|
||||
}
|
||||
else
|
||||
++row;
|
||||
}
|
||||
}
|
||||
|
||||
void Grid::incRowSize(int row, int size)
|
||||
{
|
||||
m_rowstrip[row].size += size;
|
||||
|
||||
for (int col=0; col<(int)m_colstrip.size(); ) {
|
||||
Cell* cell = m_cells[row][col];
|
||||
|
||||
if (cell->child != NULL) {
|
||||
if (cell->parent != NULL)
|
||||
cell->parent->h -= size;
|
||||
else
|
||||
cell->h -= size;
|
||||
|
||||
col += cell->hspan;
|
||||
}
|
||||
else
|
||||
++col;
|
||||
}
|
||||
}
|
66
src/gui/grid.h
Normal file
66
src/gui/grid.h
Normal file
@ -0,0 +1,66 @@
|
||||
// ASE gui library
|
||||
// Copyright (C) 2001-2011 David Capello
|
||||
//
|
||||
// This source file is ditributed under a BSD-like license, please
|
||||
// read LICENSE.txt for more information.
|
||||
|
||||
#ifndef GUI_GRID_H_INCLUDED
|
||||
#define GUI_GRID_H_INCLUDED
|
||||
|
||||
#include "gui/widget.h"
|
||||
#include <vector>
|
||||
|
||||
class Grid : public Widget
|
||||
{
|
||||
public:
|
||||
Grid(int columns, bool same_width_columns);
|
||||
~Grid();
|
||||
|
||||
void addChildInCell(Widget* child, int hspan, int vspan, int align);
|
||||
|
||||
protected:
|
||||
// Events
|
||||
bool onProcessMessage(JMessage msg);
|
||||
void onPreferredSize(PreferredSizeEvent& ev);
|
||||
|
||||
private:
|
||||
struct Cell {
|
||||
Cell* parent;
|
||||
Widget* child;
|
||||
int hspan;
|
||||
int vspan;
|
||||
int align;
|
||||
int w, h;
|
||||
|
||||
Cell();
|
||||
};
|
||||
|
||||
struct Strip {
|
||||
int size;
|
||||
int expand_count;
|
||||
};
|
||||
|
||||
void sumStripSize(const std::vector<Strip>& strip, int& size);
|
||||
void setGridPosition(JRect rect);
|
||||
void calculateCellSize(int start, int span, const std::vector<Strip>& strip, int& size);
|
||||
void calculateSize();
|
||||
void calculateStripSize(std::vector<Strip>& colstrip,
|
||||
std::vector<Strip>& rowstrip, int align);
|
||||
void expandStrip(std::vector<Strip>& colstrip,
|
||||
std::vector<Strip>& rowstrip,
|
||||
void (Grid::*incCol)(int, int));
|
||||
void distributeSize(JRect rect);
|
||||
void distributeStripSize(std::vector<Strip>& colstrip,
|
||||
int rect_size, int border_size, bool same_width);
|
||||
bool putWidgetInCell(Widget* child, int hspan, int vspan, int align);
|
||||
void expandRows(int rows);
|
||||
void incColSize(int col, int size);
|
||||
void incRowSize(int row, int size);
|
||||
|
||||
bool m_same_width_columns;
|
||||
std::vector<Strip> m_colstrip;
|
||||
std::vector<Strip> m_rowstrip;
|
||||
std::vector<std::vector<Cell*> > m_cells;
|
||||
};
|
||||
|
||||
#endif
|
@ -22,20 +22,18 @@
|
||||
|
||||
using namespace gfx;
|
||||
|
||||
/**
|
||||
* Tests two widgets in a row, each one of 10x10 pixels.
|
||||
*/
|
||||
// Tests two widgets in a row, each one of 10x10 pixels.
|
||||
TEST(JGrid, Simple2x1Grid)
|
||||
{
|
||||
JWidget grid = jgrid_new(2, false);
|
||||
JWidget w1 = new Widget(JI_WIDGET);
|
||||
JWidget w2 = new Widget(JI_WIDGET);
|
||||
Grid* grid = new Grid(2, false);
|
||||
Widget* w1 = new Widget(JI_WIDGET);
|
||||
Widget* w2 = new Widget(JI_WIDGET);
|
||||
|
||||
jwidget_set_min_size(w1, 10, 10);
|
||||
jwidget_set_min_size(w2, 10, 10);
|
||||
|
||||
jgrid_add_child(grid, w1, 1, 1, 0);
|
||||
jgrid_add_child(grid, w2, 1, 1, 0);
|
||||
grid->addChildInCell(w1, 1, 1, 0);
|
||||
grid->addChildInCell(w2, 1, 1, 0);
|
||||
|
||||
// Test request-size
|
||||
Size reqSize = grid->getPreferredSize();
|
||||
@ -66,7 +64,7 @@ TEST(JGrid, Simple2x1Grid)
|
||||
|
||||
TEST(JGrid, Expand2ndWidget)
|
||||
{
|
||||
Widget* grid = jgrid_new(2, false);
|
||||
Grid* grid = new Grid(2, false);
|
||||
Widget* w1 = new Widget(JI_WIDGET);
|
||||
Widget* w2 = new Widget(JI_WIDGET);
|
||||
JRect rect;
|
||||
@ -74,8 +72,8 @@ TEST(JGrid, Expand2ndWidget)
|
||||
jwidget_set_min_size(w1, 20, 20);
|
||||
jwidget_set_min_size(w2, 10, 10);
|
||||
|
||||
jgrid_add_child(grid, w1, 1, 1, 0);
|
||||
jgrid_add_child(grid, w2, 1, 1, JI_HORIZONTAL | JI_TOP);
|
||||
grid->addChildInCell(w1, 1, 1, 0);
|
||||
grid->addChildInCell(w2, 1, 1, JI_HORIZONTAL | JI_TOP);
|
||||
|
||||
// Test request size
|
||||
Size reqSize = grid->getPreferredSize();
|
||||
@ -102,16 +100,16 @@ TEST(JGrid, Expand2ndWidget)
|
||||
|
||||
TEST(JGrid, SameWidth2x1Grid)
|
||||
{
|
||||
JWidget grid = jgrid_new(2, true);
|
||||
JWidget w1 = new Widget(JI_WIDGET);
|
||||
JWidget w2 = new Widget(JI_WIDGET);
|
||||
Grid* grid = new Grid(2, true);
|
||||
Widget* w1 = new Widget(JI_WIDGET);
|
||||
Widget* w2 = new Widget(JI_WIDGET);
|
||||
JRect rect;
|
||||
|
||||
jwidget_set_min_size(w1, 20, 20);
|
||||
jwidget_set_min_size(w2, 10, 10);
|
||||
|
||||
jgrid_add_child(grid, w1, 1, 1, 0);
|
||||
jgrid_add_child(grid, w2, 1, 1, 0);
|
||||
grid->addChildInCell(w1, 1, 1, 0);
|
||||
grid->addChildInCell(w2, 1, 1, 0);
|
||||
|
||||
// Test request size
|
||||
Size reqSize = grid->getPreferredSize();
|
||||
@ -131,47 +129,43 @@ TEST(JGrid, SameWidth2x1Grid)
|
||||
delete grid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the next layout (a grid of 3x3 cells):
|
||||
*
|
||||
* <pre>
|
||||
* 2 (separator)
|
||||
* _|_
|
||||
* / \
|
||||
* 10 2 0 2 10
|
||||
* +---+-------+
|
||||
* | 1 | 2 | 10
|
||||
* +---+---+---+ --- 2 (separator)
|
||||
* | 3 | 4 | 4
|
||||
* | | | --- 2 (separator)
|
||||
* | | | 4
|
||||
* +-------+---+
|
||||
*
|
||||
* 1.align = 0
|
||||
* 2.align = JI_HORIZONTAL
|
||||
* 3.align = JI_HORIZONTAL | JI_VERTICAL
|
||||
* 4.align = JI_VERTICAL
|
||||
* </pre>
|
||||
*
|
||||
* When expand the grid:
|
||||
*
|
||||
* <pre>
|
||||
* +---+----------------------------+
|
||||
* | 1 | 2 |
|
||||
* +---+------------------------+---+
|
||||
* | 3 | 4 |
|
||||
* | | |
|
||||
* | | |
|
||||
* | | |
|
||||
* | | |
|
||||
* | | |
|
||||
* | | |
|
||||
* +----------------------------+---+
|
||||
* </pre>
|
||||
*/
|
||||
// Tests the next layout (a grid of 3x3 cells):
|
||||
//
|
||||
// 2 (separator)
|
||||
// _|_
|
||||
// / \
|
||||
// 10 2 0 2 10
|
||||
// +---+-------+
|
||||
// | 1 | 2 | 10
|
||||
// +---+---+---+ --- 2 (separator)
|
||||
// | 3 | 4 | 4
|
||||
// | | | --- 2 (separator)
|
||||
// | | | 4
|
||||
// +-------+---+
|
||||
//
|
||||
// 1.align = 0
|
||||
// 2.align = JI_HORIZONTAL
|
||||
// 3.align = JI_HORIZONTAL | JI_VERTICAL
|
||||
// 4.align = JI_VERTICAL
|
||||
//
|
||||
//
|
||||
// When we expand the grid we get the following layout:
|
||||
//
|
||||
// +---+----------------------------+
|
||||
// | 1 | 2 |
|
||||
// +---+------------------------+---+
|
||||
// | 3 | 4 |
|
||||
// | | |
|
||||
// | | |
|
||||
// | | |
|
||||
// | | |
|
||||
// | | |
|
||||
// | | |
|
||||
// +----------------------------+---+
|
||||
//
|
||||
TEST(JGrid, Intrincate3x3Grid)
|
||||
{
|
||||
Widget* grid = jgrid_new(3, false);
|
||||
Grid* grid = new Grid(3, false);
|
||||
Widget* w1 = new Widget(JI_WIDGET);
|
||||
Widget* w2 = new Widget(JI_WIDGET);
|
||||
Widget* w3 = new Widget(JI_WIDGET);
|
||||
@ -183,10 +177,10 @@ TEST(JGrid, Intrincate3x3Grid)
|
||||
jwidget_set_min_size(w3, 10, 10);
|
||||
jwidget_set_min_size(w4, 10, 10);
|
||||
|
||||
jgrid_add_child(grid, w1, 1, 1, 0);
|
||||
jgrid_add_child(grid, w2, 2, 1, JI_HORIZONTAL);
|
||||
jgrid_add_child(grid, w3, 2, 2, JI_HORIZONTAL | JI_VERTICAL);
|
||||
jgrid_add_child(grid, w4, 1, 2, JI_VERTICAL);
|
||||
grid->addChildInCell(w1, 1, 1, 0);
|
||||
grid->addChildInCell(w2, 2, 1, JI_HORIZONTAL);
|
||||
grid->addChildInCell(w3, 2, 2, JI_HORIZONTAL | JI_VERTICAL);
|
||||
grid->addChildInCell(w4, 1, 2, JI_VERTICAL);
|
||||
|
||||
// Test request size
|
||||
grid->child_spacing = 2;
|
@ -121,7 +121,7 @@ int jalert(const char *format, ...)
|
||||
static Frame* create_alert(char *buf, JList *labels, JList *buttons)
|
||||
{
|
||||
Box* box1, *box2, *box3, *box4, *box5;
|
||||
Widget* grid;
|
||||
Grid* grid;
|
||||
Frame* window = NULL;
|
||||
bool title = true;
|
||||
bool label = false;
|
||||
@ -196,7 +196,7 @@ static Frame* create_alert(char *buf, JList *labels, JList *buttons)
|
||||
if (window) {
|
||||
box1 = new Box(JI_VERTICAL);
|
||||
box2 = new Box(JI_VERTICAL);
|
||||
grid = jgrid_new(1, false);
|
||||
grid = new Grid(1, false);
|
||||
box3 = new Box(JI_HORIZONTAL | JI_HOMOGENEOUS);
|
||||
|
||||
/* to identify by the user */
|
||||
@ -221,7 +221,7 @@ static Frame* create_alert(char *buf, JList *labels, JList *buttons)
|
||||
jwidget_add_child(box1, box5); /* filler */
|
||||
jwidget_add_child(box1, grid); /* buttons */
|
||||
|
||||
jgrid_add_child(grid, box3, 1, 1, JI_CENTER | JI_BOTTOM);
|
||||
grid->addChildInCell(box3, 1, 1, JI_CENTER | JI_BOTTOM);
|
||||
|
||||
JI_LIST_FOR_EACH(*labels, link)
|
||||
jwidget_add_child(box2, (JWidget)link->data);
|
||||
|
@ -1,602 +0,0 @@
|
||||
// ASE gui library
|
||||
// Copyright (C) 2001-2011 David Capello
|
||||
//
|
||||
// This source file is ditributed under a BSD-like license, please
|
||||
// read LICENSE.txt for more information.
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "base/memory.h"
|
||||
#include "gfx/size.h"
|
||||
#include "gui/jlist.h"
|
||||
#include "gui/jmessage.h"
|
||||
#include "gui/jrect.h"
|
||||
#include "gui/theme.h"
|
||||
#include "gui/widget.h"
|
||||
|
||||
using namespace gfx;
|
||||
|
||||
struct Cell
|
||||
{
|
||||
struct Cell *parent;
|
||||
JWidget child;
|
||||
int hspan;
|
||||
int vspan;
|
||||
int align;
|
||||
int w, h;
|
||||
};
|
||||
|
||||
struct Strip
|
||||
{
|
||||
int size;
|
||||
int expand_count;
|
||||
};
|
||||
|
||||
struct Grid
|
||||
{
|
||||
bool same_width_columns;
|
||||
int cols;
|
||||
int rows;
|
||||
Strip *colstrip;
|
||||
Strip *rowstrip;
|
||||
Cell **cells;
|
||||
};
|
||||
|
||||
static bool grid_msg_proc(JWidget widget, JMessage msg);
|
||||
static void grid_request_size(JWidget widget, int *w, int *h);
|
||||
static void grid_set_position(JWidget widget, JRect rect);
|
||||
static void grid_calculate_size(JWidget widget);
|
||||
static void grid_distribute_size(JWidget widget, JRect rect);
|
||||
static bool grid_put_widget_in_cell(JWidget widget, JWidget child, int hspan, int vspan, int align);
|
||||
static void grid_expand_rows(JWidget widget, int rows);
|
||||
static void grid_inc_col_size(Grid *grid, int col, int size);
|
||||
static void grid_inc_row_size(Grid *grid, int row, int size);
|
||||
|
||||
JWidget jgrid_new(int columns, bool same_width_columns)
|
||||
{
|
||||
Widget* widget = new Widget(JI_GRID);
|
||||
Grid *grid = new Grid;
|
||||
int col;
|
||||
|
||||
ASSERT(columns > 0);
|
||||
|
||||
grid->same_width_columns = same_width_columns;
|
||||
grid->cols = columns;
|
||||
grid->rows = 0;
|
||||
grid->colstrip = (Strip*)base_malloc(sizeof(Strip) * grid->cols);
|
||||
grid->rowstrip = NULL;
|
||||
grid->cells = NULL;
|
||||
|
||||
for (col=0; col<grid->cols; ++col) {
|
||||
grid->colstrip[col].size = 0;
|
||||
grid->colstrip[col].expand_count = 0;
|
||||
}
|
||||
|
||||
jwidget_add_hook(widget, JI_GRID, grid_msg_proc, grid);
|
||||
jwidget_init_theme(widget);
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a child widget in the specified grid.
|
||||
*
|
||||
* @param widget The grid widget.
|
||||
* @param child The child widget.
|
||||
* @param hspan
|
||||
* @param vspan
|
||||
* @param align
|
||||
* It's a combination of the following values:
|
||||
*
|
||||
* - JI_HORIZONTAL: The widget'll get excess horizontal space.
|
||||
* - JI_VERTICAL: The widget'll get excess vertical space.
|
||||
*
|
||||
* - JI_LEFT: Sets horizontal alignment to the beginning of cell.
|
||||
* - JI_CENTER: Sets horizontal alignment to the center of cell.
|
||||
* - JI_RIGHT: Sets horizontal alignment to the end of cell.
|
||||
* - None: Uses the whole horizontal space of the cell.
|
||||
*
|
||||
* - JI_TOP: Sets vertical alignment to the beginning of the cell.
|
||||
* - JI_MIDDLE: Sets vertical alignment to the center of the cell.
|
||||
* - JI_BOTTOM: Sets vertical alignment to the end of the cell.
|
||||
* - None: Uses the whole vertical space of the cell.
|
||||
*/
|
||||
void jgrid_add_child(JWidget widget, JWidget child,
|
||||
int hspan, int vspan, int align)
|
||||
{
|
||||
Grid* grid = reinterpret_cast<Grid*>(jwidget_get_data(widget, JI_GRID));
|
||||
|
||||
ASSERT(hspan > 0);
|
||||
ASSERT(vspan > 0);
|
||||
|
||||
jwidget_add_child(widget, child);
|
||||
|
||||
if (!grid_put_widget_in_cell(widget, child, hspan, vspan, align)) {
|
||||
grid_expand_rows(widget, grid->rows+1);
|
||||
grid_put_widget_in_cell(widget, child, hspan, vspan, align);
|
||||
}
|
||||
}
|
||||
|
||||
static bool grid_msg_proc(JWidget widget, JMessage msg)
|
||||
{
|
||||
Grid* grid = reinterpret_cast<Grid*>(jwidget_get_data(widget, JI_GRID));
|
||||
|
||||
switch (msg->type) {
|
||||
|
||||
case JM_DESTROY:
|
||||
if (grid->cells != NULL) {
|
||||
int row;
|
||||
for (row=0; row<grid->rows; ++row)
|
||||
base_free(grid->cells[row]);
|
||||
base_free(grid->cells);
|
||||
}
|
||||
|
||||
if (grid->colstrip != NULL)
|
||||
base_free(grid->colstrip);
|
||||
|
||||
if (grid->rowstrip != NULL)
|
||||
base_free(grid->rowstrip);
|
||||
|
||||
delete grid;
|
||||
break;
|
||||
|
||||
case JM_REQSIZE:
|
||||
grid_request_size(widget, &msg->reqsize.w, &msg->reqsize.h);
|
||||
return true;
|
||||
|
||||
case JM_SETPOS:
|
||||
grid_set_position(widget, &msg->setpos.rect);
|
||||
return true;
|
||||
|
||||
case JM_DRAW:
|
||||
widget->getTheme()->draw_grid(widget, &msg->draw.rect);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void grid_request_size(JWidget widget, int *w, int *h)
|
||||
{
|
||||
Grid* grid = reinterpret_cast<Grid*>(jwidget_get_data(widget, JI_GRID));
|
||||
int i, j;
|
||||
|
||||
grid_calculate_size(widget);
|
||||
|
||||
/* calculate the total */
|
||||
|
||||
#define SUMSTRIPS(p_cols, p_colstrip, p_w) \
|
||||
*p_w = 0; \
|
||||
for (i=j=0; i<grid->p_cols; ++i) { \
|
||||
if (grid->p_colstrip[i].size > 0) { \
|
||||
*p_w += grid->p_colstrip[i].size; \
|
||||
if (++j > 1) \
|
||||
*p_w += widget->child_spacing; \
|
||||
} \
|
||||
}
|
||||
|
||||
SUMSTRIPS(cols, colstrip, w);
|
||||
SUMSTRIPS(rows, rowstrip, h);
|
||||
|
||||
*w += widget->border_width.l + widget->border_width.r;
|
||||
*h += widget->border_width.t + widget->border_width.b;
|
||||
}
|
||||
|
||||
static void grid_set_position(JWidget widget, JRect rect)
|
||||
{
|
||||
Grid* grid = reinterpret_cast<Grid*>(jwidget_get_data(widget, JI_GRID));
|
||||
JRect cpos = jrect_new(0, 0, 0, 0);
|
||||
int pos_x, pos_y;
|
||||
Size reqSize;
|
||||
int x, y, w, h;
|
||||
int col, row;
|
||||
int i, j;
|
||||
Cell *cell;
|
||||
|
||||
jrect_copy(widget->rc, rect);
|
||||
|
||||
grid_calculate_size(widget);
|
||||
grid_distribute_size(widget, rect);
|
||||
|
||||
pos_y = rect->y1 + widget->border_width.t;
|
||||
for (row=0; row<grid->rows; ++row) {
|
||||
pos_x = rect->x1 + widget->border_width.l;
|
||||
|
||||
cell = grid->cells[row];
|
||||
for (col=0; col<grid->cols; ++col, ++cell) {
|
||||
if (cell->child != NULL &&
|
||||
cell->parent == NULL &&
|
||||
!(cell->child->flags & JI_HIDDEN)) {
|
||||
x = pos_x;
|
||||
y = pos_y;
|
||||
w = 0;
|
||||
h = 0;
|
||||
|
||||
#define CALCULATE_CELL_SIZE(p_col, p_span, p_colstrip, p_w) \
|
||||
for (i=p_col,j=0; i<p_col+cell->p_span; ++i) { \
|
||||
if (grid->p_colstrip[i].size > 0) { \
|
||||
p_w += grid->p_colstrip[i].size; \
|
||||
if (++j > 1) \
|
||||
p_w += widget->child_spacing; \
|
||||
} \
|
||||
}
|
||||
|
||||
CALCULATE_CELL_SIZE(col, hspan, colstrip, w);
|
||||
CALCULATE_CELL_SIZE(row, vspan, rowstrip, h);
|
||||
|
||||
reqSize = cell->child->getPreferredSize();
|
||||
|
||||
if (cell->align & JI_LEFT) {
|
||||
w = reqSize.w;
|
||||
}
|
||||
else if (cell->align & JI_CENTER) {
|
||||
x += w/2 - reqSize.w/2;
|
||||
w = reqSize.w;
|
||||
}
|
||||
else if (cell->align & JI_RIGHT) {
|
||||
x += w - reqSize.w;
|
||||
w = reqSize.w;
|
||||
}
|
||||
|
||||
if (cell->align & JI_TOP) {
|
||||
h = reqSize.h;
|
||||
}
|
||||
else if (cell->align & JI_MIDDLE) {
|
||||
y += h/2 - reqSize.h/2;
|
||||
h = reqSize.h;
|
||||
}
|
||||
else if (cell->align & JI_BOTTOM) {
|
||||
y += h - reqSize.h;
|
||||
h = reqSize.h;
|
||||
}
|
||||
|
||||
jrect_replace(cpos, x, y, x+w, y+h);
|
||||
jwidget_set_rect(cell->child, cpos);
|
||||
}
|
||||
|
||||
if (grid->colstrip[col].size > 0)
|
||||
pos_x += grid->colstrip[col].size + widget->child_spacing;
|
||||
}
|
||||
|
||||
if (grid->rowstrip[row].size > 0)
|
||||
pos_y += grid->rowstrip[row].size + widget->child_spacing;
|
||||
}
|
||||
|
||||
jrect_free(cpos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the size of each strip (rows and columns) in the grid.
|
||||
*/
|
||||
static void grid_calculate_size(JWidget widget)
|
||||
{
|
||||
Grid* grid = reinterpret_cast<Grid*>(jwidget_get_data(widget, JI_GRID));
|
||||
int row, col, size;
|
||||
Size reqSize;
|
||||
int i, expand;
|
||||
int expand_count;
|
||||
int last_expand;
|
||||
int current_span;
|
||||
bool more_span;
|
||||
Cell *cell;
|
||||
|
||||
if (grid->rows == 0)
|
||||
return;
|
||||
|
||||
#define CALCULATE_STRIPS(p_col, p_cols, p_row, p_rows, p_span, \
|
||||
p_req, p_colstrip, p_align) \
|
||||
/* for each column */ \
|
||||
for (p_col=0; p_col<grid->p_cols; ++p_col) { \
|
||||
/* a counter of widgets that want more space in this column */ \
|
||||
expand_count = 0; \
|
||||
/* for each row */ \
|
||||
for (p_row=0; p_row<grid->p_rows; ++p_row) { \
|
||||
/* for each cell */ \
|
||||
cell = grid->cells[row]+col; \
|
||||
reqSize.w = reqSize.h = 0; \
|
||||
\
|
||||
if (cell->child != NULL) { \
|
||||
if (cell->parent == NULL) { \
|
||||
/* if the widget isn't hidden then we can request its size */ \
|
||||
if (!(cell->child->flags & JI_HIDDEN)) { \
|
||||
reqSize = cell->child->getPreferredSize(); \
|
||||
cell->w = reqSize.w - (cell->hspan-1) * widget->child_spacing; \
|
||||
cell->h = reqSize.h - (cell->vspan-1) * widget->child_spacing; \
|
||||
if ((cell->align & p_align) == p_align) \
|
||||
++expand_count; \
|
||||
} \
|
||||
else \
|
||||
cell->w = cell->h = 0; \
|
||||
} \
|
||||
else { \
|
||||
if (!(cell->child->flags & JI_HIDDEN)) { \
|
||||
if ((cell->parent->align & p_align) == p_align) \
|
||||
++expand_count; \
|
||||
} \
|
||||
} \
|
||||
p_row += cell->p_span-1; \
|
||||
} \
|
||||
} \
|
||||
grid->p_colstrip[p_col].size = 0; \
|
||||
grid->p_colstrip[p_col].expand_count = expand_count; \
|
||||
}
|
||||
|
||||
#define EXPAND_STRIPS(p_col, p_cols, p_row, p_rows, p_span, \
|
||||
p_size, p_colstrip, p_inc_col) \
|
||||
current_span = 1; \
|
||||
do { \
|
||||
more_span = false; \
|
||||
for (p_col=0; p_col<grid->p_cols; ++p_col) { \
|
||||
for (p_row=0; p_row<grid->p_rows; ++p_row) { \
|
||||
cell = grid->cells[row]+col; \
|
||||
\
|
||||
if (cell->child != NULL && cell->parent == NULL && \
|
||||
cell->p_size > 0) { \
|
||||
ASSERT(cell->p_span > 0); \
|
||||
\
|
||||
if (cell->p_span == current_span) { \
|
||||
expand = 0; \
|
||||
expand_count = 0; \
|
||||
last_expand = 0; \
|
||||
\
|
||||
for (i=p_col; i<p_col+cell->p_span; ++i) \
|
||||
expand_count = MAX(expand_count, \
|
||||
grid->p_colstrip[i].expand_count); \
|
||||
\
|
||||
for (i=p_col; i<p_col+cell->p_span; ++i) { \
|
||||
if (grid->p_colstrip[i].expand_count == expand_count) { \
|
||||
++expand; \
|
||||
last_expand = i; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
size = cell->p_size / expand; \
|
||||
\
|
||||
for (i=p_col; i<p_col+cell->p_span; ++i) { \
|
||||
if (grid->p_colstrip[i].expand_count == expand_count) { \
|
||||
if (last_expand == i) \
|
||||
size = cell->p_size; \
|
||||
\
|
||||
p_inc_col(grid, i, size); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
else if (cell->p_span > current_span) { \
|
||||
more_span = true; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
++current_span; \
|
||||
} while (more_span);
|
||||
|
||||
CALCULATE_STRIPS(col, cols, row, rows, vspan, reqSize.w, colstrip, JI_HORIZONTAL);
|
||||
CALCULATE_STRIPS(row, rows, col, cols, hspan, reqSize.h, rowstrip, JI_VERTICAL);
|
||||
EXPAND_STRIPS(col, cols, row, rows, hspan, w, colstrip, grid_inc_col_size);
|
||||
EXPAND_STRIPS(row, rows, col, cols, vspan, h, rowstrip, grid_inc_row_size);
|
||||
|
||||
/* same width in all columns */
|
||||
if (grid->same_width_columns) {
|
||||
int max_w = 0;
|
||||
for (col=0; col<grid->cols; ++col)
|
||||
max_w = MAX(max_w, grid->colstrip[col].size);
|
||||
|
||||
for (col=0; col<grid->cols; ++col)
|
||||
grid->colstrip[col].size = max_w;
|
||||
}
|
||||
}
|
||||
|
||||
static void grid_distribute_size(JWidget widget, JRect rect)
|
||||
{
|
||||
Grid* grid = reinterpret_cast<Grid*>(jwidget_get_data(widget, JI_GRID));
|
||||
int total_req, expand_count, wantmore_count;
|
||||
int i, j;
|
||||
int extra_total;
|
||||
int extra_foreach;
|
||||
|
||||
if (grid->rows == 0)
|
||||
return;
|
||||
|
||||
#define DISTRIBUTE_SIZE(p_cols, p_colstrip, p_l, p_r, \
|
||||
p_jrect_w, p_same_width) \
|
||||
expand_count = 0; \
|
||||
for (i=0; i<grid->p_cols; ++i) \
|
||||
expand_count = MAX(expand_count, \
|
||||
grid->p_colstrip[i].expand_count); \
|
||||
\
|
||||
total_req = 0; \
|
||||
wantmore_count = 0; \
|
||||
for (i=j=0; i<grid->p_cols; ++i) { \
|
||||
if (grid->p_colstrip[i].size > 0) { \
|
||||
total_req += grid->p_colstrip[i].size; \
|
||||
if (++j > 1) \
|
||||
total_req += widget->child_spacing; \
|
||||
} \
|
||||
\
|
||||
if (grid->p_colstrip[i].expand_count == expand_count || \
|
||||
p_same_width) { \
|
||||
++wantmore_count; \
|
||||
} \
|
||||
} \
|
||||
total_req += widget->border_width.p_l + widget->border_width.p_r; \
|
||||
\
|
||||
if (wantmore_count > 0) { \
|
||||
extra_total = p_jrect_w(rect) - total_req; \
|
||||
if (extra_total > 0) { \
|
||||
/* if a expandable column-strip was empty (size=0) then */ \
|
||||
/* we have to reduce the extra_total size because a new */ \
|
||||
/* child-spacing is added by this column */ \
|
||||
for (i=0; i<grid->p_cols; ++i) { \
|
||||
if ((grid->p_colstrip[i].size == 0) && \
|
||||
(grid->p_colstrip[i].expand_count == expand_count || \
|
||||
p_same_width)) { \
|
||||
extra_total -= widget->child_spacing; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
extra_foreach = extra_total / wantmore_count; \
|
||||
\
|
||||
for (i=0; i<grid->p_cols; ++i) { \
|
||||
if (grid->p_colstrip[i].expand_count == expand_count || \
|
||||
p_same_width) { \
|
||||
ASSERT(wantmore_count > 0); \
|
||||
\
|
||||
grid->p_colstrip[i].size += extra_foreach; \
|
||||
extra_total -= extra_foreach; \
|
||||
\
|
||||
if (--wantmore_count == 0) { \
|
||||
grid->p_colstrip[i].size += extra_total; \
|
||||
extra_total = 0; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
ASSERT(wantmore_count == 0); \
|
||||
ASSERT(extra_total == 0); \
|
||||
} \
|
||||
}
|
||||
|
||||
DISTRIBUTE_SIZE(cols, colstrip, l, r, jrect_w, grid->same_width_columns);
|
||||
DISTRIBUTE_SIZE(rows, rowstrip, t, b, jrect_h, false);
|
||||
}
|
||||
|
||||
static bool grid_put_widget_in_cell(JWidget widget, JWidget child, int hspan, int vspan, int align)
|
||||
{
|
||||
Grid* grid = reinterpret_cast<Grid*>(jwidget_get_data(widget, JI_GRID));
|
||||
int col, row, colbeg, colend, rowend;
|
||||
Cell *cell, *parentcell;
|
||||
|
||||
for (row=0; row<grid->rows; ++row) {
|
||||
cell = grid->cells[row];
|
||||
for (col=0; col<grid->cols; ++col, ++cell) {
|
||||
if (cell->child == NULL) {
|
||||
cell->child = child;
|
||||
cell->hspan = hspan;
|
||||
cell->vspan = vspan;
|
||||
cell->align = align;
|
||||
|
||||
parentcell = cell;
|
||||
colbeg = col;
|
||||
colend = MIN(col+hspan, grid->cols);
|
||||
rowend = row+vspan;
|
||||
|
||||
grid_expand_rows(widget, row+vspan);
|
||||
|
||||
for (++col, ++cell; col<colend; ++col, ++cell) {
|
||||
/* if these asserts fails, it's really possible that you
|
||||
specified bad values for hspan or vspan (they are
|
||||
overlapping with other cells) */
|
||||
ASSERT(cell->parent == NULL);
|
||||
ASSERT(cell->child == NULL);
|
||||
|
||||
cell->parent = parentcell;
|
||||
cell->child = child;
|
||||
cell->hspan = colend - col;
|
||||
cell->vspan = rowend - row;
|
||||
}
|
||||
|
||||
for (++row; row<rowend; ++row) {
|
||||
for (col=colbeg; col<colend; ++col) {
|
||||
cell = grid->cells[row]+col;
|
||||
|
||||
ASSERT(cell->parent == NULL);
|
||||
ASSERT(cell->child == NULL);
|
||||
|
||||
cell->parent = parentcell;
|
||||
cell->child = child;
|
||||
cell->hspan = colend - col;
|
||||
cell->vspan = rowend - row;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expands the grid's rows to reach the specified quantity of rows in
|
||||
* the parameter.
|
||||
*/
|
||||
static void grid_expand_rows(JWidget widget, int rows)
|
||||
{
|
||||
Grid* grid = reinterpret_cast<Grid*>(jwidget_get_data(widget, JI_GRID));
|
||||
Cell* cell;
|
||||
int row;
|
||||
|
||||
if (grid->rows < rows) {
|
||||
grid->cells = (Cell**)base_realloc(grid->cells, sizeof(Cell*) * rows);
|
||||
grid->rowstrip = (Strip*)base_realloc(grid->rowstrip, sizeof(Strip) * rows);
|
||||
|
||||
for (row=grid->rows; row<rows; ++row) {
|
||||
grid->cells[row] = (Cell*)base_malloc(sizeof(Cell)*grid->cols);
|
||||
grid->rowstrip[row].size = 0;
|
||||
grid->rowstrip[row].expand_count = 0;
|
||||
|
||||
for (cell=grid->cells[row];
|
||||
cell<grid->cells[row]+grid->cols; ++cell) {
|
||||
cell->parent = NULL;
|
||||
cell->child = NULL;
|
||||
cell->hspan = 0;
|
||||
cell->vspan = 0;
|
||||
cell->align = 0;
|
||||
cell->w = 0;
|
||||
cell->h = 0;
|
||||
}
|
||||
}
|
||||
|
||||
grid->rows = rows;
|
||||
}
|
||||
}
|
||||
|
||||
static void grid_inc_col_size(Grid *grid, int col, int size)
|
||||
{
|
||||
Cell *cell;
|
||||
int row;
|
||||
|
||||
grid->colstrip[col].size += size;
|
||||
|
||||
for (row=0; row<grid->rows; ) {
|
||||
cell = grid->cells[row]+col;
|
||||
|
||||
if (cell->child != NULL) {
|
||||
if (cell->parent != NULL)
|
||||
cell->parent->w -= size;
|
||||
else
|
||||
cell->w -= size;
|
||||
|
||||
row += cell->vspan;
|
||||
}
|
||||
else
|
||||
++row;
|
||||
}
|
||||
}
|
||||
|
||||
static void grid_inc_row_size(Grid *grid, int row, int size)
|
||||
{
|
||||
Cell *cell;
|
||||
int col;
|
||||
|
||||
grid->rowstrip[row].size += size;
|
||||
|
||||
for (col=0; col<grid->cols; ) {
|
||||
cell = grid->cells[row]+col;
|
||||
|
||||
if (cell->child != NULL) {
|
||||
if (cell->parent != NULL)
|
||||
cell->parent->h -= size;
|
||||
else
|
||||
cell->h -= size;
|
||||
|
||||
col += cell->hspan;
|
||||
}
|
||||
else
|
||||
++col;
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
// ASE gui library
|
||||
// Copyright (C) 2001-2011 David Capello
|
||||
//
|
||||
// This source file is ditributed under a BSD-like license, please
|
||||
// read LICENSE.txt for more information.
|
||||
|
||||
#ifndef GUI_JGRID_H_INCLUDED
|
||||
#define GUI_JGRID_H_INCLUDED
|
||||
|
||||
#include "gui/jbase.h"
|
||||
|
||||
JWidget jgrid_new(int columns, bool same_width_columns);
|
||||
|
||||
void jgrid_add_child(JWidget grid, JWidget child,
|
||||
int hspan, int vspan, int align);
|
||||
|
||||
#endif
|
@ -11,6 +11,7 @@
|
||||
#include "gui/button.h"
|
||||
#include "gui/entry.h"
|
||||
#include "gui/frame.h"
|
||||
#include "gui/grid.h"
|
||||
#include "gui/jaccel.h"
|
||||
#include "gui/jalert.h"
|
||||
#include "gui/jbase.h"
|
||||
@ -19,7 +20,6 @@
|
||||
#include "gui/jcustom_label.h"
|
||||
#include "gui/jdraw.h"
|
||||
#include "gui/jfont.h"
|
||||
#include "gui/jgrid.h"
|
||||
#include "gui/jhook.h"
|
||||
#include "gui/jimage.h"
|
||||
#include "gui/jlink_label.h"
|
||||
|
@ -84,8 +84,8 @@ static Model models[] = {
|
||||
Frame* colorselector_new()
|
||||
{
|
||||
Frame* window = new PopupFrame(NULL, false);
|
||||
Widget* grid1 = jgrid_new(2, false);
|
||||
Widget* grid2 = jgrid_new(5, false);
|
||||
Grid* grid1 = new Grid(2, false);
|
||||
Grid* grid2 = new Grid(5, false);
|
||||
Box* models_box = new Box(JI_HORIZONTAL);
|
||||
PalEdit* pal = new PalEdit(false);
|
||||
Label* idx = new Label("None");
|
||||
@ -123,14 +123,14 @@ Frame* colorselector_new()
|
||||
// Create the color-model container
|
||||
child = (*m->create)();
|
||||
child->setName(m->text);
|
||||
jgrid_add_child(grid2, child, 1, 1, JI_HORIZONTAL | JI_TOP);
|
||||
grid2->addChildInCell(child, 1, 1, JI_HORIZONTAL | JI_TOP);
|
||||
}
|
||||
|
||||
/* add children */
|
||||
jgrid_add_child(grid2, pal, 1, 1, JI_RIGHT | JI_TOP);
|
||||
jgrid_add_child(grid1, models_box, 1, 1, JI_HORIZONTAL | JI_BOTTOM);
|
||||
jgrid_add_child(grid1, idx, 1, 1, JI_RIGHT | JI_BOTTOM);
|
||||
jgrid_add_child(grid1, grid2, 2, 1, JI_HORIZONTAL | JI_VERTICAL);
|
||||
grid2->addChildInCell(pal, 1, 1, JI_RIGHT | JI_TOP);
|
||||
grid1->addChildInCell(models_box, 1, 1, JI_HORIZONTAL | JI_BOTTOM);
|
||||
grid1->addChildInCell(idx, 1, 1, JI_RIGHT | JI_BOTTOM);
|
||||
grid1->addChildInCell(grid2, 2, 1, JI_HORIZONTAL | JI_VERTICAL);
|
||||
jwidget_add_child(window, grid1);
|
||||
|
||||
/* hooks */
|
||||
@ -163,19 +163,19 @@ JWidget colorselector_get_paledit(JWidget widget)
|
||||
|
||||
static Widget* create_rgb_container()
|
||||
{
|
||||
Widget* grid = jgrid_new(2, false);
|
||||
Grid* grid = new Grid(2, false);
|
||||
Label* rlabel = new Label("R");
|
||||
Label* glabel = new Label("G");
|
||||
Label* blabel = new Label("B");
|
||||
Slider* rslider = new Slider(0, 255, 0);
|
||||
Slider* gslider = new Slider(0, 255, 0);
|
||||
Slider* bslider = new Slider(0, 255, 0);
|
||||
jgrid_add_child(grid, rlabel, 1, 1, JI_RIGHT);
|
||||
jgrid_add_child(grid, rslider, 1, 1, JI_HORIZONTAL);
|
||||
jgrid_add_child(grid, glabel, 1, 1, JI_RIGHT);
|
||||
jgrid_add_child(grid, gslider, 1, 1, JI_HORIZONTAL);
|
||||
jgrid_add_child(grid, blabel, 1, 1, JI_RIGHT);
|
||||
jgrid_add_child(grid, bslider, 1, 1, JI_HORIZONTAL);
|
||||
grid->addChildInCell(rlabel, 1, 1, JI_RIGHT);
|
||||
grid->addChildInCell(rslider, 1, 1, JI_HORIZONTAL);
|
||||
grid->addChildInCell(glabel, 1, 1, JI_RIGHT);
|
||||
grid->addChildInCell(gslider, 1, 1, JI_HORIZONTAL);
|
||||
grid->addChildInCell(blabel, 1, 1, JI_RIGHT);
|
||||
grid->addChildInCell(bslider, 1, 1, JI_HORIZONTAL);
|
||||
|
||||
rslider->setName("rgb_r");
|
||||
gslider->setName("rgb_g");
|
||||
@ -190,19 +190,19 @@ static Widget* create_rgb_container()
|
||||
|
||||
static Widget* create_hsv_container()
|
||||
{
|
||||
Widget* grid = jgrid_new(2, false);
|
||||
Grid* grid = new Grid(2, false);
|
||||
Label* hlabel = new Label("H");
|
||||
Label* slabel = new Label("S");
|
||||
Label* vlabel = new Label("V");
|
||||
Slider* hslider = new Slider(0, 360, 0);
|
||||
Slider* sslider = new Slider(0, 100, 0);
|
||||
Slider* vslider = new Slider(0, 100, 0);
|
||||
jgrid_add_child(grid, hlabel, 1, 1, JI_RIGHT);
|
||||
jgrid_add_child(grid, hslider, 1, 1, JI_HORIZONTAL);
|
||||
jgrid_add_child(grid, slabel, 1, 1, JI_RIGHT);
|
||||
jgrid_add_child(grid, sslider, 1, 1, JI_HORIZONTAL);
|
||||
jgrid_add_child(grid, vlabel, 1, 1, JI_RIGHT);
|
||||
jgrid_add_child(grid, vslider, 1, 1, JI_HORIZONTAL);
|
||||
grid->addChildInCell(hlabel, 1, 1, JI_RIGHT);
|
||||
grid->addChildInCell(hslider, 1, 1, JI_HORIZONTAL);
|
||||
grid->addChildInCell(slabel, 1, 1, JI_RIGHT);
|
||||
grid->addChildInCell(sslider, 1, 1, JI_HORIZONTAL);
|
||||
grid->addChildInCell(vlabel, 1, 1, JI_RIGHT);
|
||||
grid->addChildInCell(vslider, 1, 1, JI_HORIZONTAL);
|
||||
|
||||
hslider->setName("hsv_h");
|
||||
sslider->setName("hsv_s");
|
||||
@ -217,11 +217,11 @@ static Widget* create_hsv_container()
|
||||
|
||||
static Widget* create_gray_container()
|
||||
{
|
||||
Widget* grid = jgrid_new(2, false);
|
||||
Grid* grid = new Grid(2, false);
|
||||
Label* klabel = new Label("V");
|
||||
Slider* vslider = new Slider(0, 255, 0);
|
||||
jgrid_add_child(grid, klabel, 1, 1, JI_RIGHT);
|
||||
jgrid_add_child(grid, vslider, 1, 1, JI_HORIZONTAL);
|
||||
grid->addChildInCell(klabel, 1, 1, JI_RIGHT);
|
||||
grid->addChildInCell(vslider, 1, 1, JI_HORIZONTAL);
|
||||
|
||||
vslider->setName("gray_v");
|
||||
|
||||
|
@ -191,8 +191,8 @@ static Widget* convert_xmlelement_to_widget(TiXmlElement* elem, Widget* root)
|
||||
bool same_width_columns = bool_attr_is_true(elem, "same_width_columns");
|
||||
|
||||
if (columns != NULL) {
|
||||
widget = jgrid_new(ustrtol(columns, NULL, 10),
|
||||
same_width_columns);
|
||||
widget = new Grid(ustrtol(columns, NULL, 10),
|
||||
same_width_columns);
|
||||
}
|
||||
}
|
||||
/* label */
|
||||
@ -388,8 +388,10 @@ static Widget* convert_xmlelement_to_widget(TiXmlElement* elem, Widget* root)
|
||||
int hspan = cell_hspan ? ustrtol(cell_hspan, NULL, 10): 1;
|
||||
int vspan = cell_vspan ? ustrtol(cell_vspan, NULL, 10): 1;
|
||||
int align = cell_align ? convert_align_value_to_flags(cell_align): 0;
|
||||
Grid* grid = dynamic_cast<Grid*>(widget);
|
||||
ASSERT(grid != NULL);
|
||||
|
||||
jgrid_add_child(widget, child, hspan, vspan, align);
|
||||
grid->addChildInCell(child, hspan, vspan, align);
|
||||
}
|
||||
// Just add the child in any other kind of widget
|
||||
else
|
||||
|
Loading…
x
Reference in New Issue
Block a user