Mercurial > dwindows
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: |