Implement drawing and scrolling text in textview
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
|
||||
Simple serial terminal for KolibriOS.
|
||||
|
||||

|
||||
|
||||
# Requirements
|
||||
|
||||
- [Fasm](https://flatassembler.net/) 1.7x
|
||||
|
BIN
icons.png
BIN
icons.png
Binary file not shown.
Before Width: | Height: | Size: 445 B After Width: | Height: | Size: 523 B |
69
kterm.asm
69
kterm.asm
@@ -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
BIN
screenshot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.8 KiB |
@@ -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
|
Reference in New Issue
Block a user