1 /*
2 * STFL - The Structured Terminal Forms Language/Library
3 * Copyright (C) 2006, 2007 Clifford Wolf <clifford@clifford.at>
4 * Copyright (C) 2006 Andreas Krennmair <ak@synflood.at>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 3 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 * MA 02110-1301 USA
20 *
21 * wt_textview.c: Widget type 'textview'
22 */
23
24 #include "stfl_internals.h"
25
26 #include <string.h>
27 #include <stdlib.h>
28
29 #if 0
30 static void fix_offset_pos(struct stfl_widget *w)
31 {
32 int offset = stfl_widget_getkv_int(w, "offset", 0);
33 int pos = stfl_widget_getkv_int(w, "pos", 0);
34
35 int orig_offset = offset;
36 int orig_pos = pos;
37
38 while (pos < offset)
39 offset--;
40
41 if (w->h > 0)
42 while (pos >= offset+w->h)
43 offset++;
44
45 int maxpos = -1;
46 struct stfl_widget *c = w->first_child;
47 while (c) {
48 maxpos++;
49 c = c->next_sibling;
50 }
51
52 if (maxpos >= 0 && pos > maxpos)
53 pos = maxpos;
54
55 if (offset != orig_offset)
56 stfl_widget_setkv_int(w, "offset", offset);
57
58 if (pos != orig_pos)
59 stfl_widget_setkv_int(w, "pos", pos);
60 }
61 #endif
62
wt_textview_prepare(struct stfl_widget * w,struct stfl_form * f)63 static void wt_textview_prepare(struct stfl_widget *w, struct stfl_form *f)
64 {
65 struct stfl_widget *c = w->first_child;
66
67 w->min_w = 1;
68 w->min_h = 5;
69
70 if (c)
71 w->allow_focus = 1;
72
73 while (c) {
74 const wchar_t * text = stfl_widget_getkv_str(c, L"text", L"");
75 int len = wcswidth(text, wcslen(text));
76 w->min_w = len > w->min_w ? len : w->min_w;
77 c = c->next_sibling;
78 }
79 }
80
81
82
wt_textview_draw(struct stfl_widget * w,struct stfl_form * f,WINDOW * win)83 static void wt_textview_draw(struct stfl_widget *w, struct stfl_form *f, WINDOW *win)
84 {
85 //fix_offset_pos(w);
86
87 int offset = stfl_widget_getkv_int(w, L"offset", 0);
88 int is_richtext = stfl_widget_getkv_int(w, L"richtext", 0);
89
90 const wchar_t *style_normal = stfl_widget_getkv_str(w, L"style_normal", L"");
91 const wchar_t *style_end = stfl_widget_getkv_str(w, L"style_end", L"");
92
93 struct stfl_widget *c;
94 int i;
95
96 stfl_style(win, style_normal);
97 for (i=0, c=w->first_child; c && i < offset+w->h; i++, c=c->next_sibling)
98 {
99 const wchar_t *text = stfl_widget_getkv_str(c, L"text", L"");
100
101 if (i < offset) {
102 if (is_richtext)
103 stfl_print_richtext(w, win, w->y, w->x, text, 0, style_normal, 0);
104 continue;
105 }
106
107 if (is_richtext) {
108 stfl_print_richtext(w, win, w->y+i-offset, w->x, text, w->w, style_normal, 0);
109 } else {
110 mvwaddnwstr(win, w->y+i-offset, w->x, text, w->w);
111 }
112 }
113
114 stfl_style(win, style_end);
115 while (i<offset+w->h) {
116 mvwaddnwstr(win,w->y+i-offset,w->x,L"~",w->w);
117 ++i;
118 }
119
120 if (f->current_focus_id == w->id)
121 f->root->cur_x = f->root->cur_y = f->cursor_x = f->cursor_y = -1;
122 }
123
wt_textview_process(struct stfl_widget * w,struct stfl_widget * fw,struct stfl_form * f,wchar_t ch,int isfunckey)124 static int wt_textview_process(struct stfl_widget *w, struct stfl_widget *fw, struct stfl_form *f, wchar_t ch, int isfunckey)
125 {
126 //int pos = stfl_widget_getkv_int(w, "pos", 0);
127 int offset = stfl_widget_getkv_int(w,L"offset",0);
128 int maxoffset = -1;
129
130 struct stfl_widget *c = w->first_child;
131 while (c) {
132 maxoffset++;
133 c = c->next_sibling;
134 }
135
136 if (offset > 0 && stfl_matchbind(w, ch, isfunckey, L"up", L"UP")) {
137 stfl_widget_setkv_int(w, L"offset", offset-1);
138
139 //fix_offset_pos(w);
140 return 1;
141 }
142
143 if (offset < maxoffset && stfl_matchbind(w, ch, isfunckey, L"down", L"DOWN")) {
144 stfl_widget_setkv_int(w, L"offset", offset+1);
145 //fix_offset_pos(w);
146 return 1;
147 }
148
149 if (stfl_matchbind(w, ch, isfunckey, L"page_up", L"PPAGE")) {
150 if ((offset - w->h + 1) > 0) { // XXX: first page handling won't work with that
151 stfl_widget_setkv_int(w, L"offset", offset - w->h + 1);
152 } else {
153 stfl_widget_setkv_int(w, L"offset", 0);
154 }
155 return 1;
156 }
157
158 if (stfl_matchbind(w, ch, isfunckey, L"page_down", L"NPAGE")) {
159 if ((offset + w->h - 1) < maxoffset) { // XXX: last page handling won't work with that
160 stfl_widget_setkv_int(w, L"offset", offset + w->h - 1);
161 } else {
162 stfl_widget_setkv_int(w, L"offset", maxoffset);
163 }
164 return 1;
165 }
166
167 if (stfl_matchbind(w, ch, isfunckey, L"home", L"HOME")) {
168 stfl_widget_setkv_int(w, L"offset", 0);
169 return 1;
170 }
171
172 if (stfl_matchbind(w, ch, isfunckey, L"end", L"END")) {
173 stfl_widget_setkv_int(w, L"offset", (maxoffset - w->h + 2) < 0 ? 0 : maxoffset - w->h + 2);
174 return 1;
175 }
176
177 return 0;
178 }
179
180 struct stfl_widget_type stfl_widget_type_textview = {
181 L"textview",
182 0, // f_init
183 0, // f_done
184 0, // f_enter
185 0, // f_leave
186 wt_textview_prepare,
187 wt_textview_draw,
188 wt_textview_process,
189 };
190
191