textbox.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. #include <lib9.h>
  2. #include <draw.h>
  3. #include <interp.h>
  4. #include <isa.h>
  5. #include "../libinterp/runt.h"
  6. #include <drawif.h>
  7. #include <prefab.h>
  8. PCompound*
  9. layoutbox(Prefab_Environ *e, Draw_Rect rr, String *titletext, List *texttext)
  10. {
  11. Draw_Rect er, r, lr;
  12. PCompound *pc;
  13. Prefab_Compound *c;
  14. PElement *title, *text;
  15. Image *disp;
  16. Draw_Image *ddisp;
  17. Screen *screen;
  18. Heap *h;
  19. Rectangle t;
  20. int wid, w;
  21. Point p, pt;
  22. screen = lookupscreen(e->screen);
  23. if(screen == nil)
  24. return H;
  25. gchalt++;
  26. wid = Dx(rr);
  27. P2P(p, rr.min);
  28. title = H;
  29. text = H;
  30. if(texttext != H){
  31. er.min.x = 0;
  32. er.min.y = 0;
  33. er.max.x = wid-5;
  34. er.max.y = Dy(rr);
  35. text = layoutelement(e, texttext, er, EText);
  36. if(text == H){
  37. gchalt--;
  38. return H;
  39. }
  40. if(wid <= 0)
  41. wid = Dx(text->e.r)+5;
  42. }
  43. if(titletext != H){
  44. /* see how wide title wants to be */
  45. memset(&er, 0, sizeof er);
  46. title = textelement(e, titletext, er, ETitle);
  47. if(title == H){
  48. Errtitle:
  49. destroy(text);
  50. gchalt--;
  51. return H;
  52. }
  53. w = 2+1+3+Dx(title->e.r)+1;
  54. /* if title is wider than text, adjust wid accordingly */
  55. if(text!=0 && Dx(text->e.r)<w){
  56. if(Dx(text->e.r) < 100){ /* narrow text; don't let title get too wide */
  57. if(w > 250+5)
  58. w = 250+5;
  59. wid = w;
  60. }
  61. destroy(title);
  62. er.min.x = 0;
  63. er.min.y = 0;
  64. er.max.x = wid-5;
  65. er.max.y = 0;
  66. title = textelement(e, titletext, er, ETitle);
  67. if(title == H)
  68. goto Errtitle;
  69. }
  70. if(wid <= 0)
  71. wid = Dx(title->e.r)+5;
  72. }
  73. h = heapz(TCompound);
  74. pc = H2D(PCompound*, h);
  75. c = &pc->c;
  76. c->title = (Prefab_Element*)title;
  77. c->contents = (Prefab_Element*)text;
  78. /* now can just destroy c to clean up */
  79. r.min = DPOINT(p);
  80. r.max.x = r.min.x+wid;
  81. r.max.y = p.y+2+1 + 1+1;
  82. if(title != H)
  83. r.max.y += title->nkids*e->style->titlefont->height+1;
  84. if(text != H)
  85. r.max.y += Dy(text->e.r);
  86. er = edgerect(e, DPOINT(p), &r);
  87. R2R(t, er);
  88. disp = allocwindow(screen, t, Refbackup /*refreshcompound*/, DWhite);
  89. if(disp == nil){
  90. Err:
  91. destroy(c);
  92. gchalt--;
  93. return H;
  94. }
  95. if((ddisp=mkdrawimage(disp, e->screen, e->screen->display, nil)) == H){
  96. freeimage(disp);
  97. goto Err;
  98. }
  99. lr = r;
  100. if(title != H){
  101. pt.x = r.min.x+3;
  102. pt.y = r.min.y+3;
  103. translateelement(&title->e, pt);
  104. lr.min.y = title->e.r.max.y+1;
  105. }
  106. if(text != H)
  107. translateelement((Prefab_Element*)text, subpt(IPOINT(lr.min), IPOINT(text->e.r.min)));
  108. c->r = r;
  109. c->environ = e;
  110. c->image = ddisp;
  111. D2H(e)->ref++;
  112. pc->display = screen->display;
  113. gchalt--;
  114. return pc;
  115. }
  116. PCompound*
  117. textbox(Prefab_Environ *e, Draw_Rect rr, String *titletext, String *texttext)
  118. {
  119. PCompound *pc;
  120. List *l;
  121. l = listoflayout(e->style, texttext, EText);
  122. pc = layoutbox(e, rr, titletext, l);
  123. free(l);
  124. return pc;
  125. }