protected override void DoSync()
        {
            if (!AllowPlaceholders)
            {
                return;
            }
            using (UndoManager.AtomicChange)
            {
                uint       left, right, top, bottom;
                uint       row, col;
                Gtk.Widget w;
                Gtk.Widget[,] grid;
                Gtk.Table.TableChild tc;
                Gtk.Widget[]         children;
                bool addedPlaceholders = false;

                children = table.Children;
                grid     = new Gtk.Widget[NRows, NColumns];

                // First fill in the placeholders in the grid. If we find any
                // placeholders covering more than one grid square, remove them.
                // (New ones will be created below.)
                foreach (Gtk.Widget child in children)
                {
                    if (!(child is Placeholder))
                    {
                        continue;
                    }

                    tc     = table[child] as Gtk.Table.TableChild;
                    left   = tc.LeftAttach;
                    right  = tc.RightAttach;
                    top    = tc.TopAttach;
                    bottom = tc.BottomAttach;

                    if (right == left + 1 && bottom == top + 1)
                    {
                        grid[top, left] = child;
                    }
                    else
                    {
                        table.Remove(child);
                        child.Destroy();
                    }
                }

                // Now fill in the real widgets, knocking out any placeholders
                // they overlap. (If there are real widgets that overlap
                // placeholders, neither will be knocked out, and the layout
                // will probably end up wrong as well. But this situation
                // happens at least temporarily during glade import.)
                foreach (Gtk.Widget child in children)
                {
                    if (child is Placeholder)
                    {
                        continue;
                    }

                    tc     = table[child] as Gtk.Table.TableChild;
                    left   = tc.LeftAttach;
                    right  = tc.RightAttach;
                    top    = tc.TopAttach;
                    bottom = tc.BottomAttach;

                    for (row = top; row < bottom; row++)
                    {
                        for (col = left; col < right; col++)
                        {
                            w = grid[row, col];
                            if (w is Placeholder)
                            {
                                table.Remove(w);
                                w.Destroy();
                            }
                            grid[row, col] = child;
                        }
                    }
                }

                // Scan each row; if there are any empty cells, fill them in
                // with placeholders. If a row contains only placeholders, then
                // set them all to expand vertically so the row won't collapse.
                // OTOH, if the row contains any real widget, set any placeholders
                // in that row to not expand vertically, so they don't force the
                // real widgets to expand further than they should. If any row
                // is vertically expandable, then the table as a whole is.
                vexpandable = false;
                for (row = 0; row < NRows; row++)
                {
                    bool allPlaceholders = true;

                    for (col = 0; col < NColumns; col++)
                    {
                        w = grid[row, col];
                        if (w == null)
                        {
                            w = CreatePlaceholder();
                            table.Attach(w, col, col + 1, row, row + 1);
                            NotifyChildAdded(w);
                            grid[row, col]    = w;
                            addedPlaceholders = true;
                        }
                        else if (!ChildVExpandable(w) || !AutoSize[w])
                        {
                            allPlaceholders = false;
                        }
                    }

                    for (col = 0; col < NColumns; col++)
                    {
                        w = grid[row, col];
                        if (!AutoSize[w])
                        {
                            continue;
                        }
                        tc = table[w] as Gtk.Table.TableChild;
                        // We can't play with the vertical expansion property of
                        // widgets which span more than one row
                        if (tc.BottomAttach != tc.TopAttach + 1)
                        {
                            continue;
                        }
                        Gtk.AttachOptions opts = allPlaceholders ? expandOpts : fillOpts;
                        if (tc.YOptions != opts)
                        {
                            tc.YOptions = opts;
                        }
                    }

                    if (allPlaceholders)
                    {
                        vexpandable = true;
                    }
                }

                // Now do the same for columns and horizontal expansion (but we
                // don't have to worry about empty cells this time).
                hexpandable = false;
                for (col = 0; col < NColumns; col++)
                {
                    bool allPlaceholders = true;

                    for (row = 0; row < NRows; row++)
                    {
                        w = grid[row, col];
                        if (!ChildHExpandable(w) || !AutoSize[w])
                        {
                            allPlaceholders = false;
                            break;
                        }
                    }

                    for (row = 0; row < NRows; row++)
                    {
                        w = grid[row, col];
                        if (!AutoSize[w])
                        {
                            continue;
                        }
                        tc = table[w] as Gtk.Table.TableChild;
                        // We can't play with the horizontal expansion property of
                        // widgets which span more than one column
                        if (tc.RightAttach != tc.LeftAttach + 1)
                        {
                            continue;
                        }
                        Gtk.AttachOptions opts = allPlaceholders ? expandOpts : fillOpts;
                        if (tc.XOptions != opts)
                        {
                            tc.XOptions = opts;
                        }
                    }

                    if (allPlaceholders)
                    {
                        hexpandable = true;
                    }
                }

                if (addedPlaceholders)
                {
                    EmitContentsChanged();
                }
            }
        }
示例#2
0
 public void Attach(Gtk.Widget child, uint left_attach, uint right_attach, uint top_attach, uint bottom_attach, Gtk.AttachOptions xoptions, Gtk.AttachOptions yoptions, uint xpadding, uint ypadding)
 {
     gtk_table_attach(Handle, child == null ? IntPtr.Zero : child.Handle, left_attach, right_attach, top_attach, bottom_attach, (int)xoptions, (int)yoptions, xpadding, ypadding);
 }