HeavyThing - tui_progressbox.inc

Jeff Marrison

Table of functions

	; ------------------------------------------------------------------------
	; HeavyThing x86_64 assembly language library and showcase programs
	; Copyright © 2015-2018 2 Ton Digital 
	; Homepage: https://2ton.com.au/
	; Author: Jeff Marrison <jeff@2ton.com.au>
	;       
	; This file is part of the HeavyThing library.
	;       
	; HeavyThing is free software: you can redistribute it and/or modify
	; it under the terms of the GNU General Public License, or
	; (at your option) any later version.
	;       
	; HeavyThing is distributed in the hope that it will be useful, 
	; but WITHOUT ANY WARRANTY; without even the implied warranty of
	; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
	; GNU General Public License for more details.
	;       
	; You should have received a copy of the GNU General Public License along
	; with the HeavyThing library. If not, see <http://www.gnu.org/licenses/>.
	; ------------------------------------------------------------------------
	;       
	; tui_progressbox.inc: a tui_panel wrapper that includes a title, message, and a progressbar
	; 
	; similar to tui_progressbox (and largely a cut-paste), simple goods to provide a dialog box with a progressbar
	;

if used tui_progressbox$new | defined include_everything
	; tui_panel has a user variable that it doesn't itself use, we populate that with our tui_progressbar for later reference

	; five arguments: rdi == string title, rsi == string message (multiline okay), edx == panel/title colors, ecx == progress colors, r8d == progress fill colors
falign
tui_progressbox$new:
	prolog	tui_progressbox$new
	; this is largely copied from tui_alert for layout calcs, etc
	sub	rsp, 80
	mov	[rsp], rdi
	mov	[rsp+8], rsi
	mov	[rsp+16], rdx
	mov	[rsp+24], rcx
	mov	[rsp+32], r8
	; calculate the dimensions we need for our panel
	; even though it is inefficient, we split the message first so we can determine
	; the longest line (inefficient insofar as tui_label will split it again)
	mov	rdi, rsi
	mov	esi, 10
	call	string$split
	mov	[rsp+48], rax
	mov	qword [rsp+56], 0
	mov	rdi, rax
	mov	rsi, .linelength
	lea	rdx, [rsp+56]
	call	list$foreach_arg
	mov	rdi, [rsp]
	; start with min 32
	mov	r10d, 32
	; titlelen + 6 bigger?
	mov	r11, [rdi]
	add	r11d, 6
	cmp	r11d, r10d
	cmova	r10d, r11d
	; linelen(max) + 6 bigger?
	mov	r11d, [rsp+56]
	add	r11d, 6
	cmp	r11d, r10d
	cmova	r10d, r11d
	; width is complete
	mov	[rsp+64], r10d
	; height is next
	mov	rax, [rsp+48]
	mov	edx, [rax+_list_size_ofs]
	mov	ecx, edx
	; add	ecx, 1
	cmp	edx, 1
	cmova	edx, ecx
	add	edx, 6
	mov	[rsp+68], edx
	; get rid of our list
	mov	rdi, rax
	mov	rsi, heap$free
	call	list$clear
	mov	rdi, [rsp+48]
	call	heap$free
	; we can construct our panel now
	mov	edi, [rsp+64]		; width
	mov	esi, [rsp+68]		; height
	mov	rdx, [rsp]		; title
	mov	ecx, [rsp+16]		; boxcolors
	mov	r8d, [rsp+16]		; titlecolors
	call	tui_panel$new_ii
	; also, we'd like a dropshadow under our panel
	mov	dword [rax+tui_dropshadow_ofs], 1
	mov	[rsp+56], rax		; our end return object
	; prepend our message with a linefeed so it ends up padded properly:
	mov	rdi, .lfstr
	mov	rsi, [rsp+8]
	call	string$concat
	mov	[rsp+64], rax
	movq	xmm0, [_math_onehundred]
	movq	xmm1, [_math_onehundred]
	mov	rdi, rax		; filltext
	mov	esi, [rsp+16]		; colors
	mov	edx, tui_textalign_center
	call	tui_label$new_dd
	; add that as a child to our panel
	mov	rdi, [rsp+56]
	mov	rsi, rax
	mov	rdx, [rdi]
	call	qword [rdx+tui_vappendchild]
	; free our filltext
	mov	rdi, [rsp+64]
	call	heap$free
	; next up, we need a 100% wide by 2 height vbox to hold our progressbar
	mov	edi, tui_object_size
	call	heap$alloc
	mov	qword [rax], tui_object$simple_vtable
	mov	[rsp+64], rax
	mov	rdi, rax
	movq	xmm0, [_math_onehundred]
	mov	esi, 2
	call	tui_object$init_di
	mov	rdi, [rsp+64]
	mov	dword [rdi+tui_horizalign_ofs], tui_align_center
	; add that to our panel
	mov	rsi, rdi
	mov	rdi, [rsp+56]
	mov	rdx, [rdi]
	call	qword [rdx+tui_vappendchild]
	; finally, do up our progressbar
	; the width of our text == panel width - 4
	mov	r8, [rsp+56]
	mov	edi, [r8+tui_width_ofs]
	mov	esi, 1			; height
	sub	edi, 4			; width
	mov	edx, 0			; direction
	mov	ecx, [rsp+24]		; empty colors
	mov	r8d, [rsp+32]		; fillcolors
	call	tui_progressbar$new_ii
	; add it to our box
	mov	rcx, [rsp+56]
	mov	rdi, [rsp+64]
	mov	rsi, rax
	mov	rdx, [rdi]
	mov	[rcx+tui_panel_user_ofs], rax
	call	qword [rdx+tui_vappendchild]
	mov	rax, [rsp+56]
	add	rsp, 80
	epilog
