frselect.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <draw.h>
  4. #include <thread.h>
  5. #include <mouse.h>
  6. #include <frame.h>
  7. static
  8. int
  9. region(int a, int b)
  10. {
  11. if(a < b)
  12. return -1;
  13. if(a == b)
  14. return 0;
  15. return 1;
  16. }
  17. void
  18. frselect(Frame *f, Mousectl *mc) /* when called, button 1 is down */
  19. {
  20. ulong p0, p1, q;
  21. Point mp, pt0, pt1, qt;
  22. int reg, b, scrled;
  23. mp = mc->xy;
  24. b = mc->buttons;
  25. f->modified = 0;
  26. frdrawsel(f, frptofchar(f, f->p0), f->p0, f->p1, 0);
  27. p0 = p1 = frcharofpt(f, mp);
  28. f->p0 = p0;
  29. f->p1 = p1;
  30. pt0 = frptofchar(f, p0);
  31. pt1 = frptofchar(f, p1);
  32. frdrawsel(f, pt0, p0, p1, 1);
  33. reg = 0;
  34. do{
  35. scrled = 0;
  36. if(f->scroll){
  37. if(mp.y < f->r.min.y){
  38. (*f->scroll)(f, -(f->r.min.y-mp.y)/(int)f->font->height-1);
  39. p0 = f->p1;
  40. p1 = f->p0;
  41. scrled = 1;
  42. }else if(mp.y > f->r.max.y){
  43. (*f->scroll)(f, (mp.y-f->r.max.y)/(int)f->font->height+1);
  44. p0 = f->p0;
  45. p1 = f->p1;
  46. scrled = 1;
  47. }
  48. if(scrled){
  49. if(reg != region(p1, p0))
  50. q = p0, p0 = p1, p1 = q; /* undo the swap that will happen below */
  51. pt0 = frptofchar(f, p0);
  52. pt1 = frptofchar(f, p1);
  53. reg = region(p1, p0);
  54. }
  55. }
  56. q = frcharofpt(f, mp);
  57. if(p1 != q){
  58. if(reg != region(q, p0)){ /* crossed starting point; reset */
  59. if(reg > 0)
  60. frdrawsel(f, pt0, p0, p1, 0);
  61. else if(reg < 0)
  62. frdrawsel(f, pt1, p1, p0, 0);
  63. p1 = p0;
  64. pt1 = pt0;
  65. reg = region(q, p0);
  66. if(reg == 0)
  67. frdrawsel(f, pt0, p0, p1, 1);
  68. }
  69. qt = frptofchar(f, q);
  70. if(reg > 0){
  71. if(q > p1)
  72. frdrawsel(f, pt1, p1, q, 1);
  73. else if(q < p1)
  74. frdrawsel(f, qt, q, p1, 0);
  75. }else if(reg < 0){
  76. if(q > p1)
  77. frdrawsel(f, pt1, p1, q, 0);
  78. else
  79. frdrawsel(f, qt, q, p1, 1);
  80. }
  81. p1 = q;
  82. pt1 = qt;
  83. }
  84. f->modified = 0;
  85. if(p0 < p1) {
  86. f->p0 = p0;
  87. f->p1 = p1;
  88. }
  89. else {
  90. f->p0 = p1;
  91. f->p1 = p0;
  92. }
  93. if(scrled)
  94. (*f->scroll)(f, 0);
  95. flushimage(f->display, 1);
  96. if(!scrled)
  97. readmouse(mc);
  98. mp = mc->xy;
  99. }while(mc->buttons == b);
  100. }
  101. void
  102. frselectpaint(Frame *f, Point p0, Point p1, Image *col)
  103. {
  104. int n;
  105. Point q0, q1;
  106. q0 = p0;
  107. q1 = p1;
  108. q0.y += f->font->height;
  109. q1.y += f->font->height;
  110. n = (p1.y-p0.y)/f->font->height;
  111. if(f->b == nil)
  112. drawerror(f->display, "frselectpaint b==0");
  113. if(p0.y == f->r.max.y)
  114. return;
  115. if(n == 0)
  116. draw(f->b, Rpt(p0, q1), col, nil, ZP);
  117. else{
  118. if(p0.x >= f->r.max.x)
  119. p0.x = f->r.max.x-1;
  120. draw(f->b, Rect(p0.x, p0.y, f->r.max.x, q0.y), col, nil, ZP);
  121. if(n > 1)
  122. draw(f->b, Rect(f->r.min.x, q0.y, f->r.max.x, p1.y),
  123. col, nil, ZP);
  124. draw(f->b, Rect(f->r.min.x, p1.y, q1.x, q1.y),
  125. col, nil, ZP);
  126. }
  127. }