;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ; ;; Scroll.inc ; ;; ; ;; Vertical Scroll Bar Example for MenuetOS ; ;; ; ;; Version 0.2 27 February 2005 ; ;; ; ;; ; ;; GNU GENERAL PUBLIC LICENSE ; ;; Version 2, June 1991 ; ;; ; ;; Copyright 2005 Jason Delozier, ; ;; cordata51@hotmail.com ; ;; ; ;; See file COPYING for details ; ;; ; ;; Updates: ; ;; - FPU not longer used for calculations -Feb 27, 2005 ; ;; ; ;; ; ;; TODO: ; ;; - Create Message Handler and only allow runtime arguments ; ;; to be processed through the message handler ; ;; - Remove all local varibles and only allow working varible to ; ;; reside in scroll bar structure. ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;***************************************************************************** ;* ;* VScroll Structure Equates ;* ;***************************************************************************** VScroll_width equ 0 VScroll_x equ 2 VScroll_height equ 4 VScroll_y equ 6 VScroll_min equ 8 VScroll_max equ 12 VScroll_current equ 16 VScroll_s_change equ 20 VScroll_b_change equ 24 ;Example VScroll Structure ;VScroll_1: ; dw 16 ;width +0 ; dw 100 ;x +2 ; dw 200 ;height +4 ; dw 40 ;y +6 ; dd 0 ;min +8 ; dd 1000;max +12 ; dd 1 ;current +16 ; dd 1 ;small change +20 ; dd 10 ;big change +24 VScroll_Min_Height dw 16 ;scroll box Vscroll_Fixed_Height dw 16 ;height of scroll buttons (up and down) ;************************************** ;* ;* Mouse Over VScroll ;* ;************************************** vsm1 dd 0 vstoff dd 0 VScroll_mouse_over: cmp [mouseb], 1 je VScroll_Mouse_Has_Mouse cmp [mouseb], 0 jne VScroll_mouse_over_done2 mov [vsm1], 0 jmp VScroll_mouse_over_done2 VScroll_Mouse_Has_Mouse: push ecx mov ecx, [vsm1] shl ecx,2 call dword [VScroll_Mouse_Jumptable+ecx] VScroll_mouse_over_done: pop ecx VScroll_mouse_over_done2: ret VScroll_Mouse_Jumptable: dd VScroll_Mouse_Find dd VScroll_Mouse_On_Up dd VScroll_Mouse_On_Down dd VScroll_Mouse_Above_Thumb dd VScroll_Mouse_Below_Thumb dd VScroll_Mouse_On_Thumb VScroll_Mouse_Find: inc ecx call dword [VScroll_Mouse_Jumptable+ecx*4] cmp [vsm1], 0 jne VScroll_mouse_over_done2 cmp ecx, 5 je VScroll_mouse_over_done2 jmp VScroll_Mouse_Find ;************************************** ;Is Mouse at Up button VScroll_Mouse_On_Up: push eax movzx eax, word [ebp+VScroll_y] add ax, word [Vscroll_Fixed_Height] cmp [mousey], ax pop eax ja VScroll_Mouse_On_Up2 mov [vsm1], 1 call VScroll_Small_Up VScroll_Mouse_On_Up2: ret ;************************************** ;Is Mouse at Down button VScroll_Mouse_On_Down: push eax movzx eax,word [ebp+VScroll_y] add ax, word [ebp+VScroll_height] sub ax, word [Vscroll_Fixed_Height] cmp [mousey], ax pop eax jb VScroll_Mouse_On_Down2 mov [vsm1], 2 call VScroll_Small_Down VScroll_Mouse_On_Down2: ret ;************************************** ;Is Mouse above Scroll Thumb VScroll_Mouse_Above_Thumb: push eax push ecx push edx call Vscroll_SBox_Area add cx, word [ebp+VScroll_y] add cx, word [Vscroll_Fixed_Height] ;plus height of scroll button cmp cx, [mousey] pop edx pop ecx pop eax jb VScroll_Mouse_Above_Thumb2 mov [vsm1], 3 call VScroll_Big_Up VScroll_Mouse_Above_Thumb2: ret ;************************************** ;Is Mouse below scroll thumb VScroll_Mouse_Below_Thumb: push eax push ecx push edx call Vscroll_SBox_Area add cx, word [ebp+VScroll_y] add cx, word [Vscroll_Fixed_Height] ;plus height of scroll button add cx, ax cmp cx, [mousey] pop edx pop ecx pop eax ja VScroll_Mouse_Below_Thumb2 mov [vsm1], 4 call VScroll_Big_Down VScroll_Mouse_Below_Thumb2: ret ;************************************** ;Mouse is on Scroll Thumb VScroll_Mouse_On_Thumb: pusha cmp [vsm1], 5 ;first time moving since we clicked? je VScroll_Mouse_On_Thumb1 ;if not jump.. we already have offset mov [vsm1], 5 ;determine offset between mouse pointer and top of thumb call Vscroll_SBox_Area ;get top of thumb coordinate add cx, word [ebp+VScroll_y] ;make screen coordinate add cx, word [Vscroll_Fixed_Height] ;plus height of scroll button and top movzx esi,word [mousey] ;get mouse position sub esi, ecx ;make offset between top of thumb mov [vstoff], esi ;and mouse pointer then save it VScroll_Mouse_On_Thumb1: ; movzx esi, [mousey] ;get mouse y value sub si, word [ebp+VScroll_y] ;get y starting value of scroll bar sub si, [Vscroll_Fixed_Height] sub esi, [vstoff] ; call Vscroll_SBox_Area ; VScroll_Mouse_On_Thumb2: ; cmp [ebp+VScroll_current], edx ;only redraw if change occured je VScroll_Mouse_On_Thumb3 ; mov [ebp+VScroll_current], edx ;new current value call drawvscrolla ;redraw scroll background and thumb VScroll_Mouse_On_Thumb3: ; popa ; ret ;************************************** ;***************************************************************************** ;* ;* Vscroll_SBox_Area ;* ;* Purpose: To determine the area of the Scroll Bar Thumb and the current ;* value of scroll based on top pixel of thumb. ;* ;* Inputs: ;* EBP - Structure of scroll bar ;* ESI - Top of Thumb - optional ;* ;* Outputs: ;* EAX - Thumb Height ;* ECX - Top of thumb ;* EDX - Current Value based on top pixel of thumb. Valid when ESI ;* is given as input. ;* ;* This procedure is divided up into 5 specific functions. ;* 1. ((Vmax-VMin)/Small Change)= Total Changes ;* 2. Height - (2* Fixed Button Height) = Total Pixels ;* 3. Total Pixels - Total Changes = Thumb Height (must be >= 16) ;* Minimum Height of 16 is varible [VScroll_Min_Height] ;* 4. (((Tot Pixels - Thumb Height)* Current)/Max-min)=Top Pixel of Thumb ;* 5. ((Mouse Top * (max-Min))/(Total Pix - Thumb Height)) = Current ;* Step 5 is only valid if ESI is supplied as an input. ;* ;* ;***************************************************************************** Vscroll_SBox_Area: push ebx push esi push edi ;Step 1. Determine Total Changes mov eax, dword [ebp+VScroll_max] ;get max scroll sub eax, dword [ebp+VScroll_min] ;sub minmum scroll for total scro xor edx,edx push eax div dword [ebp+VScroll_s_change] ; ;eax = total changes ((max-min)/Small Change) ;Step 2. Determine Total Pixels movzx ecx, word [ebp+VScroll_height] ;height of entire scroll bar mov bx, word [Vscroll_Fixed_Height] ;minus height of both scroll button shl bx, 1 sub cx, bx push ecx ;ecx = total pixels (Total Height - (2*Fixed Button Height) ;Step 3. Determine Thumb Height cmp ecx, eax jbe vs1 sub ecx, eax cmp cx, word [VScroll_Min_Height] jb vs1 jmp vs2 vs1: movzx ecx, word [VScroll_Min_Height] vs2: ;ecx = Thumb Height (Total Pixels - Total Changes) >=16 ;Step 4. Determine Top Pixel of Thumb pop edi ;Total Pixels sub edi, ecx ; ;edi = Total Pixels - thumb Height mov eax, edi ; mul dword [ebp+VScroll_current] ;get current scroll value pop ebx ;max scroll push ecx ; div ebx ; mov ecx, eax ; ;ecx = top pixel of thumb ;Step 5. Determine Current Value based on Mouse Position cmp si,0 jge vss4 mov eax, dword [ebp+VScroll_min] jmp vsdone1 vss4: cmp esi, edi jbe vss3 mov eax, dword [ebp+VScroll_max] jmp vsdone1 vss3: mov eax,ebx ;max scroll mul esi ;Top Pixel of mouse div edi ;Total Pixels - Thumb Height ;eax = Current Value vsdone1: mov edx, eax ;Current Value pop eax ;Thumb Height pop edi pop esi pop ebx ret ;***************************************************************************** ;* ;***************************************************************************** ;ebp is structure drawvscroll: pusha ;up button mov eax, 13 ;button system function mov edx,0x00777777 ;0x6677cc ;color mov ebx, [ebp+VScroll_width] ;x-start/width mov cx, word [ebp+VScroll_y] ;get bottom of scroll bar shl ecx, 16 mov cx, [Vscroll_Fixed_Height] ;fixed height int 0x40 ;down button mov ebx, [ebp+VScroll_width] ;x-start/width mov cx, word [ebp+VScroll_y] ;get bottom of scroll bar add cx, word [ebp+VScroll_height] ; sub cx, [Vscroll_Fixed_Height] ;y-start is 12 pixel from bottom shl ecx, 16 ; mov cx, [Vscroll_Fixed_Height] ;fixed height int 0x40 ;------- 'ASCL.INC' needs to be included to use this -- putlabel 493,46,'',cl_Black putlabel 493,372,'',cl_Black ;------------------------------------------------------ popa drawvscrolla: pusha mov eax, 13 ;Draw Scroll Box Background mov edx, 0x00999999;0 ;color push edx movzx edx, word [Vscroll_Fixed_Height] mov ebx, [ebp+VScroll_width] ;x-start/width movzx ecx,word [ebp+VScroll_y] ;y-start add ecx, edx ;add fixed height button shl ecx, 16 ;do height next mov cx,word [ebp+VScroll_height] ;y-start sub cx, dx ;subtract fixed height of up button sub cx, dx ;subtract fixed height of down button pop edx int 0x40 ;tell system to draw it ;determine height of scroll box (thumb) call Vscroll_SBox_Area add cx, [ebp+VScroll_y] add cx, 16 shl ecx, 16 mov cx, ax mov eax, 13 ;draw scroll box mov ebx, [ebp+VScroll_width] ;x-start/width mov edx, 0x00bbbbbb ;0x999999 int 0x40 ;call Draw_Scroll_info popa ret ;***************************************************************************** ;***************************************************************************** ;* VScroll_Big_Up ;* VScroll_Small_Up ;***************************************************************************** ;need to update for signed values VScroll_Big_Up: push eax push ebx mov eax, dword [ebp+VScroll_b_change] jmp VScroll_Up VScroll_Small_Up: push eax push ebx mov eax, dword [ebp+VScroll_s_change] VScroll_Up: mov ebx, dword [ebp+VScroll_min] ;get minimum value cmp [ebp+VScroll_current], ebx ;are we at minimum already? je VScroll_Up_exit ;if so leave sub [ebp+VScroll_current], eax ; jnc VScroll_Up_done mov [ebp+VScroll_current], ebx VScroll_Up_done: cmp [ebp+VScroll_current], ebx ;if current is greater then max jae VScroll_Up_done2 mov [ebp+VScroll_current], ebx VScroll_Up_done2: ;redraw call drawvscroll ;temp? VScroll_Up_exit: pop ebx pop eax ret ;***************************************************************************** ;***************************************************************************** ;* VScroll_Big_Down ;* VScroll_Small_Down ;***************************************************************************** ;need to update for signed values VScroll_Big_Down: push eax push ebx mov eax, dword [ebp+VScroll_b_change];get big change value jmp VScroll_Down VScroll_Small_Down: push eax push ebx mov eax, dword [ebp+VScroll_s_change];get small change value VScroll_Down: mov ebx, dword [ebp+VScroll_max] ;get maximum scroll value cmp [ebp+VScroll_current], ebx ;are we at max already? je VScroll_Down_exit ;if so leave add [ebp+VScroll_current], eax ;add change to current jno VScroll_Down_done ;dont go beyond bounds of register mov [ebp+VScroll_current], ebx ;if we did then we at max VScroll_Down_done: ; cmp [ebp+VScroll_current], ebx ;if current is greater then max jbe VScroll_Down_done2 ; mov [ebp+VScroll_current], ebx ;then we at max VScroll_Down_done2: ; ;redraw call drawvscroll ;temp? VScroll_Down_exit: pop ebx pop eax ret ;*****************************************************************************