1 /* ------------- editbox.c ------------ */
2 #include "dflat32/dflat.h"
4 #define EditBufLen(wnd) (isMultiLine(wnd) ? EDITLEN : ENTRYLEN)
5 #define SetLinePointer(wnd, ln) (wnd->CurrLine = ln)
6 #define isWhite(c) ((c)==' '||(c)=='\n')
7 /* ---------- local prototypes ----------- */
8 static void SaveDeletedText(DFWINDOW
, char *, int);
9 static void Forward(DFWINDOW
);
10 static void Backward(DFWINDOW
);
11 static void End(DFWINDOW
);
12 static void Home(DFWINDOW
);
13 static void Downward(DFWINDOW
);
14 static void Upward(DFWINDOW
);
15 static void StickEnd(DFWINDOW
);
16 static void NextWord(DFWINDOW
);
17 static void PrevWord(DFWINDOW
);
18 static void ModTextPointers(DFWINDOW
, int, int);
19 static void SetAnchor(DFWINDOW
, int, int);
20 /* -------- local variables -------- */
21 static BOOL KeyBoardMarking
, ButtonDown
;
22 static BOOL TextMarking
;
23 static int ButtonX
, ButtonY
;
24 static int PrevY
= -1;
26 /* ----------- CREATE_WINDOW Message ---------- */
27 static int CreateWindowMsg(DFWINDOW wnd
)
29 int rtn
= BaseWndProc(EDITBOX
, wnd
, CREATE_WINDOW
, 0, 0);
30 wnd
->MaxTextLength
= MAXTEXTLEN
+1;
31 wnd
->textlen
= EditBufLen(wnd
);
32 wnd
->InsertMode
= TRUE
;
33 DfSendMessage(wnd
, CLEARTEXT
, 0, 0);
36 /* ----------- SETTEXT Message ---------- */
37 static int SetTextMsg(DFWINDOW wnd
, PARAM p1
)
40 if (strlen((char *)p1
) <= wnd
->MaxTextLength
)
41 rtn
= BaseWndProc(EDITBOX
, wnd
, SETTEXT
, p1
, 0);
44 /* ----------- CLEARTEXT Message ------------ */
45 static int ClearTextMsg(DFWINDOW wnd
)
47 int rtn
= BaseWndProc(EDITBOX
, wnd
, CLEARTEXT
, 0, 0);
48 unsigned blen
= EditBufLen(wnd
)+2;
49 wnd
->text
= DFrealloc(wnd
->text
, blen
);
50 memset(wnd
->text
, 0, blen
);
58 wnd
->TextChanged
= FALSE
;
61 /* ----------- ADDTEXT Message ---------- */
62 static int AddTextMsg(DFWINDOW wnd
, PARAM p1
, PARAM p2
)
65 if (strlen((char *)p1
)+wnd
->textlen
<= wnd
->MaxTextLength
) {
66 rtn
= BaseWndProc(EDITBOX
, wnd
, ADDTEXT
, p1
, p2
);
68 if (!isMultiLine(wnd
)) {
70 wnd
->CurrCol
= strlen((char *)p1
);
71 if (wnd
->CurrCol
>= ClientWidth(wnd
)) {
72 wnd
->wleft
= wnd
->CurrCol
-ClientWidth(wnd
);
73 wnd
->CurrCol
-= wnd
->wleft
;
75 wnd
->BlkEndCol
= wnd
->CurrCol
;
76 DfSendMessage(wnd
, KEYBOARD_CURSOR
,
83 /* ----------- GETTEXT Message ---------- */
84 static int GetTextMsg(DFWINDOW wnd
, PARAM p1
, PARAM p2
)
86 char *cp1
= (char *)p1
;
87 char *cp2
= wnd
->text
;
89 while (p2
-- && *cp2
&& *cp2
!= '\n')
96 /* ----------- SETTEXTLENGTH Message ---------- */
97 static int SetTextLengthMsg(DFWINDOW wnd
, unsigned int len
)
99 if (++len
< MAXTEXTLEN
) {
100 wnd
->MaxTextLength
= len
;
101 if (len
< wnd
->textlen
) {
102 wnd
->text
=DFrealloc(wnd
->text
, len
+2);
104 *((wnd
->text
)+len
) = '\0';
105 *((wnd
->text
)+len
+1) = '\0';
106 BuildTextPointers(wnd
);
112 /* ----------- KEYBOARD_CURSOR Message ---------- */
113 static void KeyboardCursorMsg(DFWINDOW wnd
, PARAM p1
, PARAM p2
)
115 wnd
->CurrCol
= (int)p1
+ wnd
->wleft
;
116 wnd
->WndRow
= (int)p2
;
117 wnd
->CurrLine
= (int)p2
+ wnd
->wtop
;
118 if (wnd
== inFocus
) {
119 if (CharInView(wnd
, (int)p1
, (int)p2
))
120 DfSendMessage(NULL
, SHOW_CURSOR
,
121 (wnd
->InsertMode
&& !TextMarking
), 0);
123 DfSendMessage(NULL
, HIDE_CURSOR
, 0, 0);
126 /* ----------- SIZE Message ---------- */
127 int SizeMsg(DFWINDOW wnd
, PARAM p1
, PARAM p2
)
129 int rtn
= BaseWndProc(EDITBOX
, wnd
, DFM_SIZE
, p1
, p2
);
130 if (WndCol
> ClientWidth(wnd
)-1)
131 wnd
->CurrCol
= ClientWidth(wnd
)-1 + wnd
->wleft
;
132 if (wnd
->WndRow
> ClientHeight(wnd
)-1) {
133 wnd
->WndRow
= ClientHeight(wnd
)-1;
134 SetLinePointer(wnd
, wnd
->WndRow
+wnd
->wtop
);
136 DfSendMessage(wnd
, KEYBOARD_CURSOR
, WndCol
, wnd
->WndRow
);
139 /* ----------- SCROLL Message ---------- */
140 static int ScrollMsg(DFWINDOW wnd
, PARAM p1
)
143 if (isMultiLine(wnd
)) {
144 rtn
= BaseWndProc(EDITBOX
,wnd
,SCROLL
,p1
,0);
147 /* -------- scrolling up --------- */
148 if (wnd
->WndRow
== 0) {
156 /* -------- scrolling down --------- */
157 if (wnd
->WndRow
== ClientHeight(wnd
)-1) {
158 if (wnd
->CurrLine
> 0)
165 DfSendMessage(wnd
,KEYBOARD_CURSOR
,WndCol
,wnd
->WndRow
);
170 /* ----------- HORIZSCROLL Message ---------- */
171 static int HorizScrollMsg(DFWINDOW wnd
, PARAM p1
)
174 char *currchar
= CurrChar
;
176 wnd
->CurrCol
== wnd
->wleft
&& *currchar
== '\n')) {
177 rtn
= BaseWndProc(EDITBOX
, wnd
, HORIZSCROLL
, p1
, 0);
179 if (wnd
->CurrCol
< wnd
->wleft
)
181 else if (WndCol
== ClientWidth(wnd
))
183 DfSendMessage(wnd
,KEYBOARD_CURSOR
,WndCol
,wnd
->WndRow
);
188 /* ----------- SCROLLPAGE Message ---------- */
189 static int ScrollPageMsg(DFWINDOW wnd
, PARAM p1
)
192 if (isMultiLine(wnd
)) {
193 rtn
= BaseWndProc(EDITBOX
, wnd
, SCROLLPAGE
, p1
, 0);
194 SetLinePointer(wnd
, wnd
->wtop
+wnd
->WndRow
);
196 DfSendMessage(wnd
, KEYBOARD_CURSOR
,WndCol
, wnd
->WndRow
);
200 /* ----------- HORIZSCROLLPAGE Message ---------- */
201 static int HorizPageMsg(DFWINDOW wnd
, PARAM p1
)
203 int rtn
= BaseWndProc(EDITBOX
, wnd
, HORIZPAGE
, p1
, 0);
204 if ((int) p1
== FALSE
) {
205 if (wnd
->CurrCol
> wnd
->wleft
+ClientWidth(wnd
)-1)
206 wnd
->CurrCol
= wnd
->wleft
+ClientWidth(wnd
)-1;
208 else if (wnd
->CurrCol
< wnd
->wleft
)
209 wnd
->CurrCol
= wnd
->wleft
;
210 DfSendMessage(wnd
, KEYBOARD_CURSOR
, WndCol
, wnd
->WndRow
);
213 /* ----- Extend the marked block to the new x,y position ---- */
214 static void ExtendBlock(DFWINDOW wnd
, int x
, int y
)
217 int ptop
= min(wnd
->BlkBegLine
, wnd
->BlkEndLine
);
218 int pbot
= max(wnd
->BlkBegLine
, wnd
->BlkEndLine
);
219 char *lp
= TextLine(wnd
, wnd
->wtop
+y
);
220 int len
= (int) (strchr(lp
, '\n') - lp
);
221 x
= max(0, min(x
, len
));
223 wnd
->BlkEndCol
= min(len
, x
+wnd
->wleft
);
224 wnd
->BlkEndLine
= y
+wnd
->wtop
;
225 DfSendMessage(wnd
, KEYBOARD_CURSOR
, wnd
->BlkEndCol
, wnd
->BlkEndLine
);
226 bbl
= min(wnd
->BlkBegLine
, wnd
->BlkEndLine
);
227 bel
= max(wnd
->BlkBegLine
, wnd
->BlkEndLine
);
229 WriteTextLine(wnd
, NULL
, ptop
, FALSE
);
232 for (y
= bbl
; y
<= bel
; y
++)
233 WriteTextLine(wnd
, NULL
, y
, FALSE
);
235 WriteTextLine(wnd
, NULL
, pbot
, FALSE
);
239 /* ----------- LEFT_BUTTON Message ---------- */
240 static int LeftButtonMsg(DFWINDOW wnd
, PARAM p1
, PARAM p2
)
242 int MouseX
= (int) p1
- GetClientLeft(wnd
);
243 int MouseY
= (int) p2
- GetClientTop(wnd
);
244 DFRECT rc
= ClientRect(wnd
);
249 if (WindowMoving
|| WindowSizing
)
251 if (isMultiLine(wnd
)) {
253 if (!InsideRect(p1
, p2
, rc
)) {
254 int x
= MouseX
, y
= MouseY
;
257 if ((int)p2
== GetTop(wnd
))
258 y
++, dir
= FALSE
, msg
= SCROLL
;
259 else if ((int)p2
== GetBottom(wnd
))
260 --y
, dir
= TRUE
, msg
= SCROLL
;
261 else if ((int)p1
== GetLeft(wnd
))
262 --x
, dir
= FALSE
, msg
= HORIZSCROLL
;
263 else if ((int)p1
== GetRight(wnd
))
264 x
++, dir
= TRUE
, msg
= HORIZSCROLL
;
266 if (DfSendMessage(wnd
, msg
, dir
, 0))
267 ExtendBlock(wnd
, x
, y
);
268 DfSendMessage(wnd
, PAINT
, 0, 0);
273 if (!InsideRect(p1
, p2
, rc
))
275 if (TextBlockMarked(wnd
)) {
277 DfSendMessage(wnd
, PAINT
, 0, 0);
280 if (MouseY
> wnd
->wlines
-1)
282 lp
= TextLine(wnd
, MouseY
+wnd
->wtop
);
283 len
= (int) (strchr(lp
, '\n') - lp
);
284 MouseX
= min(MouseX
, len
);
285 if (MouseX
< wnd
->wleft
) {
287 DfSendMessage(wnd
, KEYBOARD
, HOME
, 0);
295 wnd
->WndRow
= MouseY
;
296 SetLinePointer(wnd
, MouseY
+wnd
->wtop
);
298 if (isMultiLine(wnd
) ||
299 (!TextBlockMarked(wnd
)
300 && (int)(MouseX
+wnd
->wleft
) < (int)strlen(wnd
->text
)))
301 wnd
->CurrCol
= MouseX
+wnd
->wleft
;
302 DfSendMessage(wnd
, KEYBOARD_CURSOR
, WndCol
, wnd
->WndRow
);
305 /* ----------- MOUSE_MOVED Message ---------- */
306 static int MouseMovedMsg(DFWINDOW wnd
, PARAM p1
, PARAM p2
)
308 int MouseX
= (int) p1
- GetClientLeft(wnd
);
309 int MouseY
= (int) p2
- GetClientTop(wnd
);
310 DFRECT rc
= ClientRect(wnd
);
311 if (!InsideRect(p1
, p2
, rc
))
313 if (MouseY
> wnd
->wlines
-1)
316 SetAnchor(wnd
, ButtonX
+wnd
->wleft
, ButtonY
+wnd
->wtop
);
318 rc
= WindowRect(wnd
);
319 DfSendMessage(NULL
,MOUSE_TRAVEL
,(PARAM
) &rc
, 0);
322 if (TextMarking
&& !(WindowMoving
|| WindowSizing
)) {
323 ExtendBlock(wnd
, MouseX
, MouseY
);
328 static void StopMarking(DFWINDOW wnd
)
331 if (wnd
->BlkBegLine
> wnd
->BlkEndLine
) {
332 swap(wnd
->BlkBegLine
, wnd
->BlkEndLine
);
333 swap(wnd
->BlkBegCol
, wnd
->BlkEndCol
);
335 if (wnd
->BlkBegLine
== wnd
->BlkEndLine
&&
336 wnd
->BlkBegCol
> wnd
->BlkEndCol
)
337 swap(wnd
->BlkBegCol
, wnd
->BlkEndCol
);
339 /* ----------- BUTTON_RELEASED Message ---------- */
340 static int ButtonReleasedMsg(DFWINDOW wnd
)
342 if (isMultiLine(wnd
)) {
344 if (TextMarking
&& !(WindowMoving
|| WindowSizing
)) {
345 /* release the mouse ouside the edit box */
346 DfSendMessage(NULL
, MOUSE_TRAVEL
, 0, 0);
355 /* ---- Process text block keys for multiline text box ---- */
356 static void DoMultiLines(DFWINDOW wnd
, int c
, PARAM p2
)
358 if (isMultiLine(wnd
) && !KeyBoardMarking
) {
359 if ((int)p2
& (LEFTSHIFT
| RIGHTSHIFT
)) {
375 KeyBoardMarking
= TextMarking
= TRUE
;
376 SetAnchor(wnd
, wnd
->CurrCol
, wnd
->CurrLine
);
384 /* ---------- page/scroll keys ----------- */
385 static int DoScrolling(DFWINDOW wnd
, int c
, PARAM p2
)
390 if (isMultiLine(wnd
))
391 BaseWndProc(EDITBOX
, wnd
, KEYBOARD
, c
, p2
);
395 BaseWndProc(EDITBOX
, wnd
, KEYBOARD
, c
, p2
);
410 if (isMultiLine(wnd
)) {
411 DfSendMessage(wnd
, SCROLLDOC
, TRUE
, 0);
418 if (isMultiLine(wnd
) &&
419 wnd
->WndRow
+wnd
->wtop
+1 < wnd
->wlines
420 && wnd
->wlines
> 0) {
421 DfSendMessage(wnd
, SCROLLDOC
, FALSE
, 0);
422 SetLinePointer(wnd
, wnd
->wlines
-1);
424 min(ClientHeight(wnd
)-1, wnd
->wlines
-1);
430 if (isMultiLine(wnd
))
434 if (isMultiLine(wnd
))
446 if (!KeyBoardMarking
&& TextBlockMarked(wnd
)) {
448 DfSendMessage(wnd
, PAINT
, 0, 0);
450 DfSendMessage(wnd
, KEYBOARD_CURSOR
, WndCol
, wnd
->WndRow
);
453 /* -------------- Del key ---------------- */
454 static void DelKey(DFWINDOW wnd
)
456 char *currchar
= CurrChar
;
457 int repaint
= *currchar
== '\n';
458 if (TextBlockMarked(wnd
)) {
459 DfSendMessage(wnd
, DFM_COMMAND
, ID_DELETETEXT
, 0);
460 DfSendMessage(wnd
, PAINT
, 0, 0);
463 if (isMultiLine(wnd
) && *currchar
== '\n' && *(currchar
+1) == '\0')
465 strcpy(currchar
, currchar
+1);
467 BuildTextPointers(wnd
);
468 DfSendMessage(wnd
, PAINT
, 0, 0);
471 ModTextPointers(wnd
, wnd
->CurrLine
+1, -1);
472 WriteTextLine(wnd
, NULL
, wnd
->WndRow
+wnd
->wtop
, FALSE
);
474 wnd
->TextChanged
= TRUE
;
476 /* ------------ Tab key ------------ */
477 static void TabKey(DFWINDOW wnd
, PARAM p2
)
479 if (isMultiLine(wnd
)) {
480 int insmd
= wnd
->InsertMode
;
482 char *cc
= CurrChar
+1;
483 if (!insmd
&& *cc
== '\0')
485 if (wnd
->textlen
== wnd
->MaxTextLength
)
487 DfSendMessage(wnd
,KEYBOARD
,insmd
? ' ' : FWD
,0);
488 } while (wnd
->CurrCol
% cfg
.Tabs
);
491 DfPostMessage(GetParent(wnd
), KEYBOARD
, '\t', p2
);
493 /* ------------ Shift+Tab key ------------ */
494 static void ShiftTabKey(DFWINDOW wnd
, PARAM p2
)
496 if (isMultiLine(wnd
)) {
498 if (CurrChar
== GetText(wnd
))
500 DfSendMessage(wnd
,KEYBOARD
,BS
,0);
501 } while (wnd
->CurrCol
% cfg
.Tabs
);
504 DfPostMessage(GetParent(wnd
), KEYBOARD
, SHIFT_HT
, p2
);
506 /* --------- All displayable typed keys ------------- */
507 static void KeyTyped(DFWINDOW wnd
, int c
)
509 char *currchar
= CurrChar
;
510 if ((c
!= '\n' && c
< ' ') || (c
& 0x1000))
511 /* ---- not recognized by editor --- */
513 if (!isMultiLine(wnd
) && TextBlockMarked(wnd
)) {
514 DfSendMessage(wnd
, CLEARTEXT
, 0, 0);
517 /* ---- test typing at end of text ---- */
518 if (currchar
== wnd
->text
+wnd
->MaxTextLength
) {
519 /* ---- typing at the end of maximum buffer ---- */
523 if (*currchar
== '\0') {
524 /* --- insert a newline at end of text --- */
526 *(currchar
+1) = '\0';
527 BuildTextPointers(wnd
);
529 /* --- displayable char or newline --- */
530 if (c
== '\n' || wnd
->InsertMode
|| *currchar
== '\n') {
531 /* ------ inserting the keyed character ------ */
532 if (wnd
->text
[wnd
->textlen
-1] != '\0') {
533 /* --- the current text buffer is full --- */
534 if (wnd
->textlen
== wnd
->MaxTextLength
) {
535 /* --- text buffer is at maximum size --- */
539 /* ---- increase the text buffer size ---- */
540 wnd
->textlen
+= GROWLENGTH
;
541 /* --- but not above maximum size --- */
542 if (wnd
->textlen
> wnd
->MaxTextLength
)
543 wnd
->textlen
= wnd
->MaxTextLength
;
544 wnd
->text
= DFrealloc(wnd
->text
, wnd
->textlen
+2);
545 wnd
->text
[wnd
->textlen
-1] = '\0';
548 memmove(currchar
+1, currchar
, strlen(currchar
)+1);
549 ModTextPointers(wnd
, wnd
->CurrLine
+1, 1);
550 if (isMultiLine(wnd
) && wnd
->wlines
> 1)
551 wnd
->textwidth
= max(wnd
->textwidth
,
552 (int) (TextLine(wnd
, wnd
->CurrLine
+1)-
553 TextLine(wnd
, wnd
->CurrLine
)));
555 wnd
->textwidth
= max((int)wnd
->textwidth
,
556 (int)strlen(wnd
->text
));
557 WriteTextLine(wnd
, NULL
,
558 wnd
->wtop
+wnd
->WndRow
, FALSE
);
560 /* ----- put the char in the buffer ----- */
562 wnd
->TextChanged
= TRUE
;
565 BuildTextPointers(wnd
);
568 DfSendMessage(wnd
, PAINT
, 0, 0);
571 /* ---------- test end of window --------- */
572 if (WndCol
== ClientWidth(wnd
)-1) {
573 if (!isMultiLine(wnd
)) {
574 if (!(currchar
== wnd
->text
+wnd
->MaxTextLength
-2))
575 DfSendMessage(wnd
, HORIZSCROLL
, TRUE
, 0);
579 while (*cp
!= ' ' && cp
!= TextLine(wnd
, wnd
->CurrLine
))
581 if (cp
== TextLine(wnd
, wnd
->CurrLine
) ||
583 DfSendMessage(wnd
, HORIZSCROLL
, TRUE
, 0);
587 dif
= (int) (currchar
- cp
);
589 DfSendMessage(wnd
, KEYBOARD
, DEL
, 0);
592 DfSendMessage(wnd
, KEYBOARD
, '\n', 0);
600 /* ------ display the character ------ */
601 SetStandardColor(wnd
);
602 PutWindowChar(wnd
, c
, WndCol
, wnd
->WndRow
);
603 /* ----- advance the pointers ------ */
606 /* ------------ screen changing key strokes ------------- */
607 static void DoKeyStroke(DFWINDOW wnd
, int c
, PARAM p2
)
611 if (wnd
->CurrCol
== 0 && wnd
->CurrLine
== 0)
618 ShiftTabKey(wnd
, p2
);
624 if (!isMultiLine(wnd
)) {
625 DfPostMessage(GetParent(wnd
), KEYBOARD
, c
, p2
);
630 if (TextBlockMarked(wnd
)) {
631 DfSendMessage(wnd
, DFM_COMMAND
, ID_DELETETEXT
, 0);
632 DfSendMessage(wnd
, PAINT
, 0, 0);
638 /* ----------- KEYBOARD Message ---------- */
639 static int KeyboardMsg(DFWINDOW wnd
, PARAM p1
, PARAM p2
)
643 if (WindowMoving
|| WindowSizing
|| ((int)p2
& ALTKEY
))
648 /* these keys get processed by lower classes */
665 /* these keys get processed here */
675 /* other ctrl keys get processed by lower classes */
676 if ((int)p2
& CTRLKEY
)
678 /* all other keys get processed here */
682 DoMultiLines(wnd
, c
, p2
);
683 if (DoScrolling(wnd
, c
, p2
))
686 ExtendBlock(wnd
, WndCol
, wnd
->WndRow
);
688 else if (!TestAttribute(wnd
, READONLY
))
690 DoKeyStroke(wnd
, c
, p2
);
691 DfSendMessage(wnd
, KEYBOARD_CURSOR
, WndCol
, wnd
->WndRow
);
699 /* ----------- SHIFT_CHANGED Message ---------- */
700 static void ShiftChangedMsg(DFWINDOW wnd
, PARAM p1
)
702 if (!((int)p1
& (LEFTSHIFT
| RIGHTSHIFT
)) &&
705 KeyBoardMarking
= FALSE
;
708 /* ----------- ID_DELETETEXT Command ---------- */
709 static void DeleteTextCmd(DFWINDOW wnd
)
711 if (TextBlockMarked(wnd
)) {
712 char *bbl
=TextLine(wnd
,wnd
->BlkBegLine
)+wnd
->BlkBegCol
;
713 char *bel
=TextLine(wnd
,wnd
->BlkEndLine
)+wnd
->BlkEndCol
;
714 int len
= (int) (bel
- bbl
);
715 SaveDeletedText(wnd
, bbl
, len
);
716 wnd
->TextChanged
= TRUE
;
718 wnd
->CurrLine
= TextLineNumber(wnd
, bbl
-wnd
->BlkBegCol
);
719 wnd
->CurrCol
= wnd
->BlkBegCol
;
720 wnd
->WndRow
= wnd
->BlkBegLine
- wnd
->wtop
;
721 if (wnd
->WndRow
< 0) {
722 wnd
->wtop
= wnd
->BlkBegLine
;
725 DfSendMessage(wnd
, KEYBOARD_CURSOR
, WndCol
, wnd
->WndRow
);
727 BuildTextPointers(wnd
);
730 /* ----------- ID_CLEAR Command ---------- */
731 static void ClearCmd(DFWINDOW wnd
)
733 if (TextBlockMarked(wnd
)) {
734 char *bbl
=TextLine(wnd
,wnd
->BlkBegLine
)+wnd
->BlkBegCol
;
735 char *bel
=TextLine(wnd
,wnd
->BlkEndLine
)+wnd
->BlkEndCol
;
736 int len
= (int) (bel
- bbl
);
737 SaveDeletedText(wnd
, bbl
, len
);
738 wnd
->CurrLine
= TextLineNumber(wnd
, bbl
);
739 wnd
->CurrCol
= wnd
->BlkBegCol
;
740 wnd
->WndRow
= wnd
->BlkBegLine
- wnd
->wtop
;
741 if (wnd
->WndRow
< 0) {
743 wnd
->wtop
= wnd
->BlkBegLine
;
745 /* ------ change all text lines in block to \n ----- */
747 char *cp
= strchr(bbl
, '\n');
751 bel
-= (int) (cp
- bbl
);
755 BuildTextPointers(wnd
);
756 DfSendMessage(wnd
, KEYBOARD_CURSOR
, WndCol
, wnd
->WndRow
);
757 wnd
->TextChanged
= TRUE
;
760 /* ----------- ID_UNDO Command ---------- */
761 static void UndoCmd(DFWINDOW wnd
)
763 if (wnd
->DeletedText
!= NULL
) {
764 PasteText(wnd
, wnd
->DeletedText
, wnd
->DeletedLength
);
765 free(wnd
->DeletedText
);
766 wnd
->DeletedText
= NULL
;
767 wnd
->DeletedLength
= 0;
768 DfSendMessage(wnd
, PAINT
, 0, 0);
771 /* ----------- ID_PARAGRAPH Command ---------- */
772 static void ParagraphCmd(DFWINDOW wnd
)
775 char *bl
, *bbl
, *bel
, *bb
;
778 /* ---- forming paragraph from cursor position --- */
779 fl
= wnd
->wtop
+ wnd
->WndRow
;
780 bbl
= bel
= bl
= TextLine(wnd
, wnd
->CurrLine
);
781 if ((bc
= wnd
->CurrCol
) >= ClientWidth(wnd
))
784 /* ---- locate the end of the paragraph ---- */
788 /* --- blank line marks end of paragraph --- */
789 while (*bel
&& *bel
!= '\n') {
802 DfSendMessage(wnd
, KEYBOARD
, DN
, 0);
809 /* --- change all newlines in block to spaces --- */
810 while (CurrChar
< bel
) {
811 if (*CurrChar
== '\n') {
819 /* ---- insert newlines at new margin boundaries ---- */
823 if ((int)(bbl
- bb
) == ClientWidth(wnd
)-1) {
824 while (*bbl
!= ' ' && bbl
> bb
)
827 bbl
= strchr(bbl
, ' ');
828 if (bbl
== NULL
|| bbl
>= bel
)
835 BuildTextPointers(wnd
);
836 /* --- put cursor back at beginning --- */
837 wnd
->CurrLine
= TextLineNumber(wnd
, bl
);
841 wnd
->WndRow
= fl
- wnd
->wtop
;
842 DfSendMessage(wnd
, PAINT
, 0, 0);
843 DfSendMessage(wnd
, KEYBOARD_CURSOR
, WndCol
, wnd
->WndRow
);
844 wnd
->TextChanged
= TRUE
;
845 BuildTextPointers(wnd
);
847 /* ----------- COMMAND Message ---------- */
848 static int CommandMsg(DFWINDOW wnd
, PARAM p1
)
868 /* ---------- CLOSE_WINDOW Message ----------- */
869 static int CloseWindowMsg(DFWINDOW wnd
, PARAM p1
, PARAM p2
)
872 DfSendMessage(NULL
, HIDE_CURSOR
, 0, 0);
873 if (wnd
->DeletedText
!= NULL
)
874 free(wnd
->DeletedText
);
875 if (wnd
->text
!= NULL
)
880 rtn
= BaseWndProc(EDITBOX
, wnd
, CLOSE_WINDOW
, p1
, p2
);
884 /* ------- Window processing module for EDITBOX class ------ */
885 int EditBoxProc(DFWINDOW wnd
, DFMESSAGE msg
, PARAM p1
, PARAM p2
)
890 return CreateWindowMsg(wnd
);
892 return AddTextMsg(wnd
, p1
, p2
);
894 return SetTextMsg(wnd
, p1
);
896 return ClearTextMsg(wnd
);
898 return GetTextMsg(wnd
, p1
, p2
);
900 return SetTextLengthMsg(wnd
, (unsigned) p1
);
901 case KEYBOARD_CURSOR
:
902 KeyboardCursorMsg(wnd
, p1
, p2
);
906 DfSendMessage(NULL
, HIDE_CURSOR
, 0, 0);
909 rtn
= BaseWndProc(EDITBOX
, wnd
, msg
, p1
, p2
);
910 DfSendMessage(wnd
,KEYBOARD_CURSOR
,WndCol
,wnd
->WndRow
);
913 return SizeMsg(wnd
, p1
, p2
);
915 return ScrollMsg(wnd
, p1
);
917 return HorizScrollMsg(wnd
, p1
);
919 return ScrollPageMsg(wnd
, p1
);
921 return HorizPageMsg(wnd
, p1
);
923 if (LeftButtonMsg(wnd
, p1
, p2
))
927 if (MouseMovedMsg(wnd
, p1
, p2
))
930 case DFM_BUTTON_RELEASED
:
931 if (ButtonReleasedMsg(wnd
))
935 if (KeyboardMsg(wnd
, p1
, p2
))
939 ShiftChangedMsg(wnd
, p1
);
942 if (CommandMsg(wnd
, p1
))
946 return CloseWindowMsg(wnd
, p1
, p2
);
950 return BaseWndProc(EDITBOX
, wnd
, msg
, p1
, p2
);
952 /* ------ save deleted text for the Undo command ------ */
953 static void SaveDeletedText(DFWINDOW wnd
, char *bbl
, int len
)
955 wnd
->DeletedLength
= len
;
956 wnd
->DeletedText
=DFrealloc(wnd
->DeletedText
,len
);
957 memmove(wnd
->DeletedText
, bbl
, len
);
959 /* ---- cursor right key: right one character position ---- */
960 static void Forward(DFWINDOW wnd
)
962 char *cc
= CurrChar
+1;
965 if (*CurrChar
== '\n') {
971 if (WndCol
== ClientWidth(wnd
))
972 DfSendMessage(wnd
, HORIZSCROLL
, TRUE
, 0);
975 /* ----- stick the moving cursor to the end of the line ---- */
976 static void StickEnd(DFWINDOW wnd
)
978 char *cp
= TextLine(wnd
, wnd
->CurrLine
);
979 char *cp1
= strchr(cp
, '\n');
980 int len
= cp1
? (int) (cp1
- cp
) : 0;
981 wnd
->CurrCol
= min(len
, wnd
->CurrCol
);
982 if (wnd
->wleft
> wnd
->CurrCol
) {
983 wnd
->wleft
= max(0, wnd
->CurrCol
- 4);
984 DfSendMessage(wnd
, PAINT
, 0, 0);
986 else if (wnd
->CurrCol
-wnd
->wleft
>= ClientWidth(wnd
)) {
987 wnd
->wleft
= wnd
->CurrCol
- (ClientWidth(wnd
)-1);
988 DfSendMessage(wnd
, PAINT
, 0, 0);
991 /* --------- cursor down key: down one line --------- */
992 static void Downward(DFWINDOW wnd
)
994 if (isMultiLine(wnd
) &&
995 wnd
->WndRow
+wnd
->wtop
+1 < wnd
->wlines
) {
997 if (wnd
->WndRow
== ClientHeight(wnd
)-1)
998 BaseWndProc(EDITBOX
, wnd
, SCROLL
, TRUE
, 0);
1004 /* -------- cursor up key: up one line ------------ */
1005 static void Upward(DFWINDOW wnd
)
1007 if (isMultiLine(wnd
) && wnd
->CurrLine
!= 0) {
1009 if (wnd
->WndRow
== 0)
1010 BaseWndProc(EDITBOX
, wnd
, SCROLL
, FALSE
, 0);
1016 /* ---- cursor left key: left one character position ---- */
1017 static void Backward(DFWINDOW wnd
)
1021 if (wnd
->CurrCol
< wnd
->wleft
)
1022 DfSendMessage(wnd
, HORIZSCROLL
, FALSE
, 0);
1024 else if (isMultiLine(wnd
) && wnd
->CurrLine
!= 0) {
1029 /* -------- End key: to end of line ------- */
1030 static void End(DFWINDOW wnd
)
1032 while (*CurrChar
&& *CurrChar
!= '\n')
1034 if (WndCol
>= ClientWidth(wnd
)) {
1035 wnd
->wleft
= wnd
->CurrCol
- (ClientWidth(wnd
)-1);
1036 DfSendMessage(wnd
, PAINT
, 0, 0);
1039 /* -------- Home key: to beginning of line ------- */
1040 static void Home(DFWINDOW wnd
)
1043 if (wnd
->wleft
!= 0) {
1045 DfSendMessage(wnd
, PAINT
, 0, 0);
1048 /* -- Ctrl+cursor right key: to beginning of next word -- */
1049 static void NextWord(DFWINDOW wnd
)
1051 int savetop
= wnd
->wtop
;
1052 int saveleft
= wnd
->wleft
;
1054 while (!isWhite(*CurrChar
)) {
1055 char *cc
= CurrChar
+1;
1060 while (isWhite(*CurrChar
)) {
1061 char *cc
= CurrChar
+1;
1067 DfSendMessage(wnd
, KEYBOARD_CURSOR
, WndCol
, wnd
->WndRow
);
1068 if (wnd
->wtop
!= savetop
|| wnd
->wleft
!= saveleft
)
1069 DfSendMessage(wnd
, PAINT
, 0, 0);
1071 /* -- Ctrl+cursor left key: to beginning of previous word -- */
1072 static void PrevWord(DFWINDOW wnd
)
1074 int savetop
= wnd
->wtop
;
1075 int saveleft
= wnd
->wleft
;
1078 while (isWhite(*CurrChar
)) {
1079 if (wnd
->CurrLine
== 0 && wnd
->CurrCol
== 0)
1083 while (wnd
->CurrCol
!= 0 && !isWhite(*CurrChar
))
1085 if (isWhite(*CurrChar
))
1088 if (wnd
->wleft
!= saveleft
)
1089 if (wnd
->CurrCol
>= saveleft
)
1090 if (wnd
->CurrCol
- saveleft
< ClientWidth(wnd
))
1091 wnd
->wleft
= saveleft
;
1092 DfSendMessage(wnd
, KEYBOARD_CURSOR
, WndCol
, wnd
->WndRow
);
1093 if (wnd
->wtop
!= savetop
|| wnd
->wleft
!= saveleft
)
1094 DfSendMessage(wnd
, PAINT
, 0, 0);
1096 /* ----- modify text pointers from a specified position
1097 by a specified plus or minus amount ----- */
1098 static void ModTextPointers(DFWINDOW wnd
, int lineno
, int var
)
1100 while (lineno
< wnd
->wlines
)
1101 *((wnd
->TextPointers
) + lineno
++) += var
;
1103 /* ----- set anchor point for marking text block ----- */
1104 static void SetAnchor(DFWINDOW wnd
, int mx
, int my
)
1106 ClearTextBlock(wnd
);
1107 /* ------ set the anchor ------ */
1108 wnd
->BlkBegLine
= wnd
->BlkEndLine
= my
;
1109 wnd
->BlkBegCol
= wnd
->BlkEndCol
= mx
;
1110 DfSendMessage(wnd
, PAINT
, 0, 0);