| 362 grid_place_children((Grid)XtParent(widget)); |
392 grid_place_children((Grid)XtParent(widget)); |
| 363 return XtGeometryYes; |
393 return XtGeometryYes; |
| 364 } |
394 } |
| 365 |
395 |
| 366 void GridChangeManaged(Widget widget) { |
396 void GridChangeManaged(Widget widget) { |
| 367 |
397 grid_place_children((Grid)widget); |
| 368 } |
398 } |
| 369 |
399 |
| 370 Boolean ConstraintSetValues(Widget old, Widget request, Widget neww, ArgList args, Cardinal *num_args) { |
400 Boolean ConstraintSetValues(Widget old, Widget request, Widget neww, ArgList args, Cardinal *num_args) { |
| 371 GridConstraintRec *constraints = neww->core.constraints; |
401 GridConstraintRec *constraints = neww->core.constraints; |
| 372 Grid grid = (Grid)XtParent(neww); |
402 Grid grid = (Grid)XtParent(neww); |
| 373 if(constraints->grid.x > grid->mywidget.max_col) { |
403 if(constraints->grid.x > grid->grid.max_col) { |
| 374 grid->mywidget.max_col = constraints->grid.x; |
404 grid->grid.max_col = constraints->grid.x; |
| 375 } |
405 } |
| 376 if(constraints->grid.y > grid->mywidget.max_row) { |
406 if(constraints->grid.y > grid->grid.max_row) { |
| 377 grid->mywidget.max_row = constraints->grid.y; |
407 grid->grid.max_row = constraints->grid.y; |
| 378 } |
408 } |
| 379 } |
409 } |
| 380 |
410 |
| 381 |
411 |
| 382 void grid_constraint_init( |
412 void grid_constraint_init( |
| 387 ) |
417 ) |
| 388 { |
418 { |
| 389 GridConstraintRec *constraints = neww->core.constraints; |
419 GridConstraintRec *constraints = neww->core.constraints; |
| 390 |
420 |
| 391 Grid grid = (Grid)XtParent(neww); |
421 Grid grid = (Grid)XtParent(neww); |
| 392 if(constraints->grid.x > grid->mywidget.max_col) { |
422 if(constraints->grid.x > grid->grid.max_col) { |
| 393 grid->mywidget.max_col = constraints->grid.x; |
423 grid->grid.max_col = constraints->grid.x; |
| 394 } |
424 } |
| 395 if(constraints->grid.y > grid->mywidget.max_row) { |
425 if(constraints->grid.y > grid->grid.max_row) { |
| 396 grid->mywidget.max_row = constraints->grid.y; |
426 grid->grid.max_row = constraints->grid.y; |
| 397 } |
427 } |
| 398 constraints->grid.pref_width = neww->core.width; |
428 constraints->grid.pref_width = neww->core.width; |
| 399 constraints->grid.pref_height = neww->core.height; |
429 constraints->grid.pref_height = neww->core.height; |
| 400 } |
430 } |
| 401 |
431 |
| 402 void grid_place_children(Grid w) { |
432 void grid_place_children(Grid w) { |
| 403 int ncols = w->mywidget.max_col+1; |
433 if(!XtIsRealized((Widget)w)) { |
| 404 int nrows = w->mywidget.max_row+1; |
434 return; |
| |
435 } |
| |
436 |
| |
437 int ncols = w->grid.max_col+1; |
| |
438 int nrows = w->grid.max_row+1; |
| 405 GridDef *cols = calloc(ncols, sizeof(GridDef)); |
439 GridDef *cols = calloc(ncols, sizeof(GridDef)); |
| 406 GridDef *rows = calloc(nrows, sizeof(GridDef)); |
440 GridDef *rows = calloc(nrows, sizeof(GridDef)); |
| 407 int num_cols_expanding = 0; |
441 int num_cols_expanding = 0; |
| 408 int num_rows_expanding = 0; |
442 int num_rows_expanding = 0; |
| 409 int req_width = 0; |
443 int req_width = w->grid.padding_left + w->grid.padding_right; |
| 410 int req_height = 0; |
444 int req_height = w->grid.padding_top + w->grid.padding_bottom; |
| |
445 int width = w->core.width; |
| |
446 int height = w->core.height; |
| 411 |
447 |
| 412 //printf("container width: %d\n", (int)w->core.width); |
448 //printf("container width: %d\n", (int)w->core.width); |
| 413 |
449 |
| 414 // calculate the minimum size requirements for all columns and rows |
450 // calculate the minimum size requirements for all columns and rows |
| 415 // we need to run this 2 times: for widgets without colspan/rowspan first |
451 // we need to run this 2 times: for widgets without colspan/rowspan first |
| 487 for(int s=x+1;s<ncols;s++) { |
529 for(int s=x+1;s<ncols;s++) { |
| 488 last_col = &cols[s]; |
530 last_col = &cols[s]; |
| 489 span_width = last_col->size; |
531 span_width = last_col->size; |
| 490 |
532 |
| 491 } |
533 } |
| 492 int diff = constraints->grid.pref_width - span_width; |
534 int diff = elm_width - span_width; |
| 493 if(diff > 0) { |
535 if(diff > 0) { |
| 494 last_col->size += diff; |
536 last_col->size += diff; |
| 495 } |
537 } |
| 496 } else if(constraints->grid.pref_width > col->size) { |
538 } else if(elm_width > col->size) { |
| 497 col->size = constraints->grid.pref_width; |
539 col->size = elm_width; |
| 498 } |
540 } |
| 499 // row size |
541 // row size |
| 500 if(constraints->grid.rowspan > 1) { |
542 if(constraints->grid.rowspan > 1) { |
| 501 Dimension span_height = row->size; |
543 Dimension span_height = row->size; |
| 502 GridDef *last_row = row; |
544 GridDef *last_row = row; |
| 503 for(int s=x+1;s<nrows;s++) { |
545 for(int s=x+1;s<nrows;s++) { |
| 504 last_row = &rows[s]; |
546 last_row = &rows[s]; |
| 505 span_height = last_row->size; |
547 span_height = last_row->size; |
| 506 |
548 |
| 507 } |
549 } |
| 508 int diff = constraints->grid.pref_height - span_height; |
550 int diff = elm_height - span_height; |
| 509 if(diff > 0) { |
551 if(diff > 0) { |
| 510 last_row->size += diff; |
552 last_row->size += diff; |
| 511 } |
553 } |
| 512 } else if(constraints->grid.pref_height > row->size) { |
554 } else if(elm_height > row->size) { |
| 513 row->size = constraints->grid.pref_height; |
555 row->size = elm_height; |
| 514 } |
556 } |
| 515 } |
557 } |
| 516 span_max = 50000; // not sure if this is unreasonable low or high |
558 span_max = 50000; // not sure if this is unreasonable low or high |
| 517 } |
559 } |
| 518 |
560 |
| 528 num_rows_expanding++; |
570 num_rows_expanding++; |
| 529 } |
571 } |
| 530 req_height += rows[i].size; |
572 req_height += rows[i].size; |
| 531 } |
573 } |
| 532 |
574 |
| |
575 int total_colspacing = 0; |
| |
576 int total_rowspacing = 0; |
| |
577 for(int i=0;i+1<ncols;i++) { |
| |
578 if(cols[i].size > 0) { |
| |
579 total_colspacing += w->grid.columnspacing; |
| |
580 } |
| |
581 } |
| |
582 for(int i=0;i+1<nrows;i++) { |
| |
583 if(rows[i].size > 0) { |
| |
584 total_rowspacing += w->grid.rowspacing; |
| |
585 } |
| |
586 } |
| |
587 |
| 533 if(req_width > 0 && req_height > 0) { |
588 if(req_width > 0 && req_height > 0) { |
| 534 // add col/row spacing |
589 // add col/row spacing |
| 535 req_width += (ncols-1)*w->mywidget.columnspacing; |
590 req_width += total_colspacing; //(ncols-1)*w->grid.columnspacing; |
| 536 req_height += (nrows-1)*w->mywidget.rowspacing; |
591 req_height += total_rowspacing; //(nrows-1)*w->grid.rowspacing; |
| 537 |
592 |
| 538 Widget parent = w->core.parent; |
593 Widget parent = w->core.parent; |
| 539 Dimension rwidth = req_width; |
594 Dimension rwidth = req_width; |
| 540 Dimension rheight = req_height; |
595 Dimension rheight = req_height; |
| 541 if(rwidth < w->core.width) { |
596 if(rwidth < w->core.width) { |
| 543 } |
598 } |
| 544 if(rheight < w->core.height) { |
599 if(rheight < w->core.height) { |
| 545 //rheight = w->core.height; |
600 //rheight = w->core.height; |
| 546 } |
601 } |
| 547 |
602 |
| 548 if(!w->mywidget.sizerequest) { |
603 if(!w->grid.sizerequest) { |
| 549 Dimension actual_width, actual_height; |
604 Dimension actual_width, actual_height; |
| 550 w->mywidget.sizerequest = TRUE; |
605 w->grid.sizerequest = TRUE; |
| 551 |
606 |
| 552 //printf("sizerequest: %d x %d\n", (int)req_width, (int)req_height); |
607 //printf("sizerequest: %d x %d\n", (int)req_width, (int)req_height); |
| 553 |
608 |
| 554 //XtWidgetGeometry request; |
609 //XtWidgetGeometry request; |
| 555 //request.width = req_width; |
610 //request.width = req_width; |
| 556 //request.request_mode = CWWidth; |
611 //request.request_mode = CWWidth; |
| 557 //XtWidgetGeometry reply; |
612 //XtWidgetGeometry reply; |
| 558 //XtGeometryResult result = XtMakeGeometryRequest((Widget)w, &request, &reply); |
613 //XtGeometryResult result = XtMakeGeometryRequest((Widget)w, &request, &reply); |
| 559 |
614 |
| 560 XtMakeResizeRequest((Widget)w, req_width, req_height, &actual_width, &actual_height); |
615 XtMakeResizeRequest((Widget)w, req_width, req_height, &actual_width, &actual_height); |
| 561 w->mywidget.sizerequest = FALSE; |
616 w->grid.sizerequest = FALSE; |
| 562 //printf("size request: %d %d\n", (int)actual_width, (int)actual_height); |
617 //printf("size request: %d %d\n", (int)actual_width, (int)actual_height); |
| 563 } |
618 } |
| 564 |
619 |
| 565 |
620 |
| 566 |
621 |
| 567 } |
622 } |
| 568 |
623 |
| 569 // how much space can we add to each expanding col/row |
624 // how much space can we add to each expanding col/row |
| 570 int hexpand = 0; |
625 int hexpand = 0; |
| 571 int width_diff = (int)w->core.width - req_width; |
626 int width_diff = width - req_width; |
| 572 int hexpand2 = 0; |
627 int hexpand2 = 0; |
| 573 if(width_diff > 0 && num_cols_expanding > 0) { |
628 if(width_diff > 0 && num_cols_expanding > 0) { |
| 574 hexpand = width_diff / num_cols_expanding; |
629 hexpand = width_diff / num_cols_expanding; |
| 575 hexpand2 = width_diff-hexpand*num_cols_expanding; |
630 hexpand2 = width_diff-hexpand*num_cols_expanding; |
| 576 } |
631 } |
| 577 int x = 0; |
632 int x = w->grid.padding_left; |
| 578 for(int i=0;i<ncols;i++) { |
633 for(int i=0;i<ncols;i++) { |
| 579 cols[i].pos = x; |
634 cols[i].pos = x; |
| 580 if(cols[i].expand) { |
635 if(cols[i].expand) { |
| 581 cols[i].size += hexpand + hexpand2; |
636 cols[i].size += hexpand + hexpand2; |
| 582 } |
637 } |
| 583 x += cols[i].size + w->mywidget.columnspacing; |
638 if(cols[i].size > 0) { |
| |
639 x += cols[i].size + w->grid.columnspacing; |
| |
640 } |
| 584 |
641 |
| 585 hexpand2 = 0; |
642 hexpand2 = 0; |
| 586 } |
643 } |
| 587 |
644 |
| 588 int vexpand = 0; |
645 int vexpand = 0; |
| 589 int height_diff = (int)w->core.height - req_height; |
646 int height_diff = height - req_height; |
| 590 int vexpand2 = 0; |
647 int vexpand2 = 0; |
| 591 if(height_diff > 0 && num_rows_expanding > 0) { |
648 if(height_diff > 0 && num_rows_expanding > 0) { |
| 592 vexpand = height_diff / num_rows_expanding; |
649 vexpand = height_diff / num_rows_expanding; |
| 593 vexpand2 = height_diff-vexpand*num_rows_expanding; |
650 vexpand2 = height_diff-vexpand*num_rows_expanding; |
| 594 } |
651 } |
| 595 int y = 0; |
652 int y = w->grid.padding_bottom; |
| 596 for(int i=0;i<nrows;i++) { |
653 for(int i=0;i<nrows;i++) { |
| 597 rows[i].pos = y; |
654 rows[i].pos = y; |
| 598 if(rows[i].expand) { |
655 if(rows[i].expand) { |
| 599 rows[i].size += vexpand + vexpand2; |
656 rows[i].size += vexpand + vexpand2; |
| 600 } |
657 } |
| 601 y += rows[i].size += w->mywidget.rowspacing; |
658 if(rows[i].size > 0) { |
| |
659 y += rows[i].size += w->grid.rowspacing; |
| |
660 } |
| 602 |
661 |
| 603 vexpand2 = 0; |
662 vexpand2 = 0; |
| 604 } |
663 } |
| 605 |
664 |
| 606 for(int i=0;i<w->composite.num_children;i++) { |
665 for(int i=0;i<w->composite.num_children;i++) { |
| 607 Widget child = w->composite.children[i]; |
666 Widget child = w->composite.children[i]; |
| 608 GridConstraintRec *constraints = child->core.constraints; |
667 GridConstraintRec *constraints = child->core.constraints; |
| 609 GridDef c = cols[constraints->grid.x]; |
668 GridDef c = cols[constraints->grid.x]; |
| 610 GridDef r = rows[constraints->grid.y]; |
669 GridDef r = rows[constraints->grid.y]; |
| 611 int x = c.pos; |
670 int x = c.pos + constraints->grid.margin_left; |
| 612 int y = r.pos; |
671 int y = r.pos + constraints->grid.margin_top; |
| 613 int width = constraints->grid.pref_width; |
672 int width = constraints->grid.pref_width; |
| 614 int height = constraints->grid.pref_height; |
673 int height = constraints->grid.pref_height; |
| 615 if(constraints->grid.hfill) { |
674 if(constraints->grid.hfill) { |
| 616 if(constraints->grid.colspan > 1) { |
675 if(constraints->grid.colspan > 1) { |
| 617 Dimension cwidth = 0; |
676 Dimension cwidth = 0; |
| 618 for(int j=0;j<constraints->grid.colspan;j++) { |
677 for(int j=0;j<constraints->grid.colspan;j++) { |
| 619 if(constraints->grid.x+j < ncols) { |
678 if(constraints->grid.x+j < ncols) { |
| 620 cwidth += cols[constraints->grid.x+j].size + (j > 0 ? w->mywidget.columnspacing : 0); |
679 cwidth += cols[constraints->grid.x+j].size + (j > 0 ? w->grid.columnspacing : 0); |
| 621 } |
680 } |
| 622 } |
681 } |
| 623 width = cwidth; |
682 width = cwidth; |
| 624 } else { |
683 } else { |
| 625 width = c.size - w->mywidget.columnspacing; |
684 width = c.size - w->grid.columnspacing - constraints->grid.margin_left - constraints->grid.margin_right; |
| 626 } |
685 } |
| 627 } |
686 } |
| 628 if(constraints->grid.vfill) { |
687 if(constraints->grid.vfill) { |
| 629 if(constraints->grid.rowspan > 1) { |
688 if(constraints->grid.rowspan > 1) { |
| 630 Dimension cheight = 0; |
689 Dimension cheight = 0; |
| 631 for(int j=0;j<constraints->grid.rowspan;j++) { |
690 for(int j=0;j<constraints->grid.rowspan;j++) { |
| 632 if(constraints->grid.y+j < nrows) { |
691 if(constraints->grid.y+j < nrows) { |
| 633 cheight += rows[constraints->grid.y+j].size + (j > 0 ? w->mywidget.rowspacing : 0); |
692 cheight += rows[constraints->grid.y+j].size + (j > 0 ? w->grid.rowspacing : 0); |
| 634 } |
693 } |
| 635 } |
694 } |
| 636 height = cheight; |
695 height = cheight; |
| 637 } else { |
696 } else { |
| 638 height = r.size - w->mywidget.rowspacing; |
697 height = r.size - w->grid.rowspacing - constraints->grid.margin_top - constraints->grid.margin_bottom; |
| 639 } |
698 } |
| 640 } |
699 } |
| 641 |
700 |
| 642 if(width > 0 && height > 0) { |
701 if(width > 0 && height > 0) { |
| 643 XtConfigureWidget(child, x, y, width, height, child->core.border_width); |
702 XtConfigureWidget(child, x, y, width, height, child->core.border_width); |
| 644 } |
703 } |
| 645 //printf("child %d %d - %d %d\n", (int)child->core.x, (int)child->core.y, (int)child->core.width, (int)child->core.height); |
704 //printf("child %d %d - %d %d\n", (int)child->core.x, (int)child->core.y, (int)child->core.width, (int)child->core.height); |
| 646 } |
705 } |