1 /* ------------- listbox.c ------------ */
5 #ifdef INCLUDE_EXTENDEDSELECTIONS
6 static int ExtendSelections(DFWINDOW
, int, int);
7 static void TestExtended(DFWINDOW
, PARAM
);
8 static void ClearAllSelections(DFWINDOW
);
9 static void SetSelection(DFWINDOW
, int);
10 static void FlipSelection(DFWINDOW
, int);
11 static void ClearSelection(DFWINDOW
, int);
13 #define TestExtended(w,p) /**/
15 static void ChangeSelection(DFWINDOW
, int, int);
16 static void WriteSelection(DFWINDOW
, int, int, DFRECT
*);
17 static BOOL
SelectionInWindow(DFWINDOW
, int);
19 static int py
= -1; /* the previous y mouse coordinate */
21 #ifdef INCLUDE_EXTENDEDSELECTIONS
22 /* --------- SHIFT_F8 Key ------------ */
23 static void AddModeKey(DFWINDOW wnd
)
25 if (isMultiLine(wnd
)) {
27 DfSendMessage(GetParent(wnd
), ADDSTATUS
,
28 wnd
->AddMode
? ((PARAM
) "Add Mode") : 0, 0);
33 /* --------- UP (Up Arrow) Key ------------ */
34 static void UpKey(DFWINDOW wnd
, PARAM p2
)
36 if (wnd
->selection
> 0) {
37 if (wnd
->selection
== wnd
->wtop
) {
38 BaseWndProc(LISTBOX
, wnd
, KEYBOARD
, UP
, p2
);
39 DfPostMessage(wnd
, LB_SELECTION
, wnd
->selection
-1,
40 isMultiLine(wnd
) ? p2
: FALSE
);
43 int newsel
= wnd
->selection
-1;
44 if (wnd
->wlines
== ClientHeight(wnd
))
45 while (*TextLine(wnd
, newsel
) == LINE
)
47 DfPostMessage(wnd
, LB_SELECTION
, newsel
,
48 #ifdef INCLUDE_EXTENDEDSELECTIONS
49 isMultiLine(wnd
) ? p2
:
56 /* --------- DN (Down Arrow) Key ------------ */
57 static void DnKey(DFWINDOW wnd
, PARAM p2
)
59 if (wnd
->selection
< wnd
->wlines
-1) {
60 if (wnd
->selection
== wnd
->wtop
+ClientHeight(wnd
)-1) {
61 BaseWndProc(LISTBOX
, wnd
, KEYBOARD
, DN
, p2
);
62 DfPostMessage(wnd
, LB_SELECTION
, wnd
->selection
+1,
63 isMultiLine(wnd
) ? p2
: FALSE
);
66 int newsel
= wnd
->selection
+1;
67 if (wnd
->wlines
== ClientHeight(wnd
))
68 while (*TextLine(wnd
, newsel
) == LINE
)
70 DfPostMessage(wnd
, LB_SELECTION
, newsel
,
71 #ifdef INCLUDE_EXTENDEDSELECTIONS
72 isMultiLine(wnd
) ? p2
:
79 /* --------- HOME and PGUP Keys ------------ */
80 static void HomePgUpKey(DFWINDOW wnd
, PARAM p1
, PARAM p2
)
82 BaseWndProc(LISTBOX
, wnd
, KEYBOARD
, p1
, p2
);
83 DfPostMessage(wnd
, LB_SELECTION
, wnd
->wtop
,
84 #ifdef INCLUDE_EXTENDEDSELECTIONS
85 isMultiLine(wnd
) ? p2
:
90 /* --------- END and PGDN Keys ------------ */
91 static void EndPgDnKey(DFWINDOW wnd
, PARAM p1
, PARAM p2
)
94 BaseWndProc(LISTBOX
, wnd
, KEYBOARD
, p1
, p2
);
95 bot
= wnd
->wtop
+ClientHeight(wnd
)-1;
96 if (bot
> wnd
->wlines
-1)
98 DfPostMessage(wnd
, LB_SELECTION
, bot
,
99 #ifdef INCLUDE_EXTENDEDSELECTIONS
100 isMultiLine(wnd
) ? p2
:
105 #ifdef INCLUDE_EXTENDEDSELECTIONS
106 /* --------- Space Bar Key ------------ */
107 static void SpacebarKey(DFWINDOW wnd
, PARAM p2
)
109 if (isMultiLine(wnd
)) {
110 int sel
= DfSendMessage(wnd
, LB_CURRENTSELECTION
, 0, 0);
113 FlipSelection(wnd
, sel
);
114 if (ItemSelected(wnd
, sel
)) {
115 if (!((int) p2
& (LEFTSHIFT
| RIGHTSHIFT
)))
116 wnd
->AnchorPoint
= sel
;
117 ExtendSelections(wnd
, sel
, (int) p2
);
120 wnd
->AnchorPoint
= -1;
121 DfSendMessage(wnd
, PAINT
, 0, 0);
127 /* --------- Enter ('\r') Key ------------ */
128 static void EnterKey(DFWINDOW wnd
)
130 if (wnd
->selection
!= -1) {
131 DfSendMessage(wnd
, LB_SELECTION
, wnd
->selection
, TRUE
);
132 DfSendMessage(wnd
, LB_CHOOSE
, wnd
->selection
, 0);
136 /* --------- All Other Key Presses ------------ */
137 static void KeyPress(DFWINDOW wnd
, PARAM p1
, PARAM p2
)
139 int sel
= wnd
->selection
+1;
140 while (sel
< wnd
->wlines
) {
141 char *cp
= TextLine(wnd
, sel
);
144 #ifdef INCLUDE_EXTENDEDSELECTIONS
145 if (isMultiLine(wnd
))
148 /* --- special for directory list box --- */
151 if (tolower(*cp
) == (int)p1
) {
152 DfSendMessage(wnd
, LB_SELECTION
, sel
,
153 isMultiLine(wnd
) ? p2
: FALSE
);
154 if (!SelectionInWindow(wnd
, sel
)) {
155 wnd
->wtop
= sel
-ClientHeight(wnd
)+1;
156 DfSendMessage(wnd
, PAINT
, 0, 0);
164 /* --------- KEYBOARD Message ------------ */
165 static int KeyboardMsg(DFWINDOW wnd
, PARAM p1
, PARAM p2
)
168 #ifdef INCLUDE_EXTENDEDSELECTIONS
174 TestExtended(wnd
, p2
);
178 TestExtended(wnd
, p2
);
183 TestExtended(wnd
, p2
);
184 HomePgUpKey(wnd
, p1
, p2
);
188 TestExtended(wnd
, p2
);
189 EndPgDnKey(wnd
, p1
, p2
);
191 #ifdef INCLUDE_EXTENDEDSELECTIONS
193 SpacebarKey(wnd
, p2
);
200 KeyPress(wnd
, p1
, p2
);
206 /* ------- LEFT_BUTTON Message -------- */
207 static int LeftButtonMsg(DFWINDOW wnd
, PARAM p1
, PARAM p2
)
209 int my
= (int) p2
- GetTop(wnd
);
210 if (my
>= wnd
->wlines
-wnd
->wtop
)
211 my
= wnd
->wlines
- wnd
->wtop
;
213 if (!InsideRect(p1
, p2
, ClientRect(wnd
)))
215 if (wnd
->wlines
&& my
!= py
) {
216 int sel
= wnd
->wtop
+my
-1;
217 #ifdef INCLUDE_EXTENDEDSELECTIONS
219 if (!(sh
& (LEFTSHIFT
| RIGHTSHIFT
))) {
221 ClearAllSelections(wnd
);
222 wnd
->AnchorPoint
= sel
;
223 DfSendMessage(wnd
, PAINT
, 0, 0);
226 DfSendMessage(wnd
, LB_SELECTION
, sel
, TRUE
);
232 /* ------------- DOUBLE_CLICK Message ------------ */
233 static int DoubleClickMsg(DFWINDOW wnd
, PARAM p1
, PARAM p2
)
235 if (WindowMoving
|| WindowSizing
)
238 DFRECT rc
= ClientRect(wnd
);
239 BaseWndProc(LISTBOX
, wnd
, DOUBLE_CLICK
, p1
, p2
);
240 if (InsideRect(p1
, p2
, rc
))
241 DfSendMessage(wnd
, LB_CHOOSE
, wnd
->selection
, 0);
246 /* ------------ ADDTEXT Message -------------- */
247 static int AddTextMsg(DFWINDOW wnd
, PARAM p1
, PARAM p2
)
249 int rtn
= BaseWndProc(LISTBOX
, wnd
, ADDTEXT
, p1
, p2
);
250 if (wnd
->selection
== -1)
251 DfSendMessage(wnd
, LB_SETSELECTION
, 0, 0);
252 #ifdef INCLUDE_EXTENDEDSELECTIONS
253 if (*(char *)p1
== LISTSELECTOR
)
259 /* --------- GETTEXT Message ------------ */
260 static void GetTextMsg(DFWINDOW wnd
, PARAM p1
, PARAM p2
)
263 char *cp1
= (char *)p1
;
264 char *cp2
= TextLine(wnd
, (int)p2
);
265 while (cp2
&& *cp2
&& *cp2
!= '\n')
271 /* --------- LISTBOX Window Processing Module ------------ */
272 int ListBoxProc(DFWINDOW wnd
, DFMESSAGE msg
, PARAM p1
, PARAM p2
)
276 BaseWndProc(LISTBOX
, wnd
, msg
, p1
, p2
);
278 #ifdef INCLUDE_EXTENDEDSELECTIONS
279 wnd
->AnchorPoint
= -1;
283 if (WindowMoving
|| WindowSizing
)
285 if (KeyboardMsg(wnd
, p1
, p2
))
289 if (LeftButtonMsg(wnd
, p1
, p2
) == TRUE
)
293 if (DoubleClickMsg(wnd
, p1
, p2
))
296 case DFM_BUTTON_RELEASED
:
297 if (WindowMoving
|| WindowSizing
|| VSliding
)
302 return AddTextMsg(wnd
, p1
, p2
);
304 GetTextMsg(wnd
, p1
, p2
);
308 #ifdef INCLUDE_EXTENDEDSELECTIONS
309 wnd
->AnchorPoint
= -1;
311 wnd
->SelectCount
= 0;
314 BaseWndProc(LISTBOX
, wnd
, msg
, p1
, p2
);
315 WriteSelection(wnd
, wnd
->selection
, TRUE
, (DFRECT
*)p1
);
322 BaseWndProc(LISTBOX
, wnd
, msg
, p1
, p2
);
323 WriteSelection(wnd
,wnd
->selection
,TRUE
,NULL
);
326 DfSendMessage(GetParent(wnd
), LB_CHOOSE
, p1
, p2
);
329 ChangeSelection(wnd
, (int) p1
, (int) p2
);
330 DfSendMessage(GetParent(wnd
), LB_SELECTION
,
333 case LB_CURRENTSELECTION
:
334 return wnd
->selection
;
335 case LB_SETSELECTION
:
336 ChangeSelection(wnd
, (int) p1
, 0);
338 #ifdef INCLUDE_EXTENDEDSELECTIONS
340 if (isMultiLine(wnd
) && wnd
->AddMode
) {
341 wnd
->AddMode
= FALSE
;
342 DfSendMessage(GetParent(wnd
), ADDSTATUS
, 0, 0);
349 return BaseWndProc(LISTBOX
, wnd
, msg
, p1
, p2
);
352 static BOOL
SelectionInWindow(DFWINDOW wnd
, int sel
)
354 return (wnd
->wlines
&& sel
>= wnd
->wtop
&&
355 sel
< wnd
->wtop
+ClientHeight(wnd
));
358 static void WriteSelection(DFWINDOW wnd
, int sel
,
359 int reverse
, DFRECT
*rc
)
362 if (SelectionInWindow(wnd
, sel
))
363 WriteTextLine(wnd
, rc
, sel
, reverse
);
366 #ifdef INCLUDE_EXTENDEDSELECTIONS
367 /* ----- Test for extended selections in the listbox ----- */
368 static void TestExtended(DFWINDOW wnd
, PARAM p2
)
370 if (isMultiLine(wnd
) && !wnd
->AddMode
&&
371 !((int) p2
& (LEFTSHIFT
| RIGHTSHIFT
))) {
372 if (wnd
->SelectCount
> 1) {
373 ClearAllSelections(wnd
);
374 DfSendMessage(wnd
, PAINT
, 0, 0);
379 /* ----- Clear selections in the listbox ----- */
380 static void ClearAllSelections(DFWINDOW wnd
)
382 if (isMultiLine(wnd
) && wnd
->SelectCount
> 0) {
384 for (sel
= 0; sel
< wnd
->wlines
; sel
++)
385 ClearSelection(wnd
, sel
);
389 /* ----- Invert a selection in the listbox ----- */
390 static void FlipSelection(DFWINDOW wnd
, int sel
)
392 if (isMultiLine(wnd
)) {
393 if (ItemSelected(wnd
, sel
))
394 ClearSelection(wnd
, sel
);
396 SetSelection(wnd
, sel
);
400 static int ExtendSelections(DFWINDOW wnd
, int sel
, int shift
)
402 if (shift
& (LEFTSHIFT
| RIGHTSHIFT
) &&
403 wnd
->AnchorPoint
!= -1) {
405 int j
= wnd
->AnchorPoint
;
411 SetSelection(wnd
, j
++);
417 static void SetSelection(DFWINDOW wnd
, int sel
)
419 if (isMultiLine(wnd
) && !ItemSelected(wnd
, sel
)) {
420 char *lp
= TextLine(wnd
, sel
);
426 static void ClearSelection(DFWINDOW wnd
, int sel
)
428 if (isMultiLine(wnd
) && ItemSelected(wnd
, sel
)) {
429 char *lp
= TextLine(wnd
, sel
);
435 BOOL
ItemSelected(DFWINDOW wnd
, int sel
)
437 if (sel
!= -1 && isMultiLine(wnd
) && sel
< wnd
->wlines
) {
438 char *cp
= TextLine(wnd
, sel
);
439 return (int)((*cp
) & 255) == LISTSELECTOR
;
445 static void ChangeSelection(DFWINDOW wnd
,int sel
,int shift
)
447 if (sel
!= wnd
->selection
) {
448 #ifdef INCLUDE_EXTENDEDSELECTIONS
449 if (isMultiLine(wnd
)) {
452 ClearAllSelections(wnd
);
453 sels
= ExtendSelections(wnd
, sel
, shift
);
455 DfSendMessage(wnd
, PAINT
, 0, 0);
456 if (sels
== 0 && !wnd
->AddMode
) {
457 ClearSelection(wnd
, wnd
->selection
);
458 SetSelection(wnd
, sel
);
459 wnd
->AnchorPoint
= sel
;
463 WriteSelection(wnd
, wnd
->selection
, FALSE
, NULL
);
464 wnd
->selection
= sel
;
465 WriteSelection(wnd
, sel
, TRUE
, NULL
);