1 /* Copyright (c) 2006-2014 Jonas Fonseca <jonas.fonseca@gmail.com>
3 * This program is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU General Public License as
5 * published by the Free Software Foundation; either version 2 of
6 * the License, or (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
23 set_view_attr(struct view
*view
, enum line_type type
)
25 if (!view
->curline
->selected
&& view
->curtype
!= type
) {
26 (void) wattrset(view
->win
, get_line_attr(type
));
27 wchgat(view
->win
, -1, 0, get_line_color(type
), NULL
);
32 #define VIEW_MAX_LEN(view) ((view)->width + (view)->pos.col - (view)->col)
35 draw_chars(struct view
*view
, enum line_type type
, const char *string
,
36 int max_len
, bool use_tilde
)
41 size_t skip
= view
->pos
.col
> view
->col
? view
->pos
.col
- view
->col
: 0;
44 return VIEW_MAX_LEN(view
) <= 0;
46 if (opt_iconv_out
!= ICONV_NONE
) {
47 string
= encoding_iconv(opt_iconv_out
, string
);
49 return VIEW_MAX_LEN(view
) <= 0;
52 len
= utf8_length(&string
, skip
, &col
, max_len
, &trimmed
, use_tilde
, opt_tab_size
);
54 set_view_attr(view
, type
);
56 waddnstr(view
->win
, string
, len
);
58 if (trimmed
&& use_tilde
) {
59 set_view_attr(view
, LINE_DELIMITER
);
60 waddch(view
->win
, '~');
66 return VIEW_MAX_LEN(view
) <= 0;
70 draw_space(struct view
*view
, enum line_type type
, int max
, int spaces
)
72 static char space
[] = " ";
74 spaces
= MIN(max
, spaces
);
77 int len
= MIN(spaces
, sizeof(space
) - 1);
79 if (draw_chars(view
, type
, space
, len
, FALSE
))
84 return VIEW_MAX_LEN(view
) <= 0;
88 draw_text_expanded(struct view
*view
, enum line_type type
, const char *string
, int max_len
, bool use_tilde
)
90 static char text
[SIZEOF_STR
];
93 size_t pos
= string_expand(text
, sizeof(text
), string
, opt_tab_size
);
95 if (draw_chars(view
, type
, text
, max_len
, use_tilde
))
100 return VIEW_MAX_LEN(view
) <= 0;
104 draw_text(struct view
*view
, enum line_type type
, const char *string
)
106 return draw_text_expanded(view
, type
, string
, VIEW_MAX_LEN(view
), TRUE
);
110 draw_text_overflow(struct view
*view
, const char *text
, bool on
, int overflow
, enum line_type type
)
113 int max
= MIN(VIEW_MAX_LEN(view
), overflow
);
114 int len
= strlen(text
);
116 if (draw_text_expanded(view
, type
, text
, max
, max
< overflow
))
119 text
= len
> overflow
? text
+ overflow
: "";
120 type
= LINE_OVERFLOW
;
123 if (*text
&& draw_text(view
, type
, text
))
126 return VIEW_MAX_LEN(view
) <= 0;
129 bool PRINTF_LIKE(3, 4)
130 draw_formatted(struct view
*view
, enum line_type type
, const char *format
, ...)
132 char text
[SIZEOF_STR
];
135 FORMAT_BUFFER(text
, sizeof(text
), format
, retval
, TRUE
);
136 return retval
>= 0 ? draw_text(view
, type
, text
) : VIEW_MAX_LEN(view
) <= 0;
140 draw_graphic(struct view
*view
, enum line_type type
, const chtype graphic
[], size_t size
, bool separator
)
142 size_t skip
= view
->pos
.col
> view
->col
? view
->pos
.col
- view
->col
: 0;
143 int max
= VIEW_MAX_LEN(view
);
149 set_view_attr(view
, type
);
150 /* Using waddch() instead of waddnstr() ensures that
151 * they'll be rendered correctly for the cursor line. */
152 for (i
= skip
; i
< size
; i
++)
153 waddch(view
->win
, graphic
[i
]);
157 if (size
< max
&& skip
<= size
)
158 waddch(view
->win
, ' ');
162 return VIEW_MAX_LEN(view
) <= 0;
166 draw_field(struct view
*view
, enum line_type type
, const char *text
, int width
, enum align align
, bool trim
)
168 int max
= MIN(VIEW_MAX_LEN(view
), width
+ 1);
172 return draw_space(view
, type
, max
, max
);
174 if (align
== ALIGN_RIGHT
) {
175 int textlen
= strlen(text
);
176 int leftpad
= max
- textlen
- 1;
179 if (draw_space(view
, type
, leftpad
, leftpad
))
186 return draw_chars(view
, type
, text
, max
- 1, trim
)
187 || draw_space(view
, LINE_DEFAULT
, max
- (view
->col
- col
), max
);
191 draw_date(struct view
*view
, struct time
*time
)
193 const char *date
= mkdate(time
, opt_show_date
);
194 int cols
= opt_show_date
== DATE_SHORT
? DATE_SHORT_WIDTH
: DATE_WIDTH
;
196 if (opt_show_date
== DATE_NO
)
199 return draw_field(view
, LINE_DATE
, date
, cols
, ALIGN_LEFT
, FALSE
);
203 draw_author(struct view
*view
, const struct ident
*author
)
205 bool trim
= author_trim(opt_author_width
);
206 const char *text
= mkauthor(author
, opt_author_width
, opt_show_author
);
208 if (opt_show_author
== AUTHOR_NO
)
211 return draw_field(view
, LINE_AUTHOR
, text
, opt_author_width
, ALIGN_LEFT
, trim
);
215 draw_id_custom(struct view
*view
, enum line_type type
, const char *id
, int width
)
217 return draw_field(view
, type
, id
, width
, ALIGN_LEFT
, FALSE
);
221 draw_id(struct view
*view
, const char *id
)
226 return draw_id_custom(view
, LINE_ID
, id
, opt_id_width
);
230 draw_filename(struct view
*view
, const char *filename
, bool auto_enabled
)
232 bool trim
= filename
&& strlen(filename
) >= opt_show_filename_width
;
234 if (opt_show_filename
== FILENAME_NO
)
237 if (opt_show_filename
== FILENAME_AUTO
&& !auto_enabled
)
240 return draw_field(view
, LINE_FILENAME
, filename
, opt_show_filename_width
, ALIGN_LEFT
, trim
);
244 draw_file_size(struct view
*view
, unsigned long size
, int width
, bool pad
)
246 const char *str
= pad
? NULL
: mkfilesize(size
, opt_show_file_size
);
248 if (!width
|| opt_show_file_size
== FILE_SIZE_NO
)
251 return draw_field(view
, LINE_FILE_SIZE
, str
, width
, ALIGN_RIGHT
, FALSE
);
255 draw_mode(struct view
*view
, mode_t mode
)
257 const char *str
= mkmode(mode
);
259 return draw_field(view
, LINE_MODE
, str
, STRING_SIZE("-rw-r--r--"), ALIGN_LEFT
, FALSE
);
263 draw_lineno(struct view
*view
, unsigned int lineno
)
266 int digits3
= view
->digits
< 3 ? 3 : view
->digits
;
267 int max
= MIN(VIEW_MAX_LEN(view
), digits3
);
269 chtype separator
= opt_line_graphics
? ACS_VLINE
: '|';
271 if (!opt_show_line_numbers
)
274 lineno
+= view
->pos
.offset
+ 1;
275 if (lineno
== 1 || (lineno
% opt_line_number_interval
) == 0) {
276 static char fmt
[] = "%1ld";
278 fmt
[1] = '0' + (view
->digits
<= 9 ? digits3
: 1);
279 if (string_format(number
, fmt
, lineno
))
283 draw_chars(view
, LINE_LINE_NUMBER
, text
, max
, TRUE
);
285 draw_space(view
, LINE_LINE_NUMBER
, max
, digits3
);
286 return draw_graphic(view
, LINE_DEFAULT
, &separator
, 1, TRUE
);
290 draw_refs(struct view
*view
, struct ref_list
*refs
)
294 if (!opt_show_refs
|| !refs
)
297 for (i
= 0; i
< refs
->size
; i
++) {
298 struct ref
*ref
= refs
->refs
[i
];
299 enum line_type type
= get_line_type_from_ref(ref
);
301 if (draw_formatted(view
, type
, "[%s]", ref
->name
))
304 if (draw_text(view
, LINE_DEFAULT
, " "))
312 draw_view_line(struct view
*view
, unsigned int lineno
)
315 bool selected
= (view
->pos
.offset
+ lineno
== view
->pos
.lineno
);
317 /* FIXME: Disabled during code split.
318 assert(view_is_displayed(view));
321 if (view
->pos
.offset
+ lineno
>= view
->lines
)
324 line
= &view
->line
[view
->pos
.offset
+ lineno
];
326 wmove(view
->win
, lineno
, 0);
328 wclrtoeol(view
->win
);
330 view
->curline
= line
;
331 view
->curtype
= LINE_NONE
;
332 line
->selected
= FALSE
;
333 line
->dirty
= line
->cleareol
= 0;
336 set_view_attr(view
, LINE_CURSOR
);
337 line
->selected
= TRUE
;
338 view
->ops
->select(view
, line
);
341 return view
->ops
->draw(view
, line
, lineno
);
345 redraw_view_dirty(struct view
*view
)
350 for (lineno
= 0; lineno
< view
->height
; lineno
++) {
351 if (view
->pos
.offset
+ lineno
>= view
->lines
)
353 if (!view
->line
[view
->pos
.offset
+ lineno
].dirty
)
356 if (!draw_view_line(view
, lineno
))
362 wnoutrefresh(view
->win
);
366 redraw_view_from(struct view
*view
, int lineno
)
368 assert(0 <= lineno
&& lineno
< view
->height
);
370 for (; lineno
< view
->height
; lineno
++) {
371 if (!draw_view_line(view
, lineno
))
375 wnoutrefresh(view
->win
);
379 redraw_view(struct view
*view
)
382 redraw_view_from(view
, 0);
385 /* vim: set ts=8 sw=8 noexpandtab: */