comparison win/dw.c @ 1438:bde7ebced556

Initial layout engine 2.0 for Windows and OS/2...Plus some updates for the Mac code... Improved auto-window sizing on Windows and added OS/2 and Mac support.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Thu, 08 Dec 2011 09:30:32 +0000
parents 18c1b999dd65
children c50f445e891a
comparison
equal deleted inserted replaced
1437:a50e8b486a1a 1438:bde7ebced556
1124 } 1124 }
1125 1125
1126 /* This function calculates how much space the widgets and boxes require 1126 /* This function calculates how much space the widgets and boxes require
1127 * and does expansion as necessary. 1127 * and does expansion as necessary.
1128 */ 1128 */
1129 int _resize_box(Box *thisbox, int *depth, int x, int y, int *usedx, int *usedy, 1129 static void _resize_box(Box *thisbox, int *depth, int x, int y, int pass)
1130 int pass, int *usedpadx, int *usedpady) 1130 {
1131 { 1131 /* Current item position */
1132 int z, currentx = 0, currenty = 0; 1132 int z, currentx = thisbox->pad, currenty = thisbox->pad;
1133 /* Used x, y and padding maximum values...
1134 * These will be used to find the widest or
1135 * tallest items in a box.
1136 */
1133 int uymax = 0, uxmax = 0; 1137 int uymax = 0, uxmax = 0;
1134 int upymax = 0, upxmax = 0; 1138 int upymax = 0, upxmax = 0;
1135 /* Used for the SIZEEXPAND */ 1139
1136 int nux = *usedx, nuy = *usedy; 1140 /* Reset the box sizes */
1137 int nupx = *usedpadx, nupy = *usedpady; 1141 thisbox->minwidth = thisbox->minheight = thisbox->usedpadx = thisbox->usedpady = thisbox->pad * 2;
1138
1139 (*usedx) += (thisbox->pad * 2);
1140 (*usedy) += (thisbox->pad * 2);
1141 1142
1142 if(thisbox->grouphwnd) 1143 if(thisbox->grouphwnd)
1143 { 1144 {
1144 char *text = dw_window_get_text(thisbox->grouphwnd); 1145 char *text = dw_window_get_text(thisbox->grouphwnd);
1145 1146
1162 else 1163 else
1163 thisbox->grouppady = 6; 1164 thisbox->grouppady = 6;
1164 1165
1165 thisbox->grouppadx = 6; 1166 thisbox->grouppadx = 6;
1166 1167
1167 (*usedx) += thisbox->grouppadx; 1168 thisbox->minwidth += thisbox->grouppadx;
1168 (*usedpadx) += thisbox->grouppadx; 1169 thisbox->usedpadx += thisbox->grouppadx;
1169 (*usedy) += thisbox->grouppady; 1170 thisbox->minheight += thisbox->grouppady;
1170 (*usedpady) += thisbox->grouppady; 1171 thisbox->usedpady += thisbox->grouppady;
1171 } 1172 }
1172 1173
1174 /* Count up all the space for all items in the box */
1173 for(z=0;z<thisbox->count;z++) 1175 for(z=0;z<thisbox->count;z++)
1174 { 1176 {
1177 int itempad, itemwidth, itemheight;
1178
1175 if(thisbox->items[z].type == TYPEBOX) 1179 if(thisbox->items[z].type == TYPEBOX)
1176 { 1180 {
1177 int initialx, initialy;
1178 Box *tmp = (Box *)GetWindowLongPtr(thisbox->items[z].hwnd, GWLP_USERDATA); 1181 Box *tmp = (Box *)GetWindowLongPtr(thisbox->items[z].hwnd, GWLP_USERDATA);
1179
1180 initialx = x - (*usedx);
1181 initialy = y - (*usedy);
1182 1182
1183 if(tmp) 1183 if(tmp)
1184 { 1184 {
1185 int newx, newy; 1185 /* On the first pass calculate the box contents */
1186 int nux = *usedx, nuy = *usedy; 1186 if(pass == 1)
1187 int upx = *usedpadx + (tmp->pad*2), upy = *usedpady + (tmp->pad*2);
1188
1189 /* On the second pass we know how big the box needs to be and how
1190 * much space we have, so we can calculate a ratio for the new box.
1191 */
1192 if(pass == 2)
1193 { 1187 {
1194 int deep = *depth + 1; 1188 (*depth)++;
1195 1189
1196 _resize_box(tmp, &deep, x, y, &nux, &nuy, 1, &upx, &upy); 1190 /* Save the newly calculated values on the box */
1197 1191 _resize_box(tmp, depth, x, y, pass);
1198 tmp->upx = upx - *usedpadx; 1192
1199 tmp->upy = upy - *usedpady; 1193 /* Duplicate the values in the item list for use below */
1200 1194 thisbox->items[z].width = tmp->minwidth;
1201 newx = x - nux; 1195 thisbox->items[z].height = tmp->minheight;
1202 newy = y - nuy; 1196
1203 1197 (*depth)--;
1204 tmp->width = thisbox->items[z].width = initialx - newx;
1205 tmp->height = thisbox->items[z].height = initialy - newy;
1206
1207 tmp->parentxratio = thisbox->xratio;
1208 tmp->parentyratio = thisbox->yratio;
1209
1210 tmp->parentpad = tmp->pad;
1211 tmp->hsize = thisbox->items[z].hsize;
1212 tmp->vsize = thisbox->items[z].vsize;
1213
1214 /* Just in case */
1215 tmp->xratio = thisbox->xratio;
1216 tmp->yratio = thisbox->yratio;
1217
1218 if(thisbox->type == DW_VERT)
1219 {
1220 int tmppad = (thisbox->items[z].pad*2)+(tmp->pad*2)+tmp->grouppady;
1221
1222 if((thisbox->items[z].width - tmppad)!=0)
1223 tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-tmppad))/((float)(thisbox->items[z].width-tmppad));
1224 }
1225 else
1226 {
1227 if((thisbox->items[z].width-tmp->upx)!=0)
1228 tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-tmp->upx))/((float)(thisbox->items[z].width-tmp->upx));
1229 }
1230 if(thisbox->type == DW_HORZ)
1231 {
1232 int tmppad = (thisbox->items[z].pad*2)+(tmp->pad*2)+tmp->grouppadx;
1233
1234 if((thisbox->items[z].height-tmppad)!=0)
1235 tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-tmppad))/((float)(thisbox->items[z].height-tmppad));
1236 }
1237 else
1238 {
1239 if((thisbox->items[z].height-tmp->upy)!=0)
1240 tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-tmp->upy))/((float)(thisbox->items[z].height-tmp->upy));
1241 }
1242
1243 nux = *usedx; nuy = *usedy;
1244 upx = *usedpadx + (tmp->pad*2); upy = *usedpady + (tmp->pad*2);
1245 }
1246
1247 (*depth)++;
1248
1249 _resize_box(tmp, depth, x, y, &nux, &nuy, pass, &upx, &upy);
1250
1251 (*depth)--;
1252
1253 newx = x - nux;
1254 newy = y - nuy;
1255
1256 tmp->minwidth = thisbox->items[z].width = initialx - newx;
1257 tmp->minheight = thisbox->items[z].height = initialy - newy;
1258 }
1259 }
1260
1261 if(pass > 1 && *depth > 0)
1262 {
1263 if(thisbox->type == DW_VERT)
1264 {
1265 int tmppad = (thisbox->items[z].pad*2)+(thisbox->parentpad*2)+thisbox->grouppadx;
1266
1267 if((thisbox->minwidth-tmppad) == 0)
1268 thisbox->items[z].xratio = 1.0;
1269 else
1270 thisbox->items[z].xratio = ((float)((thisbox->width * thisbox->parentxratio)-tmppad))/((float)(thisbox->minwidth-tmppad));
1271 }
1272 else
1273 {
1274 if(thisbox->minwidth-thisbox->upx == 0)
1275 thisbox->items[z].xratio = 1.0;
1276 else
1277 thisbox->items[z].xratio = ((float)((thisbox->width * thisbox->parentxratio)-thisbox->upx))/((float)(thisbox->minwidth-thisbox->upx));
1278 }
1279
1280 if(thisbox->type == DW_HORZ)
1281 {
1282 int tmppad = (thisbox->items[z].pad*2)+(thisbox->parentpad*2)+thisbox->grouppady;
1283
1284 if((thisbox->minheight-tmppad) == 0)
1285 thisbox->items[z].yratio = 1.0;
1286 else
1287 thisbox->items[z].yratio = ((float)((thisbox->height * thisbox->parentyratio)-tmppad))/((float)(thisbox->minheight-tmppad));
1288 }
1289 else
1290 {
1291 if(thisbox->minheight-thisbox->upy == 0)
1292 thisbox->items[z].yratio = 1.0;
1293 else
1294 thisbox->items[z].yratio = ((float)((thisbox->height * thisbox->parentyratio)-thisbox->upy))/((float)(thisbox->minheight-thisbox->upy));
1295 }
1296
1297 if(thisbox->items[z].type == TYPEBOX)
1298 {
1299 Box *tmp = (Box *)GetWindowLongPtr(thisbox->items[z].hwnd, GWLP_USERDATA);
1300
1301 if(tmp)
1302 {
1303 tmp->parentxratio = thisbox->items[z].xratio;
1304 tmp->parentyratio = thisbox->items[z].yratio;
1305 } 1198 }
1306 } 1199 }
1307 } 1200 }
1308 else 1201
1309 { 1202 /* Precalculate these values, since they will
1310 thisbox->items[z].xratio = thisbox->xratio; 1203 * be used used repeatedly in the next section.
1311 thisbox->items[z].yratio = thisbox->yratio; 1204 */
1312 } 1205 itempad = thisbox->items[z].pad * 2;
1313 1206 itemwidth = thisbox->items[z].width + itempad;
1207 itemheight = thisbox->items[z].height + itempad;
1208
1209 /* Calculate the totals and maximums */
1314 if(thisbox->type == DW_VERT) 1210 if(thisbox->type == DW_VERT)
1315 { 1211 {
1316 int itemwidth = (thisbox->items[z].pad*2) + thisbox->items[z].width;
1317
1318 if(itemwidth > uxmax) 1212 if(itemwidth > uxmax)
1319 uxmax = itemwidth; 1213 uxmax = itemwidth;
1214
1320 if(thisbox->items[z].hsize != SIZEEXPAND) 1215 if(thisbox->items[z].hsize != SIZEEXPAND)
1321 { 1216 {
1322 if(itemwidth > upxmax) 1217 if(itemwidth > upxmax)
1323 upxmax = itemwidth; 1218 upxmax = itemwidth;
1324 } 1219 }
1325 else 1220 else
1326 { 1221 {
1327 if(thisbox->items[z].pad*2 > upxmax) 1222 if(itempad > upxmax)
1328 upxmax = thisbox->items[z].pad*2; 1223 upxmax = itempad;
1329 } 1224 }
1225 thisbox->minheight += itemheight;
1226 if(thisbox->items[z].vsize != SIZEEXPAND)
1227 thisbox->usedpady += itemheight;
1228 else
1229 thisbox->usedpady += itempad;
1330 } 1230 }
1331 else 1231 else
1332 { 1232 {
1333 (*usedx) += thisbox->items[z].width + (thisbox->items[z].pad*2);
1334 if(thisbox->items[z].hsize != SIZEEXPAND)
1335 (*usedpadx) += (thisbox->items[z].pad*2) + thisbox->items[z].width;
1336 else
1337 (*usedpadx) += thisbox->items[z].pad*2;
1338 }
1339 if(thisbox->type == DW_HORZ)
1340 {
1341 int itemheight = (thisbox->items[z].pad*2) + thisbox->items[z].height;
1342
1343 if(itemheight > uymax) 1233 if(itemheight > uymax)
1344 uymax = itemheight; 1234 uymax = itemheight;
1345 if(thisbox->items[z].vsize != SIZEEXPAND) 1235 if(thisbox->items[z].vsize != SIZEEXPAND)
1346 { 1236 {
1347 if(itemheight > upymax) 1237 if(itemheight > upymax)
1348 upymax = itemheight; 1238 upymax = itemheight;
1349 } 1239 }
1350 else 1240 else
1351 { 1241 {
1352 if(thisbox->items[z].pad*2 > upymax) 1242 if(itempad > upymax)
1353 upymax = thisbox->items[z].pad*2; 1243 upymax = itempad;
1354 } 1244 }
1355 } 1245 thisbox->minwidth += itemwidth;
1356 else 1246 if(thisbox->items[z].hsize != SIZEEXPAND)
1357 { 1247 thisbox->usedpadx += itemwidth;
1358 (*usedy) += thisbox->items[z].height + (thisbox->items[z].pad*2);
1359 if(thisbox->items[z].vsize != SIZEEXPAND)
1360 (*usedpady) += (thisbox->items[z].pad*2) + thisbox->items[z].height;
1361 else 1248 else
1362 (*usedpady) += thisbox->items[z].pad*2; 1249 thisbox->usedpadx += itempad;
1363 } 1250 }
1364 } 1251 }
1365 1252
1366 (*usedx) += uxmax; 1253 /* Add the maximums which were calculated in the previous loop */
1367 (*usedy) += uymax; 1254 thisbox->minwidth += uxmax;
1368 (*usedpadx) += upxmax; 1255 thisbox->minheight += uymax;
1369 (*usedpady) += upymax; 1256 thisbox->usedpadx += upxmax;
1370 1257 thisbox->usedpady += upymax;
1371 currentx += thisbox->pad; 1258
1372 currenty += thisbox->pad; 1259 /* Move the groupbox start past the group border */
1373
1374 if(thisbox->grouphwnd) 1260 if(thisbox->grouphwnd)
1375 { 1261 {
1376 currentx += 3; 1262 currentx += 3;
1377 currenty += thisbox->grouppady - 3; 1263 currenty += thisbox->grouppady - 3;
1378 } 1264 }
1379 1265
1380 /* The second pass is for expansion and actual placement. */ 1266 /* The second pass is for actual placement. */
1381 if(pass > 1) 1267 if(pass > 1)
1382 { 1268 {
1383 /* Any SIZEEXPAND items should be set to uxmax/uymax */
1384 for(z=0;z<thisbox->count;z++)
1385 {
1386 if(thisbox->items[z].hsize == SIZEEXPAND && thisbox->type == DW_VERT)
1387 thisbox->items[z].width = uxmax-(thisbox->items[z].pad*2);
1388 if(thisbox->items[z].vsize == SIZEEXPAND && thisbox->type == DW_HORZ)
1389 thisbox->items[z].height = uymax-(thisbox->items[z].pad*2);
1390 /* Run this code segment again to finalize the sized after setting uxmax/uymax values. */
1391 if(thisbox->items[z].type == TYPEBOX)
1392 {
1393 Box *tmp = (Box *)GetWindowLongPtr(thisbox->items[z].hwnd, GWLP_USERDATA);
1394
1395 if(tmp)
1396 {
1397 if(*depth > 0)
1398 {
1399 float calcval;
1400
1401 if(thisbox->type == DW_VERT)
1402 {
1403 calcval = (float)(tmp->minwidth-((thisbox->items[z].pad*2)+(thisbox->pad*2)));
1404 if(calcval == 0.0)
1405 tmp->xratio = thisbox->xratio;
1406 else
1407 tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-((thisbox->items[z].pad*2)+(thisbox->pad*2))))/calcval;
1408 tmp->width = thisbox->items[z].width;
1409 }
1410 if(thisbox->type == DW_HORZ)
1411 {
1412 calcval = (float)(tmp->minheight-((thisbox->items[z].pad*2)+(thisbox->pad*2)));
1413 if(calcval == 0.0)
1414 tmp->yratio = thisbox->yratio;
1415 else
1416 tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-((thisbox->items[z].pad*2)+(thisbox->pad*2))))/calcval;
1417 tmp->height = thisbox->items[z].height;
1418 }
1419 }
1420
1421 (*depth)++;
1422
1423 _resize_box(tmp, depth, x, y, &nux, &nuy, 3, &nupx, &nupy);
1424
1425 (*depth)--;
1426
1427 }
1428 }
1429 }
1430
1431 for(z=0;z<(thisbox->count);z++) 1269 for(z=0;z<(thisbox->count);z++)
1432 { 1270 {
1433 int height = thisbox->items[z].height; 1271 int height = thisbox->items[z].height;
1434 int width = thisbox->items[z].width; 1272 int width = thisbox->items[z].width;
1435 int pad = thisbox->items[z].pad; 1273 int itempad = thisbox->items[z].pad * 2;
1436 HWND handle = thisbox->items[z].hwnd; 1274 int thispad = thisbox->pad * 2;
1437 int vectorx, vectory; 1275
1438 1276 /* Calculate the new sizes */
1439 /* When upxmax != pad*2 then ratios are incorrect. */ 1277 if(thisbox->items[z].hsize == SIZEEXPAND)
1440 vectorx = (int)((width*thisbox->items[z].xratio)-width); 1278 {
1441 vectory = (int)((height*thisbox->items[z].yratio)-height); 1279 if(thisbox->type == DW_HORZ)
1442 1280 {
1281 int expandablex = thisbox->minwidth - thisbox->usedpadx;
1282
1283 if(expandablex)
1284 width = (int)(((float)width / (float)expandablex) * (float)(x - thisbox->usedpadx));
1285 }
1286 else
1287 width = x - (itempad + thispad + thisbox->grouppadx);
1288 }
1289 if(thisbox->items[z].vsize == SIZEEXPAND)
1290 {
1291 if(thisbox->type == DW_VERT)
1292 {
1293 int expandabley = thisbox->minheight - thisbox->usedpady;
1294
1295 if(expandabley)
1296 height = (int)(((float)height / (float)expandabley) * (float)(y - thisbox->usedpady));
1297 }
1298 else
1299 height = y - (itempad + thispad + thisbox->grouppady);
1300 }
1301
1302 if(width < 1 || height < 1)
1303 {
1304 char tmpbuf[100];
1305
1306 GetClassName(thisbox->items[z].hwnd, tmpbuf, 99);
1307 dw_debug("Class %s %dx%d width %d height %d\n", tmpbuf, currentx + thisbox->items[z].pad, currenty + thisbox->items[z].pad, width, height);
1308 }
1309
1310 /* If the calculated size is valid... */
1443 if(width > 0 && height > 0) 1311 if(width > 0 && height > 0)
1444 { 1312 {
1313 int pad = thisbox->items[z].pad;
1314 HWND handle = thisbox->items[z].hwnd;
1445 char tmpbuf[100]; 1315 char tmpbuf[100];
1446 /* This is a hack to fix rounding of the sizing */
1447 if(*depth == 0)
1448 {
1449 vectorx++;
1450 vectory++;
1451 }
1452
1453 /* If this item isn't going to expand... reset the vectors to 0 */
1454 if(thisbox->items[z].vsize != SIZEEXPAND)
1455 vectory = 0;
1456 if(thisbox->items[z].hsize != SIZEEXPAND)
1457 vectorx = 0;
1458
1459 if(thisbox->type == DW_VERT && thisbox->hsize == SIZESTATIC && thisbox->items[z].hsize == SIZEEXPAND && thisbox->width)
1460 {
1461 width = thisbox->width;
1462 vectorx = 0;
1463 }
1464 if(thisbox->type == DW_HORZ && thisbox->vsize == SIZESTATIC && thisbox->items[z].vsize == SIZEEXPAND && thisbox->height)
1465 {
1466 height = thisbox->height;
1467 vectory = 0;
1468 }
1469 1316
1470 GetClassName(handle, tmpbuf, 99); 1317 GetClassName(handle, tmpbuf, 99);
1318 dw_debug("Class %s %dx%d width %d height %d\n", tmpbuf, currentx + pad, currenty + pad, width, height);
1471 1319
1472 if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0) 1320 if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
1473 { 1321 {
1474 /* Handle special case Combobox */ 1322 /* Handle special case Combobox */
1475 MoveWindow(handle, currentx + pad, currenty + pad, 1323 MoveWindow(handle, currentx + pad, currenty + pad,
1476 width + vectorx, (height + vectory) + 400, FALSE); 1324 width, height + 400, FALSE);
1477 } 1325 }
1478 else if(strnicmp(tmpbuf, UPDOWN_CLASS, strlen(UPDOWN_CLASS)+1)==0) 1326 else if(strnicmp(tmpbuf, UPDOWN_CLASS, strlen(UPDOWN_CLASS)+1)==0)
1479 { 1327 {
1480 /* Handle special case Spinbutton */ 1328 /* Handle special case Spinbutton */
1481 ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA); 1329 ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
1482 1330
1483 MoveWindow(handle, currentx + pad + ((width + vectorx) - 20), currenty + pad, 1331 MoveWindow(handle, currentx + pad + (width - 20), currenty + pad,
1484 20, height + vectory, FALSE); 1332 20, height, FALSE);
1485 1333
1486 if(cinfo) 1334 if(cinfo)
1487 { 1335 {
1488 MoveWindow(cinfo->buddy, currentx + pad, currenty + pad, 1336 MoveWindow(cinfo->buddy, currentx + pad, currenty + pad,
1489 (width + vectorx) - 20, height + vectory, FALSE); 1337 width - 20, height, FALSE);
1490 } 1338 }
1491 } 1339 }
1492 else if(strncmp(tmpbuf, ScrollClassName, strlen(ScrollClassName)+1)==0) 1340 else if(strncmp(tmpbuf, ScrollClassName, strlen(ScrollClassName)+1)==0)
1493 { 1341 {
1494 /* Handle special case of scrollbox */ 1342 /* Handle special case of scrollbox */
1495 ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA); 1343 ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
1496 int cx = width + vectorx; 1344 int cx, cy, depth = 0;
1497 int cy = height + vectory;
1498 int usedx = 0, usedy = 0, usedpadx = 0, usedpady = 0, depth = 0;
1499 Box *thisbox = (Box *)GetWindowLongPtr(cinfo->combo, GWLP_USERDATA); 1345 Box *thisbox = (Box *)GetWindowLongPtr(cinfo->combo, GWLP_USERDATA);
1500 SCROLLINFO hsi, vsi; 1346 SCROLLINFO hsi, vsi;
1501 RECT rect; 1347 RECT rect;
1502 1348
1503 vsi.cbSize = hsi.cbSize = sizeof(SCROLLINFO); 1349 vsi.cbSize = hsi.cbSize = sizeof(SCROLLINFO);
1506 /* Save the current scroll positions */ 1352 /* Save the current scroll positions */
1507 GetScrollInfo(handle, SB_HORZ, &hsi); 1353 GetScrollInfo(handle, SB_HORZ, &hsi);
1508 GetScrollInfo(handle, SB_VERT, &vsi); 1354 GetScrollInfo(handle, SB_VERT, &vsi);
1509 1355
1510 /* Position the scrollbox */ 1356 /* Position the scrollbox */
1511 MoveWindow(handle, currentx + pad, currenty + pad, cx, cy, FALSE); 1357 MoveWindow(handle, currentx + pad, currenty + pad, width, height, FALSE);
1512 1358
1513 GetClientRect(handle, &rect); 1359 GetClientRect(handle, &rect);
1514 cx = rect.right; 1360 cx = rect.right;
1515 cy = rect.bottom; 1361 cy = rect.bottom;
1516 1362
1517 1363
1518 /* Get the required space for the box */ 1364 /* Get the required space for the box */
1519 _resize_box(thisbox, &depth, cx, cy, &usedx, &usedy, 1, &usedpadx, &usedpady); 1365 _resize_box(thisbox, &depth, cx, cy, 1);
1520 1366
1521 if(cx < usedx) 1367 if(cx < thisbox->minwidth)
1522 { 1368 {
1523 cx = usedx; 1369 cx = thisbox->minwidth;
1524 } 1370 }
1525 if(cy < usedy) 1371 if(cy < thisbox->minheight)
1526 { 1372 {
1527 cy = usedy; 1373 cy = thisbox->minheight;
1528 } 1374 }
1529 1375
1530 /* Position the scrolled box */ 1376 /* Position the scrolled box */
1531 vsi.fMask = hsi.fMask = SIF_POS | SIF_RANGE | SIF_PAGE | SIF_DISABLENOSCROLL; 1377 vsi.fMask = hsi.fMask = SIF_POS | SIF_RANGE | SIF_PAGE | SIF_DISABLENOSCROLL;
1532 vsi.nMin = hsi.nMin = vsi.nMax = hsi.nMax = 0; 1378 vsi.nMin = hsi.nMin = vsi.nMax = hsi.nMax = 0;
1533 if(rect.bottom < usedy) 1379 if(rect.bottom < thisbox->minheight)
1534 { 1380 {
1535 vsi.nMax = usedy; 1381 vsi.nMax = thisbox->minheight;
1536 vsi.nPage = rect.bottom; 1382 vsi.nPage = rect.bottom;
1537 if(vsi.nPos > vsi.nMax) 1383 if(vsi.nPos > vsi.nMax)
1538 { 1384 {
1539 vsi.nPos = vsi.nMax; 1385 vsi.nPos = vsi.nMax;
1540 } 1386 }
1541 } 1387 }
1542 if(rect.right < usedx) 1388 if(rect.right < thisbox->minwidth)
1543 { 1389 {
1544 hsi.nMax = usedx; 1390 hsi.nMax = thisbox->minwidth;
1545 hsi.nPage = rect.right; 1391 hsi.nPage = rect.right;
1546 if(hsi.nPos > hsi.nMax) 1392 if(hsi.nPos > hsi.nMax)
1547 { 1393 {
1548 hsi.nPos = hsi.nMax; 1394 hsi.nPos = hsi.nMax;
1549 } 1395 }
1558 else if(strncmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0) 1404 else if(strncmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0)
1559 { 1405 {
1560 /* Then try the bottom or right box */ 1406 /* Then try the bottom or right box */
1561 float *percent = (float *)dw_window_get_data(handle, "_dw_percent"); 1407 float *percent = (float *)dw_window_get_data(handle, "_dw_percent");
1562 int type = (int)dw_window_get_data(handle, "_dw_type"); 1408 int type = (int)dw_window_get_data(handle, "_dw_type");
1563 int cx = width + vectorx;
1564 int cy = height + vectory;
1565 1409
1566 MoveWindow(handle, currentx + pad, currenty + pad, 1410 MoveWindow(handle, currentx + pad, currenty + pad,
1567 cx, cy, FALSE); 1411 width, height, FALSE);
1568 1412
1569 if(cx > 0 && cy > 0 && percent) 1413 if(percent)
1570 _handle_splitbar_resize(handle, *percent, type, cx, cy); 1414 _handle_splitbar_resize(handle, *percent, type, width, height);
1571 } 1415 }
1572 else if(strnicmp(tmpbuf, STATICCLASSNAME, strlen(STATICCLASSNAME)+1)==0) 1416 else if(strnicmp(tmpbuf, STATICCLASSNAME, strlen(STATICCLASSNAME)+1)==0)
1573 { 1417 {
1574 /* Handle special case Vertically Center static text */ 1418 /* Handle special case Vertically Center static text */
1575 ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA); 1419 ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
1576 1420
1577 if(cinfo && cinfo->vcenter) 1421 if(cinfo && cinfo->vcenter)
1578 { 1422 {
1579 /* We are centered so calculate a new position */ 1423 /* We are centered so calculate a new position */
1580 char tmpbuf[1024]; 1424 char tmpbuf[1024];
1581 int textheight, diff, total = height + vectory; 1425 int textheight, diff, total = height;
1582 1426
1583 GetWindowText(handle, tmpbuf, 1023); 1427 GetWindowText(handle, tmpbuf, 1023);
1584 1428
1585 /* Figure out how big the text is */ 1429 /* Figure out how big the text is */
1586 dw_font_text_extents_get(handle, 0, tmpbuf, 0, &textheight); 1430 dw_font_text_extents_get(handle, 0, tmpbuf, 0, &textheight);
1587 1431
1588 diff = (total - textheight) / 2; 1432 diff = (total - textheight) / 2;
1589 1433
1590 MoveWindow(handle, currentx + pad, currenty + pad + diff, 1434 MoveWindow(handle, currentx + pad, currenty + pad + diff,
1591 width + vectorx, height + vectory - diff, FALSE); 1435 width, height - diff, FALSE);
1592 } 1436 }
1593 else 1437 else
1594 { 1438 {
1595 MoveWindow(handle, currentx + pad, currenty + pad, 1439 MoveWindow(handle, currentx + pad, currenty + pad,
1596 width + vectorx, height + vectory, FALSE); 1440 width, height, FALSE);
1597 } 1441 }
1598 } 1442 }
1599 else 1443 else
1600 { 1444 {
1601 /* Everything else */ 1445 /* Everything else */
1602 MoveWindow(handle, currentx + pad, currenty + pad, 1446 MoveWindow(handle, currentx + pad, currenty + pad,
1603 width + vectorx, height + vectory, FALSE); 1447 width, height, FALSE);
1448
1449 /* After placing a box... place its components */
1604 if(thisbox->items[z].type == TYPEBOX) 1450 if(thisbox->items[z].type == TYPEBOX)
1605 { 1451 {
1606 Box *boxinfo = (Box *)GetWindowLongPtr(handle, GWLP_USERDATA); 1452 Box *boxinfo = (Box *)GetWindowLongPtr(handle, GWLP_USERDATA);
1607 1453
1608 if(boxinfo && boxinfo->grouphwnd) 1454 if(boxinfo)
1609 { 1455 {
1610 MoveWindow(boxinfo->grouphwnd, 0, 0, 1456 /* Move the group border into place */
1611 width + vectorx, height + vectory, FALSE); 1457 if(boxinfo->grouphwnd)
1458 {
1459 MoveWindow(boxinfo->grouphwnd, 0, 0,
1460 width, height, FALSE);
1461 }
1462 /* Dive into the box */
1463 (*depth)++;
1464 _resize_box(boxinfo, depth, width, height, pass);
1465 (*depth)--;
1612 } 1466 }
1613
1614 } 1467 }
1615 } 1468 }
1616 1469
1617 /* Notebook dialog requires additional processing */ 1470 /* Notebook dialog requires additional processing */
1618 if(strncmp(tmpbuf, WC_TABCONTROL, strlen(WC_TABCONTROL))==0) 1471 if(strncmp(tmpbuf, WC_TABCONTROL, strlen(WC_TABCONTROL))==0)
1628 MoveWindow(array[pageid]->hwnd, rect.left, rect.top, 1481 MoveWindow(array[pageid]->hwnd, rect.left, rect.top,
1629 rect.right - rect.left, rect.bottom-rect.top, FALSE); 1482 rect.right - rect.left, rect.bottom-rect.top, FALSE);
1630 } 1483 }
1631 } 1484 }
1632 /* So does the List View... handle delayed cursoring */ 1485 /* So does the List View... handle delayed cursoring */
1633 if(strnicmp(tmpbuf, WC_LISTVIEW, strlen(WC_LISTVIEW)+1)==0 && width + vectorx > 10 && height + vectory > 10) 1486 if(strnicmp(tmpbuf, WC_LISTVIEW, strlen(WC_LISTVIEW)+1)==0 && width > 10 && height > 10)
1634 { 1487 {
1635 int index = DW_POINTER_TO_INT(dw_window_get_data(handle, "_dw_cursor")); 1488 int index = DW_POINTER_TO_INT(dw_window_get_data(handle, "_dw_cursor"));
1636 1489
1637 if(index > 0) 1490 if(index > 0)
1638 ListView_EnsureVisible(handle, index, TRUE); 1491 ListView_EnsureVisible(handle, index, TRUE);
1639 } 1492 }
1640 1493
1494 /* Advance the current position in the box */
1641 if(thisbox->type == DW_HORZ) 1495 if(thisbox->type == DW_HORZ)
1642 currentx += width + vectorx + (pad * 2); 1496 currentx += width + (pad * 2);
1643 if(thisbox->type == DW_VERT) 1497 if(thisbox->type == DW_VERT)
1644 currenty += height + vectory + (pad * 2); 1498 currenty += height + (pad * 2);
1645 } 1499 }
1646 } 1500 }
1647 } 1501 }
1648 return 0;
1649 } 1502 }
1650 1503
1651 void _do_resize(Box *thisbox, int x, int y) 1504 void _do_resize(Box *thisbox, int x, int y)
1652 { 1505 {
1653 if(x != 0 && y != 0) 1506 if(x != 0 && y != 0)
1654 { 1507 {
1655 if(thisbox) 1508 if(thisbox)
1656 { 1509 {
1657 int usedx = 0, usedy = 0, depth = 0, usedpadx = 0, usedpady = 0; 1510 int depth = 0;
1658 1511
1659 _resize_box(thisbox, &depth, x, y, &usedx, &usedy, 1, &usedpadx, &usedpady); 1512 /* Calculate space requirements */
1660 1513 _resize_box(thisbox, &depth, x, y, 1);
1661 if(usedx-usedpadx == 0 || usedy-usedpady == 0) 1514
1662 return; 1515 /* Finally place all the boxes and controls */
1663 1516 _resize_box(thisbox, &depth, x, y, 2);
1664 thisbox->xratio = ((float)(x-usedpadx))/((float)(usedx-usedpadx));
1665 thisbox->yratio = ((float)(y-usedpady))/((float)(usedy-usedpady));
1666
1667 usedpadx = usedpady = usedx = usedy = depth = 0;
1668
1669 _resize_box(thisbox, &depth, x, y, &usedx, &usedy, 2, &usedpadx, &usedpady);
1670 } 1517 }
1671 } 1518 }
1672 } 1519 }
1673 1520
1674 int _HandleScroller(HWND handle, int bar, int pos, int which) 1521 int _HandleScroller(HWND handle, int bar, int pos, int which)
4746 { 4593 {
4747 HWND hwndframe; 4594 HWND hwndframe;
4748 Box *newbox = calloc(sizeof(Box), 1); 4595 Box *newbox = calloc(sizeof(Box), 1);
4749 ULONG flStyleEx = 0; 4596 ULONG flStyleEx = 0;
4750 4597
4751 newbox->pad = 0;
4752 newbox->type = DW_VERT; 4598 newbox->type = DW_VERT;
4753 newbox->count = 0; 4599 newbox->vsize = newbox->hsize = SIZEEXPAND;
4754 newbox->cinfo.fore = newbox->cinfo.back = -1; 4600 newbox->cinfo.fore = newbox->cinfo.back = -1;
4755
4756 /* Hmm, the "correct" way doesn't seem to be
4757 * working, but the old hackish SetParent()
4758 * at the bottom seems to work, so I'll leave
4759 * it like this for now.
4760 */
4761 #if 0
4762 if(hwndOwner)
4763 flStyleEx |= WS_EX_MDICHILD;
4764 #endif
4765 4601
4766 if(!(flStyle & WS_CAPTION)) 4602 if(!(flStyle & WS_CAPTION))
4767 flStyle |= WS_POPUPWINDOW; 4603 flStyle |= WS_POPUPWINDOW;
4768 4604
4769 if(flStyle & DW_FCF_TASKLIST) 4605 if(flStyle & DW_FCF_TASKLIST)
6709 * width: New width in pixels. 6545 * width: New width in pixels.
6710 * height: New height in pixels. 6546 * height: New height in pixels.
6711 */ 6547 */
6712 void API dw_window_set_size(HWND handle, ULONG width, ULONG height) 6548 void API dw_window_set_size(HWND handle, ULONG width, ULONG height)
6713 { 6549 {
6714 int usedx = 0, usedy = 0, depth = 0, usedpadx = 0, usedpady = 0;
6715 Box *thisbox; 6550 Box *thisbox;
6551
6716 /* 6552 /*
6717 * The following is an attempt to dynamically size a window based on the size of its 6553 * The following is an attempt to dynamically size a window based on the size of its
6718 * children before realization. Only applicable when width or height is zero. 6554 * children before realization. Only applicable when width or height is less than one.
6719 * It doesn't work vey well :-(
6720 */ 6555 */
6721 thisbox = (Box *)GetWindowLongPtr(handle, GWLP_USERDATA); 6556 if ( (width < 1 || height < 1) && (thisbox = (Box *)GetWindowLongPtr(handle, GWLP_USERDATA)) )
6722 if ( thisbox ) 6557 {
6723 { 6558 int depth = 0;
6724 _resize_box(thisbox, &depth, 0, 0, &usedx, &usedy, 1, &usedpadx, &usedpady); 6559
6725 _resize_box(thisbox, &depth, usedx, usedy, &usedx, &usedy, 2, &usedpadx, &usedpady); 6560 /* Calculate space requirements */
6726 } 6561 _resize_box(thisbox, &depth, width, height, 1);
6727 if ( width == 0 ) width = usedx; 6562
6728 if ( height == 0 ) height = usedy; 6563 /* Might need to take into account the window border here */
6564 if ( width < 1 ) width = thisbox->minwidth;
6565 if ( height < 1 ) height = thisbox->minheight;
6566 }
6567
6568 /* Finally set the size */
6729 SetWindowPos(handle, (HWND)NULL, 0, 0, width, height, SWP_SHOWWINDOW | SWP_NOZORDER | SWP_NOMOVE); 6569 SetWindowPos(handle, (HWND)NULL, 0, 0, width, height, SWP_SHOWWINDOW | SWP_NOZORDER | SWP_NOMOVE);
6730 } 6570 }
6731 6571
6732 /* 6572 /*
6733 * Gets the size the system thinks the widget should be. 6573 * Gets the size the system thinks the widget should be.
6792 * width: Width of the widget. 6632 * width: Width of the widget.
6793 * height: Height of the widget. 6633 * height: Height of the widget.
6794 */ 6634 */
6795 void API dw_window_set_pos_size(HWND handle, long x, long y, ULONG width, ULONG height) 6635 void API dw_window_set_pos_size(HWND handle, long x, long y, ULONG width, ULONG height)
6796 { 6636 {
6797 int usedx = 0, usedy = 0, depth = 0, usedpadx = 0, usedpady = 0;
6798 Box *thisbox; 6637 Box *thisbox;
6638
6799 /* 6639 /*
6800 * The following is an attempt to dynamically size a window based on the size of its 6640 * The following is an attempt to dynamically size a window based on the size of its
6801 * children before realization. Only applicable when width or height is zero. 6641 * children before realization. Only applicable when width or height is less than one.
6802 * It doesn't work vey well :-(
6803 */ 6642 */
6804 thisbox = (Box *)GetWindowLongPtr(handle, GWLP_USERDATA); 6643 if ( (width < 1 || height < 1) && (thisbox = (Box *)GetWindowLongPtr(handle, GWLP_USERDATA)) )
6805 if ( thisbox ) 6644 {
6806 { 6645 int depth = 0;
6807 _resize_box(thisbox, &depth, 0, 0, &usedx, &usedy, 1, &usedpadx, &usedpady); 6646
6808 _resize_box(thisbox, &depth, usedx, usedy, &usedx, &usedy, 2, &usedpadx, &usedpady); 6647 /* Calculate space requirements */
6809 } 6648 _resize_box(thisbox, &depth, width, height, 1);
6810 if ( width == 0 ) width = usedx; 6649
6811 if ( height == 0 ) height = usedy; 6650 /* Might need to take into account the window border here */
6651 if ( width < 1 ) width = thisbox->minwidth;
6652 if ( height < 1 ) height = thisbox->minheight;
6653 }
6654
6655 /* Finally set the size */
6812 SetWindowPos(handle, (HWND)NULL, x, y, width, height, SWP_NOZORDER | SWP_SHOWWINDOW | SWP_NOACTIVATE); 6656 SetWindowPos(handle, (HWND)NULL, x, y, width, height, SWP_NOZORDER | SWP_SHOWWINDOW | SWP_NOACTIVATE);
6813 #if 0
6814 /* force a configure event */
6815 SendMessage( handle, WM_SIZE, 0, MAKELPARAM(width, height) );
6816 #endif
6817 } 6657 }
6818 6658
6819 /* 6659 /*
6820 * Gets the position and size of a given window (widget). 6660 * Gets the position and size of a given window (widget).
6821 * Parameters: 6661 * Parameters: