summaryrefslogtreecommitdiff
path: root/fluid/Fl_Grid_Type.cxx
diff options
context:
space:
mode:
authorMatthias Melcher <github@matthiasm.com>2025-03-07 16:34:35 +0100
committerMatthias Melcher <github@matthiasm.com>2025-03-07 16:34:48 +0100
commit1985aefc0e502048f92b91beef87c0dfbe669fed (patch)
treeaf62874def4590e437a47784b4428d975ceb262f /fluid/Fl_Grid_Type.cxx
parent42a04c064d4b31c3a85210311f3ada163c406a25 (diff)
Restructuring Fluid source files.
Diffstat (limited to 'fluid/Fl_Grid_Type.cxx')
-rw-r--r--fluid/Fl_Grid_Type.cxx993
1 files changed, 0 insertions, 993 deletions
diff --git a/fluid/Fl_Grid_Type.cxx b/fluid/Fl_Grid_Type.cxx
deleted file mode 100644
index 45110a880..000000000
--- a/fluid/Fl_Grid_Type.cxx
+++ /dev/null
@@ -1,993 +0,0 @@
-//
-// Fl_Grid object code for the Fast Light Tool Kit (FLTK).
-//
-// Copyright 2023 by Bill Spitzak and others.
-//
-// This library is free software. Distribution and use rights are outlined in
-// the file "COPYING" which should have been included with this file. If this
-// file is missing or damaged, see the license at:
-//
-// https://www.fltk.org/COPYING.php
-//
-// Please see the following page on how to report bugs and issues:
-//
-// https://www.fltk.org/bugs.php
-//
-
-#include "Fl_Grid_Type.h"
-
-#include "fluid.h"
-#include "file.h"
-#include "code.h"
-#include "widget_browser.h"
-#include "undo.h"
-#include "Fd_Snap_Action.h"
-#include "custom_widgets.h"
-
-#include <FL/Fl_Grid.H>
-#include <FL/Fl_Value_Input.H>
-#include <FL/Fl_Button.H>
-#include <FL/Fl_Choice.H>
-#include "../src/flstring.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-
-// ---- Fl_Grid_Proxy --------------------------------------------------- MARK: -
-
-/**
- An implementation of the Fl_Grid widget with additional functionality.
-
- Fl_Grid_Proxy add a list of transient children, i.e. children that are
- temporarily assigned to a cell that is already taken by another child.
- */
-Fl_Grid_Proxy::Fl_Grid_Proxy(int X,int Y,int W,int H)
-: Fl_Grid(X,Y,W,H),
- transient_(NULL),
- num_transient_(0),
- cap_transient_(0)
-{
-}
-
-Fl_Grid_Proxy::~Fl_Grid_Proxy() {
- int i;
- if (transient_) {
- for (i=0; i<num_transient_; i++) {
- if (transient_[i].cell) ::free(transient_[i].cell);
- }
- ::free(transient_);
- }
-}
-
-// Override group's resize behavior to do nothing to children:
-void Fl_Grid_Proxy::resize(int X, int Y, int W, int H) {
- if (Fl_Type::allow_layout > 0) {
- Fl_Grid::resize(X, Y, W, H);
- } else {
- Fl_Widget::resize(X, Y, W, H);
- }
- redraw();
-}
-
-/**
- Override draw() to make groups with no box or flat box background visible.
- */
-void Fl_Grid_Proxy::draw() {
- if (show_ghosted_outline && (box() == FL_NO_BOX)) {
- fl_rect(x(), y(), w(), h(), Fl::box_color(fl_color_average(FL_FOREGROUND_COLOR, color(), .1f)));
- }
- Fl_Grid::draw();
-}
-
-/**
- Draw additional markings in the overlay plane when a grid is selected.
- */
-void Fl_Grid_Proxy::draw_overlay() {
- fl_line_style(FL_DOT);
- grid_color = fl_color();
- draw_grid();
- fl_color(grid_color);
-}
-
-/**
- Move a cell into the grid or within the grid.
-
- If the target cell is already taken, \p how will determine what to do:
-
- If \p how is 0, the existing cell at \p to_row, \p to_col will be deleted,
- unlinking the occupant from the grid. \p in_child will the be inserted at the
- given location.
-
- If \p how is 1, the old cell will remain intact, however \p in_child will be
- unlinked from the grid.
-
- If \p how is 2, the old cell will remain intact, and \p in_child will be
- removed from the grid, but it will be stored in the transient list and
- resized to the target cell position and size. If \p in_child is later
- moved to an unoccupied cell, it will be removed from the transient list and
- relinked to the grid. Rowspan and colspan are ignored here.
-
- \param[in] in_child must already be a child of grid
- \param[in] to_row, to_col move the child into this cell
- \param[in] how 0: replace occupant, 1: don't replace, 2: make transient
- if occupied
- */
-void Fl_Grid_Proxy::move_cell(Fl_Widget *in_child, int to_row, int to_col, int how) {
- // the child must already be a true child of grid
- assert(find(in_child)<children());
-
- short rowspan = 1, colspan = 1;
- Fl_Grid_Align align = FL_GRID_FILL;
- int w = 20, h = 20;
- const Fl_Grid::Cell *old_cell = cell(in_child);
- if (old_cell) {
- if (old_cell->row() == to_row && old_cell->col() == to_col) return;
- rowspan = old_cell->rowspan();
- colspan = old_cell->colspan();
- align = old_cell->align();
- old_cell->minimum_size(&w, &h);
- }
- if ((to_row < 0) || (to_row+rowspan > rows())) return;
- if ((to_col < 0) || (to_col+colspan > cols())) return;
- Fl_Grid::Cell *new_cell = NULL;
- if (how == 0) { // replace old occupant in cell, making that one homeless
- new_cell = widget(in_child, to_row, to_col, rowspan, colspan, align);
- } else if (how == 1) { // don't replace an old occupant, making ourselves homeless
- // todo: colspan, rowspan?
- if (cell(to_row, to_col) == NULL) {
- new_cell = widget(in_child, to_row, to_col, rowspan, colspan, align);
- } else {
- if (old_cell) remove_cell(old_cell->row(), old_cell->col());
- }
- } else if (how == 2) {
- Cell *current = cell(to_row, to_col);
- if (current == NULL) {
- new_cell = widget(in_child, to_row, to_col, rowspan, colspan, align);
- } else {
- if (old_cell) remove_cell(old_cell->row(), old_cell->col());
- new_cell = transient_widget(in_child, to_row, to_col, rowspan, colspan, align);
- Fl_Widget *w = current->widget();
- Fl_Type::allow_layout++;
- in_child->resize(w->x(), w->y(), w->w(), w->h());
- Fl_Type::allow_layout--;
- }
- }
- if (new_cell) new_cell->minimum_size(w, h);
-}
-
-/**
- Generate or replace a transient widget entry.
-
- If the widget is in the cell list, it will be removed there.
- If the widget is already transient, the cell will be replaced.
-
- \param[in] wi a child of this Fl_Grid_Proxy, that may be linked to a cell or transient cell
- \param[in] row, col, row_span, col_span, align cell parameters
- */
-Fl_Grid::Cell* Fl_Grid_Proxy::transient_widget(Fl_Widget *wi, int row, int col, int row_span, int col_span, Fl_Grid_Align align) {
- int i = 0;
- bool remove_old_cell = false;
- Cell *old_cell = cell(wi);
- if (old_cell) {
- remove_old_cell = true;
- } else {
- for (i=0; i<num_transient_; i++) {
- if (transient_[i].widget == wi) {
- old_cell = transient_[i].cell;
- break;
- }
- }
- }
- Cell *new_cell = new Cell(wi, row, col);
- new_cell->rowspan(row_span);
- new_cell->colspan(col_span);
- new_cell->align(align);
- if (old_cell) {
- int mw, mh;
- old_cell->minimum_size(&mw, &mh);
- new_cell->minimum_size(mw, mh);
- if (remove_old_cell) {
- remove_cell(old_cell->row(), old_cell->col());
- } else {
- delete old_cell;
- }
- }
- if (i == num_transient_) {
- transient_make_room_(num_transient_ + 1);
- transient_[i].widget = wi;
- num_transient_++;
- }
- transient_[i].cell = new_cell;
- return new_cell;
-}
-
-/**
- Make room for at least n transient widgets in the array.
- \param[in] n minimum number of entries
- */
-void Fl_Grid_Proxy::transient_make_room_(int n) {
- if (n > cap_transient_) {
- cap_transient_ = n + 10;
- transient_ = (Cell_Widget_Pair*)::realloc(transient_, cap_transient_ * sizeof(Cell_Widget_Pair));
- }
-}
-
-/**
- Remove a widget form the list and deallocate the transient cell.
- \param[in] w remove the transient cell for this widget
- */
-void Fl_Grid_Proxy::transient_remove_(Fl_Widget *w) {
- for (int i=0; i<num_transient_; i++) {
- if (transient_[i].widget==w) {
- if (transient_[i].cell) {
- ::free(transient_[i].cell);
- ::memmove(transient_+i, transient_+i+1, sizeof(Cell_Widget_Pair)*(num_transient_-i-1));
- num_transient_--;
- return;
- }
- }
- }
-}
-
-/**
- Find a cell in the grid or in the transient cell list.
- \param[in] widget must be a child of the grid.
- \return the cell, the transient cell, or NULL if neither was found.
- */
-Fl_Grid_Proxy::Cell *Fl_Grid_Proxy::any_cell(Fl_Widget *widget) const {
- Cell *c = cell(widget);
- if (c) return c;
- return transient_cell(widget);
-}
-
-/**
- Find a cell in the transient cell list.
- \param[in] widget must be a child of the grid.
- \return the transient cell, or NULL if it was not found.
- */
-Fl_Grid_Proxy::Cell *Fl_Grid_Proxy::transient_cell(Fl_Widget *widget) const {
- for (int i=0; i<num_transient_; i++) {
- if (transient_[i].widget == widget)
- return transient_[i].cell;
- }
- return NULL;
-}
-
-/**
- Forwarding the call.
- \param[in] wi generate a cell for this widget
- \param[in] row, col, align cell parameters
- */
-Fl_Grid::Cell *Fl_Grid_Proxy::widget(Fl_Widget *wi, int row, int col, Fl_Grid_Align align) {
- return widget(wi, row, col, 1, 1, align);
-}
-
-/**
- Just like the Fl_Grid original, but removes potential transient cell.
- \param[in] wi generate a cell for this widget
- \param[in] row, col, rowspan, colspan, align cell parameters
- */
-Fl_Grid::Cell *Fl_Grid_Proxy::widget(Fl_Widget *wi, int row, int col, int rowspan, int colspan, Fl_Grid_Align align) {
- transient_remove_(wi);
- return Fl_Grid::widget(wi, row, col, rowspan, colspan, align);
-}
-
-
-
-// ---- Fl_Grid_Type --------------------------------------------------- MARK: -
-
-const char grid_type_name[] = "Fl_Grid";
-
-Fl_Grid_Type Fl_Grid_type; // the "factory"
-
-Fl_Grid_Type::Fl_Grid_Type() {
-}
-
-Fl_Widget *Fl_Grid_Type::widget(int X,int Y,int W,int H) {
- Fl_Grid *g = new Fl_Grid_Proxy(X,Y,W,H);
- g->layout(3, 3);
- Fl_Group::current(0);
- return g;
-}
-
-Fl_Widget *Fl_Grid_Type::enter_live_mode(int top) {
- Fl_Grid *grid = new Fl_Grid(o->x(), o->y(), o->w(), o->h());
- return propagate_live_mode(grid);
-}
-
-void Fl_Grid_Type::leave_live_mode() {
-}
-
-void Fl_Grid_Type::copy_properties()
-{
- super::copy_properties();
- Fl_Grid *d = (Fl_Grid*)live_widget, *s =(Fl_Grid*)o;
- d->layout(s->rows(), s->cols());
- int lm, tm, rm, bm;
- s->margin(&lm, &tm, &rm, &bm);
- d->margin(lm, tm, rm, bm);
- int rg, cg;
- s->gap(&rg, &cg);
- d->gap(rg, cg);
- // copy col widths, heights, and gaps
- for (int c=0; c<s->cols(); c++) {
- d->col_width(c, s->col_width(c));
- d->col_gap(c, s->col_gap(c));
- d->col_weight(c, s->col_weight(c));
- }
- // copy row widths, heights, and gaps
- for (int r=0; r<s->rows(); r++) {
- d->row_height(r, s->row_height(r));
- d->row_gap(r, s->row_gap(r));
- d->row_weight(r, s->row_weight(r));
- }
-}
-
-void Fl_Grid_Type::copy_properties_for_children() {
- Fl_Grid *d = (Fl_Grid*)live_widget, *s =(Fl_Grid*)o;
- for (int i=0; i<s->children(); i++) {
- Fl_Grid::Cell *cell = s->cell(s->child(i));
- if (cell && i<d->children()) {
- d->widget(d->child(i),
- cell->row(), cell->col(),
- cell->rowspan(), cell->colspan(),
- cell->align());
- }
- }
- d->layout();
-}
-
-void Fl_Grid_Type::write_properties(Fd_Project_Writer &f)
-{
- super::write_properties(f);
- Fl_Grid* grid = (Fl_Grid*)o;
- int i, rows = grid->rows(), cols = grid->cols();
- f.write_indent(level+1);
- f.write_string("dimensions {%d %d}", rows, cols);
- int lm, tm, rm, bm;
- grid->margin(&lm, &tm, &rm, &bm);
- if (lm!=0 || tm!=0 || rm!=0 || bm!=0)
- f.write_string("margin {%d %d %d %d}", lm, tm, rm, bm);
- int rg, cg;
- grid->gap(&rg, &cg);
- if (rg!=0 || cg!=0)
- f.write_string("gap {%d %d}", rg, cg);
- // -- write all row heights if one of them is not the default 0
- for (i=0; i<rows; i++) if (grid->row_height(i)!=0) break;
- if (i<rows) {
- f.write_indent(level+1);
- f.write_string("rowheights {");
- for (i=0; i<rows; i++) f.write_string("%d", grid->row_height(i));
- f.write_string("}");
- }
- // -- write all row weights if one of them is not the default 50
- for (i=0; i<rows; i++) if (grid->row_weight(i)!=50) break;
- if (i<rows) {
- f.write_indent(level+1);
- f.write_string("rowweights {");
- for (i=0; i<rows; i++) f.write_string("%d", grid->row_weight(i));
- f.write_string("}");
- }
- // -- write all row gaps if one of them is not the default -1
- for (i=0; i<rows; i++) if (grid->row_gap(i)!=-1) break;
- if (i<rows) {
- f.write_indent(level+1);
- f.write_string("rowgaps {");
- for (i=0; i<rows; i++) f.write_string("%d", grid->row_gap(i));
- f.write_string("}");
- }
- // -- write all col widths if one of them is not the default 0
- for (i=0; i<cols; i++) if (grid->col_width(i)!=0) break;
- if (i<cols) {
- f.write_indent(level+1);
- f.write_string("colwidths {");
- for (i=0; i<cols; i++) f.write_string("%d", grid->col_width(i));
- f.write_string("}");
- }
- // -- write all col weights if one of them is not the default 50
- for (i=0; i<cols; i++) if (grid->col_weight(i)!=50) break;
- if (i<cols) {
- f.write_indent(level+1);
- f.write_string("colweights {");
- for (i=0; i<cols; i++) f.write_string("%d", grid->col_weight(i));
- f.write_string("}");
- }
- // -- write all col gaps if one of them is not the default -1
- for (i=0; i<cols; i++) if (grid->col_gap(i)!=-1) break;
- if (i<cols) {
- f.write_indent(level+1);
- f.write_string("colgaps {");
- for (i=0; i<cols; i++) f.write_string("%d", grid->col_gap(i));
- f.write_string("}");
- }
-}
-
-void Fl_Grid_Type::read_property(Fd_Project_Reader &f, const char *c)
-{
- Fl_Grid* grid = (Fl_Grid*)o;
- if (!strcmp(c,"dimensions")) {
- int rows = 3, cols = 3;
- if (sscanf(f.read_word(),"%d %d", &rows, &cols) == 2)
- grid->layout(rows, cols);
- } else if (!strcmp(c,"margin")) {
- int lm, tm, rm, bm;
- if (sscanf(f.read_word(),"%d %d %d %d", &lm, &tm, &rm, &bm) == 4)
- grid->margin(lm, tm, rm, bm);
- } else if (!strcmp(c,"gap")) {
- int rg, cg;
- if (sscanf(f.read_word(),"%d %d", &rg, &cg) == 2)
- grid->gap(rg, cg);
- } else if (!strcmp(c,"rowheights")) {
- int rows = grid->rows();
- f.read_word(1); // "{"
- for (int i=0; i<rows; i++) grid->row_height(i, f.read_int());
- f.read_word(1); // "}"
- } else if (!strcmp(c,"rowweights")) {
- int rows = grid->rows();
- f.read_word(1); // "{"
- for (int i=0; i<rows; i++) grid->row_weight(i, f.read_int());
- f.read_word(1); // "}"
- } else if (!strcmp(c,"rowgaps")) {
- int rows = grid->rows();
- f.read_word(1); // "{"
- for (int i=0; i<rows; i++) grid->row_gap(i, f.read_int());
- f.read_word(1); // "}"
- } else if (!strcmp(c,"colwidths")) {
- int cols = grid->cols();
- f.read_word(1); // "{"
- for (int i=0; i<cols; i++) grid->col_width(i, f.read_int());
- f.read_word(1); // "}"
- } else if (!strcmp(c,"colweights")) {
- int cols = grid->cols();
- f.read_word(1); // "{"
- for (int i=0; i<cols; i++) grid->col_weight(i, f.read_int());
- f.read_word(1); // "}"
- } else if (!strcmp(c,"colgaps")) {
- int cols = grid->cols();
- f.read_word(1); // "{"
- for (int i=0; i<cols; i++) grid->col_gap(i, f.read_int());
- f.read_word(1); // "}"
- } else {
- super::read_property(f, c);
- }
-}
-
-void Fl_Grid_Type::write_parent_properties(Fd_Project_Writer &f, Fl_Type *child, bool encapsulate) {
- Fl_Grid *grid;
- Fl_Widget *child_widget;
- Fl_Grid::Cell *cell;
- if (!child->is_true_widget()) return super::write_parent_properties(f, child, true);
- grid = (Fl_Grid*)o;
- child_widget = ((Fl_Widget_Type*)child)->o;
- cell = grid->cell(child_widget);
- if (!cell) return super::write_parent_properties(f, child, true);
- if (encapsulate) {
- f.write_indent(level+2);
- f.write_string("parent_properties {");
- }
- f.write_indent(level+3);
- f.write_string("location {%d %d}", cell->row(), cell->col());
- int v = cell->colspan();
- if (v>1) {
- f.write_indent(level+3);
- f.write_string("colspan %d", v);
- }
- v = cell->rowspan();
- if (v>1) {
- f.write_indent(level+3);
- f.write_string("rowspan %d", v);
- }
- v = (int)cell->align();
- if (v!=FL_GRID_FILL) {
- f.write_indent(level+3);
- f.write_string("align %d", v);
- }
- int min_w = 0, min_h = 0;
- cell->minimum_size(&min_w, &min_h);
- if (min_w!=20 || min_h!=20) {
- f.write_indent(level+3);
- f.write_string("minsize {%d %d}", min_w, min_h);
- }
- super::write_parent_properties(f, child, false);
- if (encapsulate) {
- f.write_indent(level+2);
- f.write_string("}");
- }
- return;
-}
-
-// NOTE: we have to do this in a loop just as ::read_property() in case a new
-// property is added. In the current setup, all the remaining properties
-// will be skipped
-void Fl_Grid_Type::read_parent_property(Fd_Project_Reader &f, Fl_Type *child, const char *property) {
- if (!child->is_true_widget()) {
- super::read_parent_property(f, child, property);
- return;
- }
- Fl_Grid *grid = (Fl_Grid*)o;
- Fl_Widget *child_widget = ((Fl_Widget_Type*)child)->o;
- if (!strcmp(property, "location")) {
- int row = -1, col = -1;
- const char *value = f.read_word();
- sscanf(value, "%d %d", &row, &col);
- Fl_Grid::Cell *cell = grid->widget(child_widget, row, col);
- if (cell) {
- int min_w = 20, min_h = 20;
- cell->minimum_size(min_w, min_h);
- }
- } else if (!strcmp(property, "colspan")) {
- int colspan = atoi(f.read_word());
- Fl_Grid::Cell *cell = grid->cell(child_widget);
- if (cell) cell->colspan(colspan);
- } else if (!strcmp(property, "rowspan")) {
- int rowspan = atoi(f.read_word());
- Fl_Grid::Cell *cell = grid->cell(child_widget);
- if (cell) cell->rowspan(rowspan);
- } else if (!strcmp(property, "align")) {
- int align = atoi(f.read_word());
- Fl_Grid::Cell *cell = grid->cell(child_widget);
- if (cell) cell->align((Fl_Grid_Align)align);
- } if (!strcmp(property, "minsize")) {
- int min_w = 20, min_h = 20;
- const char *value = f.read_word();
- sscanf(value, "%d %d", &min_w, &min_h);
- Fl_Grid::Cell *cell = grid->cell(child_widget);
- if (cell) cell->minimum_size(min_w, min_h);
- } else {
- super::read_parent_property(f, child, property);
- }
-}
-
-void Fl_Grid_Type::write_code1(Fd_Code_Writer& f) {
- const char *var = name() ? name() : "o";
- Fl_Grid* grid = (Fl_Grid*)o;
- Fl_Widget_Type::write_code1(f);
- int i, rows = grid->rows(), cols = grid->cols();
- f.write_c("%s%s->layout(%d, %d);\n", f.indent(), var, rows, cols);
- int lm, tm, rm, bm;
- grid->margin(&lm, &tm, &rm, &bm);
- if (lm!=0 || tm!=0 || rm!=0 || bm!=0)
- f.write_c("%s%s->margin(%d, %d, %d, %d);\n", f.indent(), var, lm, tm, rm, bm);
- int rg, cg;
- grid->gap(&rg, &cg);
- if (rg!=0 || cg!=0)
- f.write_c("%s%s->gap(%d, %d);\n", f.indent(), var, rg, cg);
- // -- write all row heights if one of them is not the default 0
- for (i=0; i<rows; i++) if (grid->row_height(i)!=0) break;
- if (i<rows) {
- f.write_c("%sstatic const int rowheights[] = { %d", f.indent(), grid->row_height(0));
- for (i=1; i<rows; i++) f.write_c(", %d", grid->row_height(i));
- f.write_c(" };\n");
- f.write_c("%s%s->row_height(rowheights, %d);\n", f.indent(), var, rows);
- }
- // -- write all row weights if one of them is not the default 50
- for (i=0; i<rows; i++) if (grid->row_weight(i)!=50) break;
- if (i<rows) {
- f.write_c("%sstatic const int rowweights[] = { %d", f.indent(), grid->row_weight(0));
- for (i=1; i<rows; i++) f.write_c(", %d", grid->row_weight(i));
- f.write_c(" };\n");
- f.write_c("%s%s->row_weight(rowweights, %d);\n", f.indent(), var, rows);
- }
- // -- write all row gaps if one of them is not the default -1
- for (i=0; i<rows; i++) if (grid->row_gap(i)!=-1) break;
- if (i<rows) {
- f.write_c("%sstatic const int rowgaps[] = { %d", f.indent(), grid->row_gap(0));
- for (i=1; i<rows; i++) f.write_c(", %d", grid->row_gap(i));
- f.write_c(" };\n");
- f.write_c("%s%s->row_gap(rowgaps, %d);\n", f.indent(), var, rows);
- }
- // -- write all col widths if one of them is not the default 0
- for (i=0; i<cols; i++) if (grid->col_width(i)!=0) break;
- if (i<cols) {
- f.write_c("%sstatic const int colwidths[] = { %d", f.indent(), grid->col_width(0));
- for (i=1; i<cols; i++) f.write_c(", %d", grid->col_width(i));
- f.write_c(" };\n");
- f.write_c("%s%s->col_width(colwidths, %d);\n", f.indent(), var, cols);
- }
- // -- write all col weights if one of them is not the default 50
- for (i=0; i<cols; i++) if (grid->col_weight(i)!=50) break;
- if (i<cols) {
- f.write_c("%sstatic const int colweights[] = { %d", f.indent(), grid->col_weight(0));
- for (i=1; i<cols; i++) f.write_c(", %d", grid->col_weight(i));
- f.write_c(" };\n");
- f.write_c("%s%s->col_weight(colweights, %d);\n", f.indent(), var, cols);
- }
- // -- write all col gaps if one of them is not the default -1
- for (i=0; i<cols; i++) if (grid->col_gap(i)!=-1) break;
- if (i<cols) {
- f.write_c("%sstatic const int colgaps[] = { %d", f.indent(), grid->col_gap(0));
- for (i=1; i<cols; i++) f.write_c(", %d", grid->col_gap(i));
- f.write_c(" };\n");
- f.write_c("%s%s->col_gap(colgaps, %d);\n", f.indent(), var, cols);
- }
-}
-
-void Fl_Grid_Type::write_code2(Fd_Code_Writer& f) {
- const char *var = name() ? name() : "o";
- Fl_Grid* grid = (Fl_Grid*)o;
- bool first_cell = true;
- for (int i=0; i<grid->children(); i++) {
- Fl_Widget *c = grid->child(i);
- Fl_Grid::Cell *cell = grid->cell(c);
- if (cell) {
- if (first_cell) {
- f.write_c("%sFl_Grid::Cell *cell = NULL;\n", f.indent());
- first_cell = false;
- }
- f.write_c("%scell = %s->widget(%s->child(%d), %d, %d, %d, %d, %d);\n",
- f.indent(), var, var, i, cell->row(), cell->col(),
- cell->rowspan(), cell->colspan(), cell->align());
- int min_w = 20, min_h = 20;
- cell->minimum_size(&min_w, &min_h);
- f.write_c("%sif (cell) cell->minimum_size(%d, %d);\n", f.indent(), min_w, min_h);
- }
- }
- super::write_code2(f);
-}
-
-void Fl_Grid_Type::add_child(Fl_Type* a, Fl_Type* b) {
- super::add_child(a, b);
- Fl_Grid* grid = (Fl_Grid*)o;
- grid->need_layout(1);
- grid->redraw();
-}
-
-void Fl_Grid_Type::move_child(Fl_Type* a, Fl_Type* b) {
- super::move_child(a, b);
- Fl_Grid* grid = (Fl_Grid*)o;
- grid->need_layout(1);
- grid->redraw();
-}
-
-void Fl_Grid_Type::remove_child(Fl_Type* a) {
- super::remove_child(a);
- Fl_Grid* grid = (Fl_Grid*)o;
- grid->need_layout(1);
- grid->redraw();
-}
-
-/** Update the initial size of a child widget.
- Fl_Grid keeps track of the size of children when they are first added. In
- FLUID, users will want to resize children. So we need to trick Fl_Grid into
- taking the new size as the initial size.
- */
-void Fl_Grid_Type::child_resized(Fl_Widget_Type *child_type) {
- Fl_Grid *grid = (Fl_Grid*)o;
- Fl_Widget *child = child_type->o;
- Fl_Grid::Cell *cell = grid->cell(child);
- if (cell && ((cell->align()&FL_GRID_VERTICAL)==0)) {
- int min_w = 0, min_h = 0;
- cell->minimum_size(&min_w, &min_h);
- cell->minimum_size(min_w, child->h());
- }
- if (cell && ((cell->align()&FL_GRID_HORIZONTAL)==0)) {
- int min_w = 0, min_h = 0;
- cell->minimum_size(&min_w, &min_h);
- cell->minimum_size(child->w(), min_h);
- }
- // TODO: if the user resizes an FL_GRID_FILL widget, should we change the alignment?
-}
-
-/** Return the currently selected Grid widget if is a Grid Type. */
-Fl_Grid *Fl_Grid_Type::selected() {
- if (current_widget && current_widget->is_a(ID_Grid))
- return ((Fl_Grid*)((Fl_Grid_Type*)current_widget)->o);
- return NULL;
-}
-
-/**
- Insert a child widget into the cell at the x, y position inside the window.
- /param[in] child
- /param[in] x, y pixels from the top left of the window
- */
-void Fl_Grid_Type::insert_child_at(Fl_Widget *child, int x, int y) {
- Fl_Grid_Proxy *grid = (Fl_Grid_Proxy*)o;
- int row = -1, col = -1, ml, mt, grg, gcg;
- grid->margin(&ml, &mt, NULL, NULL);
- grid->gap(&grg, &gcg);
- int x0 = grid->x() + Fl::box_dx(grid->box()) + ml;
- int y0 = grid->y() + Fl::box_dy(grid->box()) + mt;
-
- for (int r = 0; r < grid->rows(); r++) {
- if (y>y0) row = r;
- int gap = grid->row_gap(r)>=0 ? grid->row_gap(r) : grg;
- y0 += grid->computed_row_height(r);
- y0 += gap;
- }
-
- for (int c = 0; c < grid->cols(); c++) {
- if (x>x0) col = c;
- int gap = grid->col_gap(c)>=0 ? grid->col_gap(c) : gcg;
- x0 += grid->computed_col_width(c);
- x0 += gap;
- }
-
- grid->move_cell(child, row, col, 2);
-}
-
-/**
- Insert a child widget into the first new cell we can find .
-
- There are many other possible strategies. How about inserting to the right
- of the last added child. Also, what happens if the grid is full? Should
- we add a new row at the bottom?
-
- /param[in] child
- */
-void Fl_Grid_Type::insert_child_at_next_free_cell(Fl_Widget *child) {
- Fl_Grid_Proxy *grid = (Fl_Grid_Proxy*)o;
- if (grid->cell(child)) return;
-// The code below would insert the new widget after the last selected one, but
-// unfortunately the current_widget is already invalid.
-// if (current_widget && (current_widget->parent == this)) {
-// Fl_Grid::Cell *current_cell = grid->any_cell(current_widget->o);
-// if (current_cell) {
-// r = current_cell->row();
-// c = current_cell->col();
-// }
-// }
- for (int r = 0; r < grid->rows(); r++) {
- for (int c = 0; c < grid->cols(); c++) {
- if (!grid->cell(r, c)) {
- grid->move_cell(child, r, c);
- return;
- }
- }
- }
- grid->layout(grid->rows() + 1, grid->cols());
- grid->move_cell(child, grid->rows() - 1, 0);
-}
-
-/** Move cells around using the keyboard.
- \note this fails if we have two children selected side by side and press 'right',
- which will move the left child first, removing the right child from the
- cell system. When trying to move the second child, it has no longer an
- assigned row or column.
- \param[in] child pointer to the child type
- \param[in] key code of the last keypress when handling a FL_KEYBOARD event.
- */
-void Fl_Grid_Type::keyboard_move_child(Fl_Widget_Type *child, int key) {
- Fl_Grid_Proxy *grid = ((Fl_Grid_Proxy*)o);
- Fl_Grid::Cell *cell = grid->any_cell(child->o);
- if (!cell) return;
- if (key == FL_Right) {
- grid->move_cell(child->o, cell->row(), cell->col()+1, 2);
- } else if (key == FL_Left) {
- grid->move_cell(child->o, cell->row(), cell->col()-1, 2);
- } else if (key == FL_Up) {
- grid->move_cell(child->o, cell->row()-1, cell->col(), 2);
- } else if (key == FL_Down) {
- grid->move_cell(child->o, cell->row()+1, cell->col(), 2);
- }
-}
-
-void Fl_Grid_Type::layout_widget() {
- allow_layout++;
- ((Fl_Grid*)o)->layout();
- allow_layout--;
-}
-
-
-// ---- Widget Panel Callbacks ---------------------------------------- MARK: -
-
-// TODO: better grid overlay?
-// TODO: grid_child_cb should move all selected cells, not just the current_selected.
-// TODO: buttons to add and delete rows and columns in the widget dialog
-// TODO: ways to resize rows and columns, add and delete them in the project window, pulldown menu?
-// TODO: alignment can be FL_GRID_LEFT|FL_GRID_VERTICAL?
-
-extern Fluid_Coord_Input *widget_grid_row_input, *widget_grid_col_input,
-*widget_grid_rowspan_input, *widget_grid_colspan_input;
-extern Fl_Group *widget_tab_grid_child;
-
-void grid_child_cb(Fluid_Coord_Input* i, void* v, int what) {
- if ( !current_widget
- || !current_widget->parent
- || !current_widget->parent->is_a(ID_Grid))
- {
- return;
- }
- Fl_Widget *child = ((Fl_Widget_Type*)current_widget)->o;
- Fl_Grid_Proxy *g = ((Fl_Grid_Proxy*)((Fl_Widget_Type*)current_widget->parent)->o);
- Fl_Grid::Cell *cell = g->any_cell(child);
- if (v == LOAD) {
- int v = -1;
- if (cell) {
- switch (what & 0x00ff) {
- case 8: v = cell->row(); break;
- case 9: v = cell->col(); break;
- case 10: v = cell->rowspan(); break;
- case 11: v = cell->colspan(); break;
- case 12: cell->minimum_size(&v, NULL); break;
- case 13: cell->minimum_size(NULL, &v); break;
- }
- }
- i->value(v);
- } else {
- undo_checkpoint();
- int v2 = -2, old_v = -2, v = i->value();
- if (i==widget_grid_row_input) v2 = widget_grid_col_input->value();
- if (i==widget_grid_col_input) v2 = widget_grid_row_input->value();
- Fl_Grid::Cell *new_cell = NULL;
- if (cell) {
- switch (what & 0x00ff) {
- case 8: old_v = cell->row(); v2 = cell->col(); break;
- case 9: old_v = cell->col(); v2 = cell->row(); break;
- case 10: old_v = cell->rowspan(); break;
- case 11: old_v = cell->colspan(); break;
- case 12: cell->minimum_size(&old_v, &v2); break;
- case 13: cell->minimum_size(&v2, &old_v); break;
- }
- }
- switch (what & 0xff00) {
- case 0x0100: v--; break;
- case 0x0200: v++; break;
- }
- if (old_v != v) {
- switch (what & 0x00ff) {
- case 8:
- if (v2 == -1 && v >= 0) v2 = 0;
- g->move_cell(current_widget->o, v, v2, 2); i->value(v);
- break;
- case 9:
- if (v2 == -1 && v >= 0) v2 = 0;
- g->move_cell(current_widget->o, v2, v, 2); i->value(v);
- break;
- case 10: if (cell && cell->row()+v<=g->rows() && v>0) cell->rowspan(v);
- break;
- case 11: if (cell && cell->col()+v<=g->cols() && v>0) cell->colspan(v);
- break;
- case 12: if (cell && v>=0) cell->minimum_size(v, v2);
- break;
- case 13: if (cell && v>=0) cell->minimum_size(v2, v);
- break;
- }
- if (!cell && new_cell)
- new_cell->minimum_size(20, 20);
- g->need_layout(true);
- set_modflag(1);
- }
- }
-}
-void grid_set_row_cb(Fluid_Coord_Input* i, void* v) {
- grid_child_cb(i, v, 8);
- if (v!=LOAD) widget_tab_grid_child->do_callback(widget_tab_grid_child, LOAD);
-}
-void grid_dec_row_cb(Fl_Button* i, void* v) {
- if (v!=LOAD) {
- grid_child_cb(widget_grid_row_input, v, 0x0100 + 8);
- widget_tab_grid_child->do_callback(widget_tab_grid_child, LOAD);
- }
-}
-void grid_inc_row_cb(Fl_Button* i, void* v) {
- if (v!=LOAD) {
- grid_child_cb(widget_grid_row_input, v, 0x0200 + 8);
- widget_tab_grid_child->do_callback(widget_tab_grid_child, LOAD);
- }
-}
-void grid_set_col_cb(Fluid_Coord_Input* i, void* v) {
- grid_child_cb(i, v, 9);
- if (v!=LOAD) widget_tab_grid_child->do_callback(widget_tab_grid_child, LOAD);
-}
-void grid_dec_col_cb(Fl_Button* i, void* v) {
- if (v!=LOAD) {
- grid_child_cb(widget_grid_col_input, v, 0x0100 + 9);
- widget_tab_grid_child->do_callback(widget_tab_grid_child, LOAD);
- }
-}
-void grid_inc_col_cb(Fl_Button* i, void* v) {
- if (v!=LOAD) {
- grid_child_cb(widget_grid_col_input, v, 0x0200 + 9);
- widget_tab_grid_child->do_callback(widget_tab_grid_child, LOAD);
- }
-}
-void grid_set_rowspan_cb(Fluid_Coord_Input* i, void* v) {
- grid_child_cb(i, v, 10);
- if (v!=LOAD) widget_tab_grid_child->do_callback(widget_tab_grid_child, LOAD);
-}
-void grid_dec_rowspan_cb(Fl_Button* i, void* v) {
- if (v!=LOAD) {
- grid_child_cb(widget_grid_rowspan_input, v, 0x0100 + 10);
- widget_tab_grid_child->do_callback(widget_tab_grid_child, LOAD);
- }
-}
-void grid_inc_rowspan_cb(Fl_Button* i, void* v) {
- if (v!=LOAD) {
- grid_child_cb(widget_grid_rowspan_input, v, 0x0200 + 10);
- widget_tab_grid_child->do_callback(widget_tab_grid_child, LOAD);
- }
-}
-void grid_set_colspan_cb(Fluid_Coord_Input* i, void* v) {
- grid_child_cb(i, v, 11);
- if (v!=LOAD) widget_tab_grid_child->do_callback(widget_tab_grid_child, LOAD);
-}
-void grid_dec_colspan_cb(Fl_Button* i, void* v) {
- if (v!=LOAD) {
- grid_child_cb(widget_grid_colspan_input, v, 0x0100 + 11);
- widget_tab_grid_child->do_callback(widget_tab_grid_child, LOAD);
- }
-}
-void grid_inc_colspan_cb(Fl_Button* i, void* v) {
- if (v!=LOAD) {
- grid_child_cb(widget_grid_colspan_input, v, 0x0200 + 11);
- widget_tab_grid_child->do_callback(widget_tab_grid_child, LOAD);
- }
-}
-void grid_set_min_wdt_cb(Fluid_Coord_Input* i, void* v) {
- grid_child_cb(i, v, 12);
-}
-void grid_set_min_hgt_cb(Fluid_Coord_Input* i, void* v) {
- grid_child_cb(i, v, 13);
-}
-
-void grid_align_horizontal_cb(Fl_Choice* i, void* v) {
- if ( !current_widget
- || !current_widget->parent
- || !current_widget->parent->is_a(ID_Grid))
- {
- return;
- }
- int mask = (FL_GRID_LEFT | FL_GRID_RIGHT | FL_GRID_HORIZONTAL);
- Fl_Grid *g = ((Fl_Grid*)((Fl_Widget_Type*)current_widget->parent)->o);
- if (v == LOAD) {
- int a = FL_GRID_FILL & mask;
- Fl_Grid::Cell *cell = g->cell(current_widget->o);
- if (cell) {
- a = cell->align() & mask;
- }
- const Fl_Menu_Item *mi = i->find_item_with_argument(a);
- if (mi) i->value(mi);
- } else {
- undo_checkpoint();
- int v = FL_GRID_FILL & mask, old_v = FL_GRID_FILL & mask;
- const Fl_Menu_Item *mi = i->mvalue();
- if (mi) v = (int)mi->argument();
- Fl_Grid::Cell *cell = g->cell(current_widget->o);
- if (cell) {
- old_v = cell->align() & mask;
- if (old_v != v) {
- cell->align((Fl_Grid_Align)(v | (cell->align() & ~mask)));
- g->need_layout(true);
- g->redraw();
- set_modflag(1);
- }
- }
- }
-}
-
-void grid_align_vertical_cb(Fl_Choice* i, void* v) {
- if ( !current_widget
- || !current_widget->parent
- || !current_widget->parent->is_a(ID_Grid))
- {
- return;
- }
- int mask = (FL_GRID_TOP | FL_GRID_BOTTOM | FL_GRID_VERTICAL);
- Fl_Grid *g = ((Fl_Grid*)((Fl_Widget_Type*)current_widget->parent)->o);
- if (v == LOAD) {
- int a = FL_GRID_FILL & mask;
- Fl_Grid::Cell *cell = g->cell(current_widget->o);
- if (cell) {
- a = cell->align() & mask;
- }
- const Fl_Menu_Item *mi = i->find_item_with_argument(a);
- if (mi) i->value(mi);
- } else {
- undo_checkpoint();
- int v = FL_GRID_FILL & mask, old_v = FL_GRID_FILL & mask;
- const Fl_Menu_Item *mi = i->mvalue();
- if (mi) v = (int)mi->argument();
- Fl_Grid::Cell *cell = g->cell(current_widget->o);
- if (cell) {
- old_v = cell->align() & mask;
- if (old_v != v) {
- cell->align((Fl_Grid_Align)(v | (cell->align() & ~mask)));
- g->need_layout(true);
- g->redraw();
- set_modflag(1);
- }
- }
- }
-}
-