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. Simple serial terminal for KolibriOS.
![screenshot](screenshot.png)
# Requirements # Requirements
- [Fasm](https://flatassembler.net/) 1.7x - [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_OK = 2
BTN_CANCEL = 3 BTN_CANCEL = 3
__DEBUG__ = 0 __DEBUG__ = 1
__DEBUG_LEVEL__ = 0 __DEBUG_LEVEL__ = 0
include '../../proc32.inc' include '../../proc32.inc'
@@ -43,8 +43,8 @@ include '../../dll.inc'
include '../../debug-fdo.inc' include '../../debug-fdo.inc'
include '../../develop/libraries/box_lib/trunk/box_lib.mac' include '../../develop/libraries/box_lib/trunk/box_lib.mac'
include '../../../drivers/serial/common.inc' include '../../../drivers/serial/common.inc'
include 'textview.asm' include 'textview.inc'
include 'utils.asm' include 'utils.inc'
start: start:
mcall SF_SYS_MISC, SSF_HEAP_INIT mcall SF_SYS_MISC, SSF_HEAP_INIT
@@ -54,7 +54,7 @@ start:
or eax, eax or eax, eax
jnz .exit 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 mov byte [ed_send_val], 0
stdcall text_view_init, text_view stdcall text_view_init, text_view
@@ -69,7 +69,16 @@ start:
dec eax dec eax
jz .btn jz .btn
invoke edit_box_mouse, ed_send invoke edit_box_mouse, ed_send
push [vscroll.position]
invoke scrollbar_mouse, vscroll 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 jmp .loop
.win: .win:
call .draw_window call .draw_window
@@ -93,7 +102,10 @@ start:
@@: @@:
cmp ah, BTN_CLEAR cmp ah, BTN_CLEAR
jne @f jne @f
; TODO stdcall text_view_clear, text_view
stdcall text_view_draw, text_view
call update_vscroll
invoke scrollbar_draw, vscroll
jmp .loop jmp .loop
@@: @@:
cmp ah, BTN_SEND cmp ah, BTN_SEND
@@ -134,6 +146,7 @@ start:
mcall SF_DEFINE_BUTTON, <59, 24>, <5, 24>, BTN_CLEAR, [sc.work_light] 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, <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 ebx, icons + 60 ; disconnected icon
mov al, [is_connected] mov al, [is_connected]
@@ -180,6 +193,7 @@ start:
sub eax, 2 * FONT_HEIGHT + WIN_BORDER_WIDTH + 14 + SCROLL_TOP sub eax, 2 * FONT_HEIGHT + WIN_BORDER_WIDTH + 14 + SCROLL_TOP
mov [vscroll.y_size], ax mov [vscroll.y_size], ax
call update_vscroll
invoke scrollbar_draw, vscroll invoke scrollbar_draw, vscroll
; editbox and send button ; editbox and send button
@@ -352,15 +366,29 @@ show_conn_window:
mcall SF_REDRAW, SSF_END_DRAW mcall SF_REDRAW, SSF_END_DRAW
ret ret
send_text:
stdcall text_view_append_line, text_view, ed_send_val proc send_text
xor eax, eax stdcall text_view_append_line, text_view, ed_send_val
push eax xor eax, eax
invoke edit_box_set_text, ed_send, esp push eax
pop eax invoke edit_box_set_text, ed_send, esp
stdcall text_view_draw, text_view pop eax
invoke edit_box_draw, ed_send stdcall text_view_draw, text_view
ret 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 align 16
@IMPORT: @IMPORT:
@@ -409,14 +437,14 @@ port_conf:
db 8, 1, SERIAL_CONF_PARITY_NONE, SERIAL_CONF_FLOW_CTRL_NONE db 8, 1, SERIAL_CONF_PARITY_NONE, SERIAL_CONF_FLOW_CTRL_NONE
port_conf_end: port_conf_end:
if __DEBUG__ eq 1 ;if __DEBUG__ eq 1
include_debug_strings include_debug_strings
end if ;end if
; https://javl.github.io/image2cpp/ ; https://javl.github.io/image2cpp/
icons: icons:
; 'icons', 20x60px ; 'icons', 20x80px
db 0xff, 0xff, 0xf0, 0xfc, 0xff, 0xf0, 0xf8, 0x3f, 0xf0, 0xf8, 0x1f, 0xf0, 0xfe, 0x1f, 0xf0, 0xdf 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 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 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 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 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 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 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: .palette:
dd 0xffffff dd 0xffffff
dd 0x000000 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 BUF_SIZE = 4096
FRM_WIDTH = 1
MARGIN = 1 MARGIN = 1
struct TEXT_VIEW struct TEXT_VIEW
@@ -16,7 +17,7 @@ struct TEXT_VIEW
total_lines dd ? total_lines dd ?
curr_line dd ? curr_line dd ?
max_length dd ? max_length dd ? ; length of the longest string
rows dd ? rows dd ?
cols dd ? cols dd ?
@@ -45,59 +46,40 @@ proc text_view_deinit stdcall uses ebx, text_view:dword
endp endp
proc text_view_draw stdcall uses ebx esi edi, text_view:dword proc text_view_draw stdcall uses ebx esi edi, text_view:dword
; draw frame and background
mov esi, [text_view] 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] mov ebx, [esi + TEXT_VIEW.left]
shl ebx, 16 add ebx, MARGIN + FRM_WIDTH
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
shl ebx, 16 shl ebx, 16
add ebx, [esi + TEXT_VIEW.top] add ebx, [esi + TEXT_VIEW.top]
add ebx, MARGIN + 1 ; frame width add ebx, MARGIN + FRM_WIDTH
mov edi, [esi + TEXT_VIEW.buf_data]
.draw_lines: .draw_lines:
cmp eax, [esi + TEXT_VIEW.total_lines] cmp eax, ecx
jae .draw_lines_end jae .draw_lines_end
mov ecx, 0x90000000 push eax ecx
or ecx, [esi + TEXT_VIEW.fg_color] call tv.draw_single_line
mov edx, edi
push eax
mcall SF_DRAW_TEXT
; move edi pointer to the next string ; move edi pointer to the next string
push esi
mov esi, edi
call strlen
add edi, eax add edi, eax
inc edi inc edi
pop esi pop ecx eax
; next line num inc eax ; next line num
pop eax
inc eax
add ebx, FONT_HEIGHT + MARGIN add ebx, FONT_HEIGHT + MARGIN
jmp .draw_lines jmp .draw_lines
.draw_lines_end: .draw_lines_end:
@@ -143,7 +125,112 @@ proc text_view_append_line stdcall uses ebx esi edi, text_view:dword, string:dwo
ret ret
endp 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 ; ebx = left << 16 + width
; ecx = top << 16 + height ; ecx = top << 16 + height
; edx = color ; edx = color
@@ -180,3 +267,4 @@ draw_frame:
mcall SF_DRAW_LINE mcall SF_DRAW_LINE
pop ecx ebx pop ecx ebx
ret ret
endp