cleartext .lfstr, 10
falign
.linelength:
	; called for each string line in the message, rdi == string, rsi == pointer to update with our length
	mov	edx, [rdi]
	mov	ecx, [rsi]
	cmp	edx, ecx
	cmova	ecx, edx
	mov	[rsi], ecx
	ret

end if


if used tui_progressbox$nvlimits | defined include_everything
	; three arguments: rdi == our tui_progressbox, rsi == min, rdx == max
falign
tui_progressbox$nvlimits:
	prolog	tui_progressbox$nvlimits
	mov	rdi, [rdi+tui_panel_user_ofs]
	call	tui_progressbar$nvlimits
	epilog

end if

if used tui_progressbox$nvlimitsd | defined include_everything
	; three arguments: rdi == our tui_progressbox, xmm0 == min, xmm1 == max
falign
tui_progressbox$nvlimitsd:
	prolog	tui_progressbox$nvlimitsd
	mov	rdi, [rdi+tui_panel_user_ofs]
	call	tui_progressbar$nvlimitsd
	epilog

end if

if used tui_progressbox$nvupdate | defined include_everything
	; two arguments: rdi == our tui_progressbox, rsi == cur
falign
tui_progressbox$nvupdate:
	prolog	tui_progressbox$nvupdate
	mov	rdi, [rdi+tui_panel_user_ofs]
	call	tui_progressbar$nvupdate
	epilog

end if

if used tui_progressbox$nvupdated | defined include_everything
	; two arguments: rdi == our tui_progressbox, xmm0 == cur
falign
tui_progressbox$nvupdated:
	prolog	tui_progressbox$nvupdated
	mov	rdi, [rdi+tui_panel_user_ofs]
	call	tui_progressbar$nvupdated
	epilog

end if

if used tui_progressbox$nvgetperc | defined include_everything
	; single argument rdi: our tui_progressbox
	; returns the current percentage in xmm0 (as a normal decimal, 50% == 0.5)
falign
tui_progressbox$nvgetperc:
	prolog	tui_progressbox$nvgetperc
	mov	rdi, [rdi+tui_panel_user_ofs]
	call	tui_progressbar$nvgetperc
	epilog

end if