ui/motif/Grid.c

changeset 115
e57ca2747782
parent 110
c00e968d018b
equal deleted inserted replaced
114:3da24640513a 115:e57ca2747782
58 gridColumnSpacing, 58 gridColumnSpacing,
59 gridColumnSpacing, 59 gridColumnSpacing,
60 XmRDimension, 60 XmRDimension,
61 sizeof (Dimension), 61 sizeof (Dimension),
62 XtOffsetOf( GridRec, 62 XtOffsetOf( GridRec,
63 mywidget.columnspacing), 63 grid.columnspacing),
64 XmRImmediate, 64 XmRImmediate,
65 (XtPointer) 0 65 (XtPointer) 0
66 }, 66 },
67 { 67 {
68 gridRowSpacing, 68 gridRowSpacing,
69 gridRowSpacing, 69 gridRowSpacing,
70 XmRDimension, 70 XmRDimension,
71 sizeof (Dimension), 71 sizeof (Dimension),
72 XtOffsetOf( GridRec, 72 XtOffsetOf( GridRec,
73 mywidget.rowspacing), 73 grid.rowspacing),
74 XmRImmediate, 74 XmRImmediate,
75 (XtPointer) 0 75 (XtPointer) 0
76 }, 76 },
77 { 77 {
78 gridMargin, 78 gridPaddingLeft,
79 gridMargin, 79 gridPaddingLeft,
80 XmRDimension, 80 XmRDimension,
81 sizeof (Dimension), 81 sizeof (Dimension),
82 XtOffsetOf( GridRec, 82 XtOffsetOf( GridRec,
83 mywidget.margin), 83 grid.padding_left),
84 XmRImmediate,
85 (XtPointer) 0
86 },
87 {
88 gridPaddingRight,
89 gridPaddingRight,
90 XmRDimension,
91 sizeof (Dimension),
92 XtOffsetOf( GridRec,
93 grid.padding_right),
94 XmRImmediate,
95 (XtPointer) 0
96 },
97 {
98 gridPaddingTop,
99 gridPaddingTop,
100 XmRDimension,
101 sizeof (Dimension),
102 XtOffsetOf( GridRec,
103 grid.padding_top),
104 XmRImmediate,
105 (XtPointer) 0
106 },
107 {
108 gridPaddingBottom,
109 gridPaddingBottom,
110 XmRDimension,
111 sizeof (Dimension),
112 XtOffsetOf( GridRec,
113 grid.padding_bottom),
84 XmRImmediate, 114 XmRImmediate,
85 (XtPointer) 0 115 (XtPointer) 0
86 } 116 }
87 }; 117 };
88 118
303 333
304 } 334 }
305 void grid_initialize(Widget request, Widget new, ArgList args, Cardinal num_args) { 335 void grid_initialize(Widget request, Widget new, ArgList args, Cardinal num_args) {
306 Grid mn = (Grid)new; 336 Grid mn = (Grid)new;
307 337
308 mn->mywidget.max_col = 0; 338 mn->grid.max_col = 0;
309 mn->mywidget.max_row = 0; 339 mn->grid.max_row = 0;
310 340
311 } 341 }
312 void grid_realize(Widget w,XtValueMask *valueMask,XSetWindowAttributes *attributes) { 342 void grid_realize(Widget w,XtValueMask *valueMask,XSetWindowAttributes *attributes) {
313 Grid grid = (Grid)w; 343 Grid grid = (Grid)w;
314 XtMakeResizeRequest(w, 400, 400, NULL, NULL); 344 XtMakeResizeRequest(w, 400, 400, NULL, NULL);
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
425 if(constraints->grid.pref_height == 0) { 461 if(constraints->grid.pref_height == 0) {
426 constraints->grid.pref_height = child->core.height; 462 constraints->grid.pref_height = child->core.height;
427 } 463 }
428 if(constraints->grid.pref_width < constraints->grid.min_width) { 464 if(constraints->grid.pref_width < constraints->grid.min_width) {
429 constraints->grid.pref_width = constraints->grid.min_width; 465 constraints->grid.pref_width = constraints->grid.min_width;
466 }
467 int elm_width = constraints->grid.pref_width + constraints->grid.margin_left + constraints->grid.margin_right;
468 int elm_height = constraints->grid.pref_height + constraints->grid.margin_top + constraints->grid.margin_bottom;
469 if(!XtIsManaged(child)) {
470 elm_width = 0;
471 elm_height = 0;
430 } 472 }
431 473
432 if(constraints->grid.colspan > span_max || constraints->grid.rowspan > span_max) { 474 if(constraints->grid.colspan > span_max || constraints->grid.rowspan > span_max) {
433 continue; 475 continue;
434 } 476 }
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 }

mercurial