initial release
[skippy-xd] / layout.c
1 /* Skippy - Seduces Kids Into Perversion
2  *
3  * Copyright (C) 2004 Hyriand <hyriand@thegraveyard.org>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19
20 #include "skippy.h"
21
22 void
23 layout_run(MainWin *mw, dlist *windows, unsigned int *total_width, unsigned int *total_height)
24 {
25         int sum_w = 0, max_h = 0, max_w = 0, max_row_w = 0;
26         int row_y = 0, y = 0, x = 0, row_h = 0;
27         
28         dlist *iter, *slots = 0, *slot_iter, *rows;
29         
30         rows = dlist_add(0, 0);
31         
32         windows = dlist_first(windows);
33         *total_width = *total_height = 0;
34         
35         for(iter = windows; iter; iter = iter->next)
36         {
37                 ClientWin *cw = (ClientWin *)iter->data;
38                 sum_w += cw->client.width;
39                 max_w = MAX(max_w, cw->client.width);
40                 max_h = MAX(max_h, cw->client.height);
41         }
42         
43         for(iter = windows; iter; iter = iter->next)
44         {
45                 ClientWin *cw = (ClientWin*)iter->data;
46                 dlist *slot_iter = dlist_first(slots);
47                 for(; slot_iter; slot_iter = slot_iter->next)
48                 {
49                         dlist *slot = (dlist *)slot_iter->data;
50                         int slot_h = -mw->distance;
51                         REDUCE(slot_h = slot_h + ((ClientWin*)iter->data)->client.height + mw->distance, slot);
52                         if(slot_h + mw->distance + cw->client.height < max_h)
53                         {
54                                 slot_iter->data = dlist_add(slot, cw);
55                                 break;
56                         }
57                 }
58                 if(! slot_iter)
59                         slots = dlist_add(slots, dlist_add(0, cw));
60         }
61         
62         max_row_w = sqrt(sum_w * max_h);
63         for(slot_iter = dlist_first(slots); slot_iter; slot_iter = slot_iter->next)
64         {
65                 dlist *slot = (dlist *)slot_iter->data;
66                 int slot_w = 0;
67                 REDUCE(slot_w = MAX(slot_w, ((ClientWin*)iter->data)->client.width), slot);
68                 y = row_y;
69                 for(iter = dlist_first(slot); iter; iter = iter->next)
70                 {
71                         ClientWin *cw = (ClientWin *)iter->data;
72                         cw->x = x + (slot_w - cw->client.width) / 2;
73                         cw->y = y;
74                         y += cw->client.height + mw->distance;
75                         rows->data = dlist_add((dlist *)rows->data, cw);
76                 }
77                 row_h = MAX(row_h, y - row_y);
78                 *total_height = MAX(*total_height, y);
79                 x += slot_w + mw->distance;
80                 *total_width = MAX(*total_width, x);
81                 if(x > max_row_w)
82                 {
83                         x = 0;
84                         row_y += row_h;
85                         row_h = 0;
86                         rows = dlist_add(rows, 0);
87                 }
88                 dlist_free(slot);
89         }
90         dlist_free(slots);
91         
92         *total_width -= mw->distance;
93         *total_height -= mw->distance;
94         
95         for(iter = dlist_first(rows); iter; iter = iter->next)
96         {
97                 dlist *row = (dlist *)iter->data;
98                 int row_w = 0, xoff;
99                 REDUCE(row_w = MAX(row_w, ((ClientWin*)iter->data)->x + ((ClientWin*)iter->data)->client.width), row);
100                 xoff = (*total_width - row_w) / 2;
101                 REDUCE(((ClientWin*)iter->data)->x += xoff, row);
102                 dlist_free(row);
103         }
104         
105         dlist_free(rows);
106 }