scrl.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <draw.h>
  4. #include <thread.h>
  5. #include <cursor.h>
  6. #include <mouse.h>
  7. #include <keyboard.h>
  8. #include <frame.h>
  9. #include <fcall.h>
  10. #include <plumb.h>
  11. #include "dat.h"
  12. #include "fns.h"
  13. static Image *scrtmp;
  14. static
  15. Rectangle
  16. scrpos(Rectangle r, uint p0, uint p1, uint tot)
  17. {
  18. Rectangle q;
  19. int h;
  20. q = r;
  21. h = q.max.y-q.min.y;
  22. if(tot == 0)
  23. return q;
  24. if(tot > 1024*1024){
  25. tot>>=10;
  26. p0>>=10;
  27. p1>>=10;
  28. }
  29. if(p0 > 0)
  30. q.min.y += h*p0/tot;
  31. if(p1 < tot)
  32. q.max.y -= h*(tot-p1)/tot;
  33. if(q.max.y < q.min.y+2){
  34. if(q.min.y+2 <= r.max.y)
  35. q.max.y = q.min.y+2;
  36. else
  37. q.min.y = q.max.y-2;
  38. }
  39. return q;
  40. }
  41. void
  42. scrlresize(void)
  43. {
  44. freeimage(scrtmp);
  45. scrtmp = allocimage(display, Rect(0, 0, 32, screen->r.max.y), screen->chan, 0, DNofill);
  46. if(scrtmp == nil)
  47. error("scroll alloc");
  48. }
  49. void
  50. textscrdraw(Text *t)
  51. {
  52. Rectangle r, r1, r2;
  53. Image *b;
  54. if(t->w==nil || t!=&t->w->body)
  55. return;
  56. if(scrtmp == nil)
  57. scrlresize();
  58. r = t->scrollr;
  59. b = scrtmp;
  60. r1 = r;
  61. r1.min.x = 0;
  62. r1.max.x = Dx(r);
  63. r2 = scrpos(r1, t->org, t->org+t->nchars, t->file->nc);
  64. if(!eqrect(r2, t->lastsr)){
  65. t->lastsr = r2;
  66. draw(b, r1, t->cols[BORD], nil, ZP);
  67. draw(b, r2, t->cols[BACK], nil, ZP);
  68. r2.min.x = r2.max.x-1;
  69. draw(b, r2, t->cols[BORD], nil, ZP);
  70. draw(t->b, r, b, nil, Pt(0, r1.min.y));
  71. /*flushimage(display, 1);/*BUG?*/
  72. }
  73. }
  74. void
  75. scrsleep(uint dt)
  76. {
  77. Timer *timer;
  78. static Alt alts[3];
  79. timer = timerstart(dt);
  80. alts[0].c = timer->c;
  81. alts[0].v = nil;
  82. alts[0].op = CHANRCV;
  83. alts[1].c = mousectl->c;
  84. alts[1].v = &mousectl->Mouse;
  85. alts[1].op = CHANRCV;
  86. alts[2].op = CHANEND;
  87. for(;;)
  88. switch(alt(alts)){
  89. case 0:
  90. timerstop(timer);
  91. return;
  92. case 1:
  93. timercancel(timer);
  94. return;
  95. }
  96. }
  97. void
  98. textscroll(Text *t, int but)
  99. {
  100. uint p0, oldp0;
  101. Rectangle s;
  102. int x, y, my, h, first;
  103. s = insetrect(t->scrollr, 1);
  104. h = s.max.y-s.min.y;
  105. x = (s.min.x+s.max.x)/2;
  106. oldp0 = ~0;
  107. first = TRUE;
  108. do{
  109. flushimage(display, 1);
  110. if(mouse->xy.x<s.min.x || s.max.x<=mouse->xy.x){
  111. readmouse(mousectl);
  112. }else{
  113. my = mouse->xy.y;
  114. if(my < s.min.y)
  115. my = s.min.y;
  116. if(my >= s.max.y)
  117. my = s.max.y;
  118. if(!eqpt(mouse->xy, Pt(x, my))){
  119. moveto(mousectl, Pt(x, my));
  120. readmouse(mousectl); /* absorb event generated by moveto() */
  121. }
  122. if(but == 2){
  123. y = my;
  124. if(y > s.max.y-2)
  125. y = s.max.y-2;
  126. if(t->file->nc > 1024*1024)
  127. p0 = ((t->file->nc>>10)*(y-s.min.y)/h)<<10;
  128. else
  129. p0 = t->file->nc*(y-s.min.y)/h;
  130. if(oldp0 != p0)
  131. textsetorigin(t, p0, FALSE);
  132. oldp0 = p0;
  133. readmouse(mousectl);
  134. continue;
  135. }
  136. if(but == 1)
  137. p0 = textbacknl(t, t->org, (my-s.min.y)/t->font->height);
  138. else
  139. p0 = t->org+frcharofpt(t, Pt(s.max.x, my));
  140. if(oldp0 != p0)
  141. textsetorigin(t, p0, TRUE);
  142. oldp0 = p0;
  143. /* debounce */
  144. if(first){
  145. flushimage(display, 1);
  146. sleep(200);
  147. nbrecv(mousectl->c, &mousectl->Mouse);
  148. first = FALSE;
  149. }
  150. scrsleep(80);
  151. }
  152. }while(mouse->buttons & (1<<(but-1)));
  153. while(mouse->buttons)
  154. readmouse(mousectl);
  155. }