frselect.c 3.0 KB

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