comparison os2/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 09fa437d6a5f
comparison
equal deleted inserted replaced
1437:a50e8b486a1a 1438:bde7ebced556
1052 int height = _get_height(parent); 1052 int height = _get_height(parent);
1053 1053
1054 return WinSetWindowPos(hwnd, behind, x, height - y - cy, cx, cy, fl); 1054 return WinSetWindowPos(hwnd, behind, x, height - y - cy, cx, cy, fl);
1055 } 1055 }
1056 1056
1057 #define _DW_DEFAULT_SCROLLBAR_WIDTH 16 1057 #define _DW_DEFAULT_SCROLLBAR_WIDTH 14
1058 1058
1059 /* This function calculates how much space the widgets and boxes require 1059 /* This function calculates how much space the widgets and boxes require
1060 * and does expansion as necessary. 1060 * and does expansion as necessary.
1061 */ 1061 */
1062 int _resize_box(Box *thisbox, int *depth, int x, int y, int *usedx, int *usedy, 1062 static void _resize_box(Box *thisbox, int *depth, int x, int y, int pass)
1063 int pass, int *usedpadx, int *usedpady) 1063 {
1064 { 1064 /* Current item position */
1065 int z, currentx = 0, currenty = 0; 1065 int z, currentx = thisbox->pad, currenty = thisbox->pad;
1066 /* Used x, y and padding maximum values...
1067 * These will be used to find the widest or
1068 * tallest items in a box.
1069 */
1066 int uymax = 0, uxmax = 0; 1070 int uymax = 0, uxmax = 0;
1067 int upymax = 0, upxmax = 0; 1071 int upymax = 0, upxmax = 0;
1068 /* Used for the SIZEEXPAND */ 1072
1069 int nux = *usedx, nuy = *usedy; 1073 /* Reset the box sizes */
1070 int nupx = *usedpadx, nupy = *usedpady; 1074 thisbox->minwidth = thisbox->minheight = thisbox->usedpadx = thisbox->usedpady = thisbox->pad * 2;
1071
1072 (*usedx) += (thisbox->pad * 2);
1073 (*usedy) += (thisbox->pad * 2);
1074 1075
1075 if(thisbox->grouphwnd) 1076 if(thisbox->grouphwnd)
1076 { 1077 {
1077 char *text = dw_window_get_text(thisbox->grouphwnd); 1078 char *text = dw_window_get_text(thisbox->grouphwnd);
1078 1079
1095 else 1096 else
1096 thisbox->grouppady = 6; 1097 thisbox->grouppady = 6;
1097 1098
1098 thisbox->grouppadx = 6; 1099 thisbox->grouppadx = 6;
1099 1100
1100 (*usedx) += thisbox->grouppadx; 1101 thisbox->minwidth += thisbox->grouppadx;
1101 (*usedpadx) += thisbox->grouppadx; 1102 thisbox->usedpadx += thisbox->grouppadx;
1102 (*usedy) += thisbox->grouppady; 1103 thisbox->minheight += thisbox->grouppady;
1103 (*usedpady) += thisbox->grouppady; 1104 thisbox->usedpady += thisbox->grouppady;
1104 } 1105 }
1105 1106
1107 /* Count up all the space for all items in the box */
1106 for(z=0;z<thisbox->count;z++) 1108 for(z=0;z<thisbox->count;z++)
1107 { 1109 {
1110 int itempad, itemwidth, itemheight;
1111
1108 if(thisbox->items[z].type == TYPEBOX) 1112 if(thisbox->items[z].type == TYPEBOX)
1109 { 1113 {
1110 int initialx, initialy;
1111 Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER); 1114 Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER);
1112
1113 initialx = x - (*usedx);
1114 initialy = y - (*usedy);
1115 1115
1116 if(tmp) 1116 if(tmp)
1117 { 1117 {
1118 int newx, newy; 1118 /* On the first pass calculate the box contents */
1119 int nux = *usedx, nuy = *usedy; 1119 if(pass == 1)
1120 int upx = *usedpadx + (tmp->pad*2), upy = *usedpady + (tmp->pad*2);
1121
1122 /* On the second pass we know how big the box needs to be and how
1123 * much space we have, so we can calculate a ratio for the new box.
1124 */
1125 if(pass == 2)
1126 { 1120 {
1127 int deep = *depth + 1; 1121 (*depth)++;
1128 1122
1129 _resize_box(tmp, &deep, x, y, &nux, &nuy, 1, &upx, &upy); 1123 /* Save the newly calculated values on the box */
1130 1124 _resize_box(tmp, depth, x, y, pass);
1131 tmp->upx = upx - *usedpadx; 1125
1132 tmp->upy = upy - *usedpady; 1126 /* Duplicate the values in the item list for use below */
1133 1127 thisbox->items[z].width = tmp->minwidth;
1134 newx = x - nux; 1128 thisbox->items[z].height = tmp->minheight;
1135 newy = y - nuy; 1129
1136 1130 (*depth)--;
1137 tmp->width = thisbox->items[z].width = initialx - newx;
1138 tmp->height = thisbox->items[z].height = initialy - newy;
1139
1140 tmp->parentxratio = thisbox->xratio;
1141 tmp->parentyratio = thisbox->yratio;
1142
1143 tmp->parentpad = tmp->pad;
1144 tmp->hsize = thisbox->items[z].hsize;
1145 tmp->vsize = thisbox->items[z].vsize;
1146
1147 /* Just in case */
1148 tmp->xratio = thisbox->xratio;
1149 tmp->yratio = thisbox->yratio;
1150
1151 if(thisbox->type == DW_VERT)
1152 {
1153 int tmppad = (thisbox->items[z].pad*2)+(tmp->pad*2)+tmp->grouppady;
1154
1155 if((thisbox->items[z].width - tmppad)!=0)
1156 tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-tmppad))/((float)(thisbox->items[z].width-tmppad));
1157 }
1158 else
1159 {
1160 if((thisbox->items[z].width-tmp->upx)!=0)
1161 tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-tmp->upx))/((float)(thisbox->items[z].width-tmp->upx));
1162 }
1163 if(thisbox->type == DW_HORZ)
1164 {
1165 int tmppad = (thisbox->items[z].pad*2)+(tmp->pad*2)+tmp->grouppadx;
1166
1167 if((thisbox->items[z].height-tmppad)!=0)
1168 tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-tmppad))/((float)(thisbox->items[z].height-tmppad));
1169 }
1170 else
1171 {
1172 if((thisbox->items[z].height-tmp->upy)!=0)
1173 tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-tmp->upy))/((float)(thisbox->items[z].height-tmp->upy));
1174 }
1175
1176 nux = *usedx; nuy = *usedy;
1177 upx = *usedpadx + (tmp->pad*2); upy = *usedpady + (tmp->pad*2);
1178 }
1179
1180 (*depth)++;
1181
1182 _resize_box(tmp, depth, x, y, &nux, &nuy, pass, &upx, &upy);
1183
1184 (*depth)--;
1185
1186 newx = x - nux;
1187 newy = y - nuy;
1188
1189 tmp->minwidth = thisbox->items[z].width = initialx - newx;
1190 tmp->minheight = thisbox->items[z].height = initialy - newy;
1191 }
1192 }
1193
1194 if(pass > 1 && *depth > 0)
1195 {
1196 if(thisbox->type == DW_VERT)
1197 {
1198 int tmppad = (thisbox->items[z].pad*2)+(thisbox->parentpad*2)+thisbox->grouppadx;
1199
1200 if((thisbox->minwidth-tmppad) == 0)
1201 thisbox->items[z].xratio = 1.0;
1202 else
1203 thisbox->items[z].xratio = ((float)((thisbox->width * thisbox->parentxratio)-tmppad))/((float)(thisbox->minwidth-tmppad));
1204 }
1205 else
1206 {
1207 if(thisbox->minwidth-thisbox->upx == 0)
1208 thisbox->items[z].xratio = 1.0;
1209 else
1210 thisbox->items[z].xratio = ((float)((thisbox->width * thisbox->parentxratio)-thisbox->upx))/((float)(thisbox->minwidth-thisbox->upx));
1211 }
1212
1213 if(thisbox->type == DW_HORZ)
1214 {
1215 int tmppad = (thisbox->items[z].pad*2)+(thisbox->parentpad*2)+thisbox->grouppady;
1216
1217 if((thisbox->minheight-tmppad) == 0)
1218 thisbox->items[z].yratio = 1.0;
1219 else
1220 thisbox->items[z].yratio = ((float)((thisbox->height * thisbox->parentyratio)-tmppad))/((float)(thisbox->minheight-tmppad));
1221 }
1222 else
1223 {
1224 if(thisbox->minheight-thisbox->upy == 0)
1225 thisbox->items[z].yratio = 1.0;
1226 else
1227 thisbox->items[z].yratio = ((float)((thisbox->height * thisbox->parentyratio)-thisbox->upy))/((float)(thisbox->minheight-thisbox->upy));
1228 }
1229
1230 if(thisbox->items[z].type == TYPEBOX)
1231 {
1232 Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER);
1233
1234 if(tmp)
1235 {
1236 tmp->parentxratio = thisbox->items[z].xratio;
1237 tmp->parentyratio = thisbox->items[z].yratio;
1238 } 1131 }
1239 } 1132 }
1240 } 1133 }
1241 else 1134
1242 { 1135 /* Precalculate these values, since they will
1243 thisbox->items[z].xratio = thisbox->xratio; 1136 * be used used repeatedly in the next section.
1244 thisbox->items[z].yratio = thisbox->yratio; 1137 */
1245 } 1138 itempad = thisbox->items[z].pad * 2;
1246 1139 itemwidth = thisbox->items[z].width + itempad;
1140 itemheight = thisbox->items[z].height + itempad;
1141
1142 /* Calculate the totals and maximums */
1247 if(thisbox->type == DW_VERT) 1143 if(thisbox->type == DW_VERT)
1248 { 1144 {
1249 int itemwidth = thisbox->items[z].width + (thisbox->items[z].pad*2);
1250
1251 if(itemwidth > uxmax) 1145 if(itemwidth > uxmax)
1252 uxmax = itemwidth; 1146 uxmax = itemwidth;
1147
1253 if(thisbox->items[z].hsize != SIZEEXPAND) 1148 if(thisbox->items[z].hsize != SIZEEXPAND)
1254 { 1149 {
1255 if(itemwidth > upxmax) 1150 if(itemwidth > upxmax)
1256 upxmax = itemwidth; 1151 upxmax = itemwidth;
1257 } 1152 }
1258 else 1153 else
1259 { 1154 {
1260 if(thisbox->items[z].pad*2 > upxmax) 1155 if(itempad > upxmax)
1261 upxmax = thisbox->items[z].pad*2; 1156 upxmax = itempad;
1262 } 1157 }
1158 thisbox->minheight += itemheight;
1159 if(thisbox->items[z].vsize != SIZEEXPAND)
1160 thisbox->usedpady += itemheight;
1161 else
1162 thisbox->usedpady += itempad;
1263 } 1163 }
1264 else 1164 else
1265 { 1165 {
1266 (*usedx) += thisbox->items[z].width + (thisbox->items[z].pad*2);
1267 if(thisbox->items[z].hsize != SIZEEXPAND)
1268 (*usedpadx) += (thisbox->items[z].pad*2) + thisbox->items[z].width;
1269 else
1270 (*usedpadx) += thisbox->items[z].pad*2;
1271 }
1272 if(thisbox->type == DW_HORZ)
1273 {
1274 int itemheight = thisbox->items[z].height + (thisbox->items[z].pad*2);
1275
1276 if(itemheight > uymax) 1166 if(itemheight > uymax)
1277 uymax = itemheight; 1167 uymax = itemheight;
1278 if(thisbox->items[z].vsize != SIZEEXPAND) 1168 if(thisbox->items[z].vsize != SIZEEXPAND)
1279 { 1169 {
1280 if(itemheight > upymax) 1170 if(itemheight > upymax)
1281 upymax = itemheight; 1171 upymax = itemheight;
1282 } 1172 }
1283 else 1173 else
1284 { 1174 {
1285 if(thisbox->items[z].pad*2 > upymax) 1175 if(itempad > upymax)
1286 upymax = thisbox->items[z].pad*2; 1176 upymax = itempad;
1287 } 1177 }
1288 } 1178 thisbox->minwidth += itemwidth;
1289 else 1179 if(thisbox->items[z].hsize != SIZEEXPAND)
1290 { 1180 thisbox->usedpadx += itemwidth;
1291 (*usedy) += thisbox->items[z].height + (thisbox->items[z].pad*2);
1292 if(thisbox->items[z].vsize != SIZEEXPAND)
1293 (*usedpady) += (thisbox->items[z].pad*2) + thisbox->items[z].height;
1294 else 1181 else
1295 (*usedpady) += thisbox->items[z].pad*2; 1182 thisbox->usedpadx += itempad;
1296 } 1183 }
1297 } 1184 }
1298 1185
1299 (*usedx) += uxmax; 1186 /* Add the maximums which were calculated in the previous loop */
1300 (*usedy) += uymax; 1187 thisbox->minwidth += uxmax;
1301 (*usedpadx) += upxmax; 1188 thisbox->minheight += uymax;
1302 (*usedpady) += upymax; 1189 thisbox->usedpadx += upxmax;
1303 1190 thisbox->usedpady += upymax;
1304 currentx += thisbox->pad; 1191
1305 currenty += thisbox->pad; 1192 /* Move the groupbox start past the group border */
1306
1307 if(thisbox->grouphwnd) 1193 if(thisbox->grouphwnd)
1308 { 1194 {
1309 currentx += 3; 1195 currentx += 3;
1310 currenty += thisbox->grouppady - 3; 1196 currenty += thisbox->grouppady - 3;
1311 } 1197 }
1312 1198
1313 /* The second pass is for expansion and actual placement. */ 1199 /* The second pass is for actual placement. */
1314 if(pass > 1) 1200 if(pass > 1)
1315 { 1201 {
1316 /* Any SIZEEXPAND items should be set to uxmax/uymax */
1317 for(z=0;z<thisbox->count;z++)
1318 {
1319 if(thisbox->items[z].hsize == SIZEEXPAND && thisbox->type == DW_VERT)
1320 thisbox->items[z].width = uxmax-(thisbox->items[z].pad*2);
1321 if(thisbox->items[z].vsize == SIZEEXPAND && thisbox->type == DW_HORZ)
1322 thisbox->items[z].height = uymax-(thisbox->items[z].pad*2);
1323 /* Run this code segment again to finalize the sized after setting uxmax/uymax values. */
1324 if(thisbox->items[z].type == TYPEBOX)
1325 {
1326 Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER);
1327
1328 if(tmp)
1329 {
1330 if(*depth > 0)
1331 {
1332 float calcval;
1333
1334 if(thisbox->type == DW_VERT)
1335 {
1336 calcval = (float)(tmp->minwidth-((thisbox->items[z].pad*2)+(thisbox->pad*2)));
1337 if(calcval == 0.0)
1338 tmp->xratio = thisbox->xratio;
1339 else
1340 tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-((thisbox->items[z].pad*2)+(thisbox->pad*2))))/calcval;
1341 tmp->width = thisbox->items[z].width;
1342 }
1343 if(thisbox->type == DW_HORZ)
1344 {
1345 calcval = (float)(tmp->minheight-((thisbox->items[z].pad*2)+(thisbox->pad*2)));
1346 if(calcval == 0.0)
1347 tmp->yratio = thisbox->yratio;
1348 else
1349 tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-((thisbox->items[z].pad*2)+(thisbox->pad*2))))/calcval;
1350 tmp->height = thisbox->items[z].height;
1351 }
1352 }
1353
1354 (*depth)++;
1355
1356 _resize_box(tmp, depth, x, y, &nux, &nuy, 3, &nupx, &nupy);
1357
1358 (*depth)--;
1359
1360 }
1361 }
1362 }
1363
1364 for(z=0;z<(thisbox->count);z++) 1202 for(z=0;z<(thisbox->count);z++)
1365 { 1203 {
1366 int height = thisbox->items[z].height; 1204 int height = thisbox->items[z].height;
1367 int width = thisbox->items[z].width; 1205 int width = thisbox->items[z].width;
1368 int pad = thisbox->items[z].pad; 1206 int itempad = thisbox->items[z].pad * 2;
1369 HWND handle = thisbox->items[z].hwnd; 1207 int thispad = thisbox->pad * 2;
1370 int vectorx, vectory; 1208
1371 1209 /* Calculate the new sizes */
1372 /* When upxmax != pad*2 then ratios are incorrect. */ 1210 if(thisbox->items[z].hsize == SIZEEXPAND)
1373 vectorx = (int)((width*thisbox->items[z].xratio)-width); 1211 {
1374 vectory = (int)((height*thisbox->items[z].yratio)-height); 1212 if(thisbox->type == DW_HORZ)
1375 1213 {
1214 int expandablex = thisbox->minwidth - thisbox->usedpadx;
1215
1216 if(expandablex)
1217 width = (int)(((float)width / (float)expandablex) * (float)(x - thisbox->usedpadx));
1218 }
1219 else
1220 width = x - (itempad + thispad + thisbox->grouppadx);
1221 }
1222 if(thisbox->items[z].vsize == SIZEEXPAND)
1223 {
1224 if(thisbox->type == DW_VERT)
1225 {
1226 int expandabley = thisbox->minheight - thisbox->usedpady;
1227
1228 if(expandabley)
1229 height = (int)(((float)height / (float)expandabley) * (float)(y - thisbox->usedpady));
1230 }
1231 else
1232 height = y - (itempad + thispad + thisbox->grouppady);
1233 }
1234
1235 /* If the calculated size is valid... */
1376 if(width > 0 && height > 0) 1236 if(width > 0 && height > 0)
1377 { 1237 {
1238 int pad = thisbox->items[z].pad;
1239 HWND handle = thisbox->items[z].hwnd;
1378 char tmpbuf[100]; 1240 char tmpbuf[100];
1379 /* This is a hack to fix rounding of the sizing */
1380 if(*depth == 0)
1381 {
1382 vectorx++;
1383 vectory++;
1384 }
1385
1386 /* If this item isn't going to expand... reset the vectors to 0 */
1387 if(thisbox->items[z].vsize != SIZEEXPAND)
1388 vectory = 0;
1389 if(thisbox->items[z].hsize != SIZEEXPAND)
1390 vectorx = 0;
1391
1392 if(thisbox->type == DW_VERT && thisbox->hsize == SIZESTATIC && thisbox->items[z].hsize == SIZEEXPAND && thisbox->width)
1393 {
1394 width = thisbox->width;
1395 vectorx = 0;
1396 }
1397 if(thisbox->type == DW_HORZ && thisbox->vsize == SIZESTATIC && thisbox->items[z].vsize == SIZEEXPAND && thisbox->height)
1398 {
1399 height = thisbox->height;
1400 vectory = 0;
1401 }
1402 1241
1403 WinQueryClassName(handle, 99, (PCH)tmpbuf); 1242 WinQueryClassName(handle, 99, (PCH)tmpbuf);
1404 1243
1405 if(strncmp(tmpbuf, "#2", 3)==0) 1244 if(strncmp(tmpbuf, "#2", 3)==0)
1406 { 1245 {
1407 HWND frame = (HWND)dw_window_get_data(handle, "_dw_combo_box"); 1246 HWND frame = (HWND)dw_window_get_data(handle, "_dw_combo_box");
1408 /* Make the combobox big enough to drop down. :) */ 1247 /* Make the combobox big enough to drop down. :) */
1409 WinSetWindowPos(handle, HWND_TOP, 0, -100, 1248 WinSetWindowPos(handle, HWND_TOP, 0, -100,
1410 width + vectorx, (height + vectory) + 100, SWP_MOVE | SWP_SIZE | SWP_ZORDER); 1249 width, height + 100, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
1411 _MySetWindowPos(frame, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad, 1250 _MySetWindowPos(frame, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad,
1412 width + vectorx, height + vectory, SWP_MOVE | SWP_SIZE | SWP_ZORDER); 1251 width, height, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
1413 } 1252 }
1414 else if(strncmp(tmpbuf, "#6", 3)==0) 1253 else if(strncmp(tmpbuf, "#6", 3)==0)
1415 { 1254 {
1416 /* Entryfields on OS/2 have a thick border that isn't on Windows and GTK */ 1255 /* Entryfields on OS/2 have a thick border that isn't on Windows and GTK */
1417 _MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, (currentx + pad) + 3, (currenty + pad) + 3, 1256 _MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, (currentx + pad) + 3, (currenty + pad) + 3,
1418 (width + vectorx) - 6, (height + vectory) - 6, SWP_MOVE | SWP_SIZE | SWP_ZORDER); 1257 width - 6, height - 6, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
1419 } 1258 }
1420 else if(strncmp(tmpbuf, "#40", 5)==0) 1259 else if(strncmp(tmpbuf, "#40", 5)==0)
1421 { 1260 {
1422 _MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad, 1261 _MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad,
1423 width + vectorx, height + vectory, SWP_MOVE | SWP_SIZE | SWP_ZORDER); 1262 width, height, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
1424 _check_resize_notebook(handle); 1263 _check_resize_notebook(handle);
1425 } 1264 }
1426 else if(strncmp(tmpbuf, ScrollClassName, strlen(ScrollClassName)+1)==0) 1265 else if(strncmp(tmpbuf, ScrollClassName, strlen(ScrollClassName)+1)==0)
1427 { 1266 {
1428 /* Handle special case of scrollbox */ 1267 /* Handle special case of scrollbox */
1429 int cx = width + vectorx; 1268 int cx, cy, depth = 0;
1430 int cy = height + vectory;
1431 int usedx = 0, usedy = 0, usedpadx = 0, usedpady = 0, depth = 0;
1432 HWND box = (HWND)dw_window_get_data(handle, "_dw_resizebox"); 1269 HWND box = (HWND)dw_window_get_data(handle, "_dw_resizebox");
1433 HWND client = WinWindowFromID(handle, FID_CLIENT); 1270 HWND client = WinWindowFromID(handle, FID_CLIENT);
1434 HWND vscroll = WinWindowFromID(handle, FID_VERTSCROLL); 1271 HWND vscroll = WinWindowFromID(handle, FID_VERTSCROLL);
1435 HWND hscroll = WinWindowFromID(handle, FID_HORZSCROLL); 1272 HWND hscroll = WinWindowFromID(handle, FID_HORZSCROLL);
1436 Box *contentbox = (Box *)WinQueryWindowPtr(box, QWP_USER); 1273 Box *contentbox = (Box *)WinQueryWindowPtr(box, QWP_USER);
1437 int origx, origy; 1274 int origx, origy;
1438 unsigned int hpos = (unsigned int)WinSendMsg(hscroll, SBM_QUERYPOS, 0, 0); 1275 unsigned int hpos = (unsigned int)WinSendMsg(hscroll, SBM_QUERYPOS, 0, 0);
1439 unsigned int vpos = (unsigned int)WinSendMsg(vscroll, SBM_QUERYPOS, 0, 0); 1276 unsigned int vpos = (unsigned int)WinSendMsg(vscroll, SBM_QUERYPOS, 0, 0);
1440 1277
1441 /* Position the scrollbox parts */ 1278 /* Position the scrollbox parts */
1442 _MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad, cx, cy, SWP_MOVE | SWP_SIZE | SWP_ZORDER); 1279 _MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad, width, height, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
1443 WinSetWindowPos(client, HWND_TOP, 0, _DW_DEFAULT_SCROLLBAR_WIDTH, cx - _DW_DEFAULT_SCROLLBAR_WIDTH, cy - _DW_DEFAULT_SCROLLBAR_WIDTH, SWP_MOVE | SWP_SIZE | SWP_ZORDER); 1280 WinSetWindowPos(client, HWND_TOP, 0, _DW_DEFAULT_SCROLLBAR_WIDTH, width - _DW_DEFAULT_SCROLLBAR_WIDTH, height - _DW_DEFAULT_SCROLLBAR_WIDTH, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
1444 WinSetWindowPos(hscroll, HWND_TOP, 0, 0, cx - _DW_DEFAULT_SCROLLBAR_WIDTH, _DW_DEFAULT_SCROLLBAR_WIDTH, SWP_MOVE | SWP_SIZE | SWP_ZORDER); 1281 WinSetWindowPos(hscroll, HWND_TOP, 0, 0, width - _DW_DEFAULT_SCROLLBAR_WIDTH, _DW_DEFAULT_SCROLLBAR_WIDTH, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
1445 WinSetWindowPos(vscroll, HWND_TOP, cx - _DW_DEFAULT_SCROLLBAR_WIDTH, _DW_DEFAULT_SCROLLBAR_WIDTH, _DW_DEFAULT_SCROLLBAR_WIDTH, cy - _DW_DEFAULT_SCROLLBAR_WIDTH, SWP_MOVE | SWP_SIZE | SWP_ZORDER); 1282 WinSetWindowPos(vscroll, HWND_TOP, width - _DW_DEFAULT_SCROLLBAR_WIDTH, _DW_DEFAULT_SCROLLBAR_WIDTH, _DW_DEFAULT_SCROLLBAR_WIDTH, height - _DW_DEFAULT_SCROLLBAR_WIDTH, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
1446 1283
1447 origx = cx = cx - _DW_DEFAULT_SCROLLBAR_WIDTH; 1284 origx = cx = width - _DW_DEFAULT_SCROLLBAR_WIDTH;
1448 origy = cy = cy - _DW_DEFAULT_SCROLLBAR_WIDTH; 1285 origy = cy = height - _DW_DEFAULT_SCROLLBAR_WIDTH;
1449 1286
1450 /* Get the required space for the box */ 1287 /* Get the required space for the box */
1451 _resize_box(contentbox, &depth, cx, cy, &usedx, &usedy, 1, &usedpadx, &usedpady); 1288 _resize_box(contentbox, &depth, cx, cy, 1);
1452 1289
1453 if(cx < usedx) 1290 if(cx < contentbox->minwidth)
1454 { 1291 {
1455 cx = usedx; 1292 cx = contentbox->minwidth;
1456 } 1293 }
1457 if(cy < usedy) 1294 if(cy < contentbox->minheight)
1458 { 1295 {
1459 cy = usedy; 1296 cy = contentbox->minheight;
1460 } 1297 }
1461 1298
1462 /* Setup vertical scroller */ 1299 /* Setup vertical scroller */
1463 WinSendMsg(vscroll, SBM_SETSCROLLBAR, (MPARAM)vpos, MPFROM2SHORT(0, (unsigned short)usedy - origy)); 1300 WinSendMsg(vscroll, SBM_SETSCROLLBAR, (MPARAM)vpos, MPFROM2SHORT(0, (unsigned short)contentbox->minheight - origy));
1464 WinSendMsg(vscroll, SBM_SETTHUMBSIZE, MPFROM2SHORT((unsigned short)origy, usedy), 0); 1301 WinSendMsg(vscroll, SBM_SETTHUMBSIZE, MPFROM2SHORT((unsigned short)origy, contentbox->minheight), 0);
1465 if(vpos > usedy) 1302 if(vpos > contentbox->minheight)
1466 { 1303 {
1467 vpos = usedy; 1304 vpos = contentbox->minheight;
1468 WinSendMsg(vscroll, SBM_SETPOS, (MPARAM)vpos, 0); 1305 WinSendMsg(vscroll, SBM_SETPOS, (MPARAM)vpos, 0);
1469 } 1306 }
1470 1307
1471 /* Setup horizontal scroller */ 1308 /* Setup horizontal scroller */
1472 WinSendMsg(hscroll, SBM_SETSCROLLBAR, (MPARAM)hpos, MPFROM2SHORT(0, (unsigned short)usedx - origx)); 1309 WinSendMsg(hscroll, SBM_SETSCROLLBAR, (MPARAM)hpos, MPFROM2SHORT(0, (unsigned short)contentbox->minwidth - origx));
1473 WinSendMsg(hscroll, SBM_SETTHUMBSIZE, MPFROM2SHORT((unsigned short)origx, usedx), 0); 1310 WinSendMsg(hscroll, SBM_SETTHUMBSIZE, MPFROM2SHORT((unsigned short)origx, contentbox->minwidth), 0);
1474 if(hpos > usedx) 1311 if(hpos > contentbox->minwidth)
1475 { 1312 {
1476 hpos = usedx; 1313 hpos = contentbox->minwidth;
1477 WinSendMsg(hscroll, SBM_SETPOS, (MPARAM)hpos, 0); 1314 WinSendMsg(hscroll, SBM_SETPOS, (MPARAM)hpos, 0);
1478 } 1315 }
1479 1316
1480 /* Position the scrolled box */ 1317 /* Position the scrolled box */
1481 WinSetWindowPos(box, HWND_TOP, 0, -(cy - origy), cx, cy, SWP_MOVE | SWP_SIZE | SWP_ZORDER); 1318 WinSetWindowPos(box, HWND_TOP, 0, -(cy - origy), cx, cy, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
1488 else if(strncmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0) 1325 else if(strncmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0)
1489 { 1326 {
1490 /* Then try the bottom or right box */ 1327 /* Then try the bottom or right box */
1491 float *percent = (float *)dw_window_get_data(handle, "_dw_percent"); 1328 float *percent = (float *)dw_window_get_data(handle, "_dw_percent");
1492 int type = (int)dw_window_get_data(handle, "_dw_type"); 1329 int type = (int)dw_window_get_data(handle, "_dw_type");
1493 int cx = width + vectorx;
1494 int cy = height + vectory;
1495 1330
1496 _MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad, 1331 _MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad,
1497 cx, cy, SWP_MOVE | SWP_SIZE | SWP_ZORDER); 1332 width, height, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
1498 1333
1499 if(cx > 0 && cy > 0 && percent) 1334 if(percent)
1500 _handle_splitbar_resize(handle, *percent, type, cx, cy); 1335 _handle_splitbar_resize(handle, *percent, type, width, height);
1501 } 1336 }
1502 else 1337 else
1503 { 1338 {
1339 /* Everything else */
1504 _MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad, 1340 _MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad,
1505 width + vectorx, height + vectory, SWP_MOVE | SWP_SIZE | SWP_ZORDER); 1341 width, height, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
1342
1343 /* After placing a box... place its components */
1506 if(thisbox->items[z].type == TYPEBOX) 1344 if(thisbox->items[z].type == TYPEBOX)
1507 { 1345 {
1508 Box *boxinfo = WinQueryWindowPtr(handle, QWP_USER); 1346 Box *boxinfo = WinQueryWindowPtr(handle, QWP_USER);
1509 1347
1510 if(boxinfo && boxinfo->grouphwnd) 1348 if(boxinfo)
1511 WinSetWindowPos(boxinfo->grouphwnd, HWND_TOP, 0, 0, 1349 {
1512 width + vectorx, height + vectory, SWP_MOVE | SWP_SIZE); 1350 if(boxinfo->grouphwnd)
1513 1351 {
1352 /* Move the group border into place */
1353 WinSetWindowPos(boxinfo->grouphwnd, HWND_TOP, 0, 0,
1354 width, height, SWP_MOVE | SWP_SIZE);
1355 }
1356 /* Dive into the box */
1357 (*depth)++;
1358 _resize_box(boxinfo, depth, width, height, pass);
1359 (*depth)--;
1360 }
1514 } 1361 }
1515
1516 } 1362 }
1517 1363
1364 /* Advance the current position in the box */
1518 if(thisbox->type == DW_HORZ) 1365 if(thisbox->type == DW_HORZ)
1519 currentx += width + vectorx + (pad * 2); 1366 currentx += width + (pad * 2);
1520 if(thisbox->type == DW_VERT) 1367 if(thisbox->type == DW_VERT)
1521 currenty += height + vectory + (pad * 2); 1368 currenty += height + (pad * 2);
1522 } 1369 }
1523 } 1370 }
1524 } 1371 }
1525 return 0;
1526 } 1372 }
1527 1373
1528 void _do_resize(Box *thisbox, int x, int y) 1374 void _do_resize(Box *thisbox, int x, int y)
1529 { 1375 {
1530 if(x != 0 && y != 0) 1376 if(x != 0 && y != 0)
1531 { 1377 {
1532 if(thisbox) 1378 if(thisbox)
1533 { 1379 {
1534 int usedx = 0, usedy = 0, usedpadx = 0, usedpady = 0, depth = 0; 1380 int depth = 0;
1535 1381
1536 _resize_box(thisbox, &depth, x, y, &usedx, &usedy, 1, &usedpadx, &usedpady); 1382 /* Calculate space requirements */
1537 1383 _resize_box(thisbox, &depth, x, y, 1);
1538 if(usedx-usedpadx == 0 || usedy-usedpady == 0) 1384
1539 return; 1385 /* Finally place all the boxes and controls */
1540 1386 _resize_box(thisbox, &depth, x, y, 2);
1541 thisbox->xratio = ((float)(x-usedpadx))/((float)(usedx-usedpadx));
1542 thisbox->yratio = ((float)(y-usedpady))/((float)(usedy-usedpady));
1543
1544 usedx = usedy = usedpadx = usedpady = depth = 0;
1545
1546 _resize_box(thisbox, &depth, x, y, &usedx, &usedy, 2, &usedpadx, &usedpady);
1547 } 1387 }
1548 } 1388 }
1549 } 1389 }
1550 1390
1551 /* This procedure handles WM_QUERYTRACKINFO requests from the frame */ 1391 /* This procedure handles WM_QUERYTRACKINFO requests from the frame */
4754 { 4594 {
4755 /* Check for vertical scrollbar */ 4595 /* Check for vertical scrollbar */
4756 if(strncmp(tmpbuf, "#8", 3)== 0 && 4596 if(strncmp(tmpbuf, "#8", 3)== 0 &&
4757 WinQueryWindowULong(handle, QWL_STYLE) & SBS_VERT) 4597 WinQueryWindowULong(handle, QWL_STYLE) & SBS_VERT)
4758 { 4598 {
4759 thiswidth = 14; 4599 thiswidth = _DW_DEFAULT_SCROLLBAR_WIDTH;
4760 thisheight = 100; 4600 thisheight = 100;
4761 } 4601 }
4762 else 4602 else
4763 { 4603 {
4764 thiswidth = 100; 4604 thiswidth = 100;
4765 thisheight = 14; 4605 thisheight = _DW_DEFAULT_SCROLLBAR_WIDTH;
4766 } 4606 }
4767 } 4607 }
4768 /* Spinbutton */ 4608 /* Spinbutton */
4769 else if(strncmp(tmpbuf, "#32", 4)==0) 4609 else if(strncmp(tmpbuf, "#32", 4)==0)
4770 { 4610 {
5049 HWND hwndframe; 4889 HWND hwndframe;
5050 Box *newbox = calloc(1, sizeof(Box)); 4890 Box *newbox = calloc(1, sizeof(Box));
5051 WindowData *blah = calloc(1, sizeof(WindowData)); 4891 WindowData *blah = calloc(1, sizeof(WindowData));
5052 ULONG winStyle = 0L; 4892 ULONG winStyle = 0L;
5053 4893
5054 newbox->pad = 0;
5055 newbox->type = DW_VERT; 4894 newbox->type = DW_VERT;
5056 newbox->count = 0; 4895 newbox->vsize = newbox->hsize = SIZEEXPAND;
5057 4896
5058 flStyle |= FCF_NOBYTEALIGN; 4897 flStyle |= FCF_NOBYTEALIGN;
5059 4898
5060 if(flStyle & DW_FCF_TITLEBAR) 4899 if(flStyle & DW_FCF_TITLEBAR)
5061 newbox->titlebar = 1; 4900 newbox->titlebar = 1;
7013 * width: New width in pixels. 6852 * width: New width in pixels.
7014 * height: New height in pixels. 6853 * height: New height in pixels.
7015 */ 6854 */
7016 void API dw_window_set_size(HWND handle, ULONG width, ULONG height) 6855 void API dw_window_set_size(HWND handle, ULONG width, ULONG height)
7017 { 6856 {
6857 Box *thisbox;
6858 HWND box;
6859
6860 if((width < 1 || height < 1) && (box = WinWindowFromID(window, FID_CLIENT)) &&
6861 (thisbox = WinQueryWindowPtr(box, QWP_USER)))
6862 {
6863 int depth = 0;
6864
6865 /* Calculate space requirements */
6866 _resize_box(thisbox, &depth, width, height, 1);
6867
6868 /* Might need to take into account the window border here */
6869 if(width < 1) width = thisbox->minwidth;
6870 if(height < 1) height = thisbox->minheight;
6871 }
6872
6873 /* Finally set the size */
7018 WinSetWindowPos(handle, NULLHANDLE, 0, 0, width, height, SWP_SHOW | SWP_SIZE); 6874 WinSetWindowPos(handle, NULLHANDLE, 0, 0, width, height, SWP_SHOW | SWP_SIZE);
7019 } 6875 }
7020 6876
7021 /* 6877 /*
7022 * Gets the size the system thinks the widget should be. 6878 * Gets the size the system thinks the widget should be.
7082 * height: Height of the widget. 6938 * height: Height of the widget.
7083 */ 6939 */
7084 void API dw_window_set_pos_size(HWND handle, LONG x, LONG y, ULONG width, ULONG height) 6940 void API dw_window_set_pos_size(HWND handle, LONG x, LONG y, ULONG width, ULONG height)
7085 { 6941 {
7086 int myy = _get_frame_height(handle) - (y + height); 6942 int myy = _get_frame_height(handle) - (y + height);
7087 6943 Box *thisbox;
6944 HWND box;
6945
6946 if((width < 1 || height < 1) && (box = WinWindowFromID(window, FID_CLIENT)) &&
6947 (thisbox = WinQueryWindowPtr(box, QWP_USER)))
6948 {
6949 int depth = 0;
6950
6951 /* Calculate space requirements */
6952 _resize_box(thisbox, &depth, width, height, 1);
6953
6954 /* Might need to take into account the window border here */
6955 if(width < 1) width = thisbox->minwidth;
6956 if(height < 1) height = thisbox->minheight;
6957 }
6958
6959 /* Finally set the size */
7088 WinSetWindowPos(handle, NULLHANDLE, x, myy, width, height, SWP_MOVE | SWP_SIZE | SWP_SHOW); 6960 WinSetWindowPos(handle, NULLHANDLE, x, myy, width, height, SWP_MOVE | SWP_SIZE | SWP_SHOW);
7089 } 6961 }
7090 6962
7091 /* 6963 /*
7092 * Gets the position and size of a given window (widget). 6964 * Gets the position and size of a given window (widget).