Implement drawing and scrolling text in textview

This commit is contained in:
2025-05-11 00:18:05 +05:00
parent 42299aedf5
commit 4cdc29383a
6 changed files with 186 additions and 65 deletions

View File

@@ -2,6 +2,8 @@
Simple serial terminal for KolibriOS.
![screenshot](screenshot.png)
# Requirements
- [Fasm](https://flatassembler.net/) 1.7x

BIN
icons.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 445 B

After

Width:  |  Height:  |  Size: 523 B

View File

@@ -33,7 +33,7 @@ BTN_SEND = 5
BTN_OK = 2
BTN_CANCEL = 3
__DEBUG__ = 0
__DEBUG__ = 1
__DEBUG_LEVEL__ = 0
include '../../proc32.inc'
@@ -43,8 +43,8 @@ include '../../dll.inc'
include '../../debug-fdo.inc'
include '../../develop/libraries/box_lib/trunk/box_lib.mac'
include '../../../drivers/serial/common.inc'
include 'textview.asm'
include 'utils.asm'
include 'textview.inc'
include 'utils.inc'
start:
mcall SF_SYS_MISC, SSF_HEAP_INIT
@@ -54,7 +54,7 @@ start:
or eax, eax
jnz .exit
mcall SF_SET_EVENTS_MASK, EVM_MOUSE + EVM_MOUSE_FILTER + EVM_REDRAW + EVM_BUTTON + EVM_KEY
mcall SF_SET_EVENTS_MASK, EVM_MOUSE + EVM_REDRAW + EVM_BUTTON + EVM_KEY
mov byte [ed_send_val], 0
stdcall text_view_init, text_view
@@ -69,7 +69,16 @@ start:
dec eax
jz .btn
invoke edit_box_mouse, ed_send
push [vscroll.position]
invoke scrollbar_mouse, vscroll
pop eax
cmp eax, [vscroll.position]
je @f
mov eax, [vscroll.position]
mov [text_view.curr_line], eax
DEBUGF 0, "vscroll.position=%d\n", eax
stdcall text_view_draw, text_view
@@:
jmp .loop
.win:
call .draw_window
@@ -93,7 +102,10 @@ start:
@@:
cmp ah, BTN_CLEAR
jne @f
; TODO
stdcall text_view_clear, text_view
stdcall text_view_draw, text_view
call update_vscroll
invoke scrollbar_draw, vscroll
jmp .loop
@@:
cmp ah, BTN_SEND
@@ -134,6 +146,7 @@ start:
mcall SF_DEFINE_BUTTON, <59, 24>, <5, 24>, BTN_CLEAR, [sc.work_light]
mcall SF_PUT_IMAGE_EXT, icons, <20, 20>, <3, 7>, 1, icons.palette, 0
mcall SF_PUT_IMAGE_EXT, icons + 180, <20, 20>, <61, 7>, 1, icons.palette, 0
mov ebx, icons + 60 ; disconnected icon
mov al, [is_connected]
@@ -180,6 +193,7 @@ start:
sub eax, 2 * FONT_HEIGHT + WIN_BORDER_WIDTH + 14 + SCROLL_TOP
mov [vscroll.y_size], ax
call update_vscroll
invoke scrollbar_draw, vscroll
; editbox and send button
@@ -352,15 +366,29 @@ show_conn_window:
mcall SF_REDRAW, SSF_END_DRAW
ret
send_text:
stdcall text_view_append_line, text_view, ed_send_val
xor eax, eax
push eax
invoke edit_box_set_text, ed_send, esp
pop eax
stdcall text_view_draw, text_view
invoke edit_box_draw, ed_send
ret
proc send_text
stdcall text_view_append_line, text_view, ed_send_val
xor eax, eax
push eax
invoke edit_box_set_text, ed_send, esp
pop eax
stdcall text_view_draw, text_view
invoke edit_box_draw, ed_send
call update_vscroll
invoke scrollbar_draw, vscroll
ret
endp
proc update_vscroll
mov eax, [text_view.total_lines]
mov [vscroll.max_area], eax
mov eax, [text_view.rows]
mov [vscroll.cur_area], eax
mov eax, [text_view.curr_line]
mov [vscroll.position], eax
ret
endp
align 16
@IMPORT:
@@ -409,14 +437,14 @@ port_conf:
db 8, 1, SERIAL_CONF_PARITY_NONE, SERIAL_CONF_FLOW_CTRL_NONE
port_conf_end:
if __DEBUG__ eq 1
;if __DEBUG__ eq 1
include_debug_strings
end if
;end if
; https://javl.github.io/image2cpp/
icons:
; 'icons', 20x60px
db 0xff, 0xff, 0xf0, 0xfc, 0xff, 0xf0, 0xf8, 0x3f, 0xf0, 0xf8, 0x1f, 0xf0, 0xfe, 0x1f, 0xf0, 0xdf
; 'icons', 20x80px
db 0xff, 0xff, 0xf0, 0xfc, 0x7f, 0xf0, 0xf8, 0x3f, 0xf0, 0xf8, 0x1f, 0xf0, 0xfe, 0x1f, 0xf0, 0xdf
db 0x1f, 0xf0, 0x8e, 0x1f, 0xf0, 0xa4, 0x3f, 0xf0, 0x90, 0x1f, 0xf0, 0xc8, 0x0f, 0xf0, 0xe0, 0x07
db 0xf0, 0xfe, 0x43, 0xf0, 0xff, 0x21, 0xf0, 0xff, 0x90, 0xf0, 0xff, 0xc8, 0x70, 0xff, 0xe4, 0x30
db 0xff, 0xf0, 0x70, 0xff, 0xf8, 0xf0, 0xff, 0xfd, 0xf0, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xf0, 0xff
@@ -427,7 +455,10 @@ icons:
db 0xf0, 0xff, 0xff, 0xf0, 0xff, 0x9f, 0xf0, 0xff, 0x0f, 0xf0, 0xfe, 0x07, 0xf0, 0xfe, 0x07, 0xf0
db 0xfc, 0x03, 0xf0, 0x80, 0x00, 0x10, 0x80, 0x00, 0x10, 0xfc, 0x03, 0xf0, 0xfe, 0x07, 0xf0, 0xfe
db 0x07, 0xf0, 0xff, 0x0f, 0xf0, 0xff, 0x9f, 0xf0, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xf0, 0xff, 0xff
db 0xf0, 0xff, 0xff, 0xf0
db 0xf0, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xf0, 0xff, 0xe3, 0xf0
db 0xff, 0xc9, 0xf0, 0xff, 0x9c, 0xf0, 0xff, 0x3e, 0x70, 0xfe, 0x7f, 0x70, 0xfc, 0x7f, 0x70, 0xf9
db 0x3e, 0x70, 0xf3, 0x9c, 0xf0, 0xe7, 0xc9, 0xf0, 0xef, 0xe3, 0xf0, 0xe7, 0xe7, 0xf0, 0xf3, 0xcf
db 0xf0, 0xf9, 0x9f, 0xf0, 0xfc, 0x00, 0x70, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xf0
.palette:
dd 0xffffff
dd 0x000000

BIN
screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -1,4 +1,5 @@
BUF_SIZE = 4096
FRM_WIDTH = 1
MARGIN = 1
struct TEXT_VIEW
@@ -16,7 +17,7 @@ struct TEXT_VIEW
total_lines dd ?
curr_line dd ?
max_length dd ?
max_length dd ? ; length of the longest string
rows dd ?
cols dd ?
@@ -45,59 +46,40 @@ proc text_view_deinit stdcall uses ebx, text_view:dword
endp
proc text_view_draw stdcall uses ebx esi edi, text_view:dword
; draw frame and background
mov esi, [text_view]
call tv.draw_frame_and_bg
call tv.calc_rows_and_cols
DEBUGF 0, "text_view rows=%d cols=%d\n", [esi + TEXT_VIEW.rows], [esi + TEXT_VIEW.cols]
mov eax, [esi + TEXT_VIEW.curr_line]
mov ebx, [esi + TEXT_VIEW.total_lines]
DEBUGF 0, "text_view curr_line=%d total_lines=%d\n", eax, ebx
sub ebx, eax
cmp ebx, [esi + TEXT_VIEW.rows]
jbe @f
mov ebx, [esi + TEXT_VIEW.rows]
@@:
mov edi, [esi + TEXT_VIEW.buf_data]
call goto_curr_line
mov ecx, ebx ; ecx = count lines
xor eax, eax ; eax = index from 0
mov ebx, [esi + TEXT_VIEW.left]
shl ebx, 16
add ebx, [esi + TEXT_VIEW.width]
mov ecx, [esi + TEXT_VIEW.top]
shl ecx, 16
add ecx, [esi + TEXT_VIEW.height]
mov edx, [esi + TEXT_VIEW.fg_color]
call draw_frame
add ebx, 1 shl 16
sub ebx, 2
add ecx, 1 shl 16
sub ecx, 2
mov edx, [esi + TEXT_VIEW.bg_color]
mcall SF_DRAW_RECT
; calc rows and cols
mov eax, [esi + TEXT_VIEW.width]
sub eax, MARGIN * 2
shr eax, 3 ; assume that font width is 8 px
mov [esi + TEXT_VIEW.cols], eax
xor edx, edx
mov eax, [esi + TEXT_VIEW.height]
sub eax, MARGIN * 2
mov ebx, FONT_HEIGHT + MARGIN * 2
div ebx
mov [esi + TEXT_VIEW.rows], eax
; draw lines
xor eax, eax ; rows
mov ebx, [esi + TEXT_VIEW.left]
add ebx, MARGIN + 1 ; frame width
add ebx, MARGIN + FRM_WIDTH
shl ebx, 16
add ebx, [esi + TEXT_VIEW.top]
add ebx, MARGIN + 1 ; frame width
mov edi, [esi + TEXT_VIEW.buf_data]
add ebx, MARGIN + FRM_WIDTH
.draw_lines:
cmp eax, [esi + TEXT_VIEW.total_lines]
cmp eax, ecx
jae .draw_lines_end
mov ecx, 0x90000000
or ecx, [esi + TEXT_VIEW.fg_color]
mov edx, edi
push eax
mcall SF_DRAW_TEXT
push eax ecx
call tv.draw_single_line
; move edi pointer to the next string
push esi
mov esi, edi
call strlen
add edi, eax
inc edi
pop esi
; next line num
pop eax
inc eax
pop ecx eax
inc eax ; next line num
add ebx, FONT_HEIGHT + MARGIN
jmp .draw_lines
.draw_lines_end:
@@ -143,7 +125,112 @@ proc text_view_append_line stdcall uses ebx esi edi, text_view:dword, string:dwo
ret
endp
draw_frame:
proc text_view_clear stdcall uses ebx, text_view:dword
mov edx, [text_view]
mov ecx, [edx + TEXT_VIEW.buf_data]
test ecx, ecx
jz @f
mcall SF_SYS_MISC, SSF_MEM_FREE
@@:
xor eax, eax
mov [edx + TEXT_VIEW.buf_data], eax
mov [edx + TEXT_VIEW.buf_size], eax
mov [edx + TEXT_VIEW.data_size], eax
mov [edx + TEXT_VIEW.total_lines], eax
mov [edx + TEXT_VIEW.curr_line], eax
mov [edx + TEXT_VIEW.max_length], eax
ret
endp
proc text_view_deinit stdcall uses ebx, text_view:dword
mov edx, [text_view]
mov ecx, [edx + TEXT_VIEW.buf_data]
test ecx, ecx
jz @f
mcall SF_SYS_MISC, SSF_MEM_FREE
@@:
ret
endp
proc tv.draw_frame_and_bg
; esi = text_view
mov ebx, [esi + TEXT_VIEW.left]
shl ebx, 16
add ebx, [esi + TEXT_VIEW.width]
mov ecx, [esi + TEXT_VIEW.top]
shl ecx, 16
add ecx, [esi + TEXT_VIEW.height]
mov edx, [esi + TEXT_VIEW.fg_color]
call draw_frame
add ebx, 1 shl 16
sub ebx, 2
add ecx, 1 shl 16
sub ecx, 2
mov edx, [esi + TEXT_VIEW.bg_color]
mcall SF_DRAW_RECT
ret
endp
proc tv.calc_rows_and_cols
; esi = text_view
mov eax, [esi + TEXT_VIEW.width]
sub eax, (FRM_WIDTH + MARGIN) * 2
shr eax, 3 ; assume that font width is 8 px
mov [esi + TEXT_VIEW.cols], eax
xor edx, edx
mov eax, [esi + TEXT_VIEW.height]
sub eax, MARGIN * 2
mov ebx, FONT_HEIGHT + MARGIN
div ebx
mov [esi + TEXT_VIEW.rows], eax
ret
endp
proc tv.draw_single_line uses esi
; esi = text_view
; ebx = coordinates: left << 16 + top
; edi = pointer to the first byte of string in [text_view.buf_data]
; return: eax = length of the string
mov ecx, 0x10000000 ; fixed-length string
or ecx, [esi + TEXT_VIEW.fg_color]
push esi
mov esi, edi
call strlen
pop esi
push eax
cmp eax, [esi + TEXT_VIEW.cols]
jbe .len_ok
mov eax, [esi + TEXT_VIEW.cols]
.len_ok:
mov esi, eax
mov edx, edi
mcall SF_DRAW_TEXT
pop eax
ret
endp
proc goto_curr_line uses ebx esi
; eax = curr line index
; edi = buf
mov ebx, eax
xor ecx, ecx
mov esi, edi
cld
.scan:
cmp ecx, ebx
je .exit
lodsb
test al, al
jnz .scan
inc ecx
jmp .scan
.exit:
mov eax, ebx
mov edi, esi
ret
endp
proc draw_frame
; ebx = left << 16 + width
; ecx = top << 16 + height
; edx = color
@@ -180,3 +267,4 @@ draw_frame:
mcall SF_DRAW_LINE
pop ecx ebx
ret
endp