Mercurial > projects > mde
diff mde/gui/widget/layout.d @ 39:5132301e9ed7
Implemented widget saving.
Widget creation data saving (sub-widgets, etc:) code there but not used.
Widget mutable data saving & loading: window size/position, row/column dimensions saved (still needs a fix in GridWidget.setSize()).
committer: Diggory Hardy <diggory.hardy@gmail.com>
author | Diggory Hardy <diggory.hardy@gmail.com> |
---|---|
date | Wed, 07 May 2008 13:07:03 +0100 |
parents | 8c4c96f04e7f |
children | b28d7adc786b |
line wrap: on
line diff
--- a/mde/gui/widget/layout.d Mon May 05 17:02:21 2008 +0100 +++ b/mde/gui/widget/layout.d Wed May 07 13:07:03 2008 +0100 @@ -17,34 +17,74 @@ module mde.gui.widget.layout; import mde.gui.widget.Widget; -import mde.gui.exception : WidgetDataException; +import mde.gui.exception; /** Encapsulates a grid of Widgets. * * Since a grid with either dimension zero is not useful, there must be at least one sub-widget. */ class GridLayoutWidget : Widget { - this (IWindow wind, IWidget, int[] data) { + this (IWindow wind, int[] data) { // Get grid size and check data // Check sufficient data for rows, cols, and at least one widget: - if (data.length < 3) throw new WidgetDataException; - rows = data[0]; - cols = data[1]; - if (data.length != 2 + rows * cols) throw new WidgetDataException; + if (data.length < 4) throw new WidgetDataException; + super (wind, data); + + rows = data[1]; + cols = data[2]; + if (data.length != 3 + rows * cols) throw new WidgetDataException; /* data.length >= 3 so besides checking the length is correct, this tells us: - * rows * cols >= 3 - 2 = 1 a free check! + * rows * cols >= 4 - 3 = 1 a free check! * The only thing not checked is whether both rows and cols are negative, which would * cause an exception when dynamic arrays are allocated later (and is unlikely). */ - window = wind; - // Get all sub-widgets subWidgets.length = rows*cols; foreach (i, inout subWidget; subWidgets) { - subWidget = window.makeWidget (data[i+2], this); + subWidget = window.makeWidget (data[i+3]); } } + int[] adjust (int[] data) { + // Give all sub-widgets their data: + foreach (widget; subWidgets) + data = widget.adjust (data); + if (data.length < rows + cols) throw new MutableDataException; + + /* We basically short-cut setSize by loading previous col/row sizes and doing the final + * calculations. There isn't checks that the data is valid/up-to-date... worst case is too + * small overlapping widgets or huge ones? + * Note: if setSize gets called afterwards, it should have same dimensions and so not do + * anything. */ + colW = data[0..cols]; + rowH = data[cols..rows+cols]; + setColRowSizes; + w = colW[$-1] + colX[$-1]; + h = rowY[$-1] + rowH[$-1]; + + return data[rows+cols..$]; + } + + int[] getCreationData () { + int[] ret; + ret.length = 3 + subWidgets.length; + + ret [0..3] = [widgetType, rows, cols]; // first data + + foreach (i,widget; subWidgets) // sub widgets + ret[i+3] = window.addCreationData (widget); + + return ret; + } + int[] getMutableData () { + int[] ret; + foreach (widget; subWidgets) + ret ~= widget.getMutableData; + + ret ~= colW ~ rowH; + return ret; + } + bool isWSizable () { if (colSizable == -2) { // check whether any columns are resizable for1: @@ -108,6 +148,19 @@ } void setSize (int nw, int nh) { + /* For each of width and height, there are several cases: + * [new value is] more than old value + * -> enlarge any row/column + * same as old value + * -> do nothing + * more than min but less than current value + * -> find an enlarged row/col and reduce size + * -> repeat if necessary + * minimal value or less + * -> clamp to min and use min col/row sizes + */ + // FIXME: implement! + // Step 1: calculate the minimal row/column sizes. alias w mw; // no need for extra vars, just use these alias h mh; @@ -132,34 +185,15 @@ rowH[$-1] += nh - mh; } - // Step 3: set each sub-widget's size. - foreach (i,widget; subWidgets) - widget.setSize (colW[i % cols], rowH[i / cols]); - w = nw; h = nh; + // Step 3: set each sub-widget's size. // Step 4: calculate the column and row positions - colX.length = cols; - rowY.length = rows; - int spacing = window.renderer.layoutSpacing; - - int cum = 0; - foreach (i, x; rowH) { - rowY[i] = cum; - cum += x + spacing; - } - - cum = 0; - foreach (i, x; colW) { - colX[i] = cum; - cum += x + spacing; - } + setColRowSizes; // Step 5: position needs resetting - // FIXME: find a more efficient method of doing this? - // maybe setPosition should ALWAYS be called after setSize? - setPosition (x,y); + // Currently this happens by specifying that setPosition should be run after setSize. } void setPosition (int x, int y) { @@ -228,6 +262,29 @@ } } + void setColRowSizes () { + // Calculate column and row locations: + colX.length = cols; + rowY.length = rows; + int spacing = window.renderer.layoutSpacing; + + int cum = 0; + foreach (i, x; rowH) { + rowY[i] = cum; + cum += x + spacing; + } + + cum = 0; + foreach (i, x; colW) { + colX[i] = cum; + cum += x + spacing; + } + + // Tell subwidgets their new sizes: + foreach (i,widget; subWidgets) + widget.setSize (colW[i % cols], rowH[i / cols]); + } + protected: int cols, rows; // number of cells in grid