Introduction
Introduction Statistics Contact Development Disclaimer Help
menuhit.c - sam - An updated version of the sam text editor.
git clone git://vernunftzentrum.de/sam.git
Log
Files
Refs
LICENSE
---
menuhit.c (6868B)
---
1 /* Copyright (c) 1998 Lucent Technologies - All rights reserved. */
2 #include <u.h>
3 #include <libg.h>
4 #include "libgint.h"
5
6 enum
7 {
8 Margin = 3, /* outside to text */
9 Border = 2, /* outside to selection boxes */
10 Blackborder = 1, /* width of outlining border */
11 Vspacing = 1, /* extra spacing between lines of text */
12 Maxunscroll = 25, /* maximum #entries before scrolling turns on */
13 Nscroll = 20, /* number entries in scrolling part */
14 Scrollwid = 14, /* width of scroll bar */
15 Gap = 4 /* between text and scroll bar */
16 };
17
18 extern Bitmap *darkgrey;
19
20 static int
21 fontheight() {
22 return font->ascent + font->descent;
23 }
24
25 /*
26 * r is a rectangle holding the text elements.
27 * return the rectangle, including its black edge, holding element i.
28 */
29 static Rectangle
30 menurect(Rectangle r, int i)
31 {
32 if(i < 0)
33 return Rect(0, 0, 0, 0);
34 r.min.y += (fontheight()+Vspacing)*i;
35 r.max.y = r.min.y+fontheight()+Vspacing;
36 return inset(r, Border-Margin);
37 }
38
39 /*
40 * r is a rectangle holding the text elements.
41 * return the element number containing p.
42 */
43 static int
44 menusel(Rectangle r, Point p)
45 {
46 if(!ptinrect(p, r))
47 return -1;
48 return (p.y-r.min.y)/(fontheight()+Vspacing);
49 }
50
51 /*
52 * menur is a rectangle holding all the highlightable text elements.
53 * track mouse while inside the box, return what's selected when button
54 * is raised, -1 as soon as it leaves box.
55 * invariant: nothing is highlighted on entry or exit.
56 */
57 static int
58 menuscan(int but, Mouse *m, Rectangle menur, int lasti)
59 {
60 int i;
61 Rectangle r;
62
63 r = menurect(menur, lasti);
64 bitblt(&screen, r.min, &screen, r, F&~D);
65 *m = emouse();
66 while(m->buttons & (1<<(but-1))){
67 *m = emouse();
68 i = menusel(menur, m->xy);
69 if(i == lasti)
70 continue;
71 bitblt(&screen, r.min, &screen, r, F&~D);
72 if(i == -1)
73 return i;
74 r = menurect(menur, i);
75 bitblt(&screen, r.min, &screen, r, F&~D);
76 lasti = i;
77 }
78 return lasti;
79 }
80
81 void
82 menupaint(Menu *menu, Rectangle textr, int off, int nitemdrawn)
83 {
84 int i;
85 Point pt;
86 Rectangle r;
87 char *item;
88
89 r = inset(textr, Border-Margin);
90 bitblt(&screen, r.min, &screen, r, 0);
91 pt = Pt(textr.min.x+textr.max.x, textr.min.y);
92 for(i = 0; i<nitemdrawn; i++, pt.y += fontheight()+Vspacing){
93 item = menu->item? menu->item[i+off] : (*menu->gen)(i+off);
94 string(&screen,
95 Pt((pt.x-strwidth(font, item))/2, pt.y),
96 font, item, S);
97 }
98 }
99
100 static void
101 menuscrollpaint(Rectangle scrollr, int off, int nitem, int nitemdrawn)
102 {
103 Rectangle r;
104
105 bitblt(&screen, scrollr.min, &screen, scrollr, 0);
106 r.min.x = scrollr.min.x;
107 r.max.x = scrollr.max.x;
108 r.min.y = scrollr.min.y + (Dy(scrollr)*off)/nitem;
109 r.max.y = scrollr.min.y + (Dy(scrollr)*(off+nitemdrawn))/nitem;
110 if(r.max.y < r.min.y+2)
111 r.max.y = r.min.y+2;
112 border(&screen, r, 1, F, _bgpixel);
113 if(darkgrey)
114 texture(&screen, inset(r, 1), darkgrey, S);
115 }
116
117 int
118 menuhit(int but, Mouse *m, Menu *menu)
119 {
120 int i, nitem, nitemdrawn, maxwid, lasti, off, noff, wid, screenitem;
121 bool scrolling;
122 Rectangle r, menur, sc, textr, scrollr;
123 Bitmap *b;
124 Point pt;
125 char *item;
126 extern unsigned int cursor;
127 unsigned int oldcursor = cursor;
128
129 cursorswitch(ArrowCursor);
130 sc = screen.clipr;
131 clipr(&screen, screen.r);
132 maxwid = 0;
133 for(nitem = 0;
134 (item = menu->item? menu->item[nitem] : (*menu->gen)(nitem));
135 nitem++){
136 i = strwidth(font, item);
137 if(i > maxwid)
138 maxwid = i;
139 }
140 if(menu->lasthit<0 || menu->lasthit>=nitem)
141 menu->lasthit = 0;
142 screenitem = (Dy(screen.r)-10)/(fontheight()+Vspacing);
143 if(nitem>Maxunscroll || nitem>screenitem){
144 scrolling = true;
145 nitemdrawn = Nscroll;
146 if(nitemdrawn > screenitem)
147 nitemdrawn = screenitem;
148 wid = maxwid + Gap + Scrollwid;
149 off = menu->lasthit - nitemdrawn/2;
150 if(off < 0)
151 off = 0;
152 if(off > nitem-nitemdrawn)
153 off = nitem-nitemdrawn;
154 lasti = menu->lasthit-off;
155 }else{
156 scrolling = false;
157 nitemdrawn = nitem;
158 wid = maxwid;
159 off = 0;
160 lasti = menu->lasthit;
161 }
162 r = inset(Rect(0, 0, wid, nitemdrawn*(fontheight()+Vspacing)), -Marg…
163 r = rsubp(r, Pt(wid/2, lasti*(fontheight()+Vspacing)+fontheight()/2)…
164 r = raddp(r, m->xy);
165 pt = Pt(0, 0);
166 if(r.max.x>screen.r.max.x)
167 pt.x = screen.r.max.x-r.max.x;
168 if(r.max.y>screen.r.max.y)
169 pt.y = screen.r.max.y-r.max.y;
170 if(r.min.x<screen.r.min.x)
171 pt.x = screen.r.min.x-r.min.x;
172 if(r.min.y<screen.r.min.y)
173 pt.y = screen.r.min.y-r.min.y;
174 menur = raddp(r, pt);
175 textr.max.x = menur.max.x-Margin;
176 textr.min.x = textr.max.x-maxwid;
177 textr.min.y = menur.min.y+Margin;
178 textr.max.y = textr.min.y + nitemdrawn*(fontheight()+Vspacing);
179 if(scrolling){
180 scrollr = inset(menur, Border);
181 scrollr.max.x = scrollr.min.x+Scrollwid;
182 }else
183 scrollr = Rect(0, 0, 0, 0);
184
185 b = balloc(menur, screen.ldepth);
186 if(b == 0)
187 b = &screen;
188 bitblt(b, menur.min, &screen, menur, S);
189 bitblt(&screen, menur.min, &screen, menur, 0);
190 border(&screen, menur, Blackborder, F, _bgpixel);
191 r = menurect(textr, lasti);
192 cursorset(divpt(add(r.min, r.max), 2));
193 menupaint(menu, textr, off, nitemdrawn);
194 if(scrolling)
195 menuscrollpaint(scrollr, off, nitem, nitemdrawn);
196 r = menurect(textr, lasti);
197 cursorset(divpt(add(r.min, r.max), 2));
198 menupaint(menu, textr, off, nitemdrawn);
199 if(scrolling)
200 menuscrollpaint(scrollr, off, nitem, nitemdrawn);
201 while(m->buttons & (1<<(but-1))){
202 lasti = menuscan(but, m, textr, lasti);
203 if(lasti >= 0)
204 break;
205 while(!ptinrect(m->xy, textr) && (m->buttons & (1<<(but-1)))){
206 if(scrolling && ptinrect(m->xy, scrollr)){
207 noff = ((m->xy.y-scrollr.min.y)*nitem)/Dy(scrollr);
208 noff -= nitemdrawn/2;
209 if(noff < 0)
210 noff = 0;
211 if(noff > nitem-nitemdrawn)
212 noff = nitem-nitemdrawn;
213 if(noff != off){
214 off = noff;
215 menupaint(menu, textr, off, nitemdrawn);
216 menuscrollpaint(scrollr, off, nitem, nitemdrawn);
217 }
218 }
219 *m = emouse();
220 }
221 }
222 bitblt(&screen, menur.min, b, menur, S);
223 if(b != &screen)
224 bfree(b);
225 clipr(&screen, sc);
226 if(lasti >= 0){
227 menu->lasthit = lasti+off;
228 return cursorswitch(oldcursor), menu->lasthit;
229 }
230 cursorswitch(oldcursor);
231 return -1;
232 }
You are viewing proxied material from vernunftzentrum.de. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.