Index: freshlib/TestFreshLib.fpr
==================================================================
--- freshlib/TestFreshLib.fpr
+++ freshlib/TestFreshLib.fpr
cannot compute difference between binary files
ADDED freshlib/_doc/CheckListFresh3.txt
Index: freshlib/_doc/CheckListFresh3.txt
==================================================================
--- /dev/null
+++ freshlib/_doc/CheckListFresh3.txt
@@ -0,0 +1,30 @@
+Legend:
+
+[+] - Fully implemented (more or less).
+[?] - Partially implemented/work in progress.
+[ ] - Not even started.
+
+Needed GUI controls in order to start work on Fresh IDE 3.0:
+
+ [+] TForm
+ [+] TSplitGrid
+ [+] TAction (and Action lists)
+ [+] TButton
+ [+] TCheckbox
+ [?] TTreeView
+ [ ] TabControl
+ [?] TSourceEditor
+ [ ] TToolbar
+ [?] TMenu
+ [ ] TMenuBar
+ [ ] TStatusbar
+ [+] TProgressbar
+ [ ] TListView, TListbox or other kind of table/grid control with columns.
+ [?] TEdit - line editor
+ [ ] THint
+
+ [+] General message dialog.
+ [ ] Open/Save dialogs.
+ [ ] Color selection dialog. (not so important).
+ [ ] Font select dialog.
+
Index: freshlib/data/all.asm
==================================================================
--- freshlib/data/all.asm
+++ freshlib/data/all.asm
@@ -1,8 +1,9 @@
include 'i18n.asm'
include 'arrays.asm'
include 'strlib.asm'
+include 'base64.asm'
include 'uconfig.asm'
include 'memstream.asm'
include 'markdown.asm'
include 'hashes.asm'
Index: freshlib/data/arrays.asm
==================================================================
--- freshlib/data/arrays.asm
+++ freshlib/data/arrays.asm
@@ -651,11 +651,11 @@
; (proc FreeProc, ptrItem)
; Frees the array of items
;--------------------------------------------
proc ListFree, .ptrList, .FreeProc
begin
- push edi ebx
+ pushad
mov edi, [.ptrList]
mov ebx, [edi+TArray.count]
cmp [.FreeProc], 0
@@ -670,11 +670,11 @@
.endwhile:
stdcall FreeMem, edi
.finish:
- pop ebx edi
+ popad
return
endp
endmodule
ADDED freshlib/data/base64.asm
Index: freshlib/data/base64.asm
==================================================================
--- /dev/null
+++ freshlib/data/base64.asm
@@ -0,0 +1,235 @@
+; _______________________________________________________________________________________
+;| |
+;| ..::FreshLib::.. Free, open source. Licensed under "BSD 2-clause" license." |
+;|_______________________________________________________________________________________|
+;
+; Description: OS independent string manipulation library.
+;
+; Target OS: Any
+;
+; Dependencies:
+;
+; Notes: Author of this library is Decard (Mateusz Tymek)
+;
+;_________________________________________________________________________________________
+
+module "Base64 library"
+
+if used base64_table
+ base64_table db "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ db "abcdefghijklmnopqrstuvwxyz"
+ db "0123456789+/"
+end if
+
+
+; calculates size of base64 stream after encoding
+
+proc Base64Size, .DataLen
+begin
+ push ebx ecx edx
+
+ mov eax, [.DataLen]
+ mov ebx, eax
+ add eax, 2
+
+ xor edx, edx
+
+ mov ecx, 3
+ div ecx
+
+ add ebx, 3
+
+ sub ebx, edx
+
+ mov eax, ebx
+
+ xor edx, edx
+ div ecx
+ shl eax, 2
+
+ pop edx ecx ebx
+ return
+endp
+
+
+; encodes given buffer into base64 stream
+
+proc EncodeBase64, .pData, .Length
+begin
+ push ecx edx esi edi
+
+ mov esi, [.pData]
+ mov ecx, [.Length]
+
+ stdcall StrNew
+ mov edi, eax
+
+ stdcall Base64Size, ecx
+ stdcall StrSetCapacity, edi, eax
+
+ push edi
+
+ stdcall StrPtr, edi
+ mov edi, eax
+
+ push edi
+
+.loop:
+ mov edx, [esi]
+ cmp ecx, 3
+ jae .remainder_ok
+ and edx, 0xffff
+ cmp ecx, 2
+ jae .remainder_ok
+ and edx, 0xff
+
+.remainder_ok:
+ bswap edx
+
+ mov eax, edx
+ shr eax, 26
+ and eax, 111111b
+ mov al, [base64_table+eax]
+ mov [edi], al
+ inc edi
+
+ mov eax, edx
+ shr eax, 20
+ and eax, 111111b
+ mov al, [base64_table+eax]
+ mov [edi], al
+ inc edi
+ dec ecx
+ jz .r2
+
+ mov eax, edx
+ shr eax, 14
+ and eax, 111111b
+ mov al, [base64_table+eax]
+ mov [edi], al
+ inc edi
+ dec ecx
+ jz .r1
+
+ mov eax, edx
+ shr eax, 8
+ and eax, 111111b
+ mov al, [base64_table+eax]
+ mov [edi], al
+ inc edi
+
+ add esi, 3
+ dec ecx
+ jnz .loop
+ jmp .finish
+
+.r2:
+ mov byte [edi], '-'
+ inc edi
+
+.r1:
+ mov byte [edi], '-'
+ inc edi
+
+.finish:
+ mov byte [edi], 0
+
+ mov ecx, edi
+ pop edi
+
+ sub ecx, edi ; string length.
+ mov [edi+string.len], ecx
+
+ pop eax ; string handle
+
+ pop edi esi edx ecx
+ return
+endp
+
+
+
+
+
+; decodes base64 stream into given buffer
+
+proc DecodeBase64, .hString
+.decode_table rb 0x100
+.ret dd ?
+begin
+ push ebx ecx edx esi edi
+
+ xor eax, eax
+ mov ebx, 63
+
+.make_table:
+ mov al, [base64_table+ebx]
+ mov [.decode_table+eax], bl
+ dec ebx
+ jns .make_table
+
+ mov [.decode_table+'-'], 0
+
+ stdcall StrPtr, [.hString]
+ mov esi, eax
+
+ stdcall StrLen, [.hString]
+ mov ecx, eax
+
+ lea eax, [ecx+4]
+ stdcall GetMem, eax
+ lea edi, [eax+4]
+ mov [.ret], edi
+
+ xor ebx, ebx
+ xor eax, eax
+
+.load_dword:
+ mov edx, [esi]
+ bswap edx
+ add esi, 4
+ mov al, dl
+ mov al, [.decode_table+eax]
+ shrd ebx, eax, 6
+ shr edx, 8
+ mov al, dl
+ mov al, [.decode_table+eax]
+ shrd ebx, eax, 6
+ shr edx, 8
+ mov al, dl
+ mov al, [.decode_table+eax]
+ shrd ebx, eax, 6
+ shr edx, 8
+ mov al, dl
+ mov al, [.decode_table+eax]
+ shrd ebx, eax, 6
+ bswap ebx
+
+ mov [edi], ebx
+ add edi, 3
+ sub ecx, 4
+ js .exit_loop ; this jump should be never taken
+ jnz .load_dword ; (src_size should be a multiple of four)
+
+.exit_loop:
+ sub edi, 2
+ cmp byte [edi], 0
+ je .size_ok
+
+ inc edi
+ cmp byte [edi], 0
+ je .size_ok
+
+ inc edi
+
+.size_ok:
+ mov eax, [.ret]
+ sub edi, eax
+ mov [eax-4], edi
+
+ pop edi esi edx ecx ebx
+ return
+endp
+
+
+
+endmodule
Index: freshlib/data/deflate.asm
==================================================================
--- freshlib/data/deflate.asm
+++ freshlib/data/deflate.asm
@@ -103,17 +103,18 @@
; read 2 bit header BTYPE
mov edx, eax
shr eax, 2
and edx, 3
+
sub ch, 2
dec edx
js .uncompressed ; BTYPE == 0 uncompressed type
+
mov [.b_type], edx ; 0 if fixed tree; <>0 if dynamic tree
jnz .dynamic_tree
-
; BTYPE == 1 compressed with fixed huffman tree.
; load the fixed huffman tree for literal/lengths.
pushad
@@ -122,11 +123,11 @@
lea esi, [.TreeFixed]
mov ebx, edi
xor eax, eax
xor ecx, ecx
- mov dl, 4
+ mov dl, 4 ; edx == 0 here.
.loop_fx:
lodsw
mov cl, ah
rep stosb
@@ -133,12 +134,15 @@
dec edx
jnz .loop_fx
sub edi, ebx
lea eax, [.len_tree]
- stdcall __tree_by_lengths2, ebx, edi, eax
+
+ stdcall __tree_by_lengths, ebx, edi, eax
+
popad
+
jmp .decode
.dynamic_tree:
dec edx
@@ -221,11 +225,11 @@
@@:
dec edx
jnz .loop_hc
lea ebx, [.ll_tree]
- stdcall __tree_by_lengths2, edi, 19, ebx
+ stdcall __tree_by_lengths, edi, 19, ebx
jnz .error6
; now create the two remaining huffman trees: for literal/lengths and for distances.
; First the literal/lengths huffman tree
@@ -272,19 +276,25 @@
not edx
cmp edx, 255
ja .copy_from_older ; if EDX <= 255 then it is simple encoded byte, so store it.
+
+
+; OutputValue "Literal: ", edx, 16, 2
+
; Store literal value.
mov [edi], dl
inc edi
jmp .decode
.copy_from_older:
+; OutputValue "Length code:", edx, 10, 3
+
sub edx, 257
js .next_block ; if EDX == 256 then end of block flag.
; The code is a length code. Compute the length of string to be copied from the previous decoded data.
@@ -316,10 +326,12 @@
not edx
and edx, eax
shr eax, cl
+; OutputValue "Additional value:", edx, 10, 2
+
sub ch, cl
jg .length_ok
add esi, 2
@@ -329,21 +341,31 @@
rol eax, cl
.length_ok:
lea ebx, [ebx+edx+3]
+
+; OutputValue "Copy length:", ebx, 10, 3
+
; ... so now decode the distance code
cmp [.b_type], 0
jne .decode_dist ; when there is fixed huffman table, then the distances are encoded with 5 bit fixed code
; read fixed 5 bit distance.
- mov edx, eax
- shr eax, 5
+ mov cl, 5
+ xor edx, edx
- and edx, $1f
+.bitloop4:
+ shr eax, 1
+ rcl edx, 1
+
+ dec cl
+ jnz .bitloop4
+
+; OutputValue "Distance code:", edx, 10, 2
sub ch, 5
jg .compute_distance
add esi, 2
@@ -481,12 +503,11 @@
.next_block:
mov [.pCurrent], edi
cmp [.final], 0
je .main_loop
-; free the memory and exit!
-; stdcall FreeMem; , [.p_len_tree] ; argument is already in the stack!
+; exit!
shl [.final], 1 ; If normal end [.final] is always 1; If error, [.final] is $ffffffff or $fffffffe
popad
return
@@ -620,11 +641,11 @@
; next length
cmp edi, [.p_lengths_end]
jb .loop_len
ja .errordl
- stdcall __tree_by_lengths2 ; the arguments are already in the stack.
+ stdcall __tree_by_lengths ; the arguments are already in the stack.
retn
; The assembly way of error handling. ;)
.errordl:
add esp, 3*4 + 4 ; pushed arguments and the return address.
@@ -659,11 +680,11 @@
; ZF=0 Error. The provided length list describes not valid Huffman tree.
; In this case no values are filled in the tree.
;
; The comments in the code are according to the RFC-1951
;
-proc __tree_by_lengths2, .pLengths, .count, .pTree
+proc __tree_by_lengths, .pLengths, .count, .pTree
.bl_count rd DEFLATE_MAX_BITS + 1
.next_code rd DEFLATE_MAX_BITS + 1 ; keep immediately after .bl_count
begin
Index: freshlib/data/strlib.asm
==================================================================
--- freshlib/data/strlib.asm
+++ freshlib/data/strlib.asm
@@ -2353,11 +2353,11 @@
;_______________________________________________________________________
; proc StrClipQuotes
; First removes the spaced from the beginning and from the end of the
-; string. Then chech whether the string is quoted string - i.e. starts
+; string. Then check whether the string is quoted string - i.e. starts
; and ends with equal characters single or double quote. If so, removes
; them as well.
;
; Arguments:
; hString - string to be processed
@@ -2741,11 +2741,13 @@
; UTF-8 support functions.
; Some of the above functions also need some revision in order to support
; utf-8 strings properly.
-; Bug - on [.len]=-1 sometimes in Linux returns error on normal strings.
+
+
+;! Bug - on [.len]=-1 sometimes in Linux returns error on normal strings.
proc StrLenUtf8, .hString, .len
.maxptr dd ?
begin
push esi ecx edx
Index: freshlib/equates/KolibriOS/_geometry.inc
==================================================================
--- freshlib/equates/KolibriOS/_geometry.inc
+++ freshlib/equates/KolibriOS/_geometry.inc
@@ -23,5 +23,13 @@
struct POINT
.x dd ?
.y dd ?
ends
+
+struct TBounds
+ .x dd ?
+ .y dd ?
+ .width dd ?
+ .height dd ?
+ends
+
ADDED freshlib/equates/KolibriOS/_libFT.inc
Index: freshlib/equates/KolibriOS/_libFT.inc
==================================================================
--- /dev/null
+++ freshlib/equates/KolibriOS/_libFT.inc
@@ -0,0 +1,289 @@
+; _______________________________________________________________________________________
+;| |
+;| ..::FreshLib::.. Free, open source. Licensed under "BSD 2-clause" license." |
+;|_______________________________________________________________________________________|
+;
+; Description: FreeType library constants and structures.
+;
+; Target OS: Linux
+;
+; Dependencies:
+;
+; Notes:
+;_________________________________________________________________________________________
+
+
+FT_FACE_FLAG_SCALABLE = $0001
+FT_FACE_FLAG_FIXED_SIZES = $0002
+FT_FACE_FLAG_FIXED_WIDTH = $0004
+FT_FACE_FLAG_SFNT = $0008
+FT_FACE_FLAG_HORIZONTAL = $0010
+FT_FACE_FLAG_VERTICAL = $0020
+FT_FACE_FLAG_KERNING = $0040
+FT_FACE_FLAG_FAST_GLYPHS = $0080
+FT_FACE_FLAG_MULTIPLE_MASTERS = $0100
+FT_FACE_FLAG_GLYPH_NAMES = $0200
+FT_FACE_FLAG_EXTERNAL_STREAM = $0400
+FT_FACE_FLAG_HINTER = $0800
+FT_FACE_FLAG_CID_KEYED = $1000
+FT_FACE_FLAG_TRICKY = $2000
+
+
+FT_LOAD_DEFAULT = $0
+FT_LOAD_NO_SCALE = $1
+FT_LOAD_NO_HINTING = $2
+FT_LOAD_RENDER = $4
+FT_LOAD_NO_BITMAP = $8
+FT_LOAD_VERTICAL_LAYOUT = $10
+FT_LOAD_FORCE_AUTOHINT = $20
+FT_LOAD_CROP_BITMAP = $40 ; deprecated, ignored
+FT_LOAD_PEDANTIC = $80
+FT_LOAD_ADVANCE_ONLY = $100
+FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH = $200 ; deprecated, ignored
+FT_LOAD_NO_RECURSE = $400
+FT_LOAD_IGNORE_TRANSFORM = $800
+FT_LOAD_MONOCHROME = $1000
+FT_LOAD_LINEAR_DESIGN = $2000
+FT_LOAD_SBITS_ONLY = $4000
+FT_LOAD_NO_AUTOHINT = $8000
+FT_LOAD_COLOR = $100000
+
+FT_ADVANCE_FLAG_FAST_ONLY = $20000000
+
+
+FT_RENDER_MODE_NORMAL = 0
+FT_RENDER_MODE_LIGHT = 1
+FT_RENDER_MODE_MONO = 2
+FT_RENDER_MODE_LCD = 3
+FT_RENDER_MODE_LCD_V = 4
+FT_RENDER_MODE_MAX = 5
+
+struc FT_LOAD_TARGET x {
+ . = (x and 15) shl 16
+}
+
+FT_LOAD_TARGET_NORMAL FT_LOAD_TARGET FT_RENDER_MODE_NORMAL
+FT_LOAD_TARGET_LIGHT FT_LOAD_TARGET FT_RENDER_MODE_LIGHT
+FT_LOAD_TARGET_MONO FT_LOAD_TARGET FT_RENDER_MODE_MONO
+FT_LOAD_TARGET_LCD FT_LOAD_TARGET FT_RENDER_MODE_LCD
+FT_LOAD_TARGET_LCD_V FT_LOAD_TARGET FT_RENDER_MODE_LCD_V
+
+
+
+FT_PIXEL_MODE_NONE = 0
+FT_PIXEL_MODE_MONO = 1
+FT_PIXEL_MODE_GRAY = 2
+FT_PIXEL_MODE_GRAY2 = 3
+FT_PIXEL_MODE_GRAY4 = 4
+FT_PIXEL_MODE_LCD = 5
+FT_PIXEL_MODE_LCD_V = 6
+FT_PIXEL_MODE_BGRA = 7
+
+
+struct FT_Generic
+ .data dd ?
+ .finalizer dd ? ; pointer to procedure with one argument.
+ends
+
+struct FT_BBox
+ .xMin dd ?
+ .yMin dd ?
+ .xMax dd ?
+ .yMax dd ?
+ends
+
+struct FT_Vector
+ .x dd ?
+ .y dd ?
+ends
+
+struct FT_Bitmap
+ .rows dd ?
+ .width dd ?
+ .pitch dd ?
+ .buffer dd ? ; pointer to the buffer.
+ .num_grays dw ?
+ .pixel_mode db ?
+ .palette_mode db ?
+ .palette dd ? ; pointer to the palette.
+ends
+
+
+
+
+struct FT_Outline
+ .n_contours dw ?
+ .n_points dw ?
+ .points dd ? ; pointer to array of FT_Vector elements.
+ .tags dd ? ; pointer to byte array.
+ .contours dd ? ; pointer to word array.
+ .flags dd ?
+ends
+
+
+
+struct FT_Glyph_Metrics
+ .width dd ?
+ .height dd ?
+ .horiBearingX dd ?
+ .horiBearingY dd ?
+ .horiAdvance dd ?
+
+ .vertBearingX dd ?
+ .vertBearingY dd ?
+ .vertAdvance dd ?
+ends
+
+
+
+struct FT_GlyphSlot
+ .library dd ?
+ .face dd ? ; parent FT_Face object
+ .next dd ? ; pointer tp FT_GlyphSlot
+ .reserved dd ?
+ .generic FT_Generic
+
+ .metrics FT_Glyph_Metrics
+ .linearHoriAdvance dd ?
+ .linearVertAdvance dd ?
+
+ .advance FT_Vector
+
+ .format dd ?
+
+ .bitmap FT_Bitmap
+ .bitmap_left dd ?
+ .bitmap_top dd ?
+
+ .outline FT_Outline
+
+ .num_subglyphs dd ?
+ .subglyphs dd ? ; pointer to array of FT_SubGlyphRec elements.
+
+ .control_data dd ?
+ .control_len dd ?
+
+ .lsb_delta dd ?
+ .rsb_delta dd ?
+
+ .other dd ?
+ .internal dd ? ; pointer to FT_Slot_InternalRec
+ends
+
+
+struct FT_FaceRec
+ .num_faces dd ?
+ .face_index dd ?
+ .face_flags dd ?
+ .style_flags dd ?
+ .num_glyphs dd ?
+ .family_name dd ?
+ .style_name dd ?
+
+ .num_fixed_sizes dd ?
+ .available_sizes dd ?
+
+ .num_charmaps dd ?
+ .charmaps dd ?
+ .generic FT_Generic
+
+; scalable fonts members down to .underline_thickness
+
+ .bbpx FT_BBox
+
+ .units_per_EM dw ?
+ .ascender dw ?
+ .descender dw ?
+ .height dw ?
+
+ .max_advance_width dw ?
+ .max_advance_height dw ?
+
+ .underline_position dw ?
+ .underline_thickness dw ?
+
+
+ .glyph dd ? ; pointer to FT_GlyphSlot
+ .size dd ? ; pointer to FT_Size
+ .charmap dd ? ; pointer to FT_CharMap
+
+; down is the private part.
+
+ends
+
+
+struct FT_GlyphRec
+ .library dd ?
+ .clazz dd ?
+ .format dd ?
+ .advance FT_Vector
+ends
+
+
+struct FT_BitmapGlyphRec
+ .root FT_GlyphRec
+ .left dd ?
+ .top dd ?
+ .bitmap FT_Bitmap
+ends
+
+
+FT_SIZE_REQUEST_TYPE_NOMINAL = 0
+FT_SIZE_REQUEST_TYPE_REAL_DIM = 1
+FT_SIZE_REQUEST_TYPE_BBOX = 2
+FT_SIZE_REQUEST_TYPE_CELL = 3
+FT_SIZE_REQUEST_TYPE_SCALES = 4
+
+
+struct FT_Size_RequestRec
+ .type dd ?
+ .width dd ?
+ .height dd ?
+ .horiResolution dd ?
+ .vertResolution dd ?
+ends
+
+
+struct FT_Size_Metrics
+ .x_ppem dw ? ; horizontal pixels per EM
+ .y_ppem dw ? ; vertical pixels per EM
+
+ .x_scale dd ? ; scaling values used to convert font
+ .y_scale dd ? ; units to 26.6 fractional pixels
+
+ .ascender dd ? ; ascender in 26.6 frac. pixels
+ .descender dd ? ; descender in 26.6 frac. pixels
+ .height dd ? ; text height in 26.6 frac. pixels
+ .max_advance dd ? ; max horizontal advance, in 26.6 pixels
+ends
+
+
+struct FT_SizeRec
+ .face dd ? ; parent face object
+ .generic FT_Generic ; generic pointer for client uses
+ .metrics FT_Size_Metrics ; size metrics
+ .internal:
+ends
+
+
+struct FTC_ScalerRec
+ .face_id dd ?
+ .width dd ?
+ .height dd ?
+ .pixel dd ?
+ .x_res dd ?
+ .y_res dd ?
+ends
+
+
+struct FTC_ImageType
+ .face_id dd ?
+ .width dd ?
+ .height dd ?
+ .flags dd ?
+ends
+
+
+
+
+interface FT_Face_Requester, .face_id, .library, .request_data, .pFace
Index: freshlib/equates/KolibriOS/_network.inc
==================================================================
--- freshlib/equates/KolibriOS/_network.inc
+++ freshlib/equates/KolibriOS/_network.inc
@@ -27,10 +27,16 @@
SO_REUSEADDR = 1 shl 6
SO_REUSEPORT = 1 shl 7
SO_USELOOPBACK = 1 shl 8
SO_BINDTODEVICE = 1 shl 9
SO_BLOCK = 1 shl 10
+
+SO_RCVBUF = 0
+SO_SNDBUF = 0
+SO_RCVTIMEO = 0
+SO_SNDTIMEO = 0
+SO_LINGER = 0
; Socket level
SOL_SOCKET = 0
; Socket States
Index: freshlib/equates/KolibriOS/_syscalls.inc
==================================================================
--- freshlib/equates/KolibriOS/_syscalls.inc
+++ freshlib/equates/KolibriOS/_syscalls.inc
@@ -1,5 +1,20 @@
+; _______________________________________________________________________________________
+;| |
+;| ..::FreshLib::.. Free, open source. Licensed under "BSD 2-clause" license. |
+;|_______________________________________________________________________________________|
+;
+; Description: KolibriOS system functions and related constants.
+;
+; Target OS: KolibriOS
+;
+; Dependencies:
+;
+; Notes:
+;_________________________________________________________________________________________
+
+
sys_drawwindow = 0 ; DrawWindow
syscall_setpixel = 1 ; SetPixel
sys_getkey = 2 ; GetKey
sys_clock = 3 ; GetTime
sys_writetext = 4 ; WriteText
Index: freshlib/equates/KolibriOS/allequates.inc
==================================================================
--- freshlib/equates/KolibriOS/allequates.inc
+++ freshlib/equates/KolibriOS/allequates.inc
@@ -13,6 +13,7 @@
;_________________________________________________________________________________________
include '_syscalls.inc'
include '_geometry.inc'
-include '_network.inc'
+include '_network.inc'
+include '_libFT.inc'
Index: freshlib/equates/Linux/_XLib.inc
==================================================================
--- freshlib/equates/Linux/_XLib.inc
+++ freshlib/equates/Linux/_XLib.inc
@@ -421,10 +421,18 @@
GCDashOffset = 100000h
GCDashList = 200000h
GCArcMode = 400000h
GCLastBit = 22
+
+struct XRectangle
+ .x dw ?
+ .y dw ?
+ .width dw ?
+ .height dw ?
+ends
+
GCAll = (1 shl (GCLastBit+1)) -1
struct XGCValues
.function dd ? ; logical operation
@@ -1015,131 +1023,131 @@
.pad rb 24*4 - sizeof.XAnyEvent
virtual at .xany
. XAnyEvent
end virtual
-
-
- virtual at .xany
- .xkey XKeyEvent
- end virtual
-
- virtual at .xany
- .xbutton XButtonEvent
- end virtual
-
- virtual at .xany
- .xmotion XMotionEvent
- end virtual
-
- virtual at .xany
- .xcrossing XCrossingEvent
- end virtual
-
- virtual at .xany
- .xfocus XFocusChangeEvent
- end virtual
-
- virtual at .xany
- .xexpose XExposeEvent
- end virtual
-
- virtual at .xany
- .xgraphicsexpose XGraphicsExposeEvent
- end virtual
-
- virtual at .xany
- .xnoexpose XNoExposeEvent
- end virtual
-
- virtual at .xany
- .xvisibility XVisibilityEvent
- end virtual
-
- virtual at .xany
- .xcreatewindow XCreateWindowEvent
- end virtual
-
- virtual at .xany
- .xdestroywindow XDestroyWindowEvent
- end virtual
-
- virtual at .xany
- .xunmap XUnmapEvent
- end virtual
-
- virtual at .xany
- .xmap XMapEvent
- end virtual
-
- virtual at .xany
- .xmaprequest XMapRequestEvent
- end virtual
-
- virtual at .xany
- .xreparent XReparentEvent
- end virtual
-
- virtual at .xany
- .xconfigure XConfigureEvent
- end virtual
-
- virtual at .xany
- .xgravity XGravityEvent
- end virtual
-
- virtual at .xany
- .xresizerequest XResizeEvent
- end virtual
-
- virtual at .xany
- .xconfigurerequest XConfigureRequestEvent
- end virtual
-
- virtual at .xany
- .xcirculate XCirculateEvent
- end virtual
-
- virtual at .xany
- .xcirculaterequest XCirculateRequestEvent
- end virtual
-
- virtual at .xany
- .xproperty XPropertyEvent
- end virtual
-
- virtual at .xany
- .xselectionclear XSelectionClearEvent
- end virtual
-
- virtual at .xany
- .xselectionrequest XSelectionRequestEvent
- end virtual
-
- virtual at .xany
- .xselection XSelectionEvent
- end virtual
-
- virtual at .xany
- .xcolormap XColormapEvent
- end virtual
-
- virtual at .xany
- .xclient XClientMessageEvent
- end virtual
-
- virtual at .xany
- .xmapping XMappingEvent
- end virtual
-
- virtual at .xany
- .xerror XErrorEvent
- end virtual
-
- virtual at .xany
- .xkeymap XKeymapEvent
- end virtual
+;
+;
+; virtual at .xany
+; .xkey XKeyEvent
+; end virtual
+;
+; virtual at .xany
+; .xbutton XButtonEvent
+; end virtual
+;
+; virtual at .xany
+; .xmotion XMotionEvent
+; end virtual
+;
+; virtual at .xany
+; .xcrossing XCrossingEvent
+; end virtual
+;
+; virtual at .xany
+; .xfocus XFocusChangeEvent
+; end virtual
+;
+; virtual at .xany
+; .xexpose XExposeEvent
+; end virtual
+;
+; virtual at .xany
+; .xgraphicsexpose XGraphicsExposeEvent
+; end virtual
+;
+; virtual at .xany
+; .xnoexpose XNoExposeEvent
+; end virtual
+;
+; virtual at .xany
+; .xvisibility XVisibilityEvent
+; end virtual
+;
+; virtual at .xany
+; .xcreatewindow XCreateWindowEvent
+; end virtual
+;
+; virtual at .xany
+; .xdestroywindow XDestroyWindowEvent
+; end virtual
+;
+; virtual at .xany
+; .xunmap XUnmapEvent
+; end virtual
+;
+; virtual at .xany
+; .xmap XMapEvent
+; end virtual
+;
+; virtual at .xany
+; .xmaprequest XMapRequestEvent
+; end virtual
+;
+; virtual at .xany
+; .xreparent XReparentEvent
+; end virtual
+;
+; virtual at .xany
+; .xconfigure XConfigureEvent
+; end virtual
+;
+; virtual at .xany
+; .xgravity XGravityEvent
+; end virtual
+;
+; virtual at .xany
+; .xresizerequest XResizeEvent
+; end virtual
+;
+; virtual at .xany
+; .xconfigurerequest XConfigureRequestEvent
+; end virtual
+;
+; virtual at .xany
+; .xcirculate XCirculateEvent
+; end virtual
+;
+; virtual at .xany
+; .xcirculaterequest XCirculateRequestEvent
+; end virtual
+;
+; virtual at .xany
+; .xproperty XPropertyEvent
+; end virtual
+;
+; virtual at .xany
+; .xselectionclear XSelectionClearEvent
+; end virtual
+;
+; virtual at .xany
+; .xselectionrequest XSelectionRequestEvent
+; end virtual
+;
+; virtual at .xany
+; .xselection XSelectionEvent
+; end virtual
+;
+; virtual at .xany
+; .xcolormap XColormapEvent
+; end virtual
+;
+; virtual at .xany
+; .xclient XClientMessageEvent
+; end virtual
+;
+; virtual at .xany
+; .xmapping XMappingEvent
+; end virtual
+;
+; virtual at .xany
+; .xerror XErrorEvent
+; end virtual
+;
+; virtual at .xany
+; .xkeymap XKeymapEvent
+; end virtual
ends
; Misc. Structures
Index: freshlib/equates/Linux/_geometry.inc
==================================================================
--- freshlib/equates/Linux/_geometry.inc
+++ freshlib/equates/Linux/_geometry.inc
@@ -10,10 +10,19 @@
; Dependencies:
;
; Notes:
;_________________________________________________________________________________________
+
+struct TBounds
+ .x dd ?
+ .y dd ?
+ .width dd ?
+ .height dd ?
+ends
+
+
struct RECT
.left dd ?
.top dd ?
.right dd ?
@@ -23,11 +32,6 @@
struct POINT
.x dd ?
.y dd ?
ends
-struct XRectangle
- .x dw ?
- .y dw ?
- .width dw ?
- .height dw ?
-ends
+
Index: freshlib/equates/Linux/_libFT.inc
==================================================================
--- freshlib/equates/Linux/_libFT.inc
+++ freshlib/equates/Linux/_libFT.inc
@@ -45,10 +45,13 @@
FT_LOAD_MONOCHROME = $1000
FT_LOAD_LINEAR_DESIGN = $2000
FT_LOAD_SBITS_ONLY = $4000
FT_LOAD_NO_AUTOHINT = $8000
FT_LOAD_COLOR = $100000
+
+FT_ADVANCE_FLAG_FAST_ONLY = $20000000
+
FT_RENDER_MODE_NORMAL = 0
FT_RENDER_MODE_LIGHT = 1
FT_RENDER_MODE_MONO = 2
FT_RENDER_MODE_LCD = 3
@@ -62,10 +65,11 @@
FT_LOAD_TARGET_NORMAL FT_LOAD_TARGET FT_RENDER_MODE_NORMAL
FT_LOAD_TARGET_LIGHT FT_LOAD_TARGET FT_RENDER_MODE_LIGHT
FT_LOAD_TARGET_MONO FT_LOAD_TARGET FT_RENDER_MODE_MONO
FT_LOAD_TARGET_LCD FT_LOAD_TARGET FT_RENDER_MODE_LCD
FT_LOAD_TARGET_LCD_V FT_LOAD_TARGET FT_RENDER_MODE_LCD_V
+
FT_PIXEL_MODE_NONE = 0
FT_PIXEL_MODE_MONO = 1
FT_PIXEL_MODE_GRAY = 2
@@ -205,18 +209,10 @@
; down is the private part.
ends
-
-struct FTC_ImageType
- .face_id dd ?
- .width dd ?
- .height dd ?
- .flags dd ?
-ends
-
struct FT_GlyphRec
.library dd ?
.clazz dd ?
.format dd ?
@@ -277,9 +273,17 @@
.pixel dd ?
.x_res dd ?
.y_res dd ?
ends
+
+struct FTC_ImageType
+ .face_id dd ?
+ .width dd ?
+ .height dd ?
+ .flags dd ?
+ends
+
interface FT_Face_Requester, .face_id, .library, .request_data, .pFace
Index: freshlib/equates/Linux/_linux.inc
==================================================================
--- freshlib/equates/Linux/_linux.inc
+++ freshlib/equates/Linux/_linux.inc
@@ -664,11 +664,11 @@
; Signal values
; default action is: "Term" - terminate; "Core" - terminate with core dump; "Ign" - ignore; "Stop" - stop the process; "Cont" - continue the process.
macro signal name, value {
name = value
- .mask = 1 shl value
+ name#.mask = 1 shl value
}
signal SIGHUP , 1 ; Term Hangup detected on controlling terminal or death of controlling process
signal SIGINT , 2 ; Term Interrupt from keyboard
signal SIGQUIT , 3 ; Core Quit from keyboard
Index: freshlib/equates/Win32/_GDI32.INC
==================================================================
--- freshlib/equates/Win32/_GDI32.INC
+++ freshlib/equates/Win32/_GDI32.INC
@@ -46,18 +46,61 @@
.biXPelsPerMeter dd ?
.biYPelsPerMeter dd ?
.biClrUsed dd ?
.biClrImportant dd ?
ends
+
+
+struct CIEXYZ
+ .ciexyzX dd ?
+ .ciexyzY dd ?
+ .ciexyzZ dd ?
+ends
+
+
+struct CIEXYZTRIPLE
+ .ciexyzRed CIEXYZ
+ .ciexyzGreen CIEXYZ
+ .ciexyzBlue CIEXYZ
+ends
+
+
+struct BITMAPV4HEADER
+ .biSize dd ?
+ .biWidth dd ?
+ .biHeight dd ?
+ .biPlanes dw ?
+ .biBitCount dw ?
+ .biCompression dd ?
+ .biSizeImage dd ?
+ .biXPelsPerMeter dd ?
+ .biYPelsPerMeter dd ?
+ .biClrUsed dd ?
+ .biClrImportant dd ?
+
+ .RedMask dd ?
+ .GreenMask dd ?
+ .BlueMask dd ?
+ .AlphaMask dd ?
+ .CSType dd ?
+ .Endpoints CIEXYZTRIPLE
+ .GamaRed dd ?
+ .GammaGreen dd ?
+ .GammaBlue dd ?
+ends
+
+
+
struct BITMAPFILEHEADER
.bfType dw ?
.bfSize dd ?
.bfReserved1 dw ?
.bfReserved2 dw ?
.bfOffBits dd ?
ends
+
struct TEXTMETRIC
.tmHeight dd ?
.tmAscent dd ?
.tmDescent dd ?
@@ -78,16 +121,20 @@
.tmStruckOut db ?
.tmPitchAndFamily db ?
.tmCharSet db ?
.__align rb 7
ends
+
+
struct LOGBRUSH
.lbStyle dd ?
.lbColor dd ?
.lbHatch dd ?
ends
+
+
struct LOGPEN
.lopnStyle dd ?
.lopnWidth POINT
.lopnColor dd ?
Index: freshlib/equates/Win32/_USER32.INC
==================================================================
--- freshlib/equates/Win32/_USER32.INC
+++ freshlib/equates/Win32/_USER32.INC
@@ -322,31 +322,32 @@
WS_ICONIC = WS_MINIMIZE
WS_SIZEBOX = WS_THICKFRAME
; Extended Window Styles
-WS_EX_DLGMODALFRAME = 00001h
-WS_EX_DRAGOBJECT = 00002h
-WS_EX_NOPARENTNOTIFY = 00004h
-WS_EX_TOPMOST = 00008h
-WS_EX_ACCEPTFILES = 00010h
-WS_EX_TRANSPARENT = 00020h
-WS_EX_MDICHILD = 00040h
-WS_EX_TOOLWINDOW = 00080h
-WS_EX_WINDOWEDGE = 00100h
-WS_EX_CLIENTEDGE = 00200h
-WS_EX_CONTEXTHELP = 00400h
-WS_EX_RIGHT = 01000h
-WS_EX_LEFT = 00000h
-WS_EX_RTLREADING = 02000h
-WS_EX_LTRREADING = 00000h
-WS_EX_LEFTSCROLLBAR = 04000h
-WS_EX_RIGHTSCROLLBAR = 00000h
-WS_EX_CONTROLPARENT = 10000h
-WS_EX_STATICEDGE = 20000h
-WS_EX_APPWINDOW = 40000h
-WS_EX_LAYERED = 80000h
+WS_EX_DLGMODALFRAME = 00000001h
+WS_EX_DRAGOBJECT = 00000002h
+WS_EX_NOPARENTNOTIFY = 00000004h
+WS_EX_TOPMOST = 00000008h
+WS_EX_ACCEPTFILES = 00000010h
+WS_EX_TRANSPARENT = 00000020h
+WS_EX_MDICHILD = 00000040h
+WS_EX_TOOLWINDOW = 00000080h
+WS_EX_WINDOWEDGE = 00000100h
+WS_EX_CLIENTEDGE = 00000200h
+WS_EX_CONTEXTHELP = 00000400h
+WS_EX_RIGHT = 00001000h
+WS_EX_LEFT = 00000000h
+WS_EX_RTLREADING = 00002000h
+WS_EX_LTRREADING = 00000000h
+WS_EX_LEFTSCROLLBAR = 00004000h
+WS_EX_RIGHTSCROLLBAR = 00000000h
+WS_EX_CONTROLPARENT = 00010000h
+WS_EX_STATICEDGE = 00020000h
+WS_EX_APPWINDOW = 00040000h
+WS_EX_LAYERED = 00080000h
+WS_EX_NOACTIVATE = 08000000h
WS_EX_OVERLAPPEDWINDOW = WS_EX_WINDOWEDGE or WS_EX_CLIENTEDGE
WS_EX_PALETTEWINDOW = WS_EX_WINDOWEDGE or WS_EX_TOOLWINDOW or WS_EX_TOPMOST
; MDI client style bits
ADDED freshlib/equates/Win32/_geometry.inc
Index: freshlib/equates/Win32/_geometry.inc
==================================================================
--- /dev/null
+++ freshlib/equates/Win32/_geometry.inc
@@ -0,0 +1,22 @@
+; _______________________________________________________________________________________
+;| |
+;| ..::FreshLib::.. Free, open source. Licensed under "BSD 2-clause" license." |
+;|_______________________________________________________________________________________|
+;
+; Description: Different geometry structures.
+;
+; Target OS: Windows
+;
+; Dependencies:
+;
+; Notes:
+;_________________________________________________________________________________________
+
+
+struct TBounds
+ .x dd ?
+ .y dd ?
+ .width dd ?
+ .height dd ?
+ends
+
Index: freshlib/equates/Win32/allequates.inc
==================================================================
--- freshlib/equates/Win32/allequates.inc
+++ freshlib/equates/Win32/allequates.inc
@@ -12,10 +12,11 @@
; Notes:
;_________________________________________________________________________________________
CRLF equ 13, 10
+include '_geometry.inc'
include '_kernel32.inc'
include '_user32.inc'
include '_gdi32.inc'
include '_comctl32.inc'
include '_comdlg32.inc'
Index: freshlib/equates/allequates.inc
==================================================================
--- freshlib/equates/allequates.inc
+++ freshlib/equates/allequates.inc
@@ -10,14 +10,27 @@
; Dependencies:
;
; Notes:
;_________________________________________________________________________________________
+; Very generic constants!
+
TRUE = 1
FALSE = 0
NULL = 0
+
+regEDI = 0
+regESI = 1
+regEBP = 2
+regESP = 3
+regEBX = 4
+regEDX = 5
+regECX = 6
+regEAX = 7
+
+
include '%TargetOS%/allequates.inc'
include '_sqlite3.inc'
include '_zlib1.inc'
DELETED freshlib/graphics/Dummy/backbuffer.asm
Index: freshlib/graphics/Dummy/backbuffer.asm
==================================================================
--- freshlib/graphics/Dummy/backbuffer.asm
+++ /dev/null
@@ -1,37 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "BSD 2-clause" license." |
-;|_______________________________________________________________________________________|
-;
-; Description: Provides raster bitmap, to be used for double buffer painting.
-;
-; Target OS: Dummy
-;
-; Dependencies:
-;
-; Notes:
-;_________________________________________________________________________________________
-
-
-
-proc CreateBackBuffer, .hwin, .width, .height
-begin
- stc
- return
-endp
-
-
-
-proc DestroyBackBuffer, .pBackBuffer
-begin
- stc
- return
-endp
-
-
-
-proc DrawBackBuffer, .context, .pBackBuffer, .x, .y
-begin
- stc
- return
-endp
DELETED freshlib/graphics/Dummy/context.asm
Index: freshlib/graphics/Dummy/context.asm
==================================================================
--- freshlib/graphics/Dummy/context.asm
+++ /dev/null
@@ -1,75 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "BSD 2-clause" license." |
-;|_______________________________________________________________________________________|
-;
-; Description: Context is a object that represents drawing surface in FreshLib
-;
-; Target OS: Dummy
-;
-; Dependencies:
-;
-; Notes:
-;_________________________________________________________________________________________
-
-
-cmClear = 0
-cmAnd = 0
-cmAndReverse = 0
-cmCopy = 0
-cmAndInverted = 0
-cmNoOp = 0
-cmXor = 0
-cmOr = 0
-cmNor = 0
-cmEquiv = 0
-cmInvert = 0
-cmXorReverse = 0
-cmCopyInverted = 0
-cmOrInverted = 0
-cmNand = 0
-cmSet = 0
-
-
-proc AllocateContext, .raster
-begin
- stc
- return
-endp
-
-
-
-
-proc ReleaseContext, .context
-begin
- return
-endp
-
-
-
-proc SetDrawMode, .context, .mode
-begin
- return
-endp
-
-
-
-
-proc SetLineStyle, .context, .pLineStyle
-begin
- return
-endp
-
-
-
-
-
-
-proc SetClipRectangle, .context, .pBounds
-begin
- return
-endp
-
-
-
-
DELETED freshlib/graphics/KolibriOS/backbuffer.asm
Index: freshlib/graphics/KolibriOS/backbuffer.asm
==================================================================
--- freshlib/graphics/KolibriOS/backbuffer.asm
+++ /dev/null
@@ -1,37 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "BSD 2-clause" license." |
-;|_______________________________________________________________________________________|
-;
-; Description: Provides raster bitmap, to be used for double buffer painting.
-;
-; Target OS: KolibriOS
-;
-; Dependencies:
-;
-; Notes:
-;_________________________________________________________________________________________
-
-
-
-proc CreateBackBuffer, .hwin, .width, .height
-begin
- stc
- return
-endp
-
-
-
-proc DestroyBackBuffer, .pBackBuffer
-begin
- stc
- return
-endp
-
-
-
-proc DrawBackBuffer, .context, .pBackBuffer, .x, .y
-begin
- stc
- return
-endp
DELETED freshlib/graphics/KolibriOS/context.asm
Index: freshlib/graphics/KolibriOS/context.asm
==================================================================
--- freshlib/graphics/KolibriOS/context.asm
+++ /dev/null
@@ -1,105 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "BSD 2-clause" license." |
-;|_______________________________________________________________________________________|
-;
-; Description: Context is a object that represents drawing surface in FreshLib
-;
-; Target OS: KolibriOS
-;
-; Dependencies:
-;
-; Notes:
-;_________________________________________________________________________________________
-
-
-cmCopy = 0
-cmInverted = 1
-cmXor = 2
-cmAnd = 1 ; ????
-
-struct TKolibriContext
- .CurrentColor dd ?
- .CurentDrawMode dd ?
-ends
-
-
-proc AllocateContext, .raster
-begin
- push ebx
-
- stdcall GetMem, sizeof.TContext
- jc .error
- mov ebx, eax
-
- mov eax, [.raster]
- mov [ebx+TContext.raster], eax
-
- stdcall GetMem, sizeof.TKolibriContext
- mov [ebx+TContext.handle], eax
- mov [eax+TKolibriContext.CurrentColor], 0
- mov [eax+TKolibriContext.CurentDrawMode], cmCopy
-
- mov eax, ebx
-.exit:
- pop ebx
- clc
- return
-
-.error:
- DebugMsg 'Error allocating context.'
- xor eax, eax
- pop ebx
- stc
- return
-endp
-
-
-
-
-proc ReleaseContext, .context
-begin
- push eax
- mov eax, [.context]
- mov eax, [eax+TContext.handle]
- stdcall FreeMem, eax
- stdcall FreeMem, [.context]
- pop eax
- clc
- return
-endp
-
-
-
-proc SetDrawMode, .context, .mode
-begin
- push eax
-
- mov eax, [.context]
- mov eax, [eax+TContext.handle]
-
- push [.mode]
- pop [eax+TKolibriContext.CurentDrawMode]
-
- pop eax
- return
-endp
-
-
-
-
-proc SetLineStyle, .context, .pLineStyle
-begin
- return
-endp
-
-
-
-proc SetClipRectangle, .context, .pBounds
-begin
- return
-endp
-
-
-
-
Index: freshlib/graphics/KolibriOS/fonts.asm
==================================================================
--- freshlib/graphics/KolibriOS/fonts.asm
+++ freshlib/graphics/KolibriOS/fonts.asm
@@ -11,16 +11,44 @@
;
; Notes:
;_________________________________________________________________________________________
-proc FontCreate, .fontface, .size, .weight, .flags
+
+; needed for FreeType support.
+
+proc FTCRequester as FT_Face_Requester
+begin
+
+
+
+ return
+endp
+
+
+
+
+
+body FontCreate
+begin
+
+ return
+endp
+
+
+
+
+body FontDestroy
begin
- stc
+
return
endp
-proc FontDestroy, .font
+
+
+
+body GetFontMetrics
begin
+
return
endp
Index: freshlib/graphics/KolibriOS/images.asm
==================================================================
--- freshlib/graphics/KolibriOS/images.asm
+++ freshlib/graphics/KolibriOS/images.asm
@@ -11,12 +11,18 @@
;
; Notes:
;_________________________________________________________________________________________
-; only 16, 24 and 32 bpp are supported.
-; It is stupid to support palleted modes and even 24bpp is not good...
+struct TImage
+ .width dd ? ; width in pixels.
+ .height dd ? ; height in pixels.
+ .pPixels dd ? ; pointer to the pixel memory.
+ends
+
+
+
body CreateImage
begin
stc
return
endp
@@ -27,10 +33,10 @@
return
endp
-body DrawImage
+body DrawImageRect
begin
return
endp
Index: freshlib/graphics/KolibriOS/text.asm
==================================================================
--- freshlib/graphics/KolibriOS/text.asm
+++ freshlib/graphics/KolibriOS/text.asm
@@ -11,45 +11,941 @@
;
; Notes:
;_________________________________________________________________________________________
-
-proc DrawString, .context, .ptrString, .len, .x, .y, .font, .color
-begin
- return
-endp
-
-
-
-proc DrawStringOpaque, .context, .ptrString, .len, .x, .y, .font, .color, .background
-begin
- return
-endp
-
-
-
-
-proc DrawColoredString, .context, .ptrString, .pCharAttr, .str_len_bytes, .x, .y, .char_offs, .fontwidth, .fontheight
-begin
- return
-endp
-
-
-
-
-
-
-proc GetTextBounds, .context, .ptrString, .len, .font
-begin
- return
-endp
-
-
-; returns:
-; eax - x offset of the baseline of the string.
-; edx - y offset of the baseline of the string.
-
-proc GetTextOffset, .context, .ptrString, .len, .font
-begin
- return
-endp
+iglobal
+ var flagFreeTypeLoadFlags = FT_LOAD_RENDER or FT_LOAD_TARGET_LCD or FT_LOAD_NO_AUTOHINT or FT_LOAD_COLOR
+endg
+
+
+uglobal
+ var FTC_CMapCache_Lookup = 0
+ var FTC_ImageCache_LookupScaler = 0
+
+endg
+
+
+
+body DrawDecomposedString ;, .pImage, .pArray, .x, .y, .font, .color
+.scaler FTC_ScalerRec
+.glyph dd ?
+
+.startX dd ?
+begin
+ pushad
+
+ mov edx, [.font]
+ xor ecx, ecx
+
+ mov [.scaler.face_id], edx
+ mov [.scaler.width], ecx
+
+ mov eax, [edx+__TFont.height]
+ inc ecx
+
+ mov [.scaler.height], eax
+ mov [.scaler.pixel], ecx ; ecx = 1
+
+ mov eax, [.x]
+ mov [.startX], eax
+
+ mov esi, [.pArray]
+ xor edi, edi
+ dec edi
+
+.char_loop:
+ inc edi
+ cmp edi, [esi+TArray.count]
+ jae .finish
+
+ cmp word [esi+TArray.array+8*edi+TTextChar.width], 0
+ je .char_ok
+
+ cinvoke FTC_CMapCache_Lookup, [FTCCMapCache], [.font], -1, [esi+TArray.array+8*edi+TTextChar.code]
+
+ lea ecx, [.scaler]
+ lea edx, [.glyph]
+ cinvoke FTC_ImageCache_LookupScaler, [FTCImageCache], ecx, [flagFreeTypeLoadFlags], eax, edx, 0
+
+ test eax, eax
+ jnz .char_ok
+
+ mov ebx, [.glyph]
+ mov ecx, [.x]
+ mov edx, [.y]
+
+ add ecx, [ebx+FT_BitmapGlyphRec.left]
+ sub edx, [ebx+FT_BitmapGlyphRec.top]
+
+ lea eax, [ebx+FT_BitmapGlyphRec.bitmap]
+ stdcall __DrawGlyph, [.pImage], eax, ecx, edx, [.color]
+
+ movzx eax, word [esi+TArray.array+8*edi+TTextChar.width]
+ add [.x], eax
+
+.char_ok:
+; check for new line.
+ movzx eax, word [esi+TArray.array+8*edi+TTextChar.height]
+ test eax, eax
+ jz .char_loop
+
+ add [.y], eax
+ mov eax, [.startX]
+ mov [.x], eax
+ jmp .char_loop
+
+
+.finish:
+ popad
+ return
+endp
+
+
+
+
+; Draws the string on the image using the specified font and color.
+; The string is drawn in one line. The control symbols are not
+; processed. The tabs are not expanded or replaced with spaces.
+;
+; Arguments:
+; .pImage - pointer to the image where to draw the text.
+; .pString - pointer to a UTF-8 string.
+; .len - how many bytes from the string to be drawn. If -1, the whole string will be drawn.
+; .x - X coordinate, where to start drawing.
+; .y - Y coordinate of the baseline where to draw the string.
+; .font - the font to be used.
+; .color - ARGB color to draw the glyphs.
+;
+;;;;;;;; Returns:
+;;;;;;;; EAX - the width of the string in pixels.
+;;;;;;;; EBX - the ascender of the string. It is negative.
+;;;;;;;; EDX - the height of the string in pixels.
+
+
+body DrawString ;, .pImage, .pString, .len, .x, .y, .font, .color
+
+.scaler FTC_ScalerRec
+.glyph dd ?
+
+.miny dd ?
+.maxy dd ?
+.startX dd ?
+
+begin
+ pushad
+
+ mov edx, [.font]
+ xor ecx, ecx
+
+ mov [.scaler.face_id], edx
+ mov [.scaler.width], ecx
+
+ mov eax, [edx+__TFont.height]
+ inc ecx
+
+ mov [.scaler.height], eax
+ mov [.scaler.pixel], ecx ; ecx = 1
+
+ ror ecx, 1 ; ecx = $80000000
+ mov [.maxy], ecx
+ dec ecx
+ mov [.miny], ecx ; ecx = $7fffffff
+
+ mov eax, [.x]
+ mov [.startX], eax
+
+ mov esi, [.pString]
+
+.char_loop:
+
+ stdcall DecodeUtf8, [esi]
+ jc .finish
+
+ add esi, edx
+
+ sub [.len], edx
+ jb .finish
+
+ test eax, eax
+ jz .finish
+
+ cinvoke FTC_CMapCache_Lookup, [FTCCMapCache], [.font], -1, eax
+
+ lea ecx, [.scaler]
+ lea edx, [.glyph]
+ cinvoke FTC_ImageCache_LookupScaler, [FTCImageCache], ecx, [flagFreeTypeLoadFlags], eax, edx, 0
+
+ test eax, eax
+ jnz .char_loop
+
+ mov ebx, [.glyph]
+
+ mov ecx, [.x]
+ mov edx, [.y]
+
+ add ecx, [ebx+FT_BitmapGlyphRec.left]
+ sub edx, [ebx+FT_BitmapGlyphRec.top]
+
+ cmp edx, [.miny]
+ jge @f
+ mov [.miny], edx
+@@:
+ mov eax, edx
+ add eax, [ebx+FT_BitmapGlyphRec.bitmap.rows]
+ cmp eax, [.maxy]
+ jle @f
+ mov [.maxy], eax
+@@:
+ lea eax, [ebx+FT_BitmapGlyphRec.bitmap]
+ stdcall __DrawGlyph, [.pImage], eax, ecx, edx, [.color]
+
+ mov eax, [ebx+FT_BitmapGlyphRec.root.advance.x]
+ sar eax, 16 ; format 16.16 fixed decimal point.
+ add [.x], eax
+
+ jmp .char_loop
+
+
+.finish:
+; mov eax, [.x]
+; mov edx, [.maxy]
+; mov ebx, [.miny]
+; sub eax, [.startX]
+; sub edx, ebx
+; sub ebx, [.y]
+
+; mov [esp+4*regEAX], eax
+; mov [esp+4*regEBX], ebx
+; mov [esp+4*regEDX], edx
+
+ popad
+ return
+endp
+
+
+
+; returns:
+; EAX - array with decomposed string.
+; EDX - maximal bearing_Y of the string.
+; ECX - maximal descender of the string.
+
+body TextDecompose ;, .hString, .font
+
+ .scaler FTC_ScalerRec
+ .glyph dd ?
+
+ .miny dd ?
+ .maxy dd ?
+
+begin
+ pushad
+
+ mov edx, [.font]
+ xor ecx, ecx
+
+ mov [.scaler.face_id], edx
+ mov [.scaler.width], ecx
+
+ mov eax, [edx+__TFont.height]
+ inc ecx
+
+ mov [.scaler.height], eax
+ mov [.scaler.pixel], ecx ; ecx = 1
+
+ ror ecx, 1 ; ecx = $80000000
+ mov [.maxy], ecx
+ dec ecx
+ mov [.miny], ecx ; ecx = $7fffffff
+
+ stdcall StrPtr, [.hString]
+ mov esi, eax
+
+ stdcall CreateArray, sizeof.TTextChar
+ mov edi, eax
+
+.char_loop:
+ stdcall DecodeUtf8, [esi]
+ jc .finish
+
+ add esi, edx
+ mov ebx, eax
+
+ test eax, eax
+ jz .end
+
+ cinvoke FTC_CMapCache_Lookup, [FTCCMapCache], [.font], -1, eax
+
+ lea ecx, [.scaler]
+ lea edx, [.glyph]
+ cinvoke FTC_ImageCache_LookupScaler, [FTCImageCache], ecx, [flagFreeTypeLoadFlags], eax, edx, 0
+
+ xor ecx, ecx
+
+ test eax, eax
+ jnz .glyph_size_ok ; zero width glyph ????
+
+ mov ecx, [.glyph]
+
+ mov eax, [ecx+FT_BitmapGlyphRec.top]
+ neg eax
+
+ cmp eax, [.miny]
+ jge @f
+ mov [.miny], eax
+@@:
+
+ add eax, [ecx+FT_BitmapGlyphRec.bitmap.rows]
+ cmp eax, [.maxy]
+ jle @f
+ mov [.maxy], eax
+@@:
+ mov ecx, [ecx+FT_BitmapGlyphRec.root.advance.x] ; format 16.16 fixed decimal point.
+ sar ecx, 16 ; format 16.16
+
+
+.glyph_size_ok:
+
+ stdcall AddArrayItems, edi, 1
+ mov edi, edx
+ mov dword [eax+TTextChar.width], ecx
+ mov [eax+TTextChar.code], ebx
+ jmp .char_loop
+
+.end:
+ clc
+
+.finish:
+ mov [esp+4*regEAX], edi
+
+ mov eax, [.miny]
+ neg eax
+ mov ecx, [.maxy]
+
+ mov [esp+4*regEDX], eax
+ mov [esp+4*regECX], ecx
+
+ add ecx, eax
+ mov [edi+TArray.lparam], ecx
+
+ popad
+ return
+endp
+
+
+
+; Returns an array with the widths from the begining of the text to the every character inside the string.
+
+
+proc GetTextWidthsArray, .hString, .font
+
+ .scaler FTC_ScalerRec
+ .glyph dd ?
+
+ .x dd ?
+
+begin
+ pushad
+
+ mov edx, [.font]
+ xor ecx, ecx
+
+ mov [.scaler.face_id], edx
+ mov [.scaler.width], ecx
+
+ mov eax, [edx+__TFont.height]
+ inc ecx
+
+ mov [.scaler.height], eax
+ mov [.scaler.pixel], ecx ; ecx = 1
+
+
+ stdcall StrPtr, [.hString]
+ mov esi, eax
+
+ stdcall CreateArray, 4
+ mov edi, eax
+
+ xor ebx, ebx
+
+.char_loop:
+ stdcall DecodeUtf8, [esi]
+ jc .finish
+
+ add esi, edx
+ test eax, eax
+ jz .end
+
+ cinvoke FTC_CMapCache_Lookup, [FTCCMapCache], [.font], -1, eax
+
+ lea ecx, [.scaler]
+ lea edx, [.glyph]
+ cinvoke FTC_ImageCache_LookupScaler, [FTCImageCache], ecx, [flagFreeTypeLoadFlags], eax, edx, 0
+
+ test eax, eax
+ jnz .glyph_size_ok ; zero width glyph ????
+
+
+ mov ecx, [.glyph]
+ mov ecx, [ecx+FT_BitmapGlyphRec.root.advance.x] ; format 16.16 fixed decimal point.
+
+ add ebx, ecx
+
+
+.glyph_size_ok:
+
+ stdcall AddArrayItems, edi, 1
+ mov edi, edx
+
+ mov edx, ebx
+ sar edx, 16 ; format 16.16
+ mov [eax], edx
+ jmp .char_loop
+
+.end:
+ clc
+
+.finish:
+ mov [esp+4*regEAX], edi
+ popad
+ return
+
+.error:
+ stc
+ popad
+ return
+endp
+
+
+
+
+
+
+
+
+
+
+
+; Computes the width and height of the text.
+;
+; Arguments:
+; .pString - pointer to a UTF-8 string.
+; .len - how many bytes from the string to be used. If -1 the whole string will be scanned.
+; .font - the font to be used for the computations.
+;
+; Returns:
+; EAX - the width of the string in pixels.
+; EBX - the ascender of the string. It is negative.
+; EDX - the height of the string in pixels.
+
+
+body GetTextBounds ;, .pString, .len, .font
+
+.scaler FTC_ScalerRec
+.glyph dd ?
+
+.x dd ?
+
+.miny dd ?
+.maxy dd ?
+
+.charlen dd ?
+
+begin
+ pushad
+
+ mov edx, [.font]
+ xor ecx, ecx
+
+ mov [.scaler.face_id], edx
+ mov [.scaler.width], ecx
+
+ mov [.x], ecx
+
+ mov eax, [edx+__TFont.height]
+ inc ecx
+
+ mov [.scaler.height], eax
+ mov [.scaler.pixel], ecx ; ecx = 1
+
+ ror ecx, 1 ; ecx = $80000000
+ mov [.maxy], ecx
+ dec ecx
+ mov [.miny], ecx ; ecx = $7fffffff
+
+ mov esi, [.pString]
+
+.char_loop:
+ stdcall DecodeUtf8, [esi]
+ jc .finish
+
+ add esi, edx
+ mov [.charlen], edx
+
+ test eax, eax
+ jz .finish
+
+ cinvoke FTC_CMapCache_Lookup, [FTCCMapCache], [.font], -1, eax
+
+ lea ecx, [.scaler]
+ lea edx, [.glyph]
+ cinvoke FTC_ImageCache_LookupScaler, [FTCImageCache], ecx, [flagFreeTypeLoadFlags], eax, edx, 0
+
+ test eax, eax
+ jnz .char_loop
+
+ mov ebx, [.glyph]
+
+ sub eax, [ebx+FT_BitmapGlyphRec.top] ; eax = 0 here
+ mov edx, eax
+ add edx, [ebx+FT_BitmapGlyphRec.bitmap.rows]
+
+ cmp eax, [.miny]
+ jge @f
+ mov [.miny], eax
+@@:
+ cmp edx, [.maxy]
+ jle @f
+ mov [.maxy], edx
+@@:
+
+ mov eax, [ebx+FT_GlyphRec.advance.x]
+ sar eax, 16 ; format 16.16 fixed decimal point.
+ add [.x], eax
+
+ mov eax, [.charlen]
+ sub [.len], eax
+ ja .char_loop
+
+
+.finish:
+ mov eax, [.x]
+ mov edx, [.maxy]
+ mov ebx, [.miny]
+ sub edx, ebx
+
+ mov [esp+4*regEAX], eax
+ mov [esp+4*regEBX], ebx
+ mov [esp+4*regEDX], edx
+
+ popad
+ return
+endp
+
+
+
+
+
+
+
+proc __DrawGlyph, .pImage, .pFTBitmap, .x, .y, .color
+.spitch dd ?
+.dpitch dd ?
+
+.drect RECT
+.srect RECT
+
+.pixel_mode dd ?
+
+.sstart dd ?
+.dstart dd ?
+
+.xsize dd ?
+
+.bpp dd ?
+.bit_ofs dd ?
+
+begin
+ pushad
+
+ stdcall __fix_color, [.color], regEAX
+ mov [.color], eax
+
+ mov ebx, [.pImage]
+ mov edi, [.pFTBitmap]
+
+; the glyph pixel mode handling.
+ movzx eax, [edi+FT_Bitmap.pixel_mode]
+ cmp eax, FT_PIXEL_MODE_BGRA
+ ja .finish
+
+ mov [.pixel_mode], eax
+ movzx eax, [.bpp_const+eax]
+ mov [.bpp], eax
+
+; Clip the glyph to the image surface.
+
+ mov eax, [ebx+TImage.width]
+ mov ecx, [ebx+TImage.height]
+ mov [.drect.right], eax
+ mov [.drect.bottom], ecx
+ xor eax, eax
+ mov [.drect.left], eax
+ mov [.drect.top], eax
+
+ mov eax, [.x]
+ mov ecx, [.y]
+ mov [.srect.left], eax
+ mov [.srect.top], ecx
+
+ mov eax, [edi+FT_Bitmap.width]
+ cmp [.pixel_mode], FT_PIXEL_MODE_LCD
+ jne @f
+
+ cdq
+ mov ecx, 3
+ div ecx
+
+@@:
+ add eax, [.srect.left]
+ mov [.srect.right], eax
+
+ mov eax, [.srect.top]
+ add eax, [edi+FT_Bitmap.rows]
+ mov [.srect.bottom], eax
+
+ lea eax, [.srect]
+ lea ecx, [.drect]
+ stdcall RectIntersect, ecx, eax, ecx
+ jc .finish ; the rectangles does not intersect!
+
+ mov eax, [.drect.left]
+ mov ecx, [.drect.top]
+ sub eax, [.x]
+ sub ecx, [.y]
+ mov [.srect.left], eax
+ mov [.srect.top], ecx
+
+ mov eax, [.drect.right]
+ mov ecx, [.drect.bottom]
+ sub eax, [.drect.left]
+ sub ecx, [.drect.top]
+ mov [.srect.right], eax ; width!
+ mov [.srect.bottom], ecx ; height!
+
+; End of clipping code - [.srect] contains the rectangle of the glyph that have to be drawn (left, top, width, height).
+; [.drect] contains the destination rectangle. Both have the same size.
+
+ mov ecx, [edi+FT_Bitmap.pitch]
+ mov [.spitch], ecx
+
+; glyph pixel pointer
+
+ mov esi, [edi+FT_Bitmap.buffer]
+ test esi, esi
+ jz .finish
+
+ mov eax, [.srect.top]
+ mov ecx, [.srect.left]
+
+ imul eax, [.spitch]
+ imul ecx, [.bpp]
+ mov [.bit_ofs], ecx
+ shr ecx, 3 ; byte offs
+ and [.bit_ofs], 7 ; bit offs
+
+ add esi, ecx
+ add esi, eax
+
+; TImage destination pixel pointer
+
+ mov edi, [ebx+TImage.pPixels]
+
+ mov ecx, [ebx+TImage.width]
+ mov eax, [.drect.top]
+ imul eax, ecx
+ add eax, [.drect.left]
+ lea edi, [edi+4*eax] ; in bytes.
+
+ shl ecx, 2
+ mov [.dpitch], ecx
+
+
+; prepare MMX constants
+
+ pxor mm0, mm0 ; mm0 = 0000 0000 0000 0000
+ pcmpeqw mm1, mm1 ; mm1 = ffff ffff ffff ffff
+ psrlw mm1, 15 ; mm1 = 0001 0001 0001 0001
+ psllw mm1, 8 ; mm1 = 0100 0100 0100 0100
+
+ movq mm2, mm1 ; mm2 = 0001 0001 0001 0001
+ psllq mm2, 48 ; mm2 = 0100 0000 0000 0000
+
+
+.loopy:
+
+ mov [.sstart], esi
+ mov [.dstart], edi
+
+ mov eax, [.srect.right] ; width!
+ mov [.xsize], eax
+
+ cmp [.pixel_mode], FT_PIXEL_MODE_BGRA
+ je .loopx32
+
+ cmp [.pixel_mode], FT_PIXEL_MODE_LCD
+ je .loopx24
+
+ cmp [.pixel_mode], FT_PIXEL_MODE_GRAY
+ je .loopx8
+
+ cmp [.pixel_mode], FT_PIXEL_MODE_MONO
+ jne .finish
+
+ lodsd
+ bswap eax
+ mov ch, 32
+ mov cl, byte [.bit_ofs]
+ shl eax, cl
+ sub ch, cl
+
+.loopx1:
+ shl eax, 1
+ dec ch
+ jnz @f
+
+ lodsd
+ bswap eax
+ mov ch, 32
+
+@@:
+ jnc .next_x
+
+ movd mm7, [.color] ; source pixel.
+ movd mm6, [edi] ; destination pixel.
+
+ movq mm5, mm7
+ psrlq mm5, 24 ; alpha source
+
+ punpckldq mm5, mm5 ;
+ punpcklbw mm6, mm0 ; byte to word destination pixel
+ packssdw mm5, mm5 ; mm5 = As, As, As, As
+ punpcklbw mm7, mm0 ; byte to word source pixel
+
+ movq mm4, mm1
+ psubw mm4, mm5 ; mm4 = Bs Bs Bs Bs (Bs = $100 - As)
+
+ psrlq mm5, 16 ; mm5 = 0 As As As
+ por mm5, mm2 ; mm5 = $100 As As As
+
+ pmullw mm6, mm4 ; mm6 = Cd = Cd * (256-As) = Cd * Bs (For alpha Ad = Ad*Bs)
+ pmullw mm7, mm5 ; Cs = Cs * As (For alpha As = $100*As )
+
+ paddusw mm6, mm7 ; Cd = Cs + Cd (For alpha Ad = $100*As + Ad*Bs)
+ psrlw mm6, 8 ; Cd = Cd/256 (For alpha Ad = As + Ad*Bs/$100)
+
+ packuswb mm6, mm0 ; pack words to bytes 0A 0R 0G 0B -> 0000ARGB
+ movd [edi], mm6
+
+.next_x:
+ add edi, 4
+ dec [.xsize]
+ jnz .loopx1
+ jmp .nexty
+
+
+
+.loopx8:
+ movzx eax, byte [esi] ; intensity
+ add esi, 1
+
+ movd mm6, [.color]
+ movd mm7, eax
+
+ punpcklbw mm6, mm0 ; byte to word color.
+ punpckldq mm7, mm7 ;
+ packssdw mm7, mm7 ; mm7 = I, I, I, I
+
+ pmullw mm7, mm6 ; mm7 is the color to blend = Cs*256
+
+ movd mm6, [edi] ; Destination color
+ punpcklbw mm6, mm0 ; byte to word destination pixel
+
+ movq mm5, mm7
+ psrlq mm5, 56 ; alpha source
+ punpckldq mm5, mm5
+ packssdw mm5, mm5 ; mm5 = As, As, As, As
+
+ movq mm4, mm1
+ psubw mm4, mm5 ; mm4 = Bs Bs Bs Bs (Bs = $100 - As)
+
+ pmullw mm6, mm4 ; mm6 = Cd = Cd * (256-As) = Cd * Bs
+ paddusw mm6, mm7 ; Cd = 256*Cs + Cd*(256-As)
+ psrlw mm6, 8 ; Cd = Cd/256
+
+ packuswb mm6, mm0 ; pack words to bytes 0A 0R 0G 0B -> 0000ARGB
+ movd [edi], mm6
+
+ add edi, 4
+
+ dec [.xsize]
+ jnz .loopx8
+ jmp .nexty
+
+
+.loopx24:
+
+ movzx eax, byte [esi]
+ movzx edx, byte [esi+1]
+
+ lea eax, [eax+2*edx]
+ movzx edx, byte [esi+2]
+
+ add eax, edx
+ shr eax, 2 ; grayscale.
+
+ movd mm6, [.color]
+ movd mm7, eax
+
+ punpcklbw mm6, mm0 ; byte to word color.
+ punpckldq mm7, mm7 ;
+ packssdw mm7, mm7 ; mm7 = I, I, I, I
+
+ pmullw mm7, mm6 ; mm7 is the color to blend = Cs*256
+
+ movd mm6, [edi] ; Destination color
+ punpcklbw mm6, mm0 ; byte to word destination pixel
+
+ movq mm5, mm7
+ psrlq mm5, 56 ; alpha source
+ punpckldq mm5, mm5
+ packssdw mm5, mm5 ; mm5 = As, As, As, As
+
+ movq mm4, mm1
+ psubw mm4, mm5 ; mm4 = Bs Bs Bs Bs (Bs = $100 - As)
+
+ pmullw mm6, mm4 ; mm6 = Cd = Cd * (256-As) = Cd * Bs
+ paddusw mm6, mm7 ; Cd = 256*Cs + Cd*(256-As)
+ psrlw mm6, 8 ; Cd = Cd/256
+
+ packuswb mm6, mm0 ; pack words to bytes 0A 0R 0G 0B -> 0000ARGB
+ movd [edi], mm6
+
+
+ add esi, 3
+ add edi, 4
+
+ dec [.xsize]
+ jnz .loopx24
+ jmp .nexty
+
+
+.loopx32:
+ movd mm7, [esi] ; source pixel.
+ movd mm6, [edi] ; destination pixel.
+
+ movq mm5, mm7
+ psrlq mm5, 24 ; alpha source
+
+ punpckldq mm5, mm5 ;
+ punpcklbw mm6, mm0 ; byte to word destination pixel
+ packssdw mm5, mm5 ; mm5 = As, As, As, As
+ punpcklbw mm7, mm0 ; byte to word source pixel
+
+ movq mm4, mm1
+ psubw mm4, mm5 ; mm4 = Bs Bs Bs Bs (Bs = $100 - As)
+
+ psrlq mm5, 16 ; mm5 = 0 As As As
+ por mm5, mm2 ; mm5 = $100 As As As
+
+ pmullw mm6, mm4 ; mm6 = Cd = Cd * (256-As) = Cd * Bs (For alpha Ad = Ad*Bs)
+ pmullw mm7, mm5 ; Cs = Cs * As (For alpha As = $100*As )
+
+ paddusw mm6, mm7 ; Cd = Cs + Cd (For alpha Ad = $100*As + Ad*Bs)
+ psrlw mm6, 8 ; Cd = Cd/256 (For alpha Ad = As + Ad*Bs/$100)
+
+ packuswb mm6, mm0 ; pack words to bytes 0A 0R 0G 0B -> 0000ARGB
+ movd [edi], mm6
+
+ add edi, 4
+ add esi, 4
+
+ dec [.xsize]
+ jnz .loopx32
+ jmp .nexty
+
+
+.nexty:
+ mov esi, [.sstart]
+ add esi, [.spitch]
+
+ mov edi, [.dstart]
+ add edi, [.dpitch]
+
+ dec [.srect.bottom] ; height
+ jnz .loopy
+
+
+.finish:
+ emms
+ popad
+ return
+
+.bpp_const db 0, 1, 8, 2, 4, 24, 8, 32
+
+endp
+
+
+
+; the colors must be pre-multiplied ARGB.
+
+proc _BlendPixel, .dstColor, .srcColor
+begin
+ pushad
+
+ movzx ecx, byte [.srcColor+3] ; As
+ mov ebx, $ff
+ mov esi, ebx
+
+ sub ebx, ecx ; 1 - As
+
+ movzx eax, byte [.dstColor+3] ; Ad
+ imul ecx, esi
+ mul ebx
+ add eax, ecx
+ adc edx, 0
+ div esi
+
+ mov byte [esp+4*regEAX+3], al
+
+
+ movzx eax, byte [.dstColor] ; Bd
+ movzx ecx, byte [.srcColor] ; Bs
+
+ imul ecx, esi
+ mul ebx
+ add eax, ecx
+ adc edx, 0
+ div esi
+
+ mov byte [esp+4*regEAX], al
+
+
+
+ movzx eax, byte [.dstColor+1] ; Gd
+ movzx ecx, byte [.srcColor+1] ; Gs
+
+ imul ecx, esi
+ mul ebx
+ add eax, ecx
+ adc edx, 0
+ div esi
+
+ mov byte [esp+4*regEAX+1], al
+
+
+
+ movzx eax, byte [.dstColor+2] ; Rd
+ movzx ecx, byte [.srcColor+2] ; Rs
+
+ imul ecx, esi
+ mul ebx
+ add eax, ecx
+ adc edx, 0
+ div esi
+
+ mov byte [esp+4*regEAX+2], al
+
+
+ popad
+ return
+endp
DELETED freshlib/graphics/Linux/backbuffer.asm
Index: freshlib/graphics/Linux/backbuffer.asm
==================================================================
--- freshlib/graphics/Linux/backbuffer.asm
+++ /dev/null
@@ -1,89 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "BSD 2-clause" license." |
-;|_______________________________________________________________________________________|
-;
-; Description: Provides raster bitmap, to be used for double buffer painting.
-;
-; Target OS: Linux
-;
-; Dependencies:
-;
-; Notes:
-;_________________________________________________________________________________________
-
-
-
-proc CreateBackBuffer, .hwin, .width, .height
-begin
- push ebx ecx edx
-
- stdcall GetMem, sizeof.TBackBuffer
- mov ebx, eax
-
- mov ecx, [.width]
- mov edx, [.height]
-
- xor eax, eax
- inc eax
-
- cmp ecx, eax
- jge @f
- mov ecx, eax
-@@:
- cmp edx, eax
- jge @f
- mov edx, eax
-@@:
- mov [ebx+TBackBuffer.width], ecx
- mov [ebx+TBackBuffer.height], edx
-
- cinvoke XCreatePixmap, [hApplicationDisplay], [.hwin], [ebx+TBackBuffer.width], [ebx+TBackBuffer.height], $20
- test eax, eax
- js .error
-
- mov [ebx+TBackBuffer.raster], eax
- mov eax, ebx
- clc
- pop edx ecx ebx
- return
-
-.error:
- stdcall FreeMem, ebx
- xor eax, eax
- stc
- pop edx ecx ebx
- return
-endp
-
-
-
-
-proc DestroyBackBuffer, .pBackBuffer
-begin
- push eax ecx edx
- mov eax, [.pBackBuffer]
- push eax
- cinvoke XFreePixmap, [hApplicationDisplay], [eax+TBackBuffer.raster]
- stdcall FreeMem ; from the stack
- pop edx ecx eax
- return
-endp
-
-
-
-
-
-
-proc DrawBackBuffer, .context, .pBackBuffer, .x, .y
-begin
- push eax ecx edx
- mov eax, [.pBackBuffer]
- mov ecx, [.context]
-
- cinvoke XCopyArea, [hApplicationDisplay], [eax+TBackBuffer.raster], [ecx+TContext.raster], [ecx+TContext.handle], 0, 0, [eax+TBackBuffer.width], [eax+TBackBuffer.height], [.x], [.y]
-
- pop edx ecx eax
- return
-endp
-
DELETED freshlib/graphics/Linux/context.asm
Index: freshlib/graphics/Linux/context.asm
==================================================================
--- freshlib/graphics/Linux/context.asm
+++ /dev/null
@@ -1,190 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "BSD 2-clause" license." |
-;|_______________________________________________________________________________________|
-;
-; Description: Context is a object that represents drawing surface in FreshLib
-;
-; Target OS: Linux
-;
-; Dependencies: memory.asm
-;
-; Notes:
-;_________________________________________________________________________________________
-
-uses libX11
-
-cmClear = GXclear
-cmAnd = GXand
-cmAndReverse = GXandReverse
-cmCopy = GXcopy
-cmAndInverted = GXandInverted
-cmNoOp = GXnoop
-cmXor = GXxor
-cmOr = GXor
-cmNor = GXnor
-cmEquiv = GXequiv
-cmInvert = GXinvert
-cmOrReverse = GXorReverse
-cmCopyInverted = GXcopyInverted
-cmOrInverted = GXorInverted
-cmNand = GXnand
-cmSet = GXset
-
-
-image_pointer_context = 2
-
-proc AllocateContext, .raster
-begin
- push ebx ecx edx
-
- stdcall GetMem, sizeof.TContext
- jc .error
- mov ebx, eax
-
- mov eax, [.raster]
- mov [ebx+TContext.raster], eax
-
- cinvoke XCreateGC, [hApplicationDisplay], [ebx+TContext.raster], 0, 0
- mov [ebx+TContext.handle], eax
- mov eax, ebx
-
-.exit:
- pop edx ecx ebx
- clc
- return
-
-.error:
- DebugMsg 'Error allocating context.'
- xor eax, eax
- pop edx ecx ebx
- stc
- return
-endp
-
-
-
-
-proc ReleaseContext, .context
-begin
- push eax ebx ecx edx
- mov ebx, [.context]
- cinvoke XFlush, [hApplicationDisplay]
- cinvoke XFreeGC, [hApplicationDisplay], [ebx+TContext.handle]
- cmp [ebx+TContext.clipregion], 0
- je @f
- cinvoke XDestroyRegion, [ebx+TContext.clipregion]
-@@:
- stdcall FreeMem, ebx
-
- clc
- pop edx ecx ebx eax
- return
-endp
-
-
-
-proc SetLineStyle, .context, .pLineStyle
-.color dd ?
-begin
- push eax ebx ecx edx esi
-
- mov ebx, [.context]
- mov esi, [.pLineStyle]
-
- mov eax, [esi+TLineStyle.flags]
- mov ecx, eax
- shr ecx, 8
- and eax, $ff ; cap_style
- and ecx, $ff ; join_style
-
- mov edx, LineSolid
- cmp [esi+TLineStyle.DashCount], 0
- je @f
- mov edx, LineDoubleDash
-@@:
- cinvoke XSetLineAttributes, [hApplicationDisplay], [ebx+TContext.handle], [esi+TLineStyle.width], edx, eax, ecx
- cinvoke XSetForeground, [hApplicationDisplay], [ebx+TContext.handle], [esi+TLineStyle.color]
-
- cmp [esi+TLineStyle.DashCount], 0
- je .exit
-
- lea ecx, [esi+TLineStyle.DashItems]
- cinvoke XSetDashes, [hApplicationDisplay], [ebx+TContext.handle], 0, ecx, [esi+TLineStyle.DashCount]
- cinvoke XSetBackground, [hApplicationDisplay], [ebx+TContext.handle], [esi+TLineStyle.clSpace]
-
-.exit:
- pop esi edx ecx ebx eax
- return
-endp
-
-
-proc SetDrawMode, .context, .mode
-begin
- push eax ecx edx
- mov eax, [.context]
- cinvoke XSetFunction, [hApplicationDisplay], [eax+TContext.handle], [.mode]
- pop edx ecx eax
- return
-endp
-
-
-
-
-
-proc SetClipRectangle, .context, .pBounds
-.rect XRectangle
-begin
- push eax ecx edx esi
-
- mov esi, [.context]
-
- cmp [esi+TContext.clipregion], 0
- je @f
- cinvoke XDestroyRegion, [esi+TContext.clipregion]
-@@:
- cinvoke XCreateRegion
- mov [esi+TContext.clipregion], eax
-
- mov edx, [.pBounds]
- test edx, edx
- jz .remove
-
- mov eax, [edx+TBounds.x]
- mov [.rect.x], ax
-
- mov eax, [edx+TBounds.y]
- mov [.rect.y], ax
-
- mov eax, [edx+TBounds.width]
- mov [.rect.width], ax
-
- mov eax, [edx+TBounds.height]
- mov [.rect.height], ax
-
- lea edx, [.rect]
- cinvoke XUnionRectWithRegion, edx, [esi+TContext.clipregion], [esi+TContext.clipregion]
- cinvoke XSetRegion, [hApplicationDisplay], [esi+TContext.handle], [esi+TContext.clipregion]
-
-.exit:
- pop esi edx ecx eax
- return
-
-.remove:
- cinvoke XSetClipMask, [hApplicationDisplay], [esi+TContext.handle], None
- jmp .exit
-endp
-
-
-
-
-proc IsDrawable, .raster
-begin
-
-; cinvoke XSetErrorHandler,
-
-
-
-
-
-endp
Index: freshlib/graphics/Linux/draw.asm
==================================================================
--- freshlib/graphics/Linux/draw.asm
+++ freshlib/graphics/Linux/draw.asm
@@ -31,20 +31,10 @@
pop edx ecx ebx eax
return
endp
-proc DrawFillRect, .context, .x, .y, .width, .height, .color
-begin
- push eax ebx ecx edx
- mov ebx, [.context]
- cinvoke XSetForeground, [hApplicationDisplay], [ebx+TContext.handle], [.color]
- cinvoke XFillRectangle, [hApplicationDisplay], [ebx+TContext.raster], [ebx+TContext.handle], [.x], [.y], [.width], [.height]
- pop edx ecx ebx eax
- return
-endp
-
macro Outline [type, x, y] {
common
local ..types, ..points, ..count
Index: freshlib/graphics/Linux/fonts.asm
==================================================================
--- freshlib/graphics/Linux/fonts.asm
+++ freshlib/graphics/Linux/fonts.asm
@@ -10,151 +10,224 @@
; Dependencies:
;
; Notes:
;_________________________________________________________________________________________
-
-proc FontCreate, .fontname, .size, .weight, .flags
-begin
- push ebx ecx edx
- stdcall StrDup, [.fontname]
- mov ebx, eax
-
- test [.flags], ffMonospaced
- jz @f
- stdcall StrCat, ebx, FontAttr.mono
-@@:
- sub [.size], 2
- cmp [.size], 0
- jle @f
-
- stdcall StrCat, ebx, FontAttr.size
- stdcall NumToStr, [.size], ntsDec or ntsUnsigned
- push eax
- stdcall StrCat, ebx, eax
- stdcall StrDel ; from the stack
-@@:
- cmp [.weight], 0
- je @f
- shr [.weight], 2
- stdcall StrCat, ebx, FontAttr.weight
- stdcall NumToStr, [.weight], ntsDec or ntsUnsigned
- push eax
- stdcall StrCat, ebx, eax
- stdcall StrDel ; from the stack
-
-@@:
- test [.flags], ffItalic
- jz @f
- stdcall StrCat, ebx, FontAttr.italic
-@@:
-
- stdcall StrPtr, ebx
- cinvoke XftFontOpenName, [hApplicationDisplay], 0, eax
-
- stdcall StrDel, ebx
- pop edx ecx ebx
- return
-endp
-
iglobal
if used FontAttr.mono | used FontAttr.size | used FontAttr.weight | used FontAttr.italic
label FontAttr byte
.mono db ',Mono', 0
.size db ':pixelsize=', 0
.weight db ':weight=', 0
.italic db ':slant=italic', 0
+ .regular db ':slant=roman', 0
+
+
+;fwLight = 0
+;fwDemilight = 1
+;fwNormal = 2
+;fwMedium = 3
+;fwDemibold = 4
+;fwBold = 5
+;fwExtraBold = 6
+;fwBlack = 7
+
+ .font_weights db 0, 55, 80, 100, 180, 200, 205, 210
end if
endg
-
-
-
-
-
-
-
-
-macro XftPushArg field, type, value {
- push value
- push type
- push field
- add ebx, 12
-}
-
-macro XftStartArguments {
- push 0
- mov ebx, 4
-}
-
-XftFamily text 'family'
-XftStyle text 'style'
-XftSpacing text 'spacing'
-XftSlant text 'slant'
-XftWeight text 'weight'
-XftWidth text 'width'
-XftPixelSize text 'pixelsize'
-XftAntialias text 'antialias'
-XftAutohint text 'autohint'
-XftHintStyle text 'hintstyle'
-XftHinting text 'hinting'
-XftRGBA text 'rgba'
-
-
-proc FontCreate3, .fontname, .size, .weight, .flags
-begin
- push ebx ecx edx
-
-
- XftStartArguments
-
- cmp [.fontname], 0
- je @f
- stdcall StrPtr, [.fontname]
- XftPushArg XftFamily, XftTypeString, eax
-@@:
-
- cmp [.size], 2
- jle @f
- sub [.size], 2
- XftPushArg XftPixelSize, XftTypeInteger, [.size]
-@@:
-
- cmp [.weight], 0
- jle @f
- shr [.weight], 1
- XftPushArg XftWeight, XftTypeInteger, [.weight]
-@@:
-
- test [.flags], ffItalic
- jz @f
- XftPushArg XftSlant, XftTypeInteger, XFT_SLANT_ITALIC
-@@:
-
- test [.flags], ffMonospaced
- jz @f
- XftPushArg XftSpacing, XftTypeInteger, XFT_MONO
-@@:
- XftPushArg XftAntialias, XftTypeBool, 0
- XftPushArg XftHinting, XftTypeBool, 0
- XftPushArg XftHintStyle, XftTypeInteger, 0
- XftPushArg XftRGBA, XftTypeInteger, 5
- XftPushArg XftWidth, XftTypeInteger, 100
-
- invoke XftFontOpen, [hApplicationDisplay], 0
- add ebx, 8
- add esp, ebx
-
- pop edx ecx ebx
- return
-endp
-
-
-
-
-proc FontDestroy, .font
-begin
- cinvoke XftFontClose, [hApplicationDisplay], [.font]
- return
-endp
+;initialize InitFonts
+;begin
+; cinvoke FcInit
+; return
+;endp
+;
+;
+;finalize FinalizeFonts
+;begin
+; cinvoke FcFini
+; return
+;endp
+
+
+
+proc FTCRequester as FT_Face_Requester
+.res dd ?
+.idx dd ?
+.face dd ?
+begin
+ pushad
+
+ mov esi, [.face_id]
+
+ stdcall StrDup, [esi+__TFont.hFontFace]
+ mov ebx, eax
+
+ test [esi+__TFont.flags], ffMonospaced
+ jz @f
+ stdcall StrCat, ebx, FontAttr.mono
+@@:
+ mov eax, [esi+__TFont.weight]
+ and eax, 7
+ movzx eax, byte [FontAttr.font_weights+eax]
+
+ stdcall StrCat, ebx, FontAttr.weight
+ stdcall NumToStr, eax, ntsDec or ntsUnsigned
+ push eax
+ stdcall StrCat, ebx, eax
+ stdcall StrDel ; from the stack
+
+ mov eax, FontAttr.regular
+ test [esi+__TFont.flags], ffItalic
+ jz @f
+ mov eax, FontAttr.italic
+@@:
+ stdcall StrCat, ebx, eax
+ stdcall StrPtr, ebx
+
+; OutputLn eax
+
+ cinvoke FcNameParse, eax
+ stdcall StrDel, ebx
+
+ test eax, eax
+ jnz @f
+
+ cinvoke FcNameParse, txt "Helvetica"
+ DebugMsg "Error: Bad pattern fallback."
+
+@@:
+ mov ebx, eax
+
+ cinvoke FcDefaultSubstitute, ebx
+ cinvoke FcConfigSubstitute, 0, ebx, 0
+
+ lea eax, [.res]
+ cinvoke FcFontMatch, 0, ebx, eax
+ push eax
+
+ cinvoke FcPatternDestroy, ebx
+ pop ebx
+
+ if defined options.DebugMode & options.DebugMode
+ cinvoke FcPatternPrint, ebx
+ end if
+
+ lea eax, [.res]
+ cinvoke FcPatternGetString, ebx, FC_FILE, 0, eax
+
+ OutputLn [.res]
+
+ lea eax, [.idx]
+ cinvoke FcPatternGetInteger, ebx, FC_INDEX, 0, eax
+
+ mov edi, [.pFace]
+ mov eax, [.res]
+ cinvoke FT_New_Face, [FTLibrary], eax, [.idx], edi
+
+.finish:
+ mov [esp+4*regEAX], eax
+ cinvoke FcPatternDestroy, ebx
+ popad
+ cret
+endp
+
+
+
+FC_FILE text 'file'
+FC_INDEX text 'index'
+FC_PIXEL_SIZE text 'pixelsize'
+
+
+
+body FontCreate
+begin
+ push edx
+
+ stdcall GetMem, sizeof.__TFont
+ mov edx, eax
+
+ stdcall StrDupMem, [.font_name]
+ mov [edx+__TFont.hFontFace], eax
+
+ mov eax, [.size]
+ mov [edx+__TFont.height], eax
+ mov eax, [.weight]
+ mov [edx+__TFont.weight], eax
+ mov eax, [.flags]
+ mov [edx+__TFont.flags], eax
+
+ mov eax, edx
+ pop edx
+ return
+endp
+
+
+
+body FontDestroy
+begin
+ pushad
+ mov edi, [.pFont]
+
+ cinvoke FTC_Manager_RemoveFaceID, [FTCManager], edi
+ stdcall StrDel, [edi+__TFont.hFontFace]
+ stdcall FreeMem, edi
+
+ popad
+ return
+endp
+
+
+; returns some font metrics
+;
+; Arguments:
+; .font - the font
+; Returns:
+; EAX - the line height of the font.
+; EBX - the ascender of the font.
+; EDX - the descender of the font.
+
+body GetFontMetrics
+.scaler FTC_ScalerRec
+.size dd ?
+begin
+ push ecx
+
+ mov edx, [.font]
+ xor ecx, ecx
+
+ mov [.scaler.face_id], edx
+ mov [.scaler.width], ecx
+
+ mov eax, [edx+__TFont.height]
+ inc ecx
+
+ mov [.scaler.height], eax
+ mov [.scaler.pixel], ecx ; ecx = 1
+
+ lea eax, [.scaler]
+ lea edx, [.size]
+ cinvoke FTC_Manager_LookupSize, [FTCManager], eax, edx
+ test eax, eax
+ jnz .error
+
+ mov edx, [.size]
+
+ mov eax, [edx+FT_SizeRec.metrics.height]
+ mov ebx, [edx+FT_SizeRec.metrics.ascender]
+ mov edx, [edx+FT_SizeRec.metrics.descender]
+
+ sar eax, 6
+ sar ebx, 6
+ sar edx, 6
+
+ clc
+ pop ecx
+ return
+
+.error:
+ stc
+ pop ecx
+ return
+endp
Index: freshlib/graphics/Linux/images.asm
==================================================================
--- freshlib/graphics/Linux/images.asm
+++ freshlib/graphics/Linux/images.asm
@@ -40,15 +40,15 @@
inc eax
mov ecx, [.width]
mov edx, [.height]
- test ecx, ecx
- cmovz ecx, eax
+ cmp ecx, 0
+ cmovle ecx, eax
- test edx, edx
- cmovz edx, eax
+ cmp edx, 0
+ cmovle edx, eax
mov [esi+TImage.width], ecx
mov [esi+TImage.height], edx
lea eax, [4*ecx]
@@ -64,11 +64,11 @@
cmp eax, -1
je .error_free
mov [esi+TImage.shminfo.Addr], eax
mov [esi+TImage.pPixels], eax
- mov [esi+TImage.shminfo.fReadOnly], 0
+ mov [esi+TImage.shminfo.fReadOnly], 1
lea ebx, [esi+TImage.shminfo]
cinvoke XShmCreateImage, [hApplicationDisplay], 0, $20, ZPixmap, eax, ebx, [esi+TImage.width], [esi+TImage.height]
mov [esi+TImage.ximage], eax
@@ -98,90 +98,100 @@
begin
pushad
mov esi, [.ptrImage]
test esi, esi
- jz @f
+ jz .finish
lea eax, [esi+TImage.shminfo]
cinvoke XShmDetach, [hApplicationDisplay], eax
+
cinvoke XDestroyImage, [esi+TImage.ximage]
cinvoke shmdt, [esi+TImage.shminfo.Addr]
cinvoke shmctl, [esi+TImage.shminfo.ShmID], IPC_RMID, 0
stdcall FreeMem, esi
-@@:
+
+.finish:
popad
return
endp
-if used ___CheckCompletionEvent
-___CheckCompletionEvent:
- mov eax, [esp+8] ;.pEvent
- mov eax, [eax+XEvent.type]
- cmp eax, [ShmCompletionEvent]
- sete al
- movzx eax, al
- retn
-end if
+;if used ___CheckCompletionEvent
+;___CheckCompletionEvent:
+;
+;virtual at esp+4
+; .display dd ?
+; .pEvent dd ?
+; .user dd ?
+;end virtual
+;
+;; timeout
+; stdcall GetTimestamp
+; cmp eax, [.user]
+; jbe @f
+;
+; DebugMsg "Timeout!"
+;
+; mov eax, 1
+; retn
+;
+;@@:
+; mov eax, [.pEvent] ;.pEvent
+; mov eax, [eax+XEvent.type]
+;
+; cmp eax, [ShmCompletionEvent]
+; sete al
+; movzx eax, al
+; retn
+;end if
+
-body DrawImage
+body DrawImageRect
.event XEvent
+ rb 256
begin
pushad
mov esi, [.pImage]
test esi, esi
jz .exit
mov ebx, [esi+TImage.ximage]
- mov ecx, [.context]
- cinvoke XShmPutImage, [hApplicationDisplay], [ecx+TContext.raster], [ecx+TContext.handle], [esi+TImage.ximage], 0, 0, [.x], [.y], [esi+TImage.width], [esi+TImage.height], 1
-
- lea eax, [.event]
- cinvoke XIfEvent, [hApplicationDisplay], eax, ___CheckCompletionEvent, 0
-
-.exit:
- popad
- return
-endp
-
-
-
-
-body DrawText
- .cltxt _XftColor
- .vis XVisualInfo
-begin
- push eax ebx ecx edx esi edi
-
- cmp [.font], 0
- jne @f
-
- mov eax, [_SystemFont]
- mov [.font], eax
-
-@@:
- cinvoke XDefaultScreen, [hApplicationDisplay]
- mov edx, eax
- lea eax, [.vis]
- cinvoke XMatchVisualInfo, [hApplicationDisplay], edx, $20, TrueColor, eax
-
- mov ecx, [.pImage]
- cinvoke XftDrawCreate, [hApplicationDisplay], [ecx+TImage.ximage], [.vis.Visual], 0
- mov ebx, eax
-
-; mov ecx, [.context]
-; cinvoke XftDrawSetClip, ebx, [ecx+TContext.clipregion]
-
- lea eax, [.cltxt]
- stdcall __ColorToRender, [.color], eax
-
- cinvoke XftDrawStringUtf8, ebx, eax, [.font], [.x], [.y], [.text], [.len]
- cinvoke XftDrawDestroy, ebx
-
- pop edi esi edx ecx ebx eax
- return
-endp
+ cinvoke XCreateGC, [hApplicationDisplay], [.where], 0, 0
+ mov edi, eax
+
+
+ cinvoke XShmPutImage, [hApplicationDisplay], [.where], edi, [esi+TImage.ximage], [.xSrc], [.ySrc], [.xDst], [.yDst], [.width], [.height], TRUE
+
+
+; THIS CODE SOMETIMES CAUSES HANGS!
+
+ stdcall GetTimestamp
+ lea esi, [eax+20]
+
+.loop:
+ lea eax, [.event]
+ cinvoke XCheckTypedEvent, [hApplicationDisplay], [ShmCompletionEvent], eax
+ test eax, eax
+ jnz .finish
+
+ stdcall GetTimestamp
+ cmp eax, esi
+ jb .loop
+
+
+.finish:
+ cinvoke XFreeGC, [hApplicationDisplay], edi
+
+.exit:
+ popad
+ return
+
+endp
+
+
+
+
Index: freshlib/graphics/Linux/text.asm
==================================================================
--- freshlib/graphics/Linux/text.asm
+++ freshlib/graphics/Linux/text.asm
@@ -10,252 +10,531 @@
; Dependencies:
;
; Notes: Uses XFT library to renter the text.
;_________________________________________________________________________________________
-uses libFT, libFC, libXft
-
-struct __TFont
- .hFontFace dd ? ; The name of the font face.
- .height dd ? ; The character height in pixels.
- .weight dd ? ; The weight of the characters.
- .flags dd ? ; ffItalic, ffMonospaced, etc.
-ends
-
-
-
-proc FTCRequester as FT_Face_Requester
-.res dd ?
-.idx dd ?
-.face dd ?
-begin
- pushad
-
- mov esi, [.face_id]
-
- stdcall StrDup, [esi+__TFont.hFontFace]
- mov ebx, eax
-
- test [esi+__TFont.flags], ffMonospaced
- jz @f
- stdcall StrCat, ebx, FontAttr.mono
-@@:
- mov eax, [esi+__TFont.weight]
- test eax, eax
- jz @f
-
- shr eax, 2
- stdcall StrCat, ebx, FontAttr.weight
- stdcall NumToStr, eax, ntsDec or ntsUnsigned
- push eax
- stdcall StrCat, ebx, eax
- stdcall StrDel ; from the stack
-
-@@:
- test [esi+__TFont.flags], ffItalic
- jz @f
- stdcall StrCat, ebx, FontAttr.italic
-@@:
-
- stdcall StrPtr, ebx
-
- cinvoke FcNameParse, eax
- stdcall StrDel, ebx
- mov ebx, eax
-
- cinvoke FcConfigSubstitute, 0, ebx, 0
- cinvoke FcDefaultSubstitute, ebx
-
- lea eax, [.res]
- cinvoke FcFontMatch, 0, ebx, eax
- push eax
- cinvoke FcPatternDestroy, ebx
- pop ebx
-
- lea eax, [.res]
- cinvoke FcPatternGetString, ebx, FC_FILE, 0, eax
-
- lea eax, [.idx]
- cinvoke FcPatternGetInteger, ebx, FC_INDEX, 0, eax
-
- mov edi, [.pFace]
- mov eax, [.res]
- cinvoke FT_New_Face, [FTLibrary], eax, [.idx], edi
-
-.finish:
- mov [esp+4*regEAX], eax
- cinvoke FcPatternDestroy, ebx
- popad
- cret
-endp
-
-
-
-FC_FILE text 'file'
-FC_INDEX text 'index'
-FC_PIXEL_SIZE text 'pixelsize'
-
-
-proc FontCreate4, .font_name, .size, .weight, .flags
-begin
- push edx
-
- stdcall GetMem, sizeof.__TFont
- mov edx, eax
-
- stdcall StrDupMem, [.font_name]
- mov [edx+__TFont.hFontFace], eax
-
- mov eax, [.size]
- mov [edx+__TFont.height], eax
- mov eax, [.weight]
- mov [edx+__TFont.weight], eax
- mov eax, [.flags]
- mov [edx+__TFont.flags], eax
-
- mov eax, edx
- pop edx
- return
-endp
-
-
-
-proc FontDestroy2, .pFont
-begin
- pushad
- mov edi, [.pFont]
-
- cinvoke FTC_Manager_RemoveFaceID, [FTCManager], edi
- stdcall StrDel, [edi+__TFont.hFontFace]
- stdcall FreeMem, edi
-
- popad
- return
-endp
-
-
-
-proc DrawString2, .pImage, .hString, .x, .y, .font, .color
-.type FTC_ImageType
-.scaler FTC_ScalerRec
-.size dd ?
-.face dd ?
-
-.glyph dd ?
-.prev dd ?
-.kerning FT_Vector
-
-begin
- pushad
-
- shl [.x], 6
-
- mov edx, [.font]
- xor ecx, ecx
-
- mov [.prev], ecx
-
- mov [.scaler.face_id], edx
- mov [.type.face_id], edx
-
- mov eax, [edx+__TFont.height]
- mov [.scaler.height], eax
- mov [.type.height], eax
- mov [.scaler.width], ecx
- mov [.type.width], ecx
-
- mov [.scaler.pixel], 1
- mov [.type.flags], FT_LOAD_RENDER or FT_LOAD_TARGET_LCD or FT_LOAD_COLOR
-
- lea eax, [.scaler]
- lea edx, [.size]
- cinvoke FTC_Manager_LookupSize, [FTCManager], eax, edx
-
- mov eax, [.size]
- mov ecx, [eax+FT_SizeRec.face]
- mov eax, [eax+FT_SizeRec.metrics.ascender]
- mov [.face], ecx
- sar eax, 6
- add [.y], eax
-
- stdcall StrPtr, [.hString]
- mov esi, eax
-
-.char_loop:
- stdcall DecodeUtf8, [esi]
- jc .finish
-
- add esi, edx
+uses libFT, libFC
+
+
+iglobal
+ var flagFreeTypeLoadFlags = FT_LOAD_RENDER or FT_LOAD_TARGET_NORMAL or FT_LOAD_COLOR
+endg
+
+
+
+body DrawDecomposedString ;, .pImage, .pArray, .x, .y, .font, .color
+.scaler FTC_ScalerRec
+.glyph dd ?
+
+.startX dd ?
+begin
+ pushad
+
+ mov edx, [.font]
+ xor ecx, ecx
+
+ mov [.scaler.face_id], edx
+ mov [.scaler.width], ecx
+
+ mov eax, [edx+__TFont.height]
+ inc ecx
+
+ mov [.scaler.height], eax
+ mov [.scaler.pixel], ecx ; ecx = 1
+
+ mov eax, [.x]
+ mov [.startX], eax
+
+ mov esi, [.pArray]
+ xor edi, edi
+ dec edi
+
+.char_loop:
+ inc edi
+ cmp edi, [esi+TArray.count]
+ jae .finish
+
+ cmp word [esi+TArray.array+8*edi+TTextChar.width], 0
+ je .char_ok
+
+ cinvoke FTC_CMapCache_Lookup, [FTCCMapCache], [.font], -1, [esi+TArray.array+8*edi+TTextChar.code]
+
+ lea ecx, [.scaler]
+ lea edx, [.glyph]
+ cinvoke FTC_ImageCache_LookupScaler, [FTCImageCache], ecx, [flagFreeTypeLoadFlags], eax, edx, 0
+
+ test eax, eax
+ jnz .char_ok
+
+ mov ebx, [.glyph]
+ mov ecx, [.x]
+ mov edx, [.y]
+
+ add ecx, [ebx+FT_BitmapGlyphRec.left]
+ sub edx, [ebx+FT_BitmapGlyphRec.top]
+
+ lea eax, [ebx+FT_BitmapGlyphRec.bitmap]
+ stdcall __DrawGlyph, [.pImage], eax, ecx, edx, [.color]
+
+ movzx eax, word [esi+TArray.array+8*edi+TTextChar.width]
+ add [.x], eax
+
+.char_ok:
+; check for new line.
+ movzx eax, word [esi+TArray.array+8*edi+TTextChar.height]
+ test eax, eax
+ jz .char_loop
+
+ add [.y], eax
+ mov eax, [.startX]
+ mov [.x], eax
+ jmp .char_loop
+
+
+.finish:
+ popad
+ return
+endp
+
+
+
+
+; Draws the string on the image using the specified font and color.
+; The string is drawn in one line. The control symbols are not
+; processed. The tabs are not expanded or replaced with spaces.
+;
+; Arguments:
+; .pImage - pointer to the image where to draw the text.
+; .pString - pointer to a UTF-8 string.
+; .len - how many bytes from the string to be drawn. If -1, the whole string will be drawn.
+; .x - X coordinate, where to start drawing.
+; .y - Y coordinate of the baseline where to draw the string.
+; .font - the font to be used.
+; .color - ARGB color to draw the glyphs.
+;
+;;;;;;;; Returns:
+;;;;;;;; EAX - the width of the string in pixels.
+;;;;;;;; EBX - the ascender of the string. It is negative.
+;;;;;;;; EDX - the height of the string in pixels.
+
+
+body DrawString ;, .pImage, .pString, .len, .x, .y, .font, .color
+
+.scaler FTC_ScalerRec
+.glyph dd ?
+
+.miny dd ?
+.maxy dd ?
+.startX dd ?
+
+begin
+ pushad
+
+ mov edx, [.font]
+ xor ecx, ecx
+
+ mov [.scaler.face_id], edx
+ mov [.scaler.width], ecx
+
+ mov eax, [edx+__TFont.height]
+ inc ecx
+
+ mov [.scaler.height], eax
+ mov [.scaler.pixel], ecx ; ecx = 1
+
+ ror ecx, 1 ; ecx = $80000000
+ mov [.maxy], ecx
+ dec ecx
+ mov [.miny], ecx ; ecx = $7fffffff
+
+ mov eax, [.x]
+ mov [.startX], eax
+
+ mov esi, [.pString]
+
+.char_loop:
+
+ stdcall DecodeUtf8, [esi]
+ jc .finish
+
+ add esi, edx
+
+ sub [.len], edx
+ jb .finish
test eax, eax
jz .finish
cinvoke FTC_CMapCache_Lookup, [FTCCMapCache], [.font], -1, eax
- mov ebx, eax
-
-; process the kerning;
-
- cmp [.prev], 0
- je .kerning_ok
-
- lea eax, [.kerning]
- cinvoke FT_Get_Kerning, [.face], [.prev], ebx, 0, eax
- test eax, eax
- jnz .kerning_ok
-
- mov eax, [.kerning.x]
-; sar eax, 6
-
- add [.x], eax
-
-.kerning_ok:
- mov [.prev], ebx
-
- lea ecx, [.type]
+ lea ecx, [.scaler]
lea edx, [.glyph]
- cinvoke FTC_ImageCache_Lookup, [FTCImageCache], ecx, ebx, edx, 0
+ cinvoke FTC_ImageCache_LookupScaler, [FTCImageCache], ecx, [flagFreeTypeLoadFlags], eax, edx, 0
test eax, eax
jnz .char_loop
mov ebx, [.glyph]
mov ecx, [.x]
mov edx, [.y]
- sar ecx, 6
-
add ecx, [ebx+FT_BitmapGlyphRec.left]
sub edx, [ebx+FT_BitmapGlyphRec.top]
+ cmp edx, [.miny]
+ jge @f
+ mov [.miny], edx
+@@:
+ mov eax, edx
+ add eax, [ebx+FT_BitmapGlyphRec.bitmap.rows]
+ cmp eax, [.maxy]
+ jle @f
+ mov [.maxy], eax
+@@:
lea eax, [ebx+FT_BitmapGlyphRec.bitmap]
- stdcall DrawGlyph, [.pImage], eax, ecx, edx, [.color]
+ stdcall __DrawGlyph, [.pImage], eax, ecx, edx, [.color]
mov eax, [ebx+FT_BitmapGlyphRec.root.advance.x]
- sar eax, 10 ; format 16.16 fixed decimal point.
+ sar eax, 16 ; format 16.16 fixed decimal point.
+ add [.x], eax
+
+ jmp .char_loop
+
+
+.finish:
+; mov eax, [.x]
+; mov edx, [.maxy]
+; mov ebx, [.miny]
+; sub eax, [.startX]
+; sub edx, ebx
+; sub ebx, [.y]
+
+; mov [esp+4*regEAX], eax
+; mov [esp+4*regEBX], ebx
+; mov [esp+4*regEDX], edx
+
+ popad
+ return
+endp
+
+
+
+; returns:
+; EAX - array with decomposed string.
+; EDX - maximal bearing_Y of the string.
+; ECX - maximal descender of the string.
+
+body TextDecompose ;, .hString, .font
+
+ .scaler FTC_ScalerRec
+ .glyph dd ?
+
+ .miny dd ?
+ .maxy dd ?
+
+begin
+ pushad
+
+ mov edx, [.font]
+ xor ecx, ecx
+
+ mov [.scaler.face_id], edx
+ mov [.scaler.width], ecx
+
+ mov eax, [edx+__TFont.height]
+ inc ecx
+
+ mov [.scaler.height], eax
+ mov [.scaler.pixel], ecx ; ecx = 1
+
+ ror ecx, 1 ; ecx = $80000000
+ mov [.maxy], ecx
+ dec ecx
+ mov [.miny], ecx ; ecx = $7fffffff
+
+ stdcall StrPtr, [.hString]
+ mov esi, eax
+
+ stdcall CreateArray, sizeof.TTextChar
+ mov edi, eax
+
+.char_loop:
+ stdcall DecodeUtf8, [esi]
+ jc .finish
+
+ add esi, edx
+ mov ebx, eax
+
+ test eax, eax
+ jz .end
+
+ cinvoke FTC_CMapCache_Lookup, [FTCCMapCache], [.font], -1, eax
+
+ lea ecx, [.scaler]
+ lea edx, [.glyph]
+ cinvoke FTC_ImageCache_LookupScaler, [FTCImageCache], ecx, [flagFreeTypeLoadFlags], eax, edx, 0
+
+ xor ecx, ecx
+
+ test eax, eax
+ jnz .glyph_size_ok ; zero width glyph ????
+
+ mov ecx, [.glyph]
+
+ mov eax, [ecx+FT_BitmapGlyphRec.top]
+ neg eax
+
+ cmp eax, [.miny]
+ jge @f
+ mov [.miny], eax
+@@:
+
+ add eax, [ecx+FT_BitmapGlyphRec.bitmap.rows]
+ cmp eax, [.maxy]
+ jle @f
+ mov [.maxy], eax
+@@:
+ mov ecx, [ecx+FT_BitmapGlyphRec.root.advance.x] ; format 16.16 fixed decimal point.
+ sar ecx, 16 ; format 16.16
+
+
+.glyph_size_ok:
+
+ stdcall AddArrayItems, edi, 1
+ mov edi, edx
+ mov dword [eax+TTextChar.width], ecx
+ mov [eax+TTextChar.code], ebx
+ jmp .char_loop
+
+.end:
+ clc
+
+.finish:
+ mov [esp+4*regEAX], edi
+
+ mov eax, [.miny]
+ neg eax
+ mov ecx, [.maxy]
+
+ mov [esp+4*regEDX], eax
+ mov [esp+4*regECX], ecx
+
+ add ecx, eax
+ mov [edi+TArray.lparam], ecx
+
+ popad
+ return
+endp
+
+
+
+; Returns an array with the widths from the begining of the text to the every character inside the string.
+
+
+proc GetTextWidthsArray, .hString, .font
+
+ .scaler FTC_ScalerRec
+ .glyph dd ?
+
+ .x dd ?
+
+begin
+ pushad
+
+ mov edx, [.font]
+ xor ecx, ecx
+
+ mov [.scaler.face_id], edx
+ mov [.scaler.width], ecx
+
+ mov eax, [edx+__TFont.height]
+ inc ecx
+
+ mov [.scaler.height], eax
+ mov [.scaler.pixel], ecx ; ecx = 1
+
+
+ stdcall StrPtr, [.hString]
+ mov esi, eax
+
+ stdcall CreateArray, 4
+ mov edi, eax
+
+ xor ebx, ebx
+
+.char_loop:
+ stdcall DecodeUtf8, [esi]
+ jc .finish
+
+ add esi, edx
+ test eax, eax
+ jz .end
+
+ cinvoke FTC_CMapCache_Lookup, [FTCCMapCache], [.font], -1, eax
+
+ lea ecx, [.scaler]
+ lea edx, [.glyph]
+ cinvoke FTC_ImageCache_LookupScaler, [FTCImageCache], ecx, [flagFreeTypeLoadFlags], eax, edx, 0
+
+ test eax, eax
+ jnz .glyph_size_ok ; zero width glyph ????
+
+
+ mov ecx, [.glyph]
+ mov ecx, [ecx+FT_BitmapGlyphRec.root.advance.x] ; format 16.16 fixed decimal point.
+
+ add ebx, ecx
+
+
+.glyph_size_ok:
+
+ stdcall AddArrayItems, edi, 1
+ mov edi, edx
+
+ mov edx, ebx
+ sar edx, 16 ; format 16.16
+ mov [eax], edx
+ jmp .char_loop
+
+.end:
+ clc
+
+.finish:
+ mov [esp+4*regEAX], edi
+ popad
+ return
+
+.error:
+ stc
+ popad
+ return
+endp
+
+
+
+
+
+
+
+
+
+
+
+; Computes the width and height of the text.
+;
+; Arguments:
+; .pString - pointer to a UTF-8 string.
+; .len - how many bytes from the string to be used. If -1 the whole string will be scanned.
+; .font - the font to be used for the computations.
+;
+; Returns:
+; EAX - the width of the string in pixels.
+; EBX - the ascender of the string. It is negative.
+; EDX - the height of the string in pixels.
+
+
+body GetTextBounds ;, .pString, .len, .font
+
+.scaler FTC_ScalerRec
+.glyph dd ?
+
+.x dd ?
+
+.miny dd ?
+.maxy dd ?
+
+.charlen dd ?
+
+begin
+ pushad
+
+ mov edx, [.font]
+ xor ecx, ecx
+
+ mov [.scaler.face_id], edx
+ mov [.scaler.width], ecx
+
+ mov [.x], ecx
+
+ mov eax, [edx+__TFont.height]
+ inc ecx
+
+ mov [.scaler.height], eax
+ mov [.scaler.pixel], ecx ; ecx = 1
+
+ ror ecx, 1 ; ecx = $80000000
+ mov [.maxy], ecx
+ dec ecx
+ mov [.miny], ecx ; ecx = $7fffffff
+
+ mov esi, [.pString]
+
+.char_loop:
+ stdcall DecodeUtf8, [esi]
+ jc .finish
+
+ add esi, edx
+ mov [.charlen], edx
+
+ test eax, eax
+ jz .finish
+
+ cinvoke FTC_CMapCache_Lookup, [FTCCMapCache], [.font], -1, eax
+
+ lea ecx, [.scaler]
+ lea edx, [.glyph]
+ cinvoke FTC_ImageCache_LookupScaler, [FTCImageCache], ecx, [flagFreeTypeLoadFlags], eax, edx, 0
+
+ test eax, eax
+ jnz .char_loop
+
+ mov ebx, [.glyph]
+
+ sub eax, [ebx+FT_BitmapGlyphRec.top] ; eax = 0 here
+ mov edx, eax
+ add edx, [ebx+FT_BitmapGlyphRec.bitmap.rows]
+
+ cmp eax, [.miny]
+ jge @f
+ mov [.miny], eax
+@@:
+ cmp edx, [.maxy]
+ jle @f
+ mov [.maxy], edx
+@@:
+
+ mov eax, [ebx+FT_GlyphRec.advance.x]
+ sar eax, 16 ; format 16.16 fixed decimal point.
add [.x], eax
- jmp .char_loop
+ mov eax, [.charlen]
+ sub [.len], eax
+ ja .char_loop
.finish:
- mov edx, [.size]
mov eax, [.x]
- mov edx, [edx+FT_SizeRec.metrics.height]
- sar eax, 6
- sar edx, 6
+ mov edx, [.maxy]
+ mov ebx, [.miny]
+ sub edx, ebx
mov [esp+4*regEAX], eax
+ mov [esp+4*regEBX], ebx
mov [esp+4*regEDX], edx
+
popad
return
endp
-proc DrawGlyph, .pImage, .pFTBitmap, .x, .y, .color
+
+
+
+
+proc __DrawGlyph, .pImage, .pFTBitmap, .x, .y, .color
.spitch dd ?
.dpitch dd ?
.drect RECT
.srect RECT
@@ -270,10 +549,13 @@
.bpp dd ?
.bit_ofs dd ?
begin
pushad
+
+ stdcall __fix_color, [.color], regEAX
+ mov [.color], eax
mov ebx, [.pImage]
mov edi, [.pFTBitmap]
; the glyph pixel mode handling.
@@ -456,91 +738,87 @@
jmp .nexty
.loopx8:
- movzx eax, byte [esi] ; source alpha
- inc esi
- movzx ecx, byte [.color+3] ; color alpha
-
- imul eax, ecx
- shr eax, 8
-
- mov ecx, [.color]
- bswap ecx
- mov cl, al
- bswap ecx
-
- movd mm7, ecx ; source pixel.
- movd mm6, [edi] ; destination pixel.
- movd mm5, eax ; alpha source
-
- punpckldq mm5, mm5 ;
+ movzx eax, byte [esi] ; intensity
+ add esi, 1
+
+ movd mm6, [.color]
+ movd mm7, eax
+
+ punpcklbw mm6, mm0 ; byte to word color.
+ punpckldq mm7, mm7 ;
+ packssdw mm7, mm7 ; mm7 = I, I, I, I
+
+ pmullw mm7, mm6 ; mm7 is the color to blend = Cs*256
+
+ movd mm6, [edi] ; Destination color
punpcklbw mm6, mm0 ; byte to word destination pixel
+
+ movq mm5, mm7
+ psrlq mm5, 56 ; alpha source
+ punpckldq mm5, mm5
packssdw mm5, mm5 ; mm5 = As, As, As, As
- punpcklbw mm7, mm0 ; byte to word source pixel
movq mm4, mm1
psubw mm4, mm5 ; mm4 = Bs Bs Bs Bs (Bs = $100 - As)
- psrlq mm5, 16 ; mm5 = 0 As As As
- por mm5, mm2 ; mm5 = $100 As As As
-
- pmullw mm6, mm4 ; mm6 = Cd = Cd * (256-As) = Cd * Bs (For alpha Ad = Ad*Bs)
- pmullw mm7, mm5 ; Cs = Cs * As (For alpha As = $100*As )
-
- paddusw mm6, mm7 ; Cd = Cs + Cd (For alpha Ad = $100*As + Ad*Bs)
- psrlw mm6, 8 ; Cd = Cd/256 (For alpha Ad = As + Ad*Bs/$100)
-
- packuswb mm6, mm0
- movd [edi], mm6
+ pmullw mm6, mm4 ; mm6 = Cd = Cd * (256-As) = Cd * Bs
+ paddusw mm6, mm7 ; Cd = 256*Cs + Cd*(256-As)
+ psrlw mm6, 8 ; Cd = Cd/256
+
+ packuswb mm6, mm0 ; pack words to bytes 0A 0R 0G 0B -> 0000ARGB
+ movd [edi], mm6
+
add edi, 4
dec [.xsize]
jnz .loopx8
jmp .nexty
.loopx24:
- movzx ecx, byte [.color+3] ; color alpha.
-
- mov eax, [esi] ; source alpha As, As, As
- or eax, $ff000000 ; eax = $ff Ar Ag Ab
- add esi, 3
-
- movd mm5, ecx ; mm5 = 00 00 00 00 00 00 00 Ac
- movd mm6, eax ; mm6 = 00 00 00 00 ff Ar Ag Ab
-
- punpckldq mm5, mm5 ;
- punpcklbw mm6, mm0 ; mm6 = ff Ar Ag Ab ; byte to word source alpha.
- packssdw mm5, mm5 ; mm5 = Ac Ac Ac Ac
-
- pmullw mm5, mm6
- psrlw mm5, 8 ; mm5 = Ac, Ac*Ar, Ac*Ag, Ac*Ab ; total alpha.
-
- movd mm6, [edi] ; destination pixel.
- movd mm7, [.color] ; source pixel.
-
+
+ movzx eax, byte [esi]
+ movzx edx, byte [esi+1]
+
+ lea eax, [eax+2*edx]
+ movzx edx, byte [esi+2]
+
+ add eax, edx
+ shr eax, 2 ; grayscale.
+
+ movd mm6, [.color]
+ movd mm7, eax
+
+ punpcklbw mm6, mm0 ; byte to word color.
+ punpckldq mm7, mm7 ;
+ packssdw mm7, mm7 ; mm7 = I, I, I, I
+
+ pmullw mm7, mm6 ; mm7 is the color to blend = Cs*256
+
+ movd mm6, [edi] ; Destination color
punpcklbw mm6, mm0 ; byte to word destination pixel
- punpcklbw mm7, mm0 ; byte to word source pixel
+
+ movq mm5, mm7
+ psrlq mm5, 56 ; alpha source
+ punpckldq mm5, mm5
+ packssdw mm5, mm5 ; mm5 = As, As, As, As
movq mm4, mm1
psubw mm4, mm5 ; mm4 = Bs Bs Bs Bs (Bs = $100 - As)
- psllq mm5, 16 ; mm5 = Ac*Ar Ac*Ag Ac*Ab 0
- psrlq mm5, 16 ; mm5 = 0 Ac*Ar Ac*Ag Ac*Ab
- por mm5, mm2 ; mm5 = $100 Ac*Ar Ac*Ag Ac*Ab
-
- pmullw mm6, mm4 ; mm6 = Cd = Cd * (256-As) = Cd * Bs (For alpha Ad = Ad*Bs)
- pmullw mm7, mm5 ; Cs = Cs * As (For alpha As = $100*As )
-
- paddusw mm6, mm7 ; Cd = Cs + Cd (For alpha Ad = $100*As + Ad*Bs)
- psrlw mm6, 8 ; Cd = Cd/256 (For alpha Ad = As + Ad*Bs/$100)
-
- packuswb mm6, mm0
-
- movd [edi], mm6
+ pmullw mm6, mm4 ; mm6 = Cd = Cd * (256-As) = Cd * Bs
+ paddusw mm6, mm7 ; Cd = 256*Cs + Cd*(256-As)
+ psrlw mm6, 8 ; Cd = Cd/256
+
+ packuswb mm6, mm0 ; pack words to bytes 0A 0R 0G 0B -> 0000ARGB
+ movd [edi], mm6
+
+
+ add esi, 3
add edi, 4
dec [.xsize]
jnz .loopx24
jmp .nexty
@@ -591,395 +869,81 @@
dec [.srect.bottom] ; height
jnz .loopy
.finish:
+ emms
popad
return
.bpp_const db 0, 1, 8, 2, 4, 24, 8, 32
endp
-proc GetTextBounds2, .hString, .font
-
-.type FTC_ImageType
-.scaler FTC_ScalerRec
-.size dd ?
-.face dd ?
-
-.glyph dd ?
-.prev dd ?
-.kerning FT_Vector
-
-.x dd ?
-
+; the colors must be pre-multiplied ARGB.
+
+proc _BlendPixel, .dstColor, .srcColor
begin
pushad
- mov edx, [.font]
- xor ecx, ecx
-
- mov [.x], ecx
- mov [.prev], ecx
-
- mov [.scaler.face_id], edx
- mov [.type.face_id], edx
-
- mov eax, [edx+__TFont.height]
- mov [.scaler.height], eax
- mov [.type.height], eax
- mov [.scaler.width], ecx
- mov [.type.width], ecx
-
- mov [.scaler.pixel], 1
- mov [.type.flags], FT_LOAD_RENDER or FT_LOAD_TARGET_LCD or FT_LOAD_COLOR
-
- lea eax, [.scaler]
- lea edx, [.size]
- cinvoke FTC_Manager_LookupSize, [FTCManager], eax, edx
-
- mov eax, [.size]
- mov eax, [eax+FT_SizeRec.face]
- mov [.face], eax
-
- stdcall StrPtr, [.hString]
- mov esi, eax
-
-.char_loop:
- stdcall DecodeUtf8, [esi]
- jc .finish
-
- add esi, edx
-
- test eax, eax
- jz .finish
-
- cinvoke FTC_CMapCache_Lookup, [FTCCMapCache], [.font], -1, eax
-
- mov ebx, eax
-
-; process the kerning;
-
- cmp [.prev], 0
- je .kerning_ok
-
- lea eax, [.kerning]
- cinvoke FT_Get_Kerning, [.face], [.prev], ebx, 0, eax
- test eax, eax
- jnz .kerning_ok
-
- mov eax, [.kerning.x]
- add [.x], eax
-
-.kerning_ok:
- mov [.prev], ebx
-
- lea ecx, [.type]
- lea edx, [.glyph]
- cinvoke FTC_ImageCache_Lookup, [FTCImageCache], ecx, ebx, edx, 0
-
- test eax, eax
- jnz .char_loop
-
- mov ebx, [.glyph]
-
- mov eax, [ebx+FT_GlyphRec.advance.x]
- sar eax, 10 ; format 16.16 fixed decimal point.
- add [.x], eax
-
- jmp .char_loop
-
-
-.finish:
- mov edx, [.size]
- mov eax, [.x]
- mov edx, [edx+FT_SizeRec.metrics.height]
- sar eax, 6
- sar edx, 6
-
- mov [esp+4*regEAX], eax
- mov [esp+4*regEDX], edx
+ movzx ecx, byte [.srcColor+3] ; As
+ mov ebx, $ff
+ mov esi, ebx
+
+ sub ebx, ecx ; 1 - As
+
+ movzx eax, byte [.dstColor+3] ; Ad
+ imul ecx, esi
+ mul ebx
+ add eax, ecx
+ adc edx, 0
+ div esi
+
+ mov byte [esp+4*regEAX+3], al
+
+
+ movzx eax, byte [.dstColor] ; Bd
+ movzx ecx, byte [.srcColor] ; Bs
+
+ imul ecx, esi
+ mul ebx
+ add eax, ecx
+ adc edx, 0
+ div esi
+
+ mov byte [esp+4*regEAX], al
+
+
+
+ movzx eax, byte [.dstColor+1] ; Gd
+ movzx ecx, byte [.srcColor+1] ; Gs
+
+ imul ecx, esi
+ mul ebx
+ add eax, ecx
+ adc edx, 0
+ div esi
+
+ mov byte [esp+4*regEAX+1], al
+
+
+
+ movzx eax, byte [.dstColor+2] ; Rd
+ movzx ecx, byte [.srcColor+2] ; Rs
+
+ imul ecx, esi
+ mul ebx
+ add eax, ecx
+ adc edx, 0
+ div esi
+
+ mov byte [esp+4*regEAX+2], al
+
popad
return
endp
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-proc __ColorToRender, .color, .rendercolor
-begin
- push eax ecx edx
-
- mov edx, [.rendercolor]
-
- xor eax, eax
- xor ecx, ecx
- dec eax
- dec ecx
-
- mov ah, byte [.color]
- mov ch, byte [.color+1]
-
- mov [edx+_XftColor.color.blue], ax
- mov [edx+_XftColor.color.green], cx
-
- mov ah, byte [.color+2]
- mov ch, byte [.color+3]
- mov [edx+_XftColor.color.red], ax
- mov [edx+_XftColor.color.alpha], cx
-
- pop edx ecx eax
- return
-endp
-
-
-
-proc DrawString, .context, .ptrString, .len, .x, .y, .font, .color
- .cltxt _XftColor
- .vis XVisualInfo
-begin
- push eax ebx ecx edx esi edi
-
- cmp [.font], 0
- jne @f
-
- mov eax, [_SystemFont]
- mov [.font], eax
-
-@@:
- cinvoke XDefaultScreen, [hApplicationDisplay]
- mov edx, eax
- lea eax, [.vis]
- cinvoke XMatchVisualInfo, [hApplicationDisplay], edx, $20, TrueColor, eax
-
- mov ecx, [.context]
- cinvoke XftDrawCreate, [hApplicationDisplay], [ecx+TContext.raster], [.vis.Visual], 0
- mov ebx, eax
-
- mov ecx, [.context]
- cinvoke XftDrawSetClip, ebx, [ecx+TContext.clipregion]
-
- lea eax, [.cltxt]
- stdcall __ColorToRender, [.color], eax
-
- cinvoke XftDrawStringUtf8, ebx, eax, [.font], [.x], [.y], [.ptrString], [.len]
- cinvoke XftDrawDestroy, ebx
-
- pop edi esi edx ecx ebx eax
- return
-endp
-
-
-
-
-proc DrawStringOpaque, .context, .ptrString, .len, .x, .y, .font, .color, .background
- .cltxt _XftColor
- .vis XVisualInfo
-begin
- push eax ebx ecx edx esi edi
-
- cmp [.font], 0
- jne @f
-
- mov eax, [_SystemFont]
- mov [.font], eax
-
-@@:
- cinvoke XDefaultScreen, [hApplicationDisplay]
- mov edx, eax
- lea eax, [.vis]
- cinvoke XMatchVisualInfo, [hApplicationDisplay], edx, $20, TrueColor, eax
-
- mov ecx, [.context]
- cinvoke XftDrawCreate, [hApplicationDisplay], [ecx+TContext.raster], [.vis.Visual], 0
- mov ebx, eax
-
- mov ecx, [.context]
- cinvoke XftDrawSetClip, ebx, [ecx+TContext.clipregion]
-
- lea eax, [.cltxt]
- stdcall __ColorToRender, [.color], eax
-
- cinvoke XftDrawStringUtf8, ebx, eax, [.font], [.x], [.y], [.ptrString], [.len]
- cinvoke XftDrawDestroy, ebx
-
- pop edi esi edx ecx ebx eax
- return
-endp
-
-
-
-proc DrawColoredString, .context, .ptrString, .pCharAttr, .str_len_bytes, .x, .y, .char_offs, .fontwidth, .fontheight
-.xbeg dd ?
-.cltxt _XftColor
-.char dd ?
-.height dd ?
-.offs dd ?
-.skip dd ?
-
-.vis XVisualInfo
-begin
- push eax ebx ecx edx esi edi
-
- mov esi, [.pCharAttr]
-
- mov eax, [.x]
- mov [.xbeg], eax
-
- cinvoke XDefaultScreen, [hApplicationDisplay]
- mov edx, eax
- lea eax, [.vis]
- cinvoke XMatchVisualInfo, [hApplicationDisplay], edx, $20, TrueColor, eax
-
- mov ecx, [.context]
- cinvoke XftDrawCreate, [hApplicationDisplay], [ecx+TContext.raster], [.vis.Visual], 0
- mov ebx, eax
-
- mov ecx, [.context]
- cinvoke XftDrawSetClip, ebx, [ecx+TContext.clipregion]
-
- lea edi, [.cltxt]
-
- stdcall GetTextBounds, [.context], __HeightProbeString, __HeightProbeString.length, [esi+TCharAttr.font]
- mov [.height], edx
-
- stdcall GetTextOffset, [.context], __HeightProbeString, __HeightProbeString.length, [esi+TCharAttr.font]
- mov [.offs], edx
-
-.skip_offset:
- mov ecx, [.char_offs]
- mov [.skip], ecx
-
-.drawloop:
- cmp [.str_len_bytes], 0
- jle .enddraw
-
- mov ecx, [.ptrString]
- stdcall DecodeUtf8, [ecx]
- mov [.char], edx
-
- cmp eax, $01 ; word wrap character
- je .wrapline
-
- cmp [.skip], 0
- jg .drawok
-
-; mov ecx, [.y]
-; sub ecx, [.offs]
-; sub ecx, 2
-; stdcall DrawFillRect, [.context], [.x], ecx, [.fontwidth], [.height], [esi+TCharAttr.backbround]
-
- stdcall __ColorToRender, [esi+TCharAttr.color], edi
- cinvoke XftDrawStringUtf8, ebx, edi, [esi+TCharAttr.font], [.x], [.y], [.ptrString], [.char]
-
- mov eax, [.fontwidth]
- add [.x], eax
-; sub [.width], eax
-; js .enddraw
-
-.drawok:
- dec [.skip]
- mov eax, [.char]
- add [.ptrString], eax
- sub [.str_len_bytes], eax
-
- add esi, sizeof.TCharAttr
- jne .drawloop
-
-.enddraw:
- cinvoke XftDrawDestroy, ebx
- pop edi esi edx ecx ebx eax
- return
-
-.wrapline:
- mov eax, [.fontheight]
- add [.y], eax
- mov eax, [.xbeg]
- mov [.x], eax
-
- mov eax, [.char]
- add [.ptrString], eax
- sub [.str_len_bytes], eax
-
- add esi, sizeof.TCharAttr
- jmp .skip_offset
-
-endp
-
-
-
-
-
-
-
-; returns:
-; eax - width of the string in pixels.
-; edx - heigth of the string in pixels.
-
-
-proc GetTextBounds, .context, .ptrString, .len, .font
-.extents _XGlyphInfo
-begin
- push esi ecx
-
- cmp [.font], 0
- jne @f
-
- mov eax, [_SystemFont]
- mov [.font], eax
-
-@@:
- lea esi, [.extents]
- cinvoke XftTextExtentsUtf8, [hApplicationDisplay], [.font], [.ptrString], [.len], esi
-
- movzx eax, [esi+_XGlyphInfo.xOff]
- movzx edx, [esi+_XGlyphInfo.height]
- add edx, 2
-
- pop ecx esi
- return
-endp
-
-
-; returns:
-; eax - x offset of the baseline of the string.
-; edx - y offset of the baseline of the string.
-
-proc GetTextOffset, .context, .ptrString, .len, .font
-.extents _XGlyphInfo
-begin
- push esi ecx
-
- cmp [.font], 0
- jne @f
-
- mov eax, [_SystemFont]
- mov [.font], eax
-
-@@:
- lea esi, [.extents]
- cinvoke XftTextExtentsUtf8, [hApplicationDisplay], [.font], [.ptrString], [.len], esi
-
- movzx eax, [esi+_XGlyphInfo.x]
- movzx edx, [esi+_XGlyphInfo.y]
- add edx, 2
-
- pop ecx esi
- return
-endp
DELETED freshlib/graphics/Win32/backbuffer.asm
Index: freshlib/graphics/Win32/backbuffer.asm
==================================================================
--- freshlib/graphics/Win32/backbuffer.asm
+++ /dev/null
@@ -1,118 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "BSD 2-clause" license." |
-;|_______________________________________________________________________________________|
-;
-; Description: Provides raster bitmap, to be used for double buffer painting.
-;
-; Target OS: Win32
-;
-; Dependencies:
-;
-; Notes:
-;_________________________________________________________________________________________
-
-
-
-proc CreateBackBuffer, .hwin, .width, .height
-begin
- push ebx ecx edx
-
- stdcall GetMem, sizeof.TBackBuffer
- mov ebx, eax
-
- mov ecx, [.width]
- mov edx, [.height]
-
- test ecx, ecx
- jns @f
- xor ecx, ecx
-@@:
- test edx, edx
- jns @f
- xor edx, edx
-@@:
- mov [ebx+TBackBuffer.width], ecx
- mov [ebx+TBackBuffer.height], edx
-
- invoke GetDC, [.hwin]
- push eax
- invoke CreateCompatibleBitmap, eax, [ebx+TBackBuffer.width], [ebx+TBackBuffer.height]
- mov [ebx+TBackBuffer.raster], eax
-
- invoke ReleaseDC, [.hwin] ; from the stack
-
- mov eax, ebx
- pop edx ecx ebx
- return
-endp
-
-
-
-proc DestroyBackBuffer, .pBackBuffer
-begin
- push eax ecx edx
- mov eax, [.pBackBuffer]
- push eax
- invoke DeleteObject, [eax+TBackBuffer.raster]
- stdcall FreeMem ; from the stack
- pop edx ecx eax
- return
-endp
-
-
-
-proc DrawBackBuffer, .context, .pBackBuffer, .x, .y
-begin
- push eax ecx edx esi edi
- mov esi, [.pBackBuffer]
-
- stdcall AllocateContext, [esi+TBackBuffer.raster]
- jc .exit
- mov edi, eax
-
- mov ecx, [.context]
- invoke BitBlt, [ecx+TContext.handle], [.x], [.y], [esi+TBackBuffer.width], [esi+TBackBuffer.height], [edi+TContext.handle], 0, 0, SRCCOPY
-
- stdcall ReleaseContext, edi
-
-.exit:
- pop edi esi edx ecx eax
- return
-
-
-endp
-
-
-
-
-
-
-proc BackBufferToImage, .context, .backbuffer, .bpp
-.bi BITMAPINFOHEADER
-begin
- pushad
-
- mov esi, [.backbuffer]
- mov ebx, [.context]
-
- stdcall CreateImage, [esi+TBackBuffer.width], [esi+TBackBuffer.height], [.bpp]
- mov edi, eax
-
- mov [.bi.biSize], 40
- mov ecx, [esi+TBackBuffer.width]
- mov edx, [esi+TBackBuffer.height]
- mov [.bi.biWidth], ecx
- mov [.bi.biHeight], edx
- mov [.bi.biPlanes], 1
- mov ecx, [.bpp]
- mov [.bi.biBitCount], cx
- mov [.bi.biCompression], 0
-
- lea eax, [.bi]
- invoke GetDIBits, [ebx+TContext.handle], [esi+TBackBuffer.raster], 0, [esi+TBackBuffer.height], [edi+TImage.pData], eax, DIB_RGB_COLORS
-
- mov [esp+4*regEAX], edi
- popad
- return
-endp
DELETED freshlib/graphics/Win32/context.asm
Index: freshlib/graphics/Win32/context.asm
==================================================================
--- freshlib/graphics/Win32/context.asm
+++ /dev/null
@@ -1,303 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "BSD 2-clause" license." |
-;|_______________________________________________________________________________________|
-;
-; Description: Context is a object that represents drawing surface in FreshLib
-;
-; Target OS: Win32
-;
-; Dependencies:
-;
-; Notes:
-;_________________________________________________________________________________________
-
-uses user32, gdi32
-
-; Some of these constants are probably wrong!
-cmClear = R2_BLACK
-cmAnd = R2_MASKPEN
-cmAndReverse = R2_NOTMASKPEN
-cmCopy = R2_COPYPEN
-cmAndInverted = R2_MASKPENNOT
-cmNoOp = R2_NOP
-cmXor = R2_XORPEN
-cmOr = R2_MERGEPEN
-cmNor = R2_NOTMERGEPEN
-cmEquiv = R2_NOTXORPEN
-cmInvert = R2_NOT
-cmOrReverse = R2_MERGENOTPEN
-cmCopyInverted = R2_NOTCOPYPEN
-cmOrInverted = R2_NOTMERGEPEN
-cmNand = R2_NOTMASKPEN
-cmSet = R2_WHITE
-
-
-proc AllocateContext, .raster
-begin
- push ebx ecx edx
-
- stdcall GetMem, sizeof.TContext
- mov ebx, eax
-
- push [.raster]
- pop [ebx+TContext.raster]
-
- invoke IsWindow, [.raster]
- test eax, eax
- jz .not_window
-
- invoke GetDC, [.raster]
- mov [ebx+TContext.handle], eax
- test eax, eax
- jz .error
-
- invoke SaveDC, [ebx+TContext.handle]
-
-.exit_ok:
- mov eax, ebx
- pop edx ecx ebx
- clc
- return
-
-.not_window: ; then it must be handle to image bitmap...
- invoke GetObjectType, [.raster]
- cmp eax, OBJ_BITMAP
- jne .error
-
- invoke CreateCompatibleDC, 0
- mov [ebx+TContext.handle], eax
- test eax, eax
- jz .error
-
- invoke SaveDC, ebx
- invoke SelectObject, [ebx+TContext.handle], [.raster]
- jmp .exit_ok
-
-.error:
- stdcall FreeMem, ebx
- xor eax, eax
- pop edx ecx ebx
- stc
- return
-endp
-
-
-
-
-proc ReleaseContext, .context
-begin
- push eax ebx ecx edx
-
- mov ebx, [.context]
-
-; delete all selected objects...
- invoke GetCurrentObject, [ebx+TContext.handle], OBJ_PEN
- push eax
- invoke GetCurrentObject, [ebx+TContext.handle], OBJ_BRUSH
- push eax
- invoke GetCurrentObject, [ebx+TContext.handle], OBJ_FONT
- push eax
-
- invoke RestoreDC, [ebx+TContext.handle], -1
-
- invoke DeleteObject ; from the stack
- invoke DeleteObject ; from the stack
- invoke DeleteObject ; from the stack
-
- invoke GetObjectType, [ebx+TContext.handle]
- cmp eax, OBJ_MEMDC
- je .delete
-
- cmp eax, OBJ_DC
- je .release
-
- stc
-.exit:
- pop edx ecx ebx eax
- return
-
-.delete:
- invoke DeleteDC, [ebx+TContext.handle]
- jmp .free
-
-.release:
- invoke ReleaseDC, [ebx+TContext.raster] , [ebx+TContext.handle]
-
-.free:
- stdcall FreeMem, ebx
- clc
- jmp .exit
-endp
-
-
-
-proc SetDrawMode, .context, .mode
-begin
- push eax ebx ecx edx
- mov ebx, [.context]
- test ebx, ebx
- jz .finish
-
- push [.mode]
- pop [ebx+TContext.drawmode]
- invoke SetROP2, [ebx+TContext.handle], [.mode]
-
-.finish:
- pop edx ecx ebx eax
- return
-endp
-
-
-
-
-proc SetLineStyle, .context, .pLineStyle
-begin
- push eax ebx ecx edx esi
-
- mov ebx, [.pLineStyle]
- mov esi, [.context]
-
- mov eax, [ebx+TLineStyle.color]
- bswap eax ; FreshLib uses Linux type color - red in the MSB
- ror eax, 8
- xor eax, $ff000000
-
- mov edx, PS_SOLID
- cmp [ebx+TLineStyle.DashCount], 0
- je @f
- mov edx, PS_DOT
- mov [ebx+TLineStyle.width], 0
-@@:
- invoke CreatePen, edx, [ebx+TLineStyle.width], eax ;[ebx+TLineStyle.color]
- invoke SelectObject, [esi+TContext.handle], eax
- invoke DeleteObject, eax
-
- cmp [ebx+TLineStyle.DashCount], 0
- je .exit
-
- mov eax, [ebx+TLineStyle.clSpace]
- bswap eax ; FreshLib uses Linux type color - red in the MSB
- ror eax, 8
- xor eax, $ff000000
-
- invoke SetBkColor, [esi+TContext.handle], eax
- invoke SetBkMode, [esi+TContext.handle], OPAQUE
-
-
-.exit:
- pop esi edx ecx ebx eax
- return
-endp
-
-
-
-
-
-
-proc SetClipRectangle, .context, .pBounds
-begin
- push eax ebx ecx edx
-
- xor ebx, ebx
- mov edx, [.pBounds]
- test edx, edx
- jz .setit
-
- mov eax, [edx+TBounds.width]
- mov ecx, [edx+TBounds.height]
- add eax, [edx+TBounds.x]
- add ecx, [edx+TBounds.y]
- invoke CreateRectRgn, [edx+TBounds.x], [edx+TBounds.y], eax, ecx
- mov ebx, eax
-
-.setit:
- mov edx, [.context]
- invoke SelectClipRgn, [edx+TContext.handle], ebx
-
- test ebx, ebx
- jz .exit
- invoke DeleteObject, ebx
-.exit:
- pop edx ecx ebx eax
- return
-endp
-
-
-
-
-;proc SetLineStyle, .context, .pLineStyle
-;.brush LOGBRUSH
-;.width dd ?
-;.dashcount dd ?
-;.dashes rd 16
-;begin
-; push eax ebx ecx edx esi
-;
-; mov ebx, [.pLineStyle]
-; mov esi, [.context]
-;
-; mov ecx, [ebx+TLineStyle.DashCount]
-; cmp ecx, 16
-; jbe @f
-; mov ecx, 16
-;@@:
-; mov [.dashcount], ecx
-;
-;.dashloop:
-; dec ecx
-; js .enddash
-; movzx eax, byte [ebx+TLineStyle.DashItems+ecx]
-; mov [.dashes+4*ecx], eax
-; jmp .dashloop
-;
-;.enddash:
-; push [ebx+TLineStyle.width]
-; pop [.width]
-;
-; mov [.brush.lbStyle], BS_SOLID
-; mov eax, [ebx+TLineStyle.color]
-; bswap eax ; FreshLib uses Linux type color - red in the MSB
-; ror eax, 8
-;
-; mov [.brush.lbColor], eax
-;
-; mov edx, PS_SOLID
-; xor ecx, ecx
-; cmp [.dashcount], 0
-; je @f
-; mov edx, PS_USERSTYLE
-; lea ecx, [.dashes]
-;@@:
-;
-; or edx, PS_GEOMETRIC
-; cmp [.width], 0
-; jne @f
-; and edx, not PS_GEOMETRIC
-; inc [.width]
-;@@:
-; or edx, [ebx+TLineStyle.flags]
-; lea eax, [.brush]
-;
-; invoke ExtCreatePen, edx, [.width], eax, [.dashcount], ecx
-; invoke SelectObject, [esi+TContext.handle], eax
-;
-;
-; invoke SetBkMode, [esi+TContext.handle], OPAQUE
-;
-; mov eax, [ebx+TLineStyle.color]
-; cmp [ebx+TLineStyle.DashCount], 0
-; je @f
-; mov eax, [ebx+TLineStyle.clSpace]
-;@@:
-; bswap eax ; FreshLib uses Linux type color - red in the MSB
-; ror eax, 8
-;
-; invoke SetBkColor, [esi+TContext.handle], eax
-;
-; pop esi edx ecx ebx eax
-; return
-;endp
-;
-
-
Index: freshlib/graphics/Win32/fonts.asm
==================================================================
--- freshlib/graphics/Win32/fonts.asm
+++ freshlib/graphics/Win32/fonts.asm
@@ -11,28 +11,53 @@
;
; Notes:
;_________________________________________________________________________________________
-proc FontCreate, .fontface, .size, .weight, .flags
+iglobal
+ if used FontAttr.font_weights
+
+;fwLight = 0
+;fwDemilight = 1
+;fwNormal = 2
+;fwMedium = 3
+;fwDemibold = 4
+;fwBold = 5
+;fwExtraBold = 6
+;fwBlack = 7
+
+ FontAttr:
+ .font_weights dw FW_THIN, FW_EXTRALIGHT, FW_NORMAL, FW_MEDIUM, FW_SEMIBOLD, FW_BOLD, FW_EXTRABOLD, FW_HEAVY
+ end if
+endg
+
+
+
+body FontCreate
.pwc dd ?
begin
push ebx ecx edx esi edi
+ mov eax, [.weight]
+ and eax, 7
+ movzx eax, [FontAttr.font_weights+2*eax]
+
+ mov [.weight], eax
+
neg [.size]
- stdcall StrLen, [.fontface]
+ stdcall StrLen, [.font_name]
mov ebx, eax
- stdcall StrPtr, [.fontface]
- mov [.fontface], eax
+ stdcall StrPtr, [.font_name]
+ mov [.font_name], eax
lea ecx, [8*ebx]
stdcall GetMem, ecx
mov edi, eax
- invoke MultiByteToWideChar, CP_UTF8, 0, [.fontface], ebx, edi, ecx
+ invoke MultiByteToWideChar, CP_UTF8, 0, [.font_name], ebx, edi, ecx
mov eax, [.flags]
mov ebx, eax
mov ecx, eax
mov edx, eax
@@ -45,19 +70,77 @@
@@:
invoke CreateFontW, [.size], 0, 0, 0, [.weight], ebx, ecx, edx, \
DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, \
CLIP_DEFAULT_PRECIS, PROOF_QUALITY, eax, \
edi
+
+ if defined options.DebugMode & options.DebugMode
+ pushad
+ mov esi, eax
+
+ invoke CreateCompatibleDC, 0
+ mov ebx, eax
+
+ invoke SelectObject, ebx, esi
+ push eax
+
+ invoke GetTextFaceA, ebx, 1024, fontName
+
+ OutputLn fontName
+
+ invoke SelectObject, ebx ; from the stack
+ invoke DeleteObject, ebx
+
+ popad
+ end if
stdcall FreeMem, edi
pop edi esi edx ecx ebx
return
endp
+uglobal
+ if defined options.DebugMode & options.DebugMode
+ fontName rb 1024
+ end if
+endg
-proc FontDestroy, .font
+body FontDestroy
begin
push eax ecx edx
- invoke DeleteObject, [.font]
+ invoke DeleteObject, [.pFont]
pop edx ecx eax
return
-endp
+endp
+
+
+; returns some font metrics
+;
+; Arguments:
+; .font - the font
+; Returns:
+; EAX - the line height of the font.
+; EBX - the ascender of the font.
+; EDX - the descender of the font.
+
+body GetFontMetrics
+.tm TEXTMETRIC
+begin
+ invoke CreateCompatibleDC, 0
+ mov ebx, eax
+
+ invoke SelectObject, ebx, [.font]
+ push eax
+
+ lea eax, [.tm]
+ invoke GetTextMetricsW, ebx, eax
+
+ invoke SelectObject, ebx ; from the stack
+
+ invoke DeleteDC, ebx
+
+ mov eax, [.tm.tmHeight]
+ mov ebx, [.tm.tmAscent]
+ mov edx, [.tm.tmDescent]
+
+ return
+endp
Index: freshlib/graphics/Win32/images.asm
==================================================================
--- freshlib/graphics/Win32/images.asm
+++ freshlib/graphics/Win32/images.asm
@@ -10,11 +10,11 @@
; Dependencies: memory.asm
;
; Notes:
;_________________________________________________________________________________________
-uses msimg32
+uses msimg32, gdi32
struct TImage
.width dd ? ; width in pixels.
.height dd ? ; height in pixels.
@@ -24,57 +24,62 @@
.hBitmap dd ?
ends
-; only 16, 24 and 32 bpp are supported.
-; It is stupid to support palleted modes and even 24bpp is not good...
body CreateImage
-.bmi BITMAPINFOHEADER
+ .bmi BITMAPV4HEADER
begin
pushad
stdcall GetMem, sizeof.TImage
jc .finish
+
mov esi, eax
xor eax, eax
lea edi, [.bmi]
- mov ecx, sizeof.BITMAPINFOHEADER/4
+ mov ecx, sizeof.BITMAPV4HEADER/4
rep stosd
inc eax
mov ecx, [.width]
mov edx, [.height]
- test ecx, ecx
- cmovz ecx, eax
+ cmp ecx, 0
+ cmovle ecx, eax
- test edx, edx
- cmovz edx, eax
+ cmp edx, 0
+ cmovle edx, eax
mov [esi+TImage.width], ecx
mov [esi+TImage.height], edx
- mov [.bmi.biSize], sizeof.BITMAPINFOHEADER
- mov [.bmi.biPlanes], ax
+ mov [.bmi.biSize], sizeof.BITMAPV4HEADER
+ mov [.bmi.biPlanes], 1
; it is already 0
; mov [.bmi.biCompression], BI_RGB
; mov [.bmi.biSizeImage], 0
; mov [.bmi.biClrUsed], 0
; mov [.bmi.biClrImportant], 0
+ mov [.bmi.BlueMask], $000000ff
+ mov [.bmi.GreenMask], $0000ff00
+ mov [.bmi.RedMask], $00ff0000
+ mov [.bmi.AlphaMask], $ff000000
+
mov [.bmi.biBitCount], 32
neg edx
mov [.bmi.biWidth], ecx
mov [.bmi.biHeight], edx
- lea ecx, [esi+TImage.pPixels]
lea eax, [.bmi]
- invoke CreateDIBSection, 0, eax, DIB_RGB_COLORS, ecx, 0, 0
+ lea ecx, [esi+TImage.pPixels]
+ xor edx, edx
+ invoke CreateDIBSection, edx, eax, DIB_RGB_COLORS, ecx, edx, edx
mov [esi+TImage.hBitmap], eax
clc
mov [esp+4*regEAX], esi
@@ -89,12 +94,15 @@
push eax ecx edx esi
mov esi, [.ptrImage]
cmp esi, 0
je @f
+
+ invoke GdiFlush
invoke DeleteObject, [esi+TImage.hBitmap]
stdcall FreeMem, esi
+
@@:
pop esi edx ecx eax
return
endp
@@ -108,103 +116,92 @@
; .BlendFlags db ?
; .SourceConstantAlpha db ?
; .AlphaFormat db ?
;ends
-body DrawImage
+body DrawImageRect
begin
push eax ecx edx esi edi
+
mov esi, [.pImage]
test esi, esi
jz .exit
- stdcall AllocateContext, [esi+TImage.hBitmap]
- jc .exit
- mov edi, eax
-
- mov ecx, [.context]
- mov eax, [ecx+TContext.drawmode]
- dec eax
- and eax, $0f
-
-
-; invoke AlphaBlend, [ecx+TContext.handle], [.x], [.y], [esi+TImage.width], [esi+TImage.height], [edi+TContext.handle], 0, 0, [esi+TImage.width], [esi+TImage.height], $01ff0000
- invoke BitBlt, [ecx+TContext.handle], [.x], [.y], [esi+TImage.width], [esi+TImage.height], [edi+TContext.handle], 0, 0, [4*eax+__RopTable]
-
- stdcall ReleaseContext, edi
+ invoke CreateCompatibleDC, 0
+ mov ebx, eax
+
+ invoke SelectObject, ebx, [esi+TImage.hBitmap]
+ push eax
+
+ invoke BitBlt, [.where], [.xDst], [.yDst], [.width], [.height], ebx, [.xSrc], [.ySrc], SRCCOPY
+
+ invoke SelectObject, ebx ; from the stack
+ invoke DeleteDC, ebx
.exit:
pop edi esi edx ecx eax
return
endp
-; NEEDS some edit to fill the zeroes.
-
-if used __RopTable
-__RopTable dd BLACKNESS, PATPAINT, 0, NOTSRCCOPY, \
- 0, DSTINVERT, SRCINVERT, SRCERASE, \
- SRCAND, 0, 0, 0, \
- SRCCOPY, MERGEPAINT, SRCPAINT, WHITENESS
-end if
-
-
-
-body DrawText
-.pwc dd ?
-.pwl dd ?
-.buffer rb 256
-.charlen dd ?
-begin
- push eax ebx ecx edx
-
-; first convert the string:
- lea eax, [.buffer]
- mov ecx, [.len]
- shl ecx, 3
- cmp ecx, $100
- jbe @f
-
- stdcall GetMem, ecx
-
-@@:
- mov [.pwl], ecx
- mov [.pwc], eax
-
- invoke MultiByteToWideChar, CP_UTF8, 0, [.text], [.len], [.pwc], ecx
- mov [.charlen], eax
-
-
- mov ebx, [.pImage]
- stdcall AllocateContext, [ebx+TImage.hBitmap]
- mov ebx, eax
-
- cmp [.font], 0
- jne @f
-
- invoke GetStockObject, DEFAULT_GUI_FONT
- mov [.font], eax
-
-@@:
- invoke SelectObject, [ebx+TContext.handle], [.font]
- push eax
-
- invoke SetBkMode, [ebx+TContext.handle], TRANSPARENT
- invoke SetTextAlign, [ebx+TContext.handle], TA_NOUPDATECP or TA_LEFT or TA_BASELINE
-
- mov eax, [.color]
- bswap eax
- ror eax, 8
- invoke SetTextColor, [ebx+TContext.handle], eax
- invoke TextOutW, [ebx+TContext.handle], [.x], [.y], [.pwc], [.charlen]
-
- invoke SelectObject, [ebx+TContext.handle] ; old font from the stack.
-
- cmp [.pwl], $100
- jbe @f
- stdcall FreeMem, [.pwc]
-@@:
- stdcall ReleaseContext, ebx
-
- pop edx ecx ebx eax
- return
-endp
+
+
+
+;body DrawText
+;.pwc dd ?
+;.pwl dd ?
+;.buffer rb 256
+;.charlen dd ?
+;begin
+; push eax ebx ecx edx
+;
+;; first convert the string:
+; lea eax, [.buffer]
+; mov ecx, [.len]
+; shl ecx, 3
+; cmp ecx, $100
+; jbe @f
+;
+; stdcall GetMem, ecx
+;
+;@@:
+; mov [.pwl], ecx
+; mov [.pwc], eax
+;
+; invoke MultiByteToWideChar, CP_UTF8, 0, [.text], [.len], [.pwc], ecx
+; mov [.charlen], eax
+;
+;
+; mov ebx, [.pImage]
+; stdcall AllocateContext, [ebx+TImage.hBitmap]
+; mov ebx, eax
+;
+; cmp [.font], 0
+; jne @f
+;
+; invoke GetStockObject, DEFAULT_GUI_FONT
+; mov [.font], eax
+;
+;@@:
+; invoke SelectObject, [ebx+TContext.handle], [.font]
+; push eax
+;
+; invoke SetBkMode, [ebx+TContext.handle], TRANSPARENT
+; invoke SetTextAlign, [ebx+TContext.handle], TA_NOUPDATECP or TA_LEFT or TA_BASELINE
+;
+; mov eax, [.color]
+; bswap eax
+; ror eax, 8
+; invoke SetTextColor, [ebx+TContext.handle], eax
+; invoke TextOutW, [ebx+TContext.handle], [.x], [.y], [.pwc], [.charlen]
+;
+; invoke SelectObject, [ebx+TContext.handle] ; old font from the stack.
+;
+; cmp [.pwl], $100
+; jbe @f
+; stdcall FreeMem, [.pwc]
+;@@:
+; stdcall ReleaseContext, ebx
+;
+; pop edx ecx ebx eax
+; return
+;endp
Index: freshlib/graphics/Win32/text.asm
==================================================================
--- freshlib/graphics/Win32/text.asm
+++ freshlib/graphics/Win32/text.asm
@@ -12,269 +12,478 @@
; Notes:
;_________________________________________________________________________________________
-proc DrawString, .context, .ptrString, .len, .x, .y, .font, .color
-.pwc dd ?
-.pwl dd ?
-.buffer rb 256
-.charlen dd ?
+
+body DrawDecomposedString ;, .pImage, .pArray, .x, .y, .font, .color
+
+.startX dd ?
+
+.old_font dd ?
+.old_bmp dd ?
+
+.img dd ?
+
+begin
+ pushad
+
+ mov eax, [.x]
+ mov [.startX], eax
+
+ stdcall GetFontMetrics, [.font]
+ sub [.y], ebx
+
+ mov ebx, [.pImage]
+ stdcall CreateImage, 100, 100
+ mov [.img], eax
+
+ invoke CreateCompatibleDC, 0
+ mov ebx, eax
+
+ mov eax, [.img]
+ invoke SelectObject, ebx, [eax+TImage.hBitmap]
+ mov [.old_bmp], eax
+
+ invoke SelectObject, ebx, [.font]
+ mov [.old_font], eax
+
+ invoke SetBkMode, ebx, TRANSPARENT
+ invoke SelectClipRgn, ebx, 0
+ invoke SetTextColor, ebx, $ffffff
+ invoke SetTextAlign, ebx, TA_TOP or TA_LEFT
+
+ mov esi, [.pArray]
+ xor edi, edi
+ dec edi
+
+.char_loop:
+ inc edi
+ cmp edi, [esi+TArray.count]
+ jae .finish
+
+ cmp word [esi+TArray.array+8*edi+TTextChar.width], 0
+ je .char_ok
+
+ movzx ecx, word [esi+TArray.array+8*edi+TTextChar.width]
+ stdcall DrawSolidRect, [.img], 0, 0, ecx, [esi+TArray.lparam], 0
+
+ lea eax, [esi+TArray.array+8*edi+TTextChar.code]
+ movzx ecx, word [esi+TArray.array+8*edi+TTextChar.width]
+ invoke ExtTextOutW, ebx, 0, 0, 0, 0, eax, 1, 0
+
+ movzx ecx, word [esi+TArray.array+8*edi+TTextChar.width]
+ stdcall __BlendAlphaMask, [.pImage], [.x], [.y], [.img], 0, 0, ecx, [esi+TArray.lparam], [.color]
+
+ movzx eax, word [esi+TArray.array+8*edi+TTextChar.width]
+ add [.x], eax
+
+.char_ok:
+; check for new line.
+ movzx eax, word [esi+TArray.array+8*edi+TTextChar.height]
+ test eax, eax
+ jz .char_loop
+
+ add [.y], eax
+ mov eax, [.startX]
+ mov [.x], eax
+ jmp .char_loop
+
+
+.finish:
+ invoke SelectObject, ebx, [.old_font]
+ invoke SelectObject, ebx, [.old_bmp]
+ invoke DeleteDC, ebx
+
+ stdcall DestroyImage, [.img]
+
+ popad
+ return
+endp
+
+
+
+
+body TextDecompose ;, .hString, .font
+
+ .miny dd ?
+ .maxy dd ?
+
+ .more dd ?
+ .string rd 2
+ .code dd ?
+
+ .size SIZE
+
+ .old_font dd ?
+
begin
- push eax ebx ecx edx
-
-; first convert the string:
- lea eax, [.buffer]
- mov ecx, [.len]
- shl ecx, 3
- cmp ecx, $100
- jbe @f
-
- stdcall GetMem, ecx
-
-@@:
- mov [.pwl], ecx
- mov [.pwc], eax
-
- invoke MultiByteToWideChar, CP_UTF8, 0, [.ptrString], [.len], [.pwc], ecx
- mov [.charlen], eax
-
- mov ebx, [.context]
-
- cmp [.font], 0
- jne @f
-
- invoke GetStockObject, DEFAULT_GUI_FONT
- mov [.font], eax
-
-@@:
- invoke SelectObject, [ebx+TContext.handle], [.font]
- push eax
-
- invoke SetBkMode, [ebx+TContext.handle], TRANSPARENT
- invoke SetTextAlign, [ebx+TContext.handle], TA_NOUPDATECP or TA_LEFT or TA_BASELINE
-
- mov eax, [.color]
- bswap eax
- ror eax, 8
- invoke SetTextColor, [ebx+TContext.handle], eax
- invoke TextOutW, [ebx+TContext.handle], [.x], [.y], [.pwc], [.charlen]
-
- invoke SelectObject, [ebx+TContext.handle] ; old font from the stack.
-
- cmp [.pwl], $100
- jbe @f
- stdcall FreeMem, [.pwc]
-@@:
- pop edx ecx ebx eax
+ pushad
+
+ invoke CreateCompatibleDC, 0
+ mov ebx, eax
+
+ invoke SelectClipRgn, ebx, 0
+ invoke SelectObject, ebx, [.font]
+ mov [.old_font], eax
+
+ xor ecx, ecx
+
+ mov [.string], ecx
+ mov [.string+4], ecx
+
+ inc ecx
+
+ ror ecx, 1 ; ecx = $80000000
+ mov [.maxy], ecx
+ dec ecx
+ mov [.miny], ecx ; ecx = $7fffffff
+
+
+ mov word [.string], '|'
+ mov word [.string+2], '|'
+
+ lea ecx, [.string]
+ lea eax, [.size]
+ invoke GetTextExtentPoint32W, ebx, ecx, 1, eax
+
+ mov eax, [.size.cx]
+ mov [.more], eax
+
+ stdcall StrPtr, [.hString]
+ mov esi, eax
+
+ stdcall CreateArray, sizeof.TTextChar
+ mov edi, eax
+
+.char_loop:
+
+ stdcall DecodeUtf8, [esi]
+ jc .finish
+
+ add esi, edx
+
+ test eax, eax
+ jz .end
+
+ mov [.code], eax
+ mov word [.string], ax
+
+ lea ecx, [.string]
+ lea eax, [.size]
+ invoke GetTextExtentPoint32W, ebx, ecx, 2, eax
+
+ stdcall AddArrayItems, edi, 1
+ mov edi, edx
+
+ mov ecx, [.size.cx]
+ sub ecx, [.more]
+
+ mov dword [eax+TTextChar.width], ecx
+ mov ecx, [.code]
+ mov [eax+TTextChar.code], ecx
+
+ jmp .char_loop
+
+.end:
+ clc
+
+.finish:
+ pushf
+ invoke SelectObject, ebx, [.old_font] ; old font from the stack.
+ invoke DeleteDC, ebx
+
+ stdcall GetFontMetrics, [.font]
+ popf
+
+ mov [esp+4*regEDX], ebx ; font ascent
+ mov [esp+4*regECX], edx ; font descent
+ mov [edi+TArray.lparam], eax ; line height
+
+ mov [esp+4*regEAX], edi
+
+ popad
return
endp
-proc DrawStringOpaque, .context, .ptrString, .len, .x, .y, .font, .color, .background
+
+;interface DrawString, .pImage, .pString, .len, .x, .y, .font, .color
+
+body DrawString ;, .pImage, .pString, .len, .x, .y, .font, .color
.pwc dd ?
-.pwl dd ?
-.buffer rb 256
.charlen dd ?
+
+.img dd ?
+.size SIZE
+
+.tm TEXTMETRIC
+
begin
push eax ebx ecx edx
-; first convert the string:
- lea eax, [.buffer]
+ invoke CreateCompatibleDC, 0
+ mov ebx, eax
+
+ invoke SelectObject, ebx, [.font]
+ push eax
+
+ invoke SetBkMode, ebx, TRANSPARENT
+ invoke SetTextAlign, ebx, TA_TOP or TA_LEFT
+ invoke SelectClipRgn, ebx, 0
+ invoke SetTextColor, ebx, $ffffff
+
+ lea eax, [.tm]
+ invoke GetTextMetricsW, ebx, eax
+
+ mov eax, [.tm.tmAscent]
+ sub [.y], eax
+
+; convert the string:
+
mov ecx, [.len]
shl ecx, 2
- cmp ecx, $100
- jbe @f
-
stdcall GetMem, ecx
-
-@@:
- mov [.pwl], ecx
mov [.pwc], eax
+ shr ecx, 1
- invoke MultiByteToWideChar, CP_UTF8, 0, [.ptrString], [.len], [.pwc], ecx
+ invoke MultiByteToWideChar, CP_UTF8, 0, [.pString], [.len], [.pwc], ecx
mov [.charlen], eax
- mov ebx, [.context]
-
- cmp [.font], 0
- jne @f
-
- invoke GetStockObject, DEFAULT_GUI_FONT
- mov [.font], eax
-
-@@:
- invoke SelectObject, [ebx+TContext.handle], [.font]
+ lea eax, [.size]
+ invoke GetTextExtentPoint32W, ebx, [.pwc], [.charlen], eax
+
+ stdcall CreateImage, [.size.cx], [.size.cy]
+ mov [.img], eax
+
+ invoke SelectObject, ebx, [eax+TImage.hBitmap]
push eax
- invoke SetBkMode, [ebx+TContext.handle], OPAQUE
- mov eax, [.background]
- bswap eax
- ror eax, 8
- invoke SetBkColor, [ebx+TContext.handle], eax
- invoke SetTextAlign, [ebx+TContext.handle], TA_NOUPDATECP or TA_LEFT or TA_BASELINE
-
- mov eax, [.color]
- bswap eax
- ror eax, 8
- invoke SetTextColor, [ebx+TContext.handle], eax
- invoke TextOut, [ebx+TContext.handle], [.x], [.y], [.pwc], [.charlen]
-
- invoke SelectObject, [ebx+TContext.handle] ; old font from the stack.
-
- cmp [.pwl], $100
- jbe @f
+ xor eax, eax
+ invoke ExtTextOutW, ebx, eax, eax, eax, eax, [.pwc], [.charlen], eax
+
+ invoke SelectObject, ebx ; old bitmap from the stack.
+ invoke SelectObject, ebx ; old font from the stack.
+ invoke DeleteDC, ebx
+
+ stdcall __BlendAlphaMask, [.pImage], [.x], [.y], [.img], 0, 0, [.size.cx], [.size.cy], [.color]
+
+ stdcall DestroyImage, [.img]
stdcall FreeMem, [.pwc]
-@@:
+
pop edx ecx ebx eax
return
endp
-proc DrawColoredString, .context, .ptrString, .pCharAttr, .str_len_bytes, .x, .y, .char_offs, .fontwidth, .fontheight
-.xbeg dd ?
-;.wbeg dd ?
-.pwc dd ?
-.charlen dd ?
-.point POINT
+
+proc __BlendAlphaMask, .pDstImage, .xDst, .yDst, .pSrcImage, .xSrc, .ySrc, .width, .height, .color
+.srect RECT
+.drect RECT
+.rect RECT
begin
- push eax ebx ecx edx esi edi
-
- mov eax, [.x]
-; mov ecx, [.width]
- mov [.xbeg], eax
-; mov [.wbeg], ecx
-
-; first convert the string:
- mov ecx, [.str_len_bytes]
+ pushad
+
+ stdcall __fix_color, [.color], regEAX
+ mov [.color], eax
+
+ mov esi, [.pSrcImage]
+ mov edi, [.pDstImage]
+
+ xor eax, eax
+ mov ecx, [esi+TImage.width]
+ mov edx, [esi+TImage.height]
+
+ mov [.srect.left], eax
+ mov [.srect.top], eax
+ mov [.srect.right], ecx
+ mov [.srect.bottom], edx
+
+ mov ecx, [edi+TImage.width]
+ mov edx, [edi+TImage.height]
+
+ mov [.drect.left], eax
+ mov [.drect.top], eax
+ mov [.drect.right], ecx
+ mov [.drect.bottom], edx
+
+ mov ecx, [.xSrc]
+ mov edx, [.ySrc]
+
+ mov [.rect.left], ecx
+ mov [.rect.top], edx
+
+ add ecx, [.width]
+ add edx, [.height]
+
+ mov [.rect.right], ecx
+ mov [.rect.bottom], edx
+
+ lea ecx, [.srect]
+ lea edx, [.rect]
+ stdcall RectIntersect, ecx, ecx, edx
+ jc .finish
+
+ mov ecx, [.xSrc]
+ mov edx, [.ySrc]
+ sub ecx, [.xDst]
+ sub edx, [.yDst]
+
+; convert the rect to the destination coordinates.
+ sub [.srect.left], ecx
+ sub [.srect.top], edx
+ sub [.srect.right], ecx
+ sub [.srect.bottom], edx
+
+ lea eax, [.srect]
+ lea ebx, [.drect]
+ stdcall RectIntersect, ebx, ebx, eax
+ jc .finish
+
+ stdcall RectCopy, eax, ebx ; srect = drect
+
+;convert back to source coordinates.
+ add [.srect.left], ecx
+ add [.srect.top], edx
+ add [.srect.right], ecx
+ add [.srect.bottom], edx
+
+; here [.srect] contains the source rectange
+; [.drect] contains the destination rectangle
+; the width and height of the rectangles is the same.
+
+ mov ecx, [.srect.left]
+ mov edx, [.srect.top]
+ sub [.srect.right], ecx
+ sub [.srect.bottom], edx
+
+ mov ecx, [.srect.top]
+ mov edx, [.drect.top]
+
+ imul ecx, [esi+TImage.width]
+ imul edx, [edi+TImage.width]
+
+ add ecx, [.srect.left]
+ add edx, [.drect.left]
+
shl ecx, 2
- stdcall GetMem, ecx
- mov esi, eax
- mov [.pwc], eax
-
- invoke MultiByteToWideChar, CP_UTF8, 0, [.ptrString], [.str_len_bytes], esi, ecx
- mov [.charlen], eax
-
- mov ebx, [.context]
- mov edi, [.pCharAttr]
-
- invoke SaveDC, [ebx+TContext.handle]
-
- invoke SetBkMode, [ebx+TContext.handle], TRANSPARENT
- invoke SetTextAlign, [ebx+TContext.handle], TA_LEFT or TA_BASELINE
-
-.skip_offset:
- mov ecx, [.char_offs]
-
-.offsloop:
- jecxz .loop
-
- lodsw
- add edi, sizeof.TCharAttr
- dec [.charlen]
- jz .endline
-
- dec ecx
- cmp eax, $01
- jne .offsloop
-
- mov eax, [.fontheight]
- add [.y], eax
- jmp .skip_offset
-
-.loop:
- cmp word [esi], $01
- je .wrapline
-
- mov eax, [edi+TCharAttr.font]
- test eax, eax
- jnz @f
-
- invoke GetStockObject, DEFAULT_GUI_FONT
-@@:
- invoke SelectObject, [ebx+TContext.handle], eax
- mov eax, [edi+TCharAttr.background]
- bswap eax
- ror eax, 8
- invoke SetBkColor, [ebx+TContext.handle], $ff0000
-
- mov eax, [edi+TCharAttr.color]
- bswap eax
- ror eax, 8
- invoke SetTextColor, [ebx+TContext.handle], eax
-
- invoke TextOutW, [ebx+TContext.handle], [.x], [.y], esi, 1
-
- mov eax, [.fontwidth]
- add [.x], eax
-; sub [.width], eax
-; jl .endline
-
-.nextchar:
- add esi, 2
- add edi, sizeof.TCharAttr
- dec [.charlen]
- jnz .loop
-
-.endline:
- invoke RestoreDC, [ebx+TContext.handle], -1
- stdcall FreeMem, [.pwc]
- pop edi esi edx ecx ebx eax
- return
-
-.wrapline:
- mov eax, [.fontheight]
- add [.y], eax
- mov eax, [.xbeg]
-; mov ecx, [.wbeg]
- mov [.x], eax
-; mov [.width], ecx
-
- add esi, 2
- add edi, sizeof.TCharAttr
- dec [.charlen]
- jnz .skip_offset
- jmp .endline
+ shl edx, 2
+
+ add ecx, [esi+TImage.pPixels]
+ add edx, [edi+TImage.pPixels]
+
+ mov esi, [esi+TImage.width]
+ mov edi, [edi+TImage.width]
+ lea esi, [4*esi]
+ lea edi, [4*edi]
+
+; prepare MMX constants
+
+ pxor mm0, mm0 ; mm0 = 0000 0000 0000 0000
+ pcmpeqw mm1, mm1 ; mm1 = ffff ffff ffff ffff
+
+ psrlw mm1, 15 ; mm1 = 0001 0001 0001 0001
+ psllw mm1, 8 ; mm1 = 0100 0100 0100 0100
+
+.loopY:
+ mov ebx, [.srect.right] ; the width of the source rectangle
+
+.loopX:
+ dec ebx ; The ZF will not be changed later in the inner loop.
+ js .nextY
+
+ push edx
+
+ movzx eax, byte [ecx+4*ebx]
+ movzx edx, byte [ecx+4*ebx+1]
+
+ lea eax, [eax+2*edx]
+ movzx edx, byte [ecx+4*ebx+2]
+
+ add eax, edx
+ shr eax, 2 ; grayscale.
+
+ pop edx
+
+ movd mm6, [.color]
+ movd mm7, eax
+
+ punpcklbw mm6, mm0 ; byte to word color.
+ punpckldq mm7, mm7 ;
+ packssdw mm7, mm7 ; mm7 = I, I, I, I
+
+ pmullw mm7, mm6 ; mm7 is the color to blend = Cs*256
+
+ movd mm6, [edx+4*ebx] ; Destination color
+ punpcklbw mm6, mm0 ; byte to word destination pixel
+
+ movq mm5, mm7
+ psrlq mm5, 56 ; alpha source
+ punpckldq mm5, mm5
+ packssdw mm5, mm5 ; mm5 = As, As, As, As
+
+ movq mm4, mm1
+ psubw mm4, mm5 ; mm4 = Bs Bs Bs Bs (Bs = $100 - As)
+
+ pmullw mm6, mm4 ; mm6 = Cd = Cd * (256-As) = Cd * Bs
+ paddusw mm6, mm7 ; Cd = 256*Cs + Cd*(256-As)
+ psrlw mm6, 8 ; Cd = Cd/256
+
+ packuswb mm6, mm0 ; pack words to bytes 0A 0R 0G 0B -> 0000ARGB
+ movd [edx+4*ebx], mm6
+
+ jmp .loopX
+
+
+.nextY:
+ add ecx, esi
+ add edx, edi
+
+ dec [.srect.bottom]
+ jnz .loopY
+
+.finish:
+ emms
+ popad
+ return
endp
+;interface GetTextBounds, .pString, .len, .font
-proc GetTextBounds, .context, .ptrString, .len, .font
+body GetTextBounds ;, .pString, .len, .font
.size SIZE
.pwc dd ?
.charlen dd ?
begin
push ebx ecx
+
+ invoke CreateCompatibleDC, 0
+ mov ebx, eax
; first convert the string:
mov ecx, [.len]
shl ecx, 3
stdcall GetMem, ecx
mov [.pwc], eax
- invoke MultiByteToWideChar, CP_UTF8, 0, [.ptrString], [.len], [.pwc], ecx
+ invoke MultiByteToWideChar, CP_UTF8, 0, [.pString], [.len], [.pwc], ecx
mov [.charlen], eax
- mov ebx, [.context]
-
- cmp [.font], 0
- jne @f
- invoke GetStockObject, DEFAULT_GUI_FONT
- mov [.font], eax
-
-@@:
- invoke SelectObject, [ebx+TContext.handle], [.font]
+ invoke SelectClipRgn, ebx, 0
+ invoke SelectObject, ebx, [.font]
push eax
lea eax, [.size]
- invoke GetTextExtentPoint32W, [ebx+TContext.handle], [.pwc], [.charlen], eax
- invoke SelectObject, [ebx+TContext.handle] ; from the stack.
+ invoke GetTextExtentPoint32W, ebx, [.pwc], [.charlen], eax
+ invoke SelectObject, ebx ; from the stack.
+ invoke DeleteDC, ebx
mov eax, [.size.cx]
mov edx, [.size.cy]
stdcall FreeMem, [.pwc]
Index: freshlib/graphics/all.asm
==================================================================
--- freshlib/graphics/all.asm
+++ freshlib/graphics/all.asm
@@ -9,13 +9,11 @@
; Target OS: Any
;_________________________________________________________________________________________
include 'rectangles.asm'
-include 'context.asm'
include 'images.asm'
-include 'backbuffer.asm'
include 'draw.asm'
include 'giflib.asm'
include 'pnglib.asm'
include 'fonts.asm'
include 'text.asm'
DELETED freshlib/graphics/backbuffer.asm
Index: freshlib/graphics/backbuffer.asm
==================================================================
--- freshlib/graphics/backbuffer.asm
+++ /dev/null
@@ -1,27 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "BSD 2-clause" license." |
-;|_______________________________________________________________________________________|
-;
-; Description: Provides raster bitmap, to be used for double buffer painting.
-;
-; Target OS: Any
-;
-; Dependencies:
-;
-; Notes:
-;_________________________________________________________________________________________
-module "BackBuffer library"
-
-; should be equal to the first 3 members of TImage in order to use the same draw procedure.
-
-struct TBackBuffer
- .width dd ?
- .height dd ?
- .raster dd ?
-ends
-
-
-include '%TargetOS%/backbuffer.asm'
-
-endmodule
DELETED freshlib/graphics/context.asm
Index: freshlib/graphics/context.asm
==================================================================
--- freshlib/graphics/context.asm
+++ /dev/null
@@ -1,110 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "BSD 2-clause" license." |
-;|_______________________________________________________________________________________|
-;
-; Description: Context is a object that represents drawing surface in FreshLib
-;
-; Target OS: Any
-;
-; Dependencies:
-;
-; Notes: This file contains OS independent part and includes OS dependent files.
-;_________________________________________________________________________________________
-module "Graphic context library"
-
-struct TBounds
- .x dd ?
- .y dd ?
- .width dd ?
- .height dd ?
-ends
-
-
-
-struct TContext
- .raster dd ? ; handle to raster object (depends on TargetOS)
- .handle dd ? ; handle to context object (depends on TargetOS)
- .clipregion dd ? ; clipping region.
- .drawmode dd ?
-ends
-
-
-struct TDashListItem
- .dash dd ?
- .space dd ?
-ends
-
-
-struct TLineStyle
- .width dd ? ; width of the line in pixels. Width 0 is 1px width. It have special meaning in Linux for example.
- .color dd ? ; color of the line in format (from LSB to MSB) bb, gg, rr, aa ; Use of alpha value is something not very clear for all implementations...
- .flags dd ? ; set of lsEndCapXXX; lsJoinXXX
- .clSpace dd ? ; space color.
- .DashCount dd ? ; count of dash items in the dash list. For solid lines DashCount=0
- .DashItems: ; arbitrary count of TDashListItem
-ends
-
-
-; Creates static TLineStyle structure in design time.
-
-struc LineStyle width*, color*, flags, spacecolor, [dash, space] {
-common
-local ..count, ..dashcount
- ..count = 0
-
-common
- dd width
- dd color
- if flags eq
- dd lsEndCapRound or lsJoinRound
- else
- dd flags
- end if
-
- if spacecolor eq
- dd 0
- else
- dd spacecolor
- end if
-
- dd ..dashcount
-
-forward
- if ~dash eq
- db dash, space
- ..count = ..count + 2
- end if
-
-common
- ..dashcount = ..count
-}
-
-
-
-proc SetSimpleLine, .context, .color
-.style TLineStyle
- rd 16
-begin
- push eax
-
- lea eax, [.style]
- mov [eax+TLineStyle.width], 0
- mov [eax+TLineStyle.flags], 0
- mov [eax+TLineStyle.DashCount], 0
- mov [eax+TLineStyle.clSpace],0
-
- push [.color]
- pop [eax+TLineStyle.color]
-
-
- stdcall SetLineStyle, [.context], eax
- pop eax
- return
-endp
-
-
-
-include '%TargetOS%/context.asm'
-
-endmodule
Index: freshlib/graphics/draw.asm
==================================================================
--- freshlib/graphics/draw.asm
+++ freshlib/graphics/draw.asm
@@ -12,33 +12,428 @@
; Notes: This file contains OS independent part and includes OS dependent files.
;_________________________________________________________________________________________
module "Draw library"
-include "%TargetOS%/draw.asm"
+;include "%TargetOS%/draw.asm"
+
+
+
+proc DrawSolidRect, .pDstImage, .x, .y, .width, .height, .color
+.drect RECT
+.rect RECT
+begin
+ pushad
+
+ mov esi, [.pDstImage]
+
+ xor eax, eax
+ mov ecx, [esi+TImage.width]
+ mov edx, [esi+TImage.height]
+
+ mov [.drect.left], eax
+ mov [.drect.top], eax
+ mov [.drect.right], ecx
+ mov [.drect.bottom], edx
+
+ mov ecx, [.x]
+ mov edx, [.y]
+
+ mov [.rect.left], ecx
+ mov [.rect.top], edx
+
+ add ecx, [.width]
+ add edx, [.height]
+
+ mov [.rect.right], ecx
+ mov [.rect.bottom], edx
+
+ lea ecx, [.drect]
+ lea edx, [.rect]
+ stdcall RectIntersect, ecx, ecx, edx
+ jc .finish
+
+; here [.srect] contains the source rectange
+; [.drect] contains the destination rectangle
+; the width and height of the rectangles is the same.
+
+ mov ecx, [.drect.right]
+ mov edx, [.drect.bottom]
+ sub ecx, [.drect.left]
+ sub edx, [.drect.top]
+
+ mov edi, [.drect.top]
+ imul edi, [esi+TImage.width]
+ add edi, [.drect.left]
+ lea edi, [edi*4]
+ add edi, [esi+TImage.pPixels]
+
+ mov esi, [esi+TImage.width]
+ lea esi, [4*esi]
+
+ stdcall __fix_color, [.color], regEAX
+
+.loopY:
+
+ mov ebx, ecx ; the width of the source rectangle
+
+.loopX:
+ dec ebx
+ mov [edi+4*ebx], eax ; fill the color
+ jnz .loopX
+
+ add edi, esi
+ dec edx
+ jnz .loopY
+
+
+.finish:
+ popad
+ return
+endp
+
+
+
+
+
+proc BlendSolidRect, .pDstImage, .x, .y, .width, .height, .color
+.drect RECT
+.rect RECT
+begin
+ pushad
+
+ mov esi, [.pDstImage]
+
+ xor eax, eax
+ mov ecx, [esi+TImage.width]
+ mov edx, [esi+TImage.height]
+
+ mov [.drect.left], eax
+ mov [.drect.top], eax
+ mov [.drect.right], ecx
+ mov [.drect.bottom], edx
+
+ mov ecx, [.x]
+ mov edx, [.y]
+
+ mov [.rect.left], ecx
+ mov [.rect.top], edx
+
+ add ecx, [.width]
+ add edx, [.height]
+
+ mov [.rect.right], ecx
+ mov [.rect.bottom], edx
+
+ lea ecx, [.drect]
+ lea edx, [.rect]
+ stdcall RectIntersect, ecx, ecx, edx
+ jc .finish
+
+; here [.srect] contains the source rectange
+; [.drect] contains the destination rectangle
+; the width and height of the rectangles is the same.
+
+ mov ecx, [.drect.right]
+ mov edx, [.drect.bottom]
+ sub ecx, [.drect.left]
+ sub edx, [.drect.top]
+
+ mov edi, [.drect.top]
+ imul edi, [esi+TImage.width]
+ add edi, [.drect.left]
+ lea edi, [edi*4]
+ add edi, [esi+TImage.pPixels]
+
+ mov esi, [esi+TImage.width]
+ lea esi, [4*esi]
+
+ stdcall __fix_color, [.color], regEAX
+
+; prepare MMX constants
+
+ pxor mm0, mm0 ; mm0 = 0000 0000 0000 0000
+ pcmpeqw mm1, mm1 ; mm1 = ffff ffff ffff ffff
+ psrlw mm1, 8 ; mm1 = 00ff 00ff 00ff 00ff
+
+; the color
+ movd mm7, eax
+
+ movq mm5, mm7
+ psrlq mm5, 24 ; alpha source
+ punpckldq mm5, mm5
+ packssdw mm5, mm5 ; mm5 = As, As, As, As
+
+ movq mm4, mm1
+ psubw mm4, mm5 ; mm4 = Bs Bs Bs Bs (Bs = $100 - As)
+
+ punpcklbw mm7, mm0 ; byte to word source pixel
+ psllw mm7, 8 ; Cs = Cs*256
+
+
+.loopY:
+ mov ebx, ecx ; the width of the source rectangle
+
+.loopX:
+ dec ebx ; The ZF will not be changed later in the inner loop.
+
+ movd mm6, [edi+4*ebx] ; destination pixel.
+ punpcklbw mm6, mm0 ; byte to word destination pixel
+ pmullw mm6, mm4 ; mm6 = Cd = Cd * (256-As) = Cd * Bs (For alpha Ad = Ad*Bs)
+ paddusw mm6, mm7 ; Cd = Cs + Cd
+ psrlw mm6, 8 ; Cd = Cd/256
+
+ packuswb mm6, mm0 ; pack words to bytes 0A 0R 0G 0B -> 0000ARGB
+ movd [edi+4*ebx], mm6
+
+ jnz .loopX
+
+.nextY:
+ add edi, esi
+ dec edx
+ jnz .loopY
+
+
+.finish:
+ popad
+ return
+endp
+
+
+
+
+
+
+
+proc __fix_color, .color, .reg
+begin
+ pushad
+
+ movzx ebx, byte [.color+3] ; alpha
+ mov ecx, ebx
+
+ mov esi, $ff
+
+ movzx eax, byte [.color+2] ; red
+ mul ebx
+ div esi
+
+ shl ecx, 8
+ mov cl, al
+
+ movzx eax, byte [.color+1] ; green
+ mul ebx
+ div esi
+
+ shl ecx, 8
+ mov cl, al
+
+ movzx eax, byte [.color] ; blue
+ mul ebx
+ div esi
+
+ shl ecx, 8
+ mov cl, al
+
+ mov eax, [.reg]
+ lea eax, [esp+4*eax]
+
+ mov [eax], ecx
+ popad
+ return
+endp
+
+
+
+; Draws horizontal line from .x1 to .x2 on y with color [.color]
+;
+;
+
+proc DrawHLine, .pImage, .x1, .x2, .y, .color
+begin
+
+
+
+
+
+
+ return
+endp
+
+
+
+
+
+
+proc DrawVLine, .pImage, .y1, .y2, .x, .color
+begin
+
+
+ return
+endp
+
+
+
+
+
+
+proc ApplyAlphaRect, .pImage, .x, .y, .width, .height, .alpha
+.drect RECT
+.rect RECT
+begin
+ pushad
+
+ mov edi, [.pImage]
+
+ xor eax, eax
+ mov ecx, [edi+TImage.width]
+ mov edx, [edi+TImage.height]
+
+ mov [.drect.left], eax
+ mov [.drect.top], eax
+ mov [.drect.right], ecx
+ mov [.drect.bottom], edx
+
+ mov ecx, [.x]
+ mov edx, [.y]
+
+ mov [.rect.left], ecx
+ mov [.rect.top], edx
+
+ add ecx, [.width]
+ add edx, [.height]
+
+ mov [.rect.right], ecx
+ mov [.rect.bottom], edx
+
+ lea ecx, [.drect]
+ lea edx, [.rect]
+ stdcall RectIntersect, ecx, ecx, edx
+ jc .finish
+
+; here [.drect] contains the destination rectangle
+
+ mov ecx, [.drect.left]
+ mov edx, [.drect.top]
+ sub [.drect.right], ecx
+ sub [.drect.bottom], edx
+
+ imul edx, [edi+TImage.width]
+ add edx, [.drect.left]
+ shl edx, 2
+
+ add edx, [edi+TImage.pPixels] ; pointer to the upper left corner of the rect.
+
+ mov edi, [edi+TImage.width]
+ lea edi, [4*edi]
+
+
+.loopY:
+ mov ebx, [.drect.right] ; the width of the source rectangle
+
+.loopX:
+ dec ebx ; The ZF will not be changed later in the inner loop.
+ js .nextY
+
+
+ movzx eax, byte [edx+4*ebx+3] ; dest alpha.
+ movzx ecx, byte [.alpha]
+
+; Ad = Ad * [.alpha]/256
+
+ imul eax, ecx
+ sar eax, 8
+
+ mov [edx+4*ebx+3], al
+ jmp .loopX
+
+.nextY:
+ add edx, edi
+ dec [.drect.bottom]
+ jnz .loopY
+
+
+.finish:
+ popad
+ return
+endp
+
+
-proc DrawRectangle, .context, .pBounds, .color
+proc FilterDisabled, .pImage, .no_alpha
+.gray dd ?
+.alpha dd ?
begin
- push eax ecx edx
-
- mov edx, [.pBounds]
-
- mov eax, [edx+TBounds.x]
- mov ecx, [edx+TBounds.y]
- add eax, [edx+TBounds.width]
- add ecx, [edx+TBounds.height]
- dec eax
+ pushad
+
+ mov edi, [.pImage]
+
+ mov ebx, [edi+TImage.width]
+ mov ecx, [edi+TImage.height]
+
+ mov edi, [edi+TImage.pPixels]
+
+
+.outloop:
dec ecx
-
- stdcall SetSimpleLine, [.context], [.color]
- stdcall DrawLine, [.context], [edx+TBounds.x], [edx+TBounds.y], eax, [edx+TBounds.y]
- stdcall DrawLine, [.context], eax, [edx+TBounds.y], eax, ecx
- stdcall DrawLine, [.context], [edx+TBounds.x], ecx, eax, ecx
- stdcall DrawLine, [.context], [edx+TBounds.x], [edx+TBounds.y], [edx+TBounds.x], ecx
-
- pop edx ecx eax
+ js .finish
+
+ mov esi, ebx ; Counter from 0 to IconWidth-1
+ inc esi
+
+.inloop:
+ dec esi
+ jz .outloop
+
+ movzx eax, byte [edi] ; blue
+ movzx edx, byte [edi+1] ; green
+
+ lea edx, [edx+2*eax] ; 2*Blue + Green
+
+ movzx eax, byte [edi+2]
+ add edx, eax ; + Red
+
+ movzx eax, byte [edi+3] ; Alpha
+ mov [.alpha], eax
+
+ shr edx, 2 ; div 4 -> Grayscale pixel.
+ ; This formula gives more realistic view.
+
+ mov [.gray], edx
+
+; blend alpha
+
+ cmp [.no_alpha], 0
+ jne .store
+
+ imul eax, esi
+ cdq
+ div ebx
+ mov [.alpha], eax
+
+ mov eax, [.gray]
+ imul eax, esi
+ cdq
+ div ebx
+ mov [.gray], eax
+
+.store:
+
+ mov al, byte [.alpha]
+ shl eax, 8
+ mov al ,byte [.gray]
+ shl eax, 8
+ mov al ,byte [.gray]
+ shl eax, 8
+ mov al ,byte [.gray]
+
+ stosd
+ jmp .inloop
+
+.finish:
+ popad
return
endp
endmodule
Index: freshlib/graphics/fonts.asm
==================================================================
--- freshlib/graphics/fonts.asm
+++ freshlib/graphics/fonts.asm
@@ -17,10 +17,47 @@
ffItalic = 1
ffUnderline = 2
ffStrikeOut = 4
ffMonospaced = $80
+
+
+fwLight = 0
+fwDemilight = 1
+fwNormal = 2
+fwMedium = 3
+fwDemibold = 4
+fwBold = 5
+fwExtraBold = 6
+fwBlack = 7
+
+
+
+struct __TFont
+ .hFontFace dd ? ; The name of the font face.
+ .height dd ? ; The character height in pixels.
+ .weight dd ? ; The weight of the characters.
+ .flags dd ? ; ffItalic, ffMonospaced, etc.
+ends
+
+
+interface FontCreate, .font_name, .size, .weight, .flags
+
+interface FontDestroy, .pFont
+
+
+; returns some font metrics
+;
+; Arguments:
+; .font - the font
+; Returns:
+; EAX - the line height of the font.
+; EBX - the ascender of the font.
+; EDX - the descender of the font.
+
+interface GetFontMetrics, .font
+
include '%TargetOS%/fonts.asm'
endmodule
Index: freshlib/graphics/images.asm
==================================================================
--- freshlib/graphics/images.asm
+++ freshlib/graphics/images.asm
@@ -20,28 +20,12 @@
interface DestroyImage, .ptrImage
-interface DrawImage, .context, .pImage, .x, .y
-
-
-interface DrawText, .pImage, .text, .len, .x, .y, .font, .color
-
-
-
-
-
-proc DrawMaskedImage, .context, .mask, .image, .x, .y
-begin
- stdcall SetDrawMode, [.context], cmAnd
- stdcall DrawImage, [.context], [.mask], [.x], [.y]
- stdcall SetDrawMode, [.context], cmXor
- stdcall DrawImage, [.context], [.image], [.x], [.y]
- return
-endp
-
+; Draws the image on a OS provided window surface.
+interface DrawImageRect, .where, .pImage, .xDst, .yDst, .xSrc, .ySrc, .width, .height
proc BlendImage, .pDstImage, .xDst, .yDst, .pSrcImage, .xSrc, .ySrc, .width, .height
.srect RECT
@@ -142,15 +126,14 @@
; prepare MMX constants
pxor mm0, mm0 ; mm0 = 0000 0000 0000 0000
pcmpeqw mm1, mm1 ; mm1 = ffff ffff ffff ffff
- psrlw mm1, 15 ; mm1 = 0001 0001 0001 0001
- psllw mm1, 8 ; mm1 = 0100 0100 0100 0100
+ psrlw mm1, 8 ; mm1 = 00ff 00ff 00ff 00ff
- movq mm2, mm1 ; mm2 = 0001 0001 0001 0001
- psllq mm2, 48 ; mm2 = 0100 0000 0000 0000
+; psrlw mm1, 15 ; mm1 = 0001 0001 0001 0001
+; psllw mm1, 8 ; mm1 = 0100 0100 0100 0100
.loopY:
mov ebx, [.srect.right] ; the width of the source rectangle
.loopX:
@@ -159,27 +142,23 @@
movd mm7, [ecx+4*ebx] ; source pixel.
movd mm6, [edx+4*ebx] ; destination pixel.
movq mm5, mm7
psrlq mm5, 24 ; alpha source
-
- punpckldq mm5, mm5 ;
- punpcklbw mm6, mm0 ; byte to word destination pixel
+ punpckldq mm5, mm5
packssdw mm5, mm5 ; mm5 = As, As, As, As
- punpcklbw mm7, mm0 ; byte to word source pixel
movq mm4, mm1
psubw mm4, mm5 ; mm4 = Bs Bs Bs Bs (Bs = $100 - As)
- psrlq mm5, 16 ; mm5 = 0 As As As
- por mm5, mm2 ; mm5 = $100 As As As
+ punpcklbw mm6, mm0 ; byte to word destination pixel
+ punpcklbw mm7, mm0 ; byte to word source pixel
+ psllw mm7, 8 ; Cs = Cs*256
pmullw mm6, mm4 ; mm6 = Cd = Cd * (256-As) = Cd * Bs (For alpha Ad = Ad*Bs)
- pmullw mm7, mm5 ; Cs = Cs * As (For alpha As = $100*As )
-
- paddusw mm6, mm7 ; Cd = Cs + Cd (For alpha Ad = $100*As + Ad*Bs)
- psrlw mm6, 8 ; Cd = Cd/256 (For alpha Ad = As + Ad*Bs/$100)
+ paddusw mm6, mm7 ; Cd = Cs + Cd
+ psrlw mm6, 8 ; Cd = Cd/256
packuswb mm6, mm0 ; pack words to bytes 0A 0R 0G 0B -> 0000ARGB
movd [edx+4*ebx], mm6
jnz .loopX
@@ -190,90 +169,18 @@
dec [.srect.bottom]
jnz .loopY
.finish:
+ emms
popad
return
endp
-proc DrawSolidRect, .pDstImage, .x, .y, .width, .height, .color
-.drect RECT
-.rect RECT
-begin
- pushad
-
- mov esi, [.pDstImage]
-
- xor eax, eax
- mov ecx, [esi+TImage.width]
- mov edx, [esi+TImage.height]
-
- mov [.drect.left], eax
- mov [.drect.top], eax
- mov [.drect.right], ecx
- mov [.drect.bottom], edx
-
- mov ecx, [.x]
- mov edx, [.y]
-
- mov [.rect.left], ecx
- mov [.rect.top], edx
-
- add ecx, [.width]
- add edx, [.height]
-
- mov [.rect.right], ecx
- mov [.rect.bottom], edx
-
- lea ecx, [.drect]
- lea edx, [.rect]
- stdcall RectIntersect, ecx, ecx, edx
- jc .finish
-
-; here [.srect] contains the source rectange
-; [.drect] contains the destination rectangle
-; the width and height of the rectangles is the same.
-
- mov ecx, [.drect.right]
- mov edx, [.drect.bottom]
- sub ecx, [.drect.left]
- sub edx, [.drect.top]
-
- mov edi, [.drect.top]
- imul edi, [esi+TImage.width]
- add edi, [.drect.left]
- lea edi, [edi*4]
- add edi, [esi+TImage.pPixels]
-
- mov esi, [esi+TImage.width]
- lea esi, [4*esi]
-
- mov eax, [.color]
-
-.loopY:
-
- mov ebx, ecx ; the width of the source rectangle
-
-.loopX:
- dec ebx
- mov [edi+4*ebx], eax ; fill the color
- jnz .loopX
-
- add edi, esi
- dec edx
- jnz .loopY
-
-
-.finish:
- popad
- return
-endp
-
proc CopyImageRect, .pDstImage, .xDst, .yDst, .pSrcImage, .xSrc, .ySrc, .width, .height
.srect RECT
.drect RECT
@@ -398,15 +305,114 @@
dec [.srect.bottom]
jnz .loopY
.finish:
+ emms
popad
return
endp
+
+
+
+;proc ImageMulAlpha2, .pImage, .x, .y, .width, .height
+;.drect RECT
+;.rect RECT
+;begin
+; pushad
+;
+; mov edi, [.pImage]
+;
+; xor eax, eax
+; mov ecx, [edi+TImage.width]
+; mov edx, [edi+TImage.height]
+;
+; mov [.drect.left], eax
+; mov [.drect.top], eax
+; mov [.drect.right], ecx
+; mov [.drect.bottom], edx
+;
+; mov ecx, [.x]
+; mov edx, [.y]
+;
+; mov [.rect.left], ecx
+; mov [.rect.top], edx
+;
+; add ecx, [.width]
+; add edx, [.height]
+;
+; mov [.rect.right], ecx
+; mov [.rect.bottom], edx
+;
+; lea ecx, [.drect]
+; lea edx, [.rect]
+; stdcall RectIntersect, ecx, ecx, edx
+; jc .finish
+;
+; mov ecx, [.drect.left]
+; mov edx, [.drect.top]
+; sub [.drect.right], ecx
+; sub [.drect.bottom], edx
+;
+; mov esi, [.drect.top]
+; imul esi, [edi+TImage.width]
+;
+; add esi, [.drect.left]
+; lea esi, [4*esi]
+; add esi, [edi+TImage.pPixels]
+;
+; mov edi, [edi+TImage.width]
+; lea edi, [4*edi]
+;
+;; prepare MMX constants
+;
+; pxor mm0, mm0 ; mm0 = 0000 0000 0000 0000
+; pcmpeqw mm1, mm1 ; mm1 = ffff ffff ffff ffff
+; psrlw mm1, 15 ; mm1 = 0001 0001 0001 0001
+; psllw mm1, 8 ; mm1 = 0100 0100 0100 0100
+; psllq mm1, 48 ; mm1 = 0100 0000 0000 0000
+;
+;.loopY:
+; mov ebx, [.drect.right] ; the width of the source rectangle
+;
+;.loopX:
+; dec ebx ; The ZF will not be changed later in the inner loop.
+;
+; movd mm6, [esi+4*ebx] ; destination pixel.
+;
+; movq mm5, mm6
+; psrlq mm5, 24 ; alpha
+;
+; punpckldq mm5, mm5 ;
+; punpcklbw mm6, mm0 ; byte to word destination pixel
+; packssdw mm5, mm5 ; mm5 = Ad, Ad, Ad, Ad
+;
+; psrlq mm5, 16 ; mm5 = 0 Ad Ad Ad
+; por mm5, mm1 ; mm5 = $100 Ad Ad Ad
+;
+; pmullw mm6, mm5 ; mm6 = Cd = Cd * Ad (For alpha Ad = Ad * 256)
+; psrlw mm6, 8 ; Cd = Cd/256 (For alpha Ad = Ad)
+;
+; packuswb mm6, mm0 ; pack words to bytes 0A 0R 0G 0B -> 0000ARGB
+; movd [esi+4*ebx], mm6
+;
+; jnz .loopX
+;
+;.nextY:
+; add esi, edi
+;
+; dec [.drect.bottom]
+; jnz .loopY
+;
+;.finish:
+; emms
+; popad
+; return
+;endp
+
include '%TargetOS%/images.asm'
endmodule
Index: freshlib/graphics/pnglib.asm
==================================================================
--- freshlib/graphics/pnglib.asm
+++ freshlib/graphics/pnglib.asm
@@ -568,10 +568,13 @@
shl ebx, 2
add ebx, [.pPalette]
mov edx, [ebx]
.store_px:
+
+ stdcall __fix_color, edx, regEDX ; pre-multiply alpha
+
mov [edi], edx
add edi, 4
dec [.j]
jnz .inner2
Index: freshlib/graphics/rectangles.asm
==================================================================
--- freshlib/graphics/rectangles.asm
+++ freshlib/graphics/rectangles.asm
@@ -9,10 +9,85 @@
;
; Dependencies:
; Notes:
;_________________________________________________________________________________________
module "Rectangles library"
+
+
+; Calculates the bounding rectangle of two source rectangles, pointed by [.src1] and [.src2]
+; The result rectangle is placed in RECT structure pointed by [.dest]
+;
+; All three rectangles may point to the same structures.
+;
+; Procedure preserves all registers.
+
+proc RectBounding, .dest, .src1, .src2
+begin
+ pushad
+
+
+ mov esi, [.src1]
+ mov edi, [.src2]
+ mov ebx, [.dest]
+
+; min left1, left2
+
+ mov eax, [esi+RECT.left]
+ mov edx, [edi+RECT.left]
+
+ sub edx, eax
+ sbb ecx, ecx
+ and ecx, edx
+ add eax, ecx
+
+ mov [ebx+RECT.left], eax
+
+
+; min top1, top2
+
+ mov eax, [esi+RECT.top]
+ mov edx, [edi+RECT.top]
+
+ sub edx, eax
+ sbb ecx, ecx
+ and ecx, edx
+ add eax, ecx
+
+ mov [ebx+RECT.top], eax
+
+
+; max right1, right2
+
+ mov eax, [esi+RECT.right]
+ mov edx, [edi+RECT.right]
+
+ sub edx, eax
+ sbb ecx, ecx
+ not ecx
+ and ecx, edx
+ add eax, ecx
+
+ mov [ebx+RECT.right], eax
+
+
+; max bottom1, bottom2
+
+ mov eax, [esi+RECT.bottom]
+ mov edx, [edi+RECT.bottom]
+
+ sub edx, eax
+ sbb ecx, ecx
+ not ecx
+ and ecx, edx
+ add eax, ecx
+
+ mov [ebx+RECT.bottom], eax
+
+ popad
+ return
+endp
+
; Calculates the intersection of two source rectangles, pointed by [.src1] and [.src2]
; The result rectangle is placed in RECT structure pointed by [.dest]
; All three rectangles may point to the same structures.
Index: freshlib/graphics/text.asm
==================================================================
--- freshlib/graphics/text.asm
+++ freshlib/graphics/text.asm
@@ -12,35 +12,34 @@
; Notes: This file contains OS independent part of the library and includes respective
; OS dependent files.
;_________________________________________________________________________________________
module "Text library"
-include "%TargetOS%/text.asm"
-
-
-macro min a, b, use {
- sub b, a
- sbb use, use
- and use, b
- add a, use
-}
-
-macro max a, b, use {
- sub b, a
- sbb use, use
- not use
- and use, b
- add a, use
-}
+
+interface DrawString, .pImage, .pString, .len, .x, .y, .font, .color
+
+
+interface TextDecompose, .hString, .font
+
+
+interface DrawDecomposedString, .pImage, .pArray, .x, .y, .font, .color
+
+
+interface GetTextBounds, .pString, .len, .font
+
+
struct TTextExtent
.width dd ?
.height dd ?
.OffsX dd ?
.OffsY dd ?
ends
+
+
+
struct TCharAttr
.font dd ?
.color dd ?
@@ -48,10 +47,14 @@
.flags dd ? ; for free use of the client.
ends
; dtfXXX means "draw text flag"
+
+dtfHAlignMask = $3
+dtfVAlignMask = $c
+
; horizontal align
dtfAlignLeft = 0
dtfAlignRight = 1
dtfAlignCenter = 2
@@ -64,48 +67,26 @@
; Text layout
dtfCRLF = $0100
dtfWordWrap = $0200
dtfTableTabs = $0400
+dtfSingleLine = $0800
struct _TTextChunk
.y dd ?
.width dd ?
- .height dd ?
.len dd ?
.ptr dd ?
ends
-__HeightProbeString text '18ilj.Xygl[_|"`g'
-__NumberProbeString text '8888888888888888'
-
-; returns: eax - mean width
-; returns: edx - height
-; returns: ecx - descent
-proc FontGetCharSize, .raster, .font, .probe
-begin
- push ebx
-
- stdcall AllocateContext, [.raster]
- mov ebx, eax
-
- stdcall GetTextOffset, ebx, [.probe], 16, [.font]
- mov ecx, edx
-
-; DebugMsg "Text offset y:"
-; OutputRegister regECX, 10
-
- stdcall GetTextBounds, ebx, [.probe], 16, [.font]
- stdcall ReleaseContext, ebx
-
- sub ecx, edx
- shr eax, 4
- neg ecx
- pop ebx
- return
-endp
+
+struct TTextChar
+ .code dd ? ; unicode of the character.
+ .width dw ? ; width increment in pixels.
+ .height dw ? ; height increment in pixels - if <> 0 this char must be written on new line.
+ends
proc AdjustCountUtf8
@@ -118,370 +99,985 @@
sub ebx, esi
return
endp
-proc DrawTextBox, .context, .text, .bounds, .flags, .font, .color
-.len dd ?
-.count dd ?
-.height dd ?
-.y dd ?
-
-.low dd ?
-.high dd ?
-
-.linew dd ?
-.lineh dd ?
-
-.DrawProc dd ?
-begin
- pushad
-
- mov ecx, DrawString
-
- mov eax, [.flags]
- and eax, $03
- cmp eax, dtfAlignJustify
- jne @f
- mov ecx, DrawStringJustified
-@@:
- mov [.DrawProc], ecx
-
- stdcall StrLen, [.text]
- mov [.len], eax
-
- stdcall StrPtr, [.text]
- mov esi, eax
-
- mov edi, [.bounds]
- mov eax, [edi+TBounds.height]
-; mov ecx, [edi+TBounds.y]
- mov [.height], eax
- mov [.y], 0 ;ecx
-
-; slice the string on chunks, depending on flags, rectangle width and the string content.
-; push _TTextChunk for every chunk in stack.
- mov [.count], 0
-
-.slice:
- mov ecx, [.len]
-
- test [.flags], dtfCRLF
- jz .cropit
-
- xor ecx, ecx
-
-.scanCRLF:
- cmp ecx, [.len]
- jae .cropit
-
- mov al, [esi+ecx]
-
- cmp al, $0d
- je .cropit
- cmp al, $0a
- je .cropit
- inc ecx
- jmp .scanCRLF
-
-.cropit:
- mov ebx, ecx ; high limit
-
- stdcall AdjustCountUtf8
- stdcall GetTextBounds, [.context], esi, ebx, [.font]
-
- cmp edx, [.height]
- jg .drawchunks
-
- mov [.lineh], edx
-
- cmp eax, [edi+TBounds.width]
- jle .itfits
-
- mov [.high], ebx
- mov [.low], 0
-
-.croploop:
- mov ebx, [.low]
- add ebx, [.high]
- shr ebx, 1
-
- cmp ebx, 1
- ja .check_width
-
- mov ebx, 1
- jmp .itfits
-
-.check_width:
- stdcall AdjustCountUtf8
- stdcall GetTextBounds, [.context], esi, ebx, [.font]
- cmp eax, [edi+TBounds.width]
- je .itfits
-
- jg .above
-
- cmp ebx, [.low]
- je .itfits
-
- mov [.low], ebx
- jmp .croploop
-
-.above:
- mov [.high], ebx
- jmp .croploop
-
-.itfits: ; here ebx contains the len of string that fits in the rectangle.
- mov ecx, ebx
- mov [.linew], eax
-
- test [.flags], dtfWordWrap
- jz .pushit
-
-; search the last space or tab that separates words:
- mov edx, ecx
- cmp byte [esi+edx], $0d
- je .found
- cmp byte [esi+edx], $0a
- je .found
-
-.searchword:
- cmp byte [esi+edx], 0
- je .found
- cmp byte [esi+edx], ' '
- je .found
- cmp byte [esi+edx], $09
- je .found
- cmp byte [esi+edx], $0d
- je .found
- cmp byte [esi+edx], $0a
- je .found
-
- dec edx
- jnz .searchword
-
- mov edx, ecx
-
-.found:
- push ebx
- mov ebx, edx
- stdcall AdjustCountUtf8
- stdcall GetTextBounds, [.context], esi, ebx, [.font]
- mov [.linew], eax
- mov [.lineh], edx
- mov ecx, ebx
- pop ebx
-
-.pushit:
- push esi ; pointer to the string.
- push ecx ; length of the string.
- push [.lineh] ; height of the line.
- push [.linew] ; width of the line.
- push [.y] ;
-
- inc [.count]
-
- mov eax, [.lineh]
- add [.y], eax
- sub [.height], eax
-
- lea esi, [esi+ecx]
- sub [.len], ecx
- jz .drawchunks
-
- xor ecx, ecx
-
-; search for the whitespace that have to be skip
-.skiploop:
- mov al, [esi]
- cmp al, $0d
- je .skipcrlf
- cmp al, $0a
- je .skipcrlf
- cmp al, $20
- je .skipspace
- cmp al, $09
- je .skipspace
-
- jmp .slice
-
-.skipspace:
- inc esi
- dec [.len]
- jnz .skiploop
- jmp .drawchunks
-
-.skipcrlf:
- inc esi
- dec [.len]
- xor al, $0d xor $0a
- cmp [esi], al
- jne .slice
- inc esi
- dec [.len]
- jnz .slice
-
-; pop the _TTextChunk structures and draw, depending on flags.
-.drawchunks:
- cmp [.count], 0
- je .finish
-
- mov ebx, esp
- stdcall GetTextOffset, [.context], [ebx+_TTextChunk.ptr], [ebx+_TTextChunk.len], [.font]
- mov eax, [ebx+_TTextChunk.height]
- sub eax, edx ; it should be the line y descent
- test [.flags], dtfAlignBottom
- jnz @f
- sub [.y], eax
-@@:
- mov edx, [.flags]
- and edx, dtfAlignBottom or dtfAlignMiddle
-
- mov ecx, [edi+TBounds.height]
- sub ecx, [.y]
-
- cmp edx, dtfAlignBottom
- je .yalignok
-
- sar ecx, 1
- cmp edx, dtfAlignMiddle
- je .yalignok
-
- xor ecx, ecx
-
-.yalignok:
-.drawloop:
- cmp [.count], 0
- je .finish
-
- mov ebx, esp
-
- mov eax, [edi+TBounds.width]
- sub eax, [ebx+_TTextChunk.width]
-
- mov edx, [.flags]
- and edx, $03
-
- cmp edx, dtfAlignRight
- je .hready
-
- shr eax, 1
- cmp edx, dtfAlignCenter
- je .hready
-
- xor eax, eax
-
-.hready:
- add eax, [edi+TBounds.x]
-
- push eax
- stdcall GetTextOffset, [.context], [ebx+_TTextChunk.ptr], [ebx+_TTextChunk.len], [.font]
- add edx, ecx
- add edx, [ebx+_TTextChunk.y]
- add edx, [edi+TBounds.y]
- pop eax
-
- stdcall [.DrawProc], [.context], [ebx+_TTextChunk.ptr], [ebx+_TTextChunk.len], eax, edx, [.font], [.color]
-
-; draws lines on every row of text. For debug purposes.
-iglobal
- if used __UnderlineStyle
- __UnderlineStyle LineStyle 0, $808080
- end if
-endg
-
-if defined options.DebugMode & options.DebugMode
- stdcall SetLineStyle, [.context], __UnderlineStyle
- stdcall DrawLine, [.context], [edi+TBounds.x], edx, [edi+TBounds.width], edx
-end if
-; end debug code
-
-
- add esp, sizeof._TTextChunk
- dec [.count]
- jmp .drawloop
-
-.finish:
- popad
- return
-endp
-
-
-
-
-proc DrawStringJustified, .raster, .ptrString, .len, .x, .y, .font, .color
-.XX dd ?
-.rem dd ?
-.crem dd ?
-.endptr dd ?
-begin
- pushad
-
- mov esi, [.ptrString]
- mov eax, [.len]
- add eax, esi
- mov [.endptr], eax
-
- stdcall StrLenUtf8, esi, [.len]
- mov ecx, eax
- dec ecx
- jg @f
- mov ecx, 1
-@@:
-
- stdcall GetTextBounds, [.raster], esi, [.len], [.font]
-
- sub eax, [edi+TBounds.width]
- neg eax
-
- cdq
- div ecx
-
- cmp eax, 4
- jge .cantjustify ; the needed space is too big for justify, so just draw it left aligned
-
- mov ecx, eax
- mov [.rem], edx
- mov [.crem], edx
-
- mov ebx, [.len]
- push [.x]
- pop [.XX]
-
-.drawloop:
- cmp esi, [.endptr]
- jae .finish
-
- stdcall DecodeUtf8, [esi]
- jc .finish
-
- push edx
- stdcall DrawString, [.raster], esi, edx, [.XX], [.y], [.font], [.color]
- stdcall GetTextBounds, [.raster], esi, edx, [.font]
- pop edx
- add esi, edx
- add [.XX], eax
- add [.XX], ecx
-
- cmp [.crem], 0
- je .drawloop
-
- sub ebx, [.rem]
- jge .drawloop
-
- inc [.XX]
- dec [.crem]
- mov ebx, [.len]
- sub ebx, [.rem]
- jmp .drawloop
-
-.finish:
- popad
- return
-
-.cantjustify:
- stdcall DrawString, [.raster], [.ptrString], [.len], [.x], [.y], [.font], [.color]
- jmp .finish
-endp
+
+proc JustifyLine, .CharArray, .from, .to, .current_width, .align_width
+begin
+ pushad
+
+ dec [.to] ; don't change the last character width.
+
+ mov edi, [.CharArray]
+ mov ecx, [.to]
+ sub ecx, [.from]
+ jle .finish
+
+ mov edx, [.align_width]
+ sub edx, [.current_width]
+ jle .finish
+
+ mov esi, edx
+
+ mov ebx, [.from]
+
+.align_loop:
+ inc ebx
+ cmp ebx, [.to]
+ jae .finish
+
+ cmp word [edi+TArray.array+8*ebx+TTextChar.width], 0
+ je .skip_this
+
+.sub:
+ test esi, esi
+ js .negative
+
+ sub esi, ecx
+ inc word [edi+TArray.array+8*ebx+TTextChar.width]
+ jmp .sub
+
+.negative:
+ add esi, edx
+ jmp .align_loop
+
+.skip_this:
+ dec ecx
+ jnz .align_loop
+
+.finish:
+ popad
+ return
+endp
+
+
+
+
+proc DrawTextBox, .pImage, .text, .x, .y, .width, .height, .extra_line, .flags, .font, .color
+
+.ascender dd ?
+.descender dd ?
+
+.txt_height dd ?
+
+.last_word dd ?
+.lw_width dd ?
+
+.no_just dd ?
+
+begin
+
+ pushad
+
+ stdcall TextDecompose, [.text], [.font]
+ mov edi, eax
+ mov [.ascender], edx
+ mov [.descender], ecx
+
+ add [.y], edx
+
+ xor ecx, ecx
+ mov [.txt_height], ecx
+
+ cmp [edi+TArray.count], ecx
+ je .finish
+
+.main_loop: ; start of new line
+ xor ebx, ebx ; current X coordinate.
+ or [.last_word], -1 ; end of the word -1 means there is no word from the beginning of the line.
+
+ mov eax, [.txt_height]
+ cmp eax, [.height]
+ jb .format_it
+
+ mov eax, [.extra_line]
+ sub [.txt_height], eax
+
+ mov [edi+TArray.count], ecx
+ jmp .draw_all2
+
+
+.format_it:
+ stdcall InsertArrayItems, edi, ecx, 1
+ mov edi, edx
+ mov [eax+TTextChar.code], $20
+ mov dword [eax+TTextChar.width], ebx ; Set to zero TTextChar.height as well!
+
+ mov esi, ecx ; start of the line!
+ inc ecx
+
+.slice_loop:
+
+; Is it end of a word?
+ cmp [edi+TArray.array+8*ecx+TTextChar.code], $20
+ ja .white_ok
+
+ test ecx, ecx
+ jz .white_ok
+
+ cmp [edi+TArray.array+8*ecx-8+TTextChar.code], $20 ; previous character
+ jbe .white_ok
+
+ mov [.last_word], ecx ; edx is a pointer to the end of the last word.
+ mov [.lw_width], ebx
+
+.white_ok:
+ test [.flags], dtfCRLF
+ jz .crlf_ok
+
+ mov [.no_just], 1
+
+ cmp [edi+TArray.array+8*ecx+TTextChar.code], $0d
+ je .new_line
+
+ cmp [edi+TArray.array+8*ecx+TTextChar.code], $0a
+ je .new_line
+
+.crlf_ok:
+ mov [.no_just], 0
+
+ test [.flags], dtfTableTabs
+ jz .tabs_ok
+
+; implement here check for tab and tabs expanding.
+
+.tabs_ok:
+
+; check the current line width
+
+ movzx eax, word [edi+TArray.array+8*ecx+TTextChar.width]
+ add eax, ebx
+
+ cmp eax, [.width]
+ ja .wider
+
+ mov ebx, eax
+
+ inc ecx
+ cmp ecx, [edi+TArray.count]
+ jb .slice_loop
+
+ mov [.no_just], 1
+ call .RowAlign
+ jmp .draw_all
+
+
+.wider:
+ test [.flags], dtfSingleLine
+ jnz .del_remaining
+
+ mov eax, ecx
+ sub eax, esi
+ cmp eax, 1
+ jbe .finish ; Even single char can not be displayed on this [.width]
+
+; next line
+.new_line:
+
+ test [.flags], dtfWordWrap
+ jz .word_ok
+
+; word wrap
+ cmp [.last_word], 0
+ jl .word_ok ; there is no previous word, so split on the current pos.
+
+ mov ecx, [.last_word]
+ mov ebx, [.lw_width]
+
+.word_ok:
+ call .RowAlign
+
+ mov eax, [edi+TArray.lparam] ; contains the line height computed by DecomposeText
+ add eax, [.extra_line]
+
+ add [.txt_height], eax
+ mov word [edi+TArray.array+8*ecx-8+TTextChar.height], ax
+
+ test [.flags], dtfCRLF
+ jz .skip_ws_loop
+
+ mov eax, [edi+TArray.array+8*ecx+TTextChar.code]
+ cmp eax, $0d
+ je .skip_cr
+
+ cmp eax, $0a
+ jne .skip_ws_loop
+
+.skip_cr:
+ mov word [edi+TArray.array+8*ecx+TTextChar.width], 0 ; zero width, skip it.
+ inc ecx
+ cmp ecx, [edi+TArray.count]
+ je .draw_all
+
+ xor eax, $0d xor $0a
+ cmp [edi+TArray.array+8*ecx+TTextChar.code], eax
+ jne .main_loop
+
+ mov word [edi+TArray.array+8*ecx+TTextChar.width], 0 ; zero width, skip it.
+
+ inc ecx
+ cmp ecx, [edi+TArray.count]
+ jae .draw_all
+ jmp .main_loop
+
+.del_remaining:
+
+ mov eax, [edi+TArray.count]
+ sub eax, ecx
+ stdcall DeleteArrayItems, edi, ecx, eax
+ jmp .draw_all
+
+
+.skip_ws_loop:
+ cmp [edi+TArray.array+8*ecx+TTextChar.code], $20
+ ja .main_loop
+
+ mov word [edi+TArray.array+8*ecx+TTextChar.width], 0 ; zero width, skip it.
+
+ inc ecx
+ cmp ecx, [edi+TArray.count]
+ jb .skip_ws_loop
+
+
+.draw_all:
+; compute the vertical align.
+
+ mov eax, [edi+TArray.lparam]
+ add [.txt_height], eax
+
+.draw_all2:
+ mov ecx, [.height]
+ sub ecx, [.txt_height]
+
+ mov eax, [.flags]
+ and eax, dtfVAlignMask
+
+ cmp eax, dtfAlignTop
+ je .drawit
+
+ add [.y], ecx
+
+ cmp eax, dtfAlignBottom
+ je .drawit
+
+ sar ecx, 1
+ sub [.y], ecx
+
+.drawit:
+ stdcall DrawDecomposedString, [.pImage], edi, [.x], [.y], [.font], [.color]
+
+
+.finish:
+ stdcall FreeMem, edi
+ popad
+ return
+
+
+
+
+.RowAlign:
+ mov eax, [.flags]
+ and eax, dtfHAlignMask
+
+ cmp eax, dtfAlignLeft
+ je .align_ok ; no need for extra space
+
+ cmp eax, dtfAlignJustify
+ jne .align_center_right
+
+ cmp [.no_just], 1
+ je .align_ok
+
+ stdcall JustifyLine, edi, esi, ecx, ebx, [.width]
+ jmp .align_ok
+
+.align_center_right:
+
+ mov edx, [.width]
+ sub edx, ebx
+ cmp eax, dtfAlignRight
+ je .set_align
+
+ sar edx, 1
+
+.set_align:
+ mov word [edi+TArray.array+8*esi+TTextChar.width], dx
+
+.align_ok:
+ retn
+
+endp
+
+
+
+
+
+
+;proc DrawTextBox, .pImage, .text, .x, .y, .width, .height, .flags, .font, .color
+;
+; .count dd ?
+;
+; .widths dd ?
+; .offset dd ?
+;
+;begin
+; pushad
+;
+; stdcall StrPtr, [.text]
+; mov esi, eax
+;
+; add [.y], 22
+;
+; stdcall GetTextWidthsArray, [.text], [.font]
+;
+; mov [.widths], eax
+; mov eax, [.widths]
+; lea edi, [eax+TArray.array] ; array with x coordinates of every char in the string.
+;
+;; slice the string on chunks, depending on flags, rectangle width and the string content.
+;; push _TTextChunk for every chunk in stack.
+;
+; xor ecx, ecx
+; mov [.count], ecx
+; mov [.offset], ecx
+;
+;.slice_loop:
+; push esi ; push _TTextChunk.ptr
+;
+;.scan_loop:
+; stdcall DecodeUtf8, [esi]
+;
+; test eax, eax
+; jz .slice_here
+;
+; test [.flags], dtfCRLF
+; jz .check_width
+;
+; cmp eax, $0d
+; je .cr_lf
+;
+; cmp eax, $0a
+; je .cr_lf
+;
+;
+;.check_width:
+; mov ecx, [edi]
+; sub ecx, [.offset]
+; cmp ecx, [.width]
+; jae .slice_here
+;
+; add esi, edx
+; add edi, 4
+; jmp .scan_loop
+;
+;
+;.cr_lf:
+; mov ecx, esi
+; inc esi
+; add edi, 4
+;
+; xor eax, $0d xor $0a
+; cmp byte [esi], al
+; jne @f
+; inc esi
+; dec ecx
+; add edi, 4
+;@@:
+;
+; pushd [edi]
+; popd [.offset]
+;
+; jmp .chunk_len
+;
+;
+;.slice_here:
+; mov ecx, [edi]
+; mov [.offset], ecx
+;
+;.end_string:
+; mov ecx, esi
+;
+;.chunk_len:
+; sub ecx, [esp] ; the start of the chunk!
+;
+; push ecx ; push _TTextChunk.len
+; push edx ; push _TTextChunk.width
+; push [.y] ; push _TTextChunk.y
+;
+;
+; add [.y], 22 ;TEST/DEBUG
+; inc [.count]
+;
+; test eax, eax
+; jnz .slice_loop
+;
+;; here, all slices are in the stack, so draw them from down to the top.
+;
+;
+; cmp [.count], 0
+; je .finish
+;
+;.draw_loop:
+; mov ebx, esp
+; stdcall DrawString, [.pImage], [ebx+_TTextChunk.ptr], [ebx+_TTextChunk.len], [.x], [ebx+_TTextChunk.y], [.font], [.color]
+;
+; add esp, sizeof._TTextChunk
+;
+; dec [.count]
+; jnz .draw_loop
+;
+;
+;.finish:
+; stdcall FreeMem, [.widths]
+; popad
+; return
+;
+;endp
+
+
+
+;
+;
+;
+;
+;
+; mov ecx, [.len]
+;
+; test [.flags], dtfCRLF
+; jz .cropit
+;
+; xor ecx, ecx
+;
+;.scanCRLF:
+; cmp ecx, [.len]
+; jae .cropit
+;
+; mov al, [esi+ecx]
+;
+; cmp al, $0d
+; je .cropit
+; cmp al, $0a
+; je .cropit
+; inc ecx
+; jmp .scanCRLF
+;
+;.cropit:
+; mov ebx, ecx ; high limit
+;
+; stdcall AdjustCountUtf8
+;
+; mov eax, [.widths]
+; mov eax, [eax+4*ebx+TArray.array]
+; sub eax, [.start_len]
+;
+;; stdcall GetTextBounds, [.context], esi, ebx, [.font]
+;
+;;?????
+;; cmp edx, [.height]
+;; jg .drawchunks
+;
+;; mov [.lineh], edx
+;
+; cmp eax, [edi+TBounds.width]
+; jle .itfits
+;
+; mov [.high], ebx
+; mov [.low], 0
+;
+;.croploop:
+; mov ebx, [.low]
+; add ebx, [.high]
+; shr ebx, 1
+;
+; cmp ebx, 1
+; ja .check_width
+;
+; mov ebx, 1
+; jmp .itfits
+;
+;.check_width:
+; stdcall AdjustCountUtf8
+; stdcall GetTextBounds, [.context], esi, ebx, [.font]
+; cmp eax, [edi+TBounds.width]
+; je .itfits
+;
+; jg .above
+;
+; cmp ebx, [.low]
+; je .itfits
+;
+; mov [.low], ebx
+; jmp .croploop
+;
+;.above:
+; mov [.high], ebx
+; jmp .croploop
+;
+;.itfits: ; here ebx contains the len of string that fits in the rectangle.
+; mov ecx, ebx
+; mov [.linew], eax
+;
+; test [.flags], dtfWordWrap
+; jz .pushit
+;
+;; search the last space or tab that separates words:
+; mov edx, ecx
+;
+;.searchword:
+; cmp byte [esi+edx], 0
+; je .found
+; cmp byte [esi+edx], ' '
+; je .found
+; cmp byte [esi+edx], $09
+; je .found
+; cmp byte [esi+edx], $0d
+; je .found
+; cmp byte [esi+edx], $0a
+; je .found
+;
+; dec edx
+; jnz .searchword
+;
+; mov edx, ecx
+;
+;.found:
+; push ebx
+; mov ebx, edx
+;
+; stdcall AdjustCountUtf8
+;
+; stdcall GetTextBounds, [.context], esi, ebx, [.font]
+;
+; mov [.linew], eax
+; mov [.lineh], edx
+; mov ecx, ebx
+; pop ebx
+;
+;.pushit:
+; push esi ; pointer to the string.
+; push ecx ; length of the string in bytes.
+; push [.lineh] ; height of the line in pixels.
+; push [.linew] ; width of the line in pixels.
+; push [.y] ; y coordinate of the line.
+;
+; inc [.count]
+;
+; mov eax, [.lineh]
+; add [.y], eax
+; sub [.height], eax
+;
+; lea esi, [esi+ecx]
+; sub [.len], ecx
+; jz .drawchunks
+;
+; xor ecx, ecx
+;
+;; search for the whitespace that have to be skip
+;.skiploop:
+; mov al, [esi]
+; cmp al, $0d
+; je .skipcrlf
+; cmp al, $0a
+; je .skipcrlf
+; cmp al, $20
+; je .skipspace
+; cmp al, $09
+; je .skipspace
+;
+; jmp .slice
+;
+;.skipspace:
+; inc esi
+; dec [.len]
+; jnz .skiploop
+; jmp .drawchunks
+;
+;.skipcrlf:
+; inc esi
+; dec [.len]
+; xor al, $0d xor $0a
+; cmp [esi], al
+; jne .slice
+; inc esi
+; dec [.len]
+; jnz .slice
+;
+;
+;
+;
+;
+; return
+;endp
+
+
+
+
+;proc DrawTextBox, .context, .text, .bounds, .flags, .font, .color
+;.len dd ?
+;.count dd ?
+;.height dd ?
+;.y dd ?
+;
+;.low dd ?
+;.high dd ?
+;
+;.linew dd ?
+;.lineh dd ?
+;
+;.DrawProc dd ?
+;begin
+; pushad
+;
+; mov ecx, DrawString
+;
+; mov eax, [.flags]
+; and eax, $03
+; cmp eax, dtfAlignJustify
+; jne @f
+; mov ecx, DrawStringJustified
+;@@:
+; mov [.DrawProc], ecx
+;
+; stdcall StrLen, [.text]
+; mov [.len], eax
+;
+; stdcall StrPtr, [.text]
+; mov esi, eax
+;
+; mov edi, [.bounds]
+; mov eax, [edi+TBounds.height]
+;; mov ecx, [edi+TBounds.y]
+; mov [.height], eax
+; mov [.y], 0 ;ecx
+;
+;; slice the string on chunks, depending on flags, rectangle width and the string content.
+;; push _TTextChunk for every chunk in stack.
+; mov [.count], 0
+;
+;.slice:
+; mov ecx, [.len]
+;
+; test [.flags], dtfCRLF
+; jz .cropit
+;
+; xor ecx, ecx
+;
+;.scanCRLF:
+; cmp ecx, [.len]
+; jae .cropit
+;
+; mov al, [esi+ecx]
+;
+; cmp al, $0d
+; je .cropit
+; cmp al, $0a
+; je .cropit
+; inc ecx
+; jmp .scanCRLF
+;
+;.cropit:
+; mov ebx, ecx ; high limit
+;
+; stdcall AdjustCountUtf8
+; stdcall GetTextBounds, [.context], esi, ebx, [.font]
+;
+; cmp edx, [.height]
+; jg .drawchunks
+;
+; mov [.lineh], edx
+;
+; cmp eax, [edi+TBounds.width]
+; jle .itfits
+;
+; mov [.high], ebx
+; mov [.low], 0
+;
+;.croploop:
+; mov ebx, [.low]
+; add ebx, [.high]
+; shr ebx, 1
+;
+; cmp ebx, 1
+; ja .check_width
+;
+; mov ebx, 1
+; jmp .itfits
+;
+;.check_width:
+; stdcall AdjustCountUtf8
+; stdcall GetTextBounds, [.context], esi, ebx, [.font]
+; cmp eax, [edi+TBounds.width]
+; je .itfits
+;
+; jg .above
+;
+; cmp ebx, [.low]
+; je .itfits
+;
+; mov [.low], ebx
+; jmp .croploop
+;
+;.above:
+; mov [.high], ebx
+; jmp .croploop
+;
+;.itfits: ; here ebx contains the len of string that fits in the rectangle.
+; mov ecx, ebx
+; mov [.linew], eax
+;
+; test [.flags], dtfWordWrap
+; jz .pushit
+;
+;; search the last space or tab that separates words:
+; mov edx, ecx
+; cmp byte [esi+edx], $0d
+; je .found
+; cmp byte [esi+edx], $0a
+; je .found
+;
+;.searchword:
+; cmp byte [esi+edx], 0
+; je .found
+; cmp byte [esi+edx], ' '
+; je .found
+; cmp byte [esi+edx], $09
+; je .found
+; cmp byte [esi+edx], $0d
+; je .found
+; cmp byte [esi+edx], $0a
+; je .found
+;
+; dec edx
+; jnz .searchword
+;
+; mov edx, ecx
+;
+;.found:
+; push ebx
+; mov ebx, edx
+; stdcall AdjustCountUtf8
+; stdcall GetTextBounds, [.context], esi, ebx, [.font]
+; mov [.linew], eax
+; mov [.lineh], edx
+; mov ecx, ebx
+; pop ebx
+;
+;.pushit:
+; push esi ; pointer to the string.
+; push ecx ; length of the string.
+; push [.lineh] ; height of the line.
+; push [.linew] ; width of the line.
+; push [.y] ;
+;
+; inc [.count]
+;
+; mov eax, [.lineh]
+; add [.y], eax
+; sub [.height], eax
+;
+; lea esi, [esi+ecx]
+; sub [.len], ecx
+; jz .drawchunks
+;
+; xor ecx, ecx
+;
+;; search for the whitespace that have to be skip
+;.skiploop:
+; mov al, [esi]
+; cmp al, $0d
+; je .skipcrlf
+; cmp al, $0a
+; je .skipcrlf
+; cmp al, $20
+; je .skipspace
+; cmp al, $09
+; je .skipspace
+;
+; jmp .slice
+;
+;.skipspace:
+; inc esi
+; dec [.len]
+; jnz .skiploop
+; jmp .drawchunks
+;
+;.skipcrlf:
+; inc esi
+; dec [.len]
+; xor al, $0d xor $0a
+; cmp [esi], al
+; jne .slice
+; inc esi
+; dec [.len]
+; jnz .slice
+;
+;; pop the _TTextChunk structures and draw, depending on flags.
+;.drawchunks:
+; cmp [.count], 0
+; je .finish
+;
+; mov ebx, esp
+; stdcall GetTextOffset, [.context], [ebx+_TTextChunk.ptr], [ebx+_TTextChunk.len], [.font]
+; mov eax, [ebx+_TTextChunk.height]
+; sub eax, edx ; it should be the line y descent
+; test [.flags], dtfAlignBottom
+; jnz @f
+; sub [.y], eax
+;@@:
+; mov edx, [.flags]
+; and edx, dtfAlignBottom or dtfAlignMiddle
+;
+; mov ecx, [edi+TBounds.height]
+; sub ecx, [.y]
+;
+; cmp edx, dtfAlignBottom
+; je .yalignok
+;
+; sar ecx, 1
+; cmp edx, dtfAlignMiddle
+; je .yalignok
+;
+; xor ecx, ecx
+;
+;.yalignok:
+;.drawloop:
+; cmp [.count], 0
+; je .finish
+;
+; mov ebx, esp
+;
+; mov eax, [edi+TBounds.width]
+; sub eax, [ebx+_TTextChunk.width]
+;
+; mov edx, [.flags]
+; and edx, $03
+;
+; cmp edx, dtfAlignRight
+; je .hready
+;
+; shr eax, 1
+; cmp edx, dtfAlignCenter
+; je .hready
+;
+; xor eax, eax
+;
+;.hready:
+; add eax, [edi+TBounds.x]
+;
+; push eax
+; stdcall GetTextOffset, [.context], [ebx+_TTextChunk.ptr], [ebx+_TTextChunk.len], [.font]
+; add edx, ecx
+; add edx, [ebx+_TTextChunk.y]
+; add edx, [edi+TBounds.y]
+; pop eax
+;
+; stdcall [.DrawProc], [.context], [ebx+_TTextChunk.ptr], [ebx+_TTextChunk.len], eax, edx, [.font], [.color]
+;
+;;; draws lines on every row of text. For debug purposes.
+;;iglobal
+;; if used __UnderlineStyle
+;; __UnderlineStyle LineStyle 0, $808080
+;; end if
+;;endg
+;;
+;;if defined options.DebugMode & options.DebugMode
+;; stdcall SetLineStyle, [.context], __UnderlineStyle
+;; stdcall DrawLine, [.context], [edi+TBounds.x], edx, [edi+TBounds.width], edx
+;;end if
+;;; end debug code
+;
+;
+; add esp, sizeof._TTextChunk
+; dec [.count]
+; jmp .drawloop
+;
+;.finish:
+; popad
+; return
+;endp
+;
+;
+;
+;
+;proc DrawStringJustified, .raster, .ptrString, .len, .x, .y, .font, .color
+;.XX dd ?
+;.rem dd ?
+;.crem dd ?
+;.endptr dd ?
+;begin
+; pushad
+;
+; mov esi, [.ptrString]
+; mov eax, [.len]
+; add eax, esi
+; mov [.endptr], eax
+;
+; stdcall StrLenUtf8, esi, [.len]
+; mov ecx, eax
+; dec ecx
+; jg @f
+; mov ecx, 1
+;@@:
+;
+; stdcall GetTextBounds, [.raster], esi, [.len], [.font]
+;
+; sub eax, [edi+TBounds.width]
+; neg eax
+;
+; cdq
+; div ecx
+;
+; cmp eax, 4
+; jge .cantjustify ; the needed space is too big for justify, so just draw it left aligned
+;
+; mov ecx, eax
+; mov [.rem], edx
+; mov [.crem], edx
+;
+; mov ebx, [.len]
+; push [.x]
+; pop [.XX]
+;
+;.drawloop:
+; cmp esi, [.endptr]
+; jae .finish
+;
+; stdcall DecodeUtf8, [esi]
+; jc .finish
+;
+; push edx
+; stdcall DrawString, [.raster], esi, edx, [.XX], [.y], [.font], [.color]
+; stdcall GetTextBounds, [.raster], esi, edx, [.font]
+; pop edx
+; add esi, edx
+; add [.XX], eax
+; add [.XX], ecx
+;
+; cmp [.crem], 0
+; je .drawloop
+;
+; sub ebx, [.rem]
+; jge .drawloop
+;
+; inc [.XX]
+; dec [.crem]
+; mov ebx, [.len]
+; sub ebx, [.rem]
+; jmp .drawloop
+;
+;.finish:
+; popad
+; return
+;
+;.cantjustify:
+; stdcall DrawString, [.raster], [.ptrString], [.len], [.x], [.y], [.font], [.color]
+; jmp .finish
+;endp
+
+
+include "%TargetOS%/text.asm"
+
endmodule
Index: freshlib/gui/KolibriOS/Main.asm
==================================================================
--- freshlib/gui/KolibriOS/Main.asm
+++ freshlib/gui/KolibriOS/Main.asm
@@ -39,11 +39,11 @@
; 1. The window that receives the message is not FreshLib object.
; 2. TObjectClass.procSysEventHandler = 0 for the given class and all parents.
; 3. All procSysEventHandler procedures refuse to process the event (CF=1)
;----------------------------------------------------------------------------------------------------------
-dproc __ProcessOneSystemEvent, .hwnd, .wmsg, .wparam, .lparam
+proc __ProcessOneSystemEvent, .hwnd, .wmsg, .wparam, .lparam
begin
dispatch [.wmsg]
.ondefault:
@@ -51,8 +51,11 @@
return
oncase 0
clc
return
-enddp
+
+
+ enddispatch
+endp
Index: freshlib/gui/KolibriOS/TApplication.asm
==================================================================
--- freshlib/gui/KolibriOS/TApplication.asm
+++ freshlib/gui/KolibriOS/TApplication.asm
@@ -11,10 +11,22 @@
;
; Notes:
;_________________________________________________________________________________________
-method TApplication.Create
+
+
+uglobal
+ var FTLibrary = ?
+ var FTCManager = ?
+ var FTCImageCache = ?
+ var FTCCMapCache = ?
+endg
+
+
+
+
+method TApplication.__create
begin
return
endp
Index: freshlib/gui/KolibriOS/mouse.asm
==================================================================
--- freshlib/gui/KolibriOS/mouse.asm
+++ freshlib/gui/KolibriOS/mouse.asm
@@ -24,9 +24,9 @@
begin
return
endp
-proc MouseCapture, .hwnd
+proc __MouseCapture, .hwnd
begin
return
endp
Index: freshlib/gui/KolibriOS/windows.asm
==================================================================
--- freshlib/gui/KolibriOS/windows.asm
+++ freshlib/gui/KolibriOS/windows.asm
@@ -10,110 +10,91 @@
; Dependencies:
;
; Notes:
;_________________________________________________________________________________________
+
+
+body _CreateNullWindow
+begin
+ return
+endp
+
+;_________________________________________________________________________________________
+
+
+
+body _DestroyWindow
+begin
+ return
+endp
+
+
+;_________________________________________________________________________________________
+
+
+body _GetWindowBounds
+begin
+ return
+endp
+
+
+
+;_________________________________________________________________________________________
+
+
+body _SetWindowBounds
+begin
+ return
+endp
+
+;_________________________________________________________________________________________
+
+
+
+body _ClientToScreen
+begin
+
+ return
+endp
+
+
;_________________________________________________________________________________________
-
-proc _CreateNullWindow
+body _SetWindowBorder
begin
return
endp
;_________________________________________________________________________________________
-
-
-proc _DestroyWindow, .hwnd
+body _ShowWindow
begin
return
endp
;_________________________________________________________________________________________
-proc _GetParent, .hwnd
-begin
- return
-endp
-
-;_________________________________________________________________________________________
-
-
-proc _GetChildren, .hwnd
+body _RefreshWindowRect
begin
return
endp
;_________________________________________________________________________________________
-
-proc _GetVisible, .hwnd
-begin
- return
-endp
-
-;_________________________________________________________________________________________
-
-
-proc _GetWindowBounds, .hwnd, .pBounds
-begin
- return
-endp
-
-
-
-;_________________________________________________________________________________________
-
-
-proc _SetWindowBounds, .hwnd, .pBounds
-begin
- return
-endp
-
-
-
-
-
-;_________________________________________________________________________________________
-
-proc _SetWindowBorder, .hwnd, .brdType
+body _SetWindowTextUtf8
begin
return
endp
;_________________________________________________________________________________________
-proc _ShowWindow, .hwnd, .flag
-begin
- return
-endp
-
-
-;_________________________________________________________________________________________
-
-
-proc _RefreshWindow, .hwnd
-begin
- return
-endp
-
-
-;_________________________________________________________________________________________
-
-
-proc _SetFocus, .hwnd
-begin
- return
-endp
-
-;_________________________________________________________________________________________
proc _AddChild, .hwnd, .child
begin
return
endp
@@ -127,79 +108,41 @@
;_________________________________________________________________________________________
;
; Returns the window TObject structure, from the window handle.
;_________________________________________________________________________________________
-proc _GetWindowStruct, .hwin
+body _GetWindowStruct
begin
return
endp
+
+;_________________________________________________________________________________________
+
+
+
+body _SetWindowStruct
+begin
+ return
+endp
+
;_________________________________________________________________________________________
-
-proc _SetWindowStruct, .hwin, .value
+body _SetModalTowards
begin
return
endp
;_________________________________________________________________________________________
-
-proc _SetWindowTextUtf8, .hwnd, .ptrUtf8
-begin
- return
-endp
-
-
-
-;_________________________________________________________________________________________
-
-
-
-proc _GetWindowTextUtf8, .hwnd, .ptrUtf8
-begin
- return
-endp
-
-
-
-;_________________________________________________________________________________________
-
-
-proc _EnableWindow, .hwnd, .flag
+body _FinalizeModal
begin
return
endp
;_________________________________________________________________________________________
-
-
-proc _SetModalTowards, .hwnd, .hwndParent
-begin
- return
-endp
-
-
-;_________________________________________________________________________________________
-
-
-proc _FinalizeModal, .hwnd, .hwndParent
-begin
- return
-endp
-
-
-;_________________________________________________________________________________________
-
-
-proc __CommonWindowProc, .hwnd, .wmsg, .wparam, .lparam
-begin
- return
-endp
-
Index: freshlib/gui/Linux/Main.asm
==================================================================
--- freshlib/gui/Linux/Main.asm
+++ freshlib/gui/Linux/Main.asm
@@ -17,13 +17,14 @@
fGlobalTerminate dd ?
end if
endg
-proc ProcessSystemEvents
+
+body ProcessSystemEvents
.event XEvent
- rd 256
+ rb 256
begin
push ebx ecx edx
.event_loop:
; check for quit
@@ -68,11 +69,11 @@
endp
-proc WaitForSystemEvent
+body WaitForSystemEvent
.event XEvent
begin
push eax ecx edx
lea eax, [.event]
cinvoke XPeekEvent, [hApplicationDisplay], eax
@@ -80,29 +81,14 @@
return
endp
-
-;proc EventsQueued, .pWin
-;begin
-; push eax ecx edx
-; cinvoke XQLength, [hApplicationDisplay]
-; test eax, eax
-; clc
-; jz @f
-; stc
-;@@:
-; pop edx ecx eax
-; return
-;endp
-
proc __ProcessOneSystemEvent, .linux_event
-.event rd 64
begin
pushad
mov ebx, [.linux_event]
@@ -109,75 +95,43 @@
; mov eax, [ebx+XEvent.type]
; cmp eax, [ShmCompletionEvent]
; je .shm_completion
stdcall _GetWindowStruct, [ebx+XEvent.window]
- mov esi, eax
- lea edi, [.event]
- mov eax, [ebx+XEvent.type]
-
- cmp eax, DestroyNotify
- je .destroy
-
- test esi, esi
+ jc .notprocessed
+
+ test eax, eax
jz .notprocessed
- cmp eax, MotionNotify
- je .mousemove
-
- cmp eax, EnterNotify
- je .mouseenter
-
- cmp eax, LeaveNotify
- je .mouseleave
-
- cmp eax, ButtonPress
- je .mouse_btn_press
-
- cmp eax, ButtonRelease
- je .mouse_btn_release
-
- cmp eax, Expose
- je .expose
-
- cmp eax, ClientMessage ; event from the window manager - button close for example.
- je .clientmessage
-
- cmp eax, KeyPress
- je .key_press
-
- cmp eax, KeyRelease
- je .key_release
-
- cmp eax, MappingNotify
- je .mapping_notify
-
- cmp eax, FocusIn
- je .focusin
-
- cmp eax, FocusOut
- je .focusout
-
- cmp eax, ConfigureNotify
- je .moveresize
+ mov esi, eax
+ mov ecx, [ebx+XEvent.type]
+
+ cmp ecx, LASTEvent
+ jae .notprocessed
+
+ mov ecx, [.jump_table+4*ecx]
+ jecxz .notprocessed
+
+ jmp ecx
+
.notprocessed:
popad
stc
return
-.exec_event:
- exec esi, TWindow:SysEventHandler, edi
-
.finish:
popad
clc
return
;.shm_completion:
-; mov [ShmImageLock], 0
+; DebugMsg "Put back completion event!"
+;
+; int3
+; cinvoke XPutBackEvent, [hApplicationDisplay], ebx
; jmp .finish
;.........................................................................
; seMove and seResize events.
;-------------------------------------------------------------------------
@@ -184,46 +138,34 @@
.moveresize:
cinvoke XCheckTypedWindowEvent, [hApplicationDisplay], [ebx+XConfigureEvent.window], ConfigureNotify, ebx
test eax, eax
jnz .moveresize
-; seResize event...
- mov [edi+TResizeEvent.event], seResize
-
- mov eax, [ebx+XConfigureEvent.width]
- mov ecx, [ebx+XConfigureEvent.height]
-
- mov [edi+TResizeEvent.newWidth], eax
- mov [edi+TResizeEvent.newHeight], ecx
-
- DebugMsg "Resize event sent."
- OutputRegister regEAX, 10
- OutputRegister regECX, 10
-
- exec esi, TWindow:SysEventHandler, edi
-
-; seMove event...
- mov [edi+TMoveEvent.event], seMove
-
- mov eax, [ebx+XConfigureEvent.x]
- mov ecx, [ebx+XConfigureEvent.y]
- mov [edi+TMoveEvent.newX], eax
- mov [edi+TMoveEvent.newY], ecx
- jmp .exec_event
-
-;.........................................................................
-; Focus events
-.focusout:
- mov [edi+TFocusOutEvent.event], seFocusOut
- jmp .setIC
-
-.focusin:
- mov [edi+TFocusInEvent.event], seFocusIn
-
-.setIC:
- cinvoke XSetICValues, [hInputContext], XNFocusWindow, [esi+TWindow.handle], 0
- jmp .exec_event
+; resize event...
+ mov eax, [esi+TWindow._width]
+ mov edx, [esi+TWindow._height]
+ cmp eax, [ebx+XConfigureEvent.width]
+ jne .resize
+ cmp edx, [ebx+XConfigureEvent.height]
+ je .is_move
+
+.resize:
+ exec esi, TWindow:EventResize, [ebx+XConfigureEvent.width], [ebx+XConfigureEvent.height]
+
+; move event...
+.is_move:
+ mov eax, [esi+TWindow._x]
+ mov edx, [esi+TWindow._y]
+ cmp eax, [ebx+XConfigureEvent.x]
+ jne .move
+ cmp eax, [ebx+XConfigureEvent.y]
+ je .finish
+
+.move:
+ exec esi, TWindow:EventMove, [ebx+XConfigureEvent.x], [ebx+XConfigureEvent.y]
+
+ jmp .finish
;.........................................................................
; DestroyNotify handler it invalidates the handle in TWindow structure and then destroys TWindow.
.destroy:
test esi, esi
@@ -231,75 +173,153 @@
mov [esi+TWindow.handle], 0
destroy esi
jmp .finish
+
;.........................................................................
; Mouse event handlers
-.mouseleave:
- mov [edi+TMouseEnterEvent.event], seMouseLeave
- jmp .exec_event
-
-.mouseenter:
- mov [edi+TMouseEnterEvent.event], seMouseEnter
- jmp .exec_event
-
.mousemove:
- mov [edi+TMouseMoveEvent.event], seMouseMove
- mov eax, [ebx+XMotionEvent.x]
- mov ecx, [ebx+XMotionEvent.y]
- mov [edi+TMouseMoveEvent.x], eax
- mov [edi+TMouseMoveEvent.y], ecx
- jmp .exec_event
+ cinvoke XCheckTypedWindowEvent, [hApplicationDisplay], [ebx+XConfigureEvent.window], MotionNotify, ebx
+ test eax, eax
+ jnz .mousemove
+
+
+ stdcall ServeMenuMouseMove, [ebx+XMotionEvent.window], [ebx+XMotionEvent.x], [ebx+XMotionEvent.y], [ebx+XMotionEvent.state]
+ jc .finish
+
+ cinvoke XCheckTypedWindowEvent, [hApplicationDisplay], [ebx+XMotionEvent.window], MotionNotify, ebx
+ test eax, eax
+ jnz .mousemove
+
+ mov edi, [__MouseTarget]
+ test edi, edi
+ jz .search_target_move
+
+ stdcall __GetRelativeXY, edi, [ebx+XMotionEvent.x], [ebx+XMotionEvent.y]
+ jmp .target_move
+
+.search_target_move:
+ exec esi, TWindow:ChildByXY, [ebx+XMotionEvent.x], [ebx+XMotionEvent.y], TRUE
+ mov edi, eax
+
+.target_move:
+ cmp edi, [__LastPointedWindow]
+ je .move_event
+
+ cmp [__LastPointedWindow], 0
+ je .leave_ok
+
+ exec [__LastPointedWindow], TWindow:EventMouseLeave
+
+.leave_ok:
+
+ mov [__LastPointedWindow], edi
+ exec edi, TWindow:EventMouseEnter
+
+.move_event:
+ exec edi, TWindow:EventMouseMove, ecx, edx, [ebx+XMotionEvent.state]
+ jmp .finish
+
+
+
+;.........................................................................
+
+
.mouse_btn_press:
-.mouse_btn_release:
-
- mov eax, [ebx+XButtonEvent.type]
- mov [edi+TMouseButtonEvent.event], eax ; seMouseBtnPress=ButtonPress and seMouseBtnRelease = ButtonRelease
-
- mov eax, [ebx+XButtonEvent.button]
- dec eax
-
- cmp [edi+TScrollEvent.event], seMouseBtnRelease
- je @f
-
- cmp eax, 3
+ stdcall ServeMenuButtonPress, [ebx+XButtonEvent.window], [ebx+XButtonEvent.button], [ebx+XButtonEvent.state], [ebx+XButtonEvent.x], [ebx+XButtonEvent.y]
+ jc .finish
+
+ mov edi, [__MouseTarget]
+ test edi, edi
+ jz .search_target_press
+
+ stdcall __GetRelativeXY, edi, [ebx+XButtonEvent.x], [ebx+XButtonEvent.y]
+ jmp .target_press
+
+.search_target_press:
+ exec esi, TWindow:ChildByXY, [ebx+XButtonEvent.x], [ebx+XButtonEvent.y], TRUE
+ mov edi, eax
+
+.target_press:
+ get eax, eax, TWindow:GlobalEnabled
+ test eax, eax
+ jz .finish
+
+ cmp [ebx+XButtonEvent.button], 4
jge .wheelscroll
+; deal with focus
+
+ cmp edi, [__FocusedWindow]
+ je .focusok
+
+ get eax, edi, TWindow:WantFocus
+ test eax, eax
+ jz .focusok
+
+ mov eax, [__FocusedWindow]
+ mov [__FocusedWindow], edi
+
+ test eax, eax
+ jz @f
+ exec eax, TWindow:EventFocusOut
@@:
- mov [edi+TMouseButtonEvent.Button], eax
-
- mov eax, [ebx+XButtonEvent.state]
- mov [edi+TMouseButtonEvent.kbdStatus], eax
-
- mov eax, [ebx+XButtonEvent.x]
- mov ecx, [ebx+XButtonEvent.y]
- mov [edi+TMouseButtonEvent.x], eax
- mov [edi+TMouseButtonEvent.y], ecx
-
- jmp .exec_event
+
+ exec edi, TWindow:EventFocusIn
+
+.focusok:
+ exec edi, TWindow:EventButtonPress, [ebx+XButtonEvent.button], [ebx+XButtonEvent.state], ecx, edx
+ jmp .finish
+
.wheelscroll:
mov ecx, scWheelUp
je @f
mov ecx, scWheelDn
@@:
- mov [edi+TScrollEvent.event], seScroll
- mov [edi+TScrollEvent.ScrollBar], scrollY
- mov [edi+TScrollEvent.ScrollCmd], ecx
- mov [edi+TScrollEvent.Value], 1
- jmp .exec_event
+
+ exec edi, TWindow:EventScroll, scrollY, ecx, 1
+ jmp .finish
+
+
+
+;.........................................................................
+
+
+
+.mouse_btn_release:
+ mov edi, [__MouseTarget]
+ test edi, edi
+ jz .search_target_release
+
+ stdcall __GetRelativeXY, edi, [ebx+XButtonEvent.x], [ebx+XButtonEvent.y]
+ jmp .target_release
+
+.search_target_release:
+ exec esi, TWindow:ChildByXY, [ebx+XButtonEvent.x], [ebx+XButtonEvent.y], TRUE
+ mov edi, eax
+
+.target_release:
+ get eax, eax, TWindow:GlobalEnabled
+ test eax, eax
+ jz .finish
+
+ exec edi, TWindow:EventButtonRelease, [ebx+XButtonEvent.button], [ebx+XButtonEvent.state], ecx, edx
+ jmp .finish
+
;.........................................................................
; Window paint event
.expose:
- lea eax, [ebx+XExposeEvent.x]
- stdcall __PaintWindow, esi, eax
+ get edi, esi, TWindow:ImgScreen
+
+ stdcall DrawImageRect, [esi+TWindow.handle], edi, [ebx+XExposeEvent.x], [ebx+XExposeEvent.y], [ebx+XExposeEvent.x], [ebx+XExposeEvent.y], [ebx+XExposeEvent.width], [ebx+XExposeEvent.height]
jmp .finish
;.........................................................................
; Keyboard events.
@@ -307,38 +327,40 @@
locals
.utf8buff rb 16
endl
.key_press:
- mov ecx, seKbdKeyPress
- mov [edi+TKeyboardEvent.event], ecx
- mov ecx, [ebx+XKeyEvent.state]
- mov [edi+TKeyboardEvent.kbdStatus], ecx
+
+ cmp [__FocusedWindow], 0
+ je .finish
mov dword [.utf8buff], 0
lea eax, [.utf8buff]
cinvoke Xutf8LookupString, [hInputContext], ebx, eax, 16, 0, 0
-; here, .utg8buff contains the utf-8 string with the character typed on the keyboard.
- mov eax, dword [.utf8buff]
- mov [edi+TKeyboardEvent.key], eax
-
-.scancode:
mov eax, [ebx+XKeyEvent.keycode]
cinvoke XKeycodeToKeysym, [hApplicationDisplay], eax, 0
- mov [edi+TKeyboardEvent.scancode], eax
- jmp .exec_event
+
+ exec [__FocusedWindow], TWindow:EventKeyPress, dword [.utf8buff], eax, [ebx+XKeyEvent.state]
+ jmp .finish
+
+
+
+;.........................................................................
+
.key_release:
- mov ecx, seKbdKeyRelease
- mov eax, [ebx+XKeyEvent.state]
+
+ cmp [__FocusedWindow], 0
+ je .finish
+
+ mov eax, [ebx+XKeyEvent.keycode]
+ cinvoke XKeycodeToKeysym, [hApplicationDisplay], eax, 0
- mov [edi+TKeyboardEvent.event], ecx
- mov [edi+TKeyboardEvent.kbdStatus], eax
- mov [edi+TKeyboardEvent.key], 0
- jmp .scancode
+ exec [__FocusedWindow], TWindow:EventKeyRelease, eax, [ebx+XKeyEvent.state]
+ jmp .finish
; refreshes keyboard mapping information, stored locally in XLib.
.mapping_notify:
@@ -355,78 +377,90 @@
cmp eax, [atomWMDelete]
jne .finish
; The window is closed by click on close button or by pressing Alt+F4 or by other WM method
;.close_from_wm:
- mov [edi+TCloseEvent.event], seCloseRequest
- mov [edi+TCloseEvent.reason], cerFromUser
- jmp .exec_event
-endp
-
-
-
-
-
-
-
-
-proc __PaintWindow, .pWindow, .ptrBounds
-.event TPaintEvent
-.caret dd ?
-begin
- pushad
-
- lea edi, [.event]
- mov esi, [.pWindow]
-
-if defined Caret
- mov [.caret], -1
- cmp esi, [Caret.pWindow]
- jne @f
- stdcall CaretShow, FALSE
- mov [.caret], eax
-@@:
-end if
- mov [edi+TPaintEvent.event], sePaint
-
- stdcall AllocateContext, [esi+TWindow.handle]
- mov ebx, eax
- mov [edi+TPaintEvent.context], eax
-
- xor eax, eax
- mov [edi+TPaintEvent.rect.left], eax
- mov [edi+TPaintEvent.rect.top], eax
- mov eax, $7fffffff
- mov [edi+TPaintEvent.rect.right], eax
- mov [edi+TPaintEvent.rect.bottom], eax
-
- mov edx, [.ptrBounds]
- test edx, edx
- jz .rectok
-
- mov eax, [edx+TBounds.x]
- mov ecx, [edx+TBounds.y]
-
- mov [edi+TPaintEvent.rect.left], eax
- mov [edi+TPaintEvent.rect.top], ecx
-
- mov eax, [edx+TBounds.width]
- mov ecx, [edx+TBounds.height]
- add eax, [edi+TPaintEvent.rect.left]
- add ecx, [edi+TPaintEvent.rect.top]
- mov [edi+TPaintEvent.rect.right], eax
- mov [edi+TPaintEvent.rect.bottom], ecx
-
-.rectok:
- exec esi, TWindow:SysEventHandler, edi
-
- stdcall ReleaseContext, ebx
-
-if defined Caret
- cmp [.caret], -1
- je @f
- stdcall CaretShow, [.caret]
-@@:
-end if
- popad
- return
-endp
+
+ exec esi, TWindow:CloseRequest, cerFromUser
+ jmp .finish
+
+
+; Focus handling events.
+
+.focusin:
+ call .hide_menu
+
+ stdcall __SearchWindowToFocus, esi
+
+ mov [__FocusedWindow], eax
+
+ test eax, eax
+ jz .finish
+
+ exec eax, TWindow:EventFocusIn
+ jmp .finish
+
+
+.focusout:
+ call .hide_menu
+
+ xor ebx, ebx
+ xchg [__FocusedWindow], ebx
+ test ebx, ebx
+ jz .finish
+
+ exec ebx, TWindow:EventFocusOut
+ jmp .finish
+
+
+
+.hideall:
+ DebugMsg "Hide one menu"
+ set [__ActiveMenu], TWindow:Visible, FALSE
+
+.hide_menu:
+ cmp [__ActiveMenu], 0
+ jne .hideall
+
+ retn
+
+
+
+.jump_table dd 0 ; event 0
+ dd 0 ; event 1
+ dd .key_press ; KeyPress = 2
+ dd .key_release ; KeyRelease = 3
+ dd .mouse_btn_press ; ButtonPress = 4
+ dd .mouse_btn_release ; ButtonRelease = 5
+ dd .mousemove ; MotionNotify = 6
+ dd 0 ; EnterNotify = 7
+ dd 0 ; LeaveNotify = 8
+ dd .focusin ; FocusIn = 9
+ dd .focusout ; FocusOut = 10
+ dd 0 ; KeymapNotify = 11
+ dd .expose ; Expose = 12
+ dd 0 ; GraphicsExpose = 13
+ dd 0 ; NoExpose = 14
+ dd 0 ; VisibilityNotify = 15
+ dd 0 ; CreateNotify = 16
+ dd .destroy ; DestroyNotify = 17
+ dd 0 ; UnmapNotify = 18
+ dd 0 ; MapNotify = 19
+ dd 0 ; MapRequest = 20
+ dd 0 ; ReparentNotify = 21
+ dd .moveresize ; ConfigureNotify = 22
+ dd 0 ; ConfigureRequest = 23
+ dd 0 ; GravityNotify = 24
+ dd 0 ; ResizeRequest = 25
+ dd 0 ; CirculateNotify = 26
+ dd 0 ; CirculateRequest = 27
+ dd 0 ; PropertyNotify = 28
+ dd 0 ; SelectionClear = 29
+ dd 0 ; SelectionRequest = 30
+ dd 0 ; SelectionNotify = 31
+ dd 0 ; ColormapNotify = 32
+ dd .clientmessage ; ClientMessage = 33
+ dd .mapping_notify ; MappingNotify = 34
+endp
+
+
+
Index: freshlib/gui/Linux/TApplication.asm
==================================================================
--- freshlib/gui/Linux/TApplication.asm
+++ freshlib/gui/Linux/TApplication.asm
@@ -14,100 +14,109 @@
;_________________________________________________________________________________________
uglobal
if used hApplicationDisplay
- hApplicationDisplay dd ?
- hRootWindow dd ?
-
- hInputMethod dd ?
- hInputContext dd ?
-
- _SystemFont dd ?
-
- atomWMDelete dd ?
-
- ShmCompletionEvent dd ?
- FTLibrary dd ?
- FTCManager dd ?
- FTCImageCache dd ?
- FTCCMapCache dd ?
+ var hApplicationDisplay = ?
+ var hRootWindow = ?
+
+ var hInputMethod = ?
+ var hInputContext = ?
+
+ var atomWMDelete = ?
+
+ var atomState = ?
+ var atomStateAbove = ?
+ var atomStateModal = ?
+
+ var atomAllowedActions = ?
+ var atomActionMove = ?
+ var atomActionResize = ?
+ var atomActionMinimize = ?
+ var atomActionShade = ?
+ var atomActionStick = ?
+ var atomActionMaximizeHorz = ?
+ var atomActionMaximizeVert = ?
+ var atomActionFullscreen = ?
+ var atomActionChangeDesktop = ?
+ var atomActionClose = ?
+
+ var atomWindowType = ?
+ var atomWindowTypeMenu = ?
+ var atomWindowTypeUtility = ?
+ var atomWindowTypeDialog = ?
+ var atomWindowTypeNormal = ?
+
+ var ShmCompletionEvent = ?
+ var FTLibrary = ?
+ var FTCManager = ?
+ var FTCImageCache = ?
+ var FTCCMapCache = ?
end if
endg
-;cDefaultFont text 'Tahoma-8'
-cDefaultFont text 'Liberation Sans-9'
-cDefaultFontSize = 9
-;cDefaultFont text 'Ubuntu-9:rgba=rgb'
-;cDefaultFont text 'Unifont-12' ; this one have unicode support;
-; String constants needed for XLib
-; Why, they needed so many strings????????????????? For arguments!??????????
-_cWinDeleteName text 'WM_DELETE_WINDOW'
-
-XNVaNestedList text "XNVaNestedList"
-XNSeparatorofNestedList text "separatorofNestedList"
+;XNVaNestedList text "XNVaNestedList"
+;XNSeparatorofNestedList text "separatorofNestedList"
XNQueryInputStyle text "queryInputStyle"
-XNClientWindow text "clientWindow"
+;XNClientWindow text "clientWindow"
XNInputStyle text "inputStyle"
-XNFocusWindow text "focusWindow"
-XNResourceName text "resourceName"
-XNResourceClass text "resourceClass"
-XNGeometryCallback text "geometryCallback"
-XNDestroyCallback text "destroyCallback"
-XNFilterEvents text "filterEvents"
-XNPreeditStartCallback text "preeditStartCallback"
-XNPreeditDoneCallback text "preeditDoneCallback"
-XNPreeditDrawCallback text "preeditDrawCallback"
-XNPreeditCaretCallback text "preeditCaretCallback"
-XNPreeditStateNotifyCallback text "preeditStateNotifyCallback"
-XNPreeditAttributes text "preeditAttributes"
-XNStatusStartCallback text "statusStartCallback"
-XNStatusDoneCallback text "statusDoneCallback"
-XNStatusDrawCallback text "statusDrawCallback"
-XNStatusAttributes text "statusAttributes"
-XNArea text "area"
-XNAreaNeeded text "areaNeeded"
-XNSpotLocation text "spotLocation"
-XNColormap text "colorMap"
-XNStdColormap text "stdColorMap"
-XNForeground text "foreground"
-XNBackground text "background"
-XNBackgroundPixmap text "backgroundPixmap"
-XNFontSet text "fontSet"
-XNLineSpace text "lineSpace"
-XNCursor text "cursor"
-XNQueryIMValuesList text "queryIMValuesList"
-XNQueryICValuesList text "queryICValuesList"
-XNStringConversionCallback text "stringConversionCallback"
-XNStringConversion text "stringConversion"
-XNResetState text "resetState"
-XNHotKey text "hotkey"
-XNHotKeyState text "hotkeyState"
-XNPreeditState text "preeditState"
-XNVisiblePosition text "visiblePosition"
-XNR6PreeditCallbackBehavior text "r6PreeditCallback"
-XNRequiredCharSet text "requiredCharSet"
-XNQueryOrientation text "queryOrientation"
-XNDirectionalDependentDrawing text "directionalDependentDrawing"
-XNContextualDrawing text "contextualDrawing"
-XNBaseFontName text "baseFontName"
-XNMissingCharSet text "missingCharSet"
-XNDefaultString text "defaultString"
-XNOrientation text "orientation"
-XNFontInfo text "fontInfo"
-XNOMAutomatic text "omAutomatic"
-
-
-
-
-method TApplication.Create
+;XNFocusWindow text "focusWindow"
+;XNResourceName text "resourceName"
+;XNResourceClass text "resourceClass"
+;XNGeometryCallback text "geometryCallback"
+;XNDestroyCallback text "destroyCallback"
+;XNFilterEvents text "filterEvents"
+;XNPreeditStartCallback text "preeditStartCallback"
+;XNPreeditDoneCallback text "preeditDoneCallback"
+;XNPreeditDrawCallback text "preeditDrawCallback"
+;XNPreeditCaretCallback text "preeditCaretCallback"
+;XNPreeditStateNotifyCallback text "preeditStateNotifyCallback"
+;XNPreeditAttributes text "preeditAttributes"
+;XNStatusStartCallback text "statusStartCallback"
+;XNStatusDoneCallback text "statusDoneCallback"
+;XNStatusDrawCallback text "statusDrawCallback"
+;XNStatusAttributes text "statusAttributes"
+;XNArea text "area"
+;XNAreaNeeded text "areaNeeded"
+;XNSpotLocation text "spotLocation"
+;XNColormap text "colorMap"
+;XNStdColormap text "stdColorMap"
+;XNForeground text "foreground"
+;XNBackground text "background"
+;XNBackgroundPixmap text "backgroundPixmap"
+;XNFontSet text "fontSet"
+;XNLineSpace text "lineSpace"
+;XNCursor text "cursor"
+;XNQueryIMValuesList text "queryIMValuesList"
+;XNQueryICValuesList text "queryICValuesList"
+;XNStringConversionCallback text "stringConversionCallback"
+;XNStringConversion text "stringConversion"
+;XNResetState text "resetState"
+;XNHotKey text "hotkey"
+;XNHotKeyState text "hotkeyState"
+;XNPreeditState text "preeditState"
+;XNVisiblePosition text "visiblePosition"
+;XNR6PreeditCallbackBehavior text "r6PreeditCallback"
+;XNRequiredCharSet text "requiredCharSet"
+;XNQueryOrientation text "queryOrientation"
+;XNDirectionalDependentDrawing text "directionalDependentDrawing"
+;XNContextualDrawing text "contextualDrawing"
+;XNBaseFontName text "baseFontName"
+;XNMissingCharSet text "missingCharSet"
+;XNDefaultString text "defaultString"
+;XNOrientation text "orientation"
+;XNFontInfo text "fontInfo"
+;XNOMAutomatic text "omAutomatic"
+
+
+
+
+method TApplication.__create
.ptr dd ?
begin
- push eax ecx edx
-
cinvoke XInitThreads
test eax, eax
jz .exit_error
cinvoke XSetErrorHandler, __FreshXErrorHandler
@@ -157,15 +166,59 @@
stdcall InitMouseCursors
; Creating internal atoms that to be used with Window manager of the application windows...
; Maybe this code should reside somewhere else, not in application. In initialize TWindow???
- cinvoke XInternAtom, [hApplicationDisplay], _cWinDeleteName, 0
+ cinvoke XInternAtom, [hApplicationDisplay], "WM_DELETE_WINDOW", 1
mov [atomWMDelete], eax
- cinvoke XftFontOpenName, [hApplicationDisplay], 0, cDefaultFont
- mov [_SystemFont], eax
+ cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_STATE", 1
+ mov [atomState], eax
+
+ cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_STATE_ABOVE", 1
+ mov [atomStateAbove], eax
+
+ cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_STATE_MODAL", 1
+ mov [atomStateModal], eax
+
+; cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_ALLOWED_ACTIONS", 1
+; mov [atomAllowedActions], eax
+; cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_ACTION_MOVE", 1
+; mov [atomActionMove], eax
+; cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_ACTION_RESIZE", 1
+; mov [atomActionResize], eax
+; cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_ACTION_MINIMIZE", 1
+; mov [atomActionMinimize], eax
+; cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_ACTION_SHADE", 1
+; mov [atomActionShade], eax
+; cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_ACTION_STICK", 1
+; mov [atomActionStick], eax
+; cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_ACTION_MAXIMIZE_HORZ", 1
+; mov [atomActionMaximizeHorz], eax
+; cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_ACTION_MAXIMIZE_VERT", 1
+; mov [atomActionMaximizeVert], eax
+; cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_ACTION_FULLSCREEN", 1
+; mov [atomActionFullscreen], eax
+; cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_ACTION_CHANGE_DESKTOP", 1
+; mov [atomActionChangeDesktop], eax
+; cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_ACTION_CLOSE", 1
+; mov [atomActionClose], eax
+
+ cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_WINDOW_TYPE", 1
+ mov [atomWindowType], eax
+
+ cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_WINDOW_TYPE_POPUP_MENU", 1
+ mov [atomWindowTypeMenu], eax
+
+ cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_WINDOW_TYPE_UTILITY", 1
+ mov [atomWindowTypeUtility], eax
+
+ cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_WINDOW_TYPE_DIALOG", 1
+ mov [atomWindowTypeDialog], eax
+
+ cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_WINDOW_TYPE_NORMAL", 1
+ mov [atomWindowTypeNormal], eax
cinvoke FT_Init_FreeType, FTLibrary
test eax, eax
jnz .error_ft
@@ -178,11 +231,10 @@
if __UseClipboard = 1
stdcall __InitLinuxClipboard
end if
clc
- pop edx ecx eax
return
.error_ft:
DebugMsg 'Error initializing FreeType library.'
@@ -191,15 +243,11 @@
.error_disp:
DebugMsg 'Error open display.'
.exit_error:
stc
- pop edx ecx eax
return
-
-
-
endp
Index: freshlib/gui/Linux/mouse.asm
==================================================================
--- freshlib/gui/Linux/mouse.asm
+++ freshlib/gui/Linux/mouse.asm
@@ -12,11 +12,11 @@
; Notes:
;_________________________________________________________________________________________
iglobal
if used _Xcursors
- _Xcursors db 68, 152, 34, 108, 116, 40, 40, 150 ; X standard cursor font
+ _Xcursors db 68, 152, 34, 108, 116, 40, 40, 150, 58, 52, 86 ; X standard cursor font
end if
endg
uglobal
@@ -60,30 +60,34 @@
return
endp
end if
-proc SetMouseCursor, .hCursor
+proc SetMouseCursor, .hWindow, .hCursor
begin
push eax ecx edx
- cinvoke XDefineCursor, [hApplicationDisplay], [hRootWindow], [.hCursor]
+ cinvoke XDefineCursor, [hApplicationDisplay], [.hWindow], [.hCursor]
pop edx ecx eax
return
endp
proc GetStockCursor, .index
begin
mov eax, [.index]
- and eax, 7
+ cmp eax, mcCount
+ jb @f
+ xor eax, eax
+@@:
mov eax, [StockCursors+4*eax]
return
endp
-proc MouseCapture, .hwnd
+
+proc __MouseCapture, .hwnd
begin
push eax ecx edx
cmp [.hwnd], 0
je .release
@@ -95,6 +99,7 @@
return
.release:
cinvoke XUngrabPointer, [hApplicationDisplay], CurrentTime
jmp .finish
-endp
+endp
+
Index: freshlib/gui/Linux/windows.asm
==================================================================
--- freshlib/gui/Linux/windows.asm
+++ freshlib/gui/Linux/windows.asm
@@ -11,65 +11,99 @@
;
; Notes:
;_________________________________________________________________________________________
-proc _CreateNullWindow
+
+body _CreateWindow
+
.attr XSetWindowAttributes
.vis XVisualInfo
+
+.prop dd ?
+
begin
- push ecx edx esi
+ pushad
+ mov esi, [.pWindow]
cinvoke XDefaultScreen, [hApplicationDisplay]
mov edx, eax
-
lea eax, [.vis]
cinvoke XMatchVisualInfo, [hApplicationDisplay], edx, $20, TrueColor, eax
cinvoke XCreateColormap, [hApplicationDisplay], [hRootWindow], [.vis.Visual], AllocNone
mov [.attr.colormap], eax
- mov [.attr.override_redirect], 0
- mov [.attr.backing_store], NotUseful
- mov [.attr.background_pixmap], None
- mov eax, [clDialogBk]
- mov [.attr.background_pixel], eax
- mov [.attr.border_pixel], 0
- mov [.attr.override_redirect], 0
- mov [.attr.backing_store], NotUseful
- mov [.attr.background_pixmap], None
+; border
+
+ xor eax, eax
+ mov ecx, [esi+TWindow._border]
+
+ test ecx, ecx ; borderNone = 0
+ jnz @f
+ inc eax
+@@:
+ mov [.attr.override_redirect], eax
+
+ and ecx, $3
+ mov eax, [.types+4*ecx]
+ mov [.prop], eax
+
+ xor eax, eax
+ mov [.attr.backing_store], eax ; NotUseful
+ mov [.attr.background_pixmap], eax ; None
+ mov [.attr.border_pixel], eax ; 0
mov [.attr.event_mask], ExposureMask or FocusChangeMask or \
KeyPressMask or KeyReleaseMask or \
ButtonPressMask or ButtonReleaseMask or \
EnterWindowMask or LeaveWindowMask or \
PointerMotionMask or StructureNotifyMask
lea eax, [.attr]
- cinvoke XCreateWindow, [hApplicationDisplay], [hRootWindow], 0, 0, 1, 1, 0, $20, InputOutput, [.vis.Visual], \
- CWBackPixmap or CWBackingStore or CWOverrideRedirect or CWBorderPixel or \
- CWColormap or CWBackPixel or CWEventMask, eax
- mov esi, eax
+ cinvoke XCreateWindow, [hApplicationDisplay], [hRootWindow], \
+ [esi+TWindow._x], [esi+TWindow._y], [esi+TWindow._width], [esi+TWindow._height], \
+ 0, $20, InputOutput, [.vis.Visual], \
+ CWBackingStore or CWOverrideRedirect or \
+ CWBorderPixel or CWColormap or \
+ CWEventMask or CWBackPixmap, eax
+
+ mov edi, eax
+ test eax, eax
+ jz .exit ; Error processing???
+
+ cinvoke XChangeProperty, [hApplicationDisplay], edi, [atomWindowType], XA_ATOM, 32, PropModeReplace, [.prop], 1
+ cinvoke XSetWMProtocols, [hApplicationDisplay], edi, atomWMDelete, 1
+ cinvoke XSaveContext, [hApplicationDisplay], edi, win_structure_context, esi
+
+; the caption
+ mov eax, [esi+TWindow._caption]
test eax, eax
jz .exit
- cinvoke XSetWMProtocols, [hApplicationDisplay], esi, atomWMDelete, 1
- mov eax, esi
+ stdcall StrPtr, eax
+ cinvoke XStoreName, [hApplicationDisplay], edi, eax
+
.exit:
- pop esi edx ecx
+ mov [esp+4*regEAX], edi
+ popad
return
+
+
+.types dd atomWindowTypeMenu, atomWindowTypeNormal, atomWindowTypeDialog, atomWindowTypeUtility
+
+
endp
-
;_________________________________________________________________________________________
-proc _DestroyWindow, .hwnd
+body _DestroyWindow
begin
push eax ecx edx
- stdcall _SetWindowStruct, [.hwnd], 0
+ cinvoke XSaveContext, [hApplicationDisplay], [.hwnd], win_structure_context, 0
cinvoke XDestroyWindow, [hApplicationDisplay], [.hwnd]
pop edx ecx eax
return
endp
@@ -107,162 +141,47 @@
;_________________________________________________________________________________________
-proc _GetChildren, .hwnd
- .root dd ?
- .parent dd ?
- .children dd ?
- .count dd ?
-begin
- push ebx ecx edx esi
-
-
- lea ebx, [.count]
- lea edx, [.children]
- lea ecx, [.parent]
- lea eax, [.root]
- cinvoke XQueryTree, [hApplicationDisplay], [.hwnd], eax, ecx, edx, ebx
- test eax, eax
- jz .exit ; function failed
-
- xor ebx, ebx
- mov esi, [.children]
- test esi, esi
- jz .endchildren
-
- stdcall CreateArray, sizeof.TWinArrayItem
- mov ebx, eax
- mov ecx, [.count]
-
-.loophwnd:
- dec ecx
- js .endchildren_free
-
- stdcall AddArrayItems, ebx, 1
- mov ebx, edx
-
- mov edx, [esi+4*ecx]
- mov [eax+TWinArrayItem.handle], edx
-
- jmp .loophwnd
-
-.endchildren_free:
- cinvoke XFree, esi
-
-.endchildren:
- mov eax, ebx
-.exit:
- pop esi edx ecx ebx
- return
-endp
-
-
-;_________________________________________________________________________________________
-
-
-
-proc _GetVisible, .hwnd
+body _ClientToScreen
.attr XWindowAttributes
begin
- push ebx ecx edx
-
- lea ebx, [.attr]
- cinvoke XGetWindowAttributes, [hApplicationDisplay], [.hwnd], ebx
- mov eax, [ebx+XWindowAttributes.map_state]
- test eax, eax
- jz @f
- mov eax, 1
-@@:
- pop edx ecx ebx
- return
-endp
-
-;_________________________________________________________________________________________
-
-
-proc _GetWindowBounds, .hwnd, .pBounds
-begin
- push eax ecx edx
-
- int3
- pop edx ecx eax
- return
-endp
-
-
-;_________________________________________________________________________________________
-
-
-proc _SetWindowBounds, .hwnd, .pBounds
- .wch XWindowChanges
-begin
- push eax ecx edx
-
- mov edx, [.pBounds]
-
- mov eax, [edx+TBounds.x]
- mov ecx, [edx+TBounds.y]
-
- mov [.wch.x], eax
- mov [.wch.y], ecx
-
- mov eax, [edx+TBounds.width]
- mov ecx, [edx+TBounds.height]
-
- test eax, eax
- jnz @f
- inc eax
-@@:
- test ecx, ecx
- jnz @f
- inc ecx
-@@:
- mov [.wch.width], eax
- mov [.wch.height], ecx
-
- lea eax, [.wch]
- cinvoke XConfigureWindow, [hApplicationDisplay], [.hwnd], CWX or CWY or CWWidth or CWHeight, eax
-
- pop edx ecx eax
- return
-endp
-
-
-;_________________________________________________________________________________________
-
-
-
-proc _SetWindowBorder, .hwnd, .brdType
- .attr XSetWindowAttributes
-begin
- push eax ecx edx
-
- mov [.attr.override_redirect], 1
-; mov [.attr.event_mask], ExposureMask or FocusChangeMask or KeyPressMask or KeyReleaseMask or \
-; ButtonPressMask or ButtonReleaseMask or EnterWindowMask or LeaveWindowMask or \
-; PointerMotionMask
-
- cmp [.brdType], borderNone
- je @f
- mov [.attr.override_redirect], 0
-; mov [.attr.event_mask], ExposureMask or FocusChangeMask or KeyPressMask or KeyReleaseMask or \
-; ButtonPressMask or ButtonReleaseMask or EnterWindowMask or LeaveWindowMask or \
-; PointerMotionMask; or StructureNotifyMask
-@@:
- lea eax, [.attr]
- cinvoke XChangeWindowAttributes, [hApplicationDisplay], [.hwnd], CWOverrideRedirect, eax
-
- pop edx ecx eax
- return
-endp
-
-;_________________________________________________________________________________________
-
-
-proc _ShowWindow, .hwnd, .flag
+ push eax
+
+ lea ecx, [.attr]
+ cinvoke XGetWindowAttributes, [hApplicationDisplay], [.hwnd], ecx
+
+ mov ecx, [.attr.x]
+ mov edx, [.attr.y]
+ add [.x], ecx
+ add [.y], edx
+
+ stdcall _GetParent, [.hwnd]
+ test eax, eax
+ jz .finish
+
+ lea ecx, [.attr]
+ cinvoke XGetWindowAttributes, [hApplicationDisplay], eax, ecx
+
+ mov ecx, [.attr.x]
+ mov edx, [.attr.y]
+ add [.x], ecx
+ add [.y], edx
+
+.finish:
+ mov ecx, [.x]
+ mov edx, [.y]
+ pop eax
+ return
+endp
+
+
+;_________________________________________________________________________________________
+
+
+body _ShowWindow
begin
push eax ecx edx
mov ecx, XUnmapWindow
cmp [.flag], 0
@@ -279,121 +198,76 @@
;_________________________________________________________________________________________
-proc _RefreshWindow, .hwnd
+body _RefreshWindowRect
+begin
+ push eax ecx edx
+ cinvoke XClearArea, [hApplicationDisplay], [.hwnd], [.x], [.y], [.width], [.height], TRUE
+ cinvoke XFlush, [hApplicationDisplay]
+ pop edx ecx eax
+ return
+endp
+
+
+;body _RefreshWindowRect
+;begin
+; push eax ecx edx
+;
+; stdcall _GetWindowStruct, [.hwnd]
+; get eax, eax, TWindow:ImgScreen
+;
+; stdcall DrawImageRect, [.hwnd], eax, [.x], [.y], [.x], [.y], [.width], [.height]
+; pop edx ecx eax
+; return
+;endp
+
+
+;_________________________________________________________________________________________
+
+
+body _SetWindowTextUtf8
+begin
+ push eax ecx edx
+ cinvoke XStoreName, [hApplicationDisplay], [.hwnd], [.ptrUtf8]
+ pop edx ecx eax
+ return
+endp
+
+;_________________________________________________________________________________________
+
+
+body _SetModalTowards
begin
push eax ecx edx
- cinvoke XClearArea, [hApplicationDisplay], [.hwnd], 0, 0, 0, 0, TRUE
- cinvoke XFlush, [hApplicationDisplay]
+
+
+ cinvoke XSetTransientForHint, [hApplicationDisplay], [.hwnd], [.hwndParent]
+
+; The following is not working for every window manager!!! It is not a problem of the below code. (probably... :)
+
+ cinvoke XChangeProperty, [hApplicationDisplay], [.hwnd], [atomState], XA_ATOM, 32, PropModeAppend, atomStateAbove, 1
+ cinvoke XChangeProperty, [hApplicationDisplay], [.hwnd], [atomState], XA_ATOM, 32, PropModeAppend, atomStateModal, 1
+
pop edx ecx eax
return
endp
;_________________________________________________________________________________________
-proc _SetFocus, .hwnd
-begin
- push eax ecx edx
- cinvoke XSetInputFocus, [hApplicationDisplay], [.hwnd], RevertToParent, CurrentTime
- pop edx ecx eax
- return
-endp
-
-;_________________________________________________________________________________________
-
-proc _AddChild, .hwnd, .child
-begin
- push eax ecx edx
- cinvoke XReparentWindow, [hApplicationDisplay], [.child], [.hwnd], 10, 10
- pop edx ecx eax
- return
-endp
-
-;_________________________________________________________________________________________
-
-
-proc _SetWindowTextUtf8, .hwnd, .ptrUtf8
-begin
- push eax ecx edx
- cinvoke XStoreName, [hApplicationDisplay], [.hwnd], [.ptrUtf8]
- pop edx ecx eax
- return
-endp
-
-
-
-;_________________________________________________________________________________________
-
-
-
-proc _GetWindowTextUtf8, .hwnd, .ptrUtf8
-begin
- return
-endp
-
-
-
-
-;_________________________________________________________________________________________
-
-proc _EnableWindow, .hwnd, .flag
-begin
- push eax ecx edx
-
- stdcall _GetChildren, [.hwnd]
- test eax, eax
- jz .children_ok
-
- mov edx, [eax+TArray.count]
-.child_loop:
- dec edx
- js .end_children
-
- stdcall _EnableWindow, [eax+TArray.array+sizeof.TWinArrayItem*edx+TWinArrayItem.handle], [.flag]
- jmp .child_loop
-
-.end_children:
- stdcall FreeMem, eax
-
-.children_ok:
- mov ecx, ExposureMask or StructureNotifyMask or EnterWindowMask or LeaveWindowMask or PointerMotionMask
- cmp [.flag], 0
- je @f
- or ecx, FocusChangeMask or KeyPressMask or KeyReleaseMask or \
- ButtonPressMask or ButtonReleaseMask
-@@:
- cinvoke XSelectInput, [hApplicationDisplay], [.hwnd], ecx
-
- pop edx ecx eax
- return
-endp
-
-;_________________________________________________________________________________________
-
-proc _SetModalTowards, .hwnd, .hwndParent
-begin
- push eax ecx edx
- cinvoke XSetTransientForHint, [hApplicationDisplay], [.hwnd], [.hwndParent]
- pop edx ecx eax
- return
-endp
-
-;_________________________________________________________________________________________
-
-proc _FinalizeModal, .hwnd, .hwndParent
+
+body _FinalizeModal
.flushevent XEvent
begin
push eax ecx edx
- DebugMsg "Finalize modal"
-
; dirty hack, but the button receives LeaveNotify after DestroyNotify
cinvoke XSync, [hApplicationDisplay], FALSE
+
.loop_flush:
lea eax, [.flushevent]
cinvoke XCheckMaskEvent, [hApplicationDisplay], LeaveWindowMask, eax
test eax, eax
jnz .loop_flush
@@ -407,42 +281,43 @@
win_structure_context = 1
-proc _GetWindowStruct, .hwin
+body _GetWindowStruct
.user_data dd ?
begin
push ecx edx
lea eax, [.user_data]
cinvoke XFindContext, [hApplicationDisplay], [.hwin], win_structure_context, eax
- test eax, eax
- jnz .error
+
+; test eax, eax
+; jnz .error
mov eax, [.user_data]
clc
pop edx ecx
return
-.error:
- DebugMsg 'FreshLib: Error find context.'
- mov edx, [ebp+4]
- OutputRegister regEDX, 16
-
- xor eax, eax
- pop edx ecx
- return
+;.error:
+; DebugMsg 'FreshLib: Error find context.'
+; mov edx, [ebp+4]
+; OutputRegister regEDX, 16
+;
+; stc
+; pop edx ecx
+; return
endp
;_________________________________________________________________________________________
-proc _SetWindowStruct, .hwin, .value
+body _SetWindowStruct
begin
push eax ecx edx
cinvoke XSaveContext, [hApplicationDisplay], [.hwin], win_structure_context, [.value]
pop edx ecx eax
return
Index: freshlib/gui/Main.asm
==================================================================
--- freshlib/gui/Main.asm
+++ freshlib/gui/Main.asm
@@ -13,14 +13,43 @@
; This file contains only OS independent part and includes OS dependent files.
;_________________________________________________________________________________________
module "Main library"
uglobal
- if used pApplication
- pApplication dd ?
- end if
+ var pApplication = ?
+
+ var __LastPointedWindow = ?
+ var __FocusedWindow = ?
+ var __MouseTarget = ?
+
+ var __ActiveMenu = ?
endg
+
+
+;_________________________________________________________________________________________
+;
+; Process all the events queued from the system and exits.
+; Arguments: none
+; Returns: CF = 1 if the termination event has been received.
+;_________________________________________________________________________________________
+
+interface ProcessSystemEvents
+
+
+
+
+;_________________________________________________________________________________________
+;
+; Waits for system events to arive.
+; During the wait, the application
+; does not use CPU resources.
+;_________________________________________________________________________________________
+
+interface WaitForSystemEvent
+
+
+
proc Run
begin
.mainloop:
@@ -39,30 +68,74 @@
.eventok:
stdcall WaitForSystemEvent
jmp .mainloop
.terminate:
+ DebugMsg "Terminate GUI application!"
+ return
+endp
+
+
+
+proc ServeMenuMouseMove, .window, .x, .y, .kbdState
+begin
+ cmp [__ActiveMenu], 0
+ jne .serve_menu
+
+ clc
+ return
+
+.serve_menu:
+ pushad
+
+ stdcall _ClientToScreen, [.window], [.x], [.y]
+ exec [__ActiveMenu], TWindow:EventMouseMove, ecx, edx, [.kbdState]
+
+ popad
+ stc
return
endp
+
+proc ServeMenuButtonPress, .window, .button, .kbdState, .x, .y
+begin
+ cmp [__ActiveMenu], 0
+ jne .serve_menu
+
+ clc
+ return
+
+.serve_menu:
+ pushad
+
+ stdcall _ClientToScreen, [.window], [.x], [.y]
+ exec [__ActiveMenu], TWindow:EventButtonPress, [.button], [.kbdState], ecx, edx
+
+ popad
+ stc
+ return
+endp
+
proc ShowModal, .pForm, .pParent
.prev dd ?
begin
push ecx edx
+
mov ecx, [.pParent]
mov edx, [.pForm]
+
+ set edx, TForm:Visible, TRUE
jecxz @f
stdcall _SetModalTowards, [edx+TForm.handle], [ecx+TWindow.handle]
@@:
- set edx, TForm:Visible, TRUE
jecxz @f
- stdcall _EnableWindow, [ecx+TWindow.handle], FALSE
+ set ecx, TWindow:Enabled, FALSE
@@:
set edx, TForm:ModalResult, 0
get eax, edx, TForm:OnClose
@@ -86,21 +159,20 @@
stdcall WaitForSystemEvent
jmp .modal_loop
.exit_modal:
jecxz @f
- stdcall _EnableWindow, [ecx+TWindow.handle], TRUE
+ set ecx, TWindow:Enabled, TRUE
@@:
set edx, TForm:OnClose, [.prev]
- set edx, TForm:Visible, FALSE
jecxz @f
- mov ecx, [ecx+TWindow.handle]
+ stdcall _FinalizeModal, [edx+TForm.handle], [ecx+TWindow.handle]
@@:
- stdcall _FinalizeModal, [edx+TForm.handle], ecx
+ set edx, TForm:Visible, FALSE
get eax, edx, TForm:ModalResult
pop edx ecx
return
endp
@@ -112,11 +184,95 @@
stc
return
endp
+
+
+
+proc __GetRelativeXY, .window, .x, .y
+begin
+ push eax esi
+
+ mov ecx, [.x]
+ mov edx, [.y]
+ mov esi, [.window]
+
+.loop:
+ get eax, esi, TWindow:Parent
+ test eax, eax
+ jz .finish
+
+ sub ecx, [esi+TWindow._x]
+ sub edx, [esi+TWindow._y]
+
+ mov esi, eax
+ jmp .loop
+
+.finish:
+ pop esi eax
+ return
+endp
+
+
+
+proc __SearchWindowToFocus, .pWindow
+begin
+ pushad
+ mov esi, [.pWindow]
+
+ get eax, esi, TWindow:Enabled
+ test eax, eax
+ jz .no
+
+ get eax, esi, TWindow:Visible
+ test eax, eax
+ jz .no
+
+ get eax, esi, TWindow:WantFocus
+ test eax, eax
+ jz .children
+
+ mov [esp+4*regEAX], esi
+ popad
+ return
+
+
+.children:
+ get edi, esi, TWindow:Children
+ test edi, edi
+ jnz .loopit
+
+.no:
+ xor eax, eax
+ mov [esp+4*regEAX], eax
+ popad
+ return
+
+.loopit:
+ mov ecx, [edi+TArray.count]
+ jecxz .no
+
+.children_loop:
+ dec ecx
+ js .no
+
+ mov esi, [edi+TArray.array+4*ecx]
+
+ istype esi, TWindow
+ jne .children_loop
+
+ stdcall __SearchWindowToFocus, esi
+ test eax, eax
+ jz .children_loop
+
+ mov [esp+4*regEAX], eax
+ popad
+ return
+endp
+
include '%TargetOS%/Main.asm'
endmodule
Index: freshlib/gui/ObjTemplates.asm
==================================================================
--- freshlib/gui/ObjTemplates.asm
+++ freshlib/gui/ObjTemplates.asm
@@ -26,11 +26,11 @@
.ptrVar dd ?
.params:
ends
-macro ObjTemplate flags, class, name, [id, param] {
+macro ObjTemplate flags, class, name, [idparam] {
common
local ..paramsize, ..prms, ..here
if ~defined used.#class | defined ..here
used.#class = 1
@@ -42,22 +42,45 @@
dd vtables.#class
dd ..paramsize
dd name
..prms:
+
forward
-local ..value
- dd class#.#id#.#set
- dd ..value
+local ..value, ..ofs, ..valid
+
+ ..valid equ FALSE
+ match id == param, idparam \{
+ ..ofs dd class\#.\#id\#.#set
+ dd ..value
+ ..valid EQU TRUE
+ \}
+
+ match =FALSE, ..valid \{
+ error Invalid parameter definition in template.
+ \}
+
common
dd -1
+
forward
- if param eqtype 2
- ..value = param
- else
- ..value db param, 0
- end if
+
+ match id == param, idparam \{
+ if param eqtype 2
+ ..value = param
+ else
+ if param eqtype [2]
+ match =[par=], param \\{
+ ..value = par
+ \\}
+ store byte $fe at ..ofs+3
+ else
+ ..value db param, 0
+ end if
+ end if
+ \}
+
common
local ..here
if ~defined name | defined ..here
name dd ?
@@ -88,44 +111,38 @@
stdcall GetMem, [esi+TObjTemplate.size]
mov ebx, eax
mov edi, [esi+TObjTemplate.vtable]
mov [ebx], edi
- exec ebx, TObject:Create
-
- cmp [.parent], 0
- je .parent_ok
-
- exec [.parent], TObject:AddChild, ebx
-
-.parent_ok:
- istype ebx, TWindow
- jne .border_ok
-
- cmp [.parent], 0
- jne .border_ok
-
- set ebx, TWindow:borderKind, borderFull
-
-.border_ok:
+ exec ebx, TWindow:Create, [.parent]
+
lea ecx, [esi+TObjTemplate.params]
.paramloop:
cmp dword [ecx], -1
je .paramsok
mov eax, [ecx]
- test eax, $ffff0000
+ bswap eax
+
+ mov edx, [ecx+4] ; value
+
+ cmp al, $fe ; Is it indirect?
+ jne @f
+ mov edx, [edx] ; the value is an address of a variable.
+@@:
+ bswap eax
+
+ test eax, $00ff0000
+ movzx eax, ax ; not changing flags!
jnz .method
- push dword [ecx+4]
- pop dword [ebx+eax]
+ mov [ebx+eax], edx
jmp .param_set
.method:
- and eax, $0000ffff
- stdcall dword [edi+4*eax+8], ebx, [ecx+4]
+ stdcall dword [edi+4*eax+8], ebx, edx
.param_set:
add ecx, 8
jmp .paramloop
@@ -136,23 +153,18 @@
mov [eax], ebx ; returned pointer/handle to the object.
set ebx, TObject:ptrVar, eax
.var_ok:
- istype ebx, TWindow
- jne .oncreate
-
- exec ebx, TWindow:UpdateBounds
-
-.oncreate:
get eax, ebx, TObject:OnCreate
test eax, eax
jz .gonext
; execute user OnCreate event.
+
pushad
- stdcall dword [ebx+TObject.OnCreate], ebx
+ stdcall eax, ebx
popad
.gonext:
mov edx, [esi+TObjTemplate.flags]
Index: freshlib/gui/SplitGrid.asm
==================================================================
--- freshlib/gui/SplitGrid.asm
+++ freshlib/gui/SplitGrid.asm
@@ -44,10 +44,11 @@
.width dw ?
.pos dd ?
.min dd ?
.max dd ?
ends
+
struct TCellTemplate
.type dw ?
.id dw ?
ends
@@ -54,11 +55,11 @@
macro SplitStart name {
local ..expected, ..id
..expected = 1
- ..id = 1000
+ ..id = 0
cell@expected equ ..expected
cell@id equ ..id
cell@name equ name
@@ -65,10 +66,11 @@
label name byte
macro Split type, width, pos, min, max \{
dw type, width
dd pos, min, max
+ cell@id = cell@id + 1
cell@expected = cell@expected + 1
\}
macro Cell name \{
.\#name = cell@id
@@ -125,20 +127,32 @@
if ..expected <> 0
disp 1, 'WARNING! "', `., '" split template is not consistent! Automatically added ', <..expected, 10>, " empty cells. FIXIT!", 13
end if
}
+uglobal
+ RealignCnt dd ?
+endg
+
proc RealignGrid, .ptrSplitter, .ptrRect
.rect RECT
begin
pushad
+ stdcall GetTimestamp
+ mov [RealignCnt], eax
+
mov edi, [.ptrSplitter]
mov esi, [.ptrRect]
call _DoRealign
+ stdcall GetTimestamp
+ sub eax, [RealignCnt]
+
+ OutputValue "Realign time:", eax, 10, 4
+
popad
return
endp
@@ -190,10 +204,19 @@
sub ebx, [esi+ecx+TSplitRect.rect.left] ; size of rect (x or y depending on type)
mov edx, [esi+TSplitRect.spWidth]
sub ebx, edx
mov eax, [esi+TSplitRect.pos]
+
+ cmp eax, [esi+TSplitRect.min]
+ cmovl eax, [esi+TSplitRect.min]
+
+ cmp eax, [esi+TSplitRect.max]
+ cmovg eax, [esi+TSplitRect.max]
+
+ mov [esi+TSplitRect.pos],eax
+
mov ecx, [esi+TSplitRect.type]
and ecx, $ff
test [esi+TSplitRect.type], stRelative
@@ -231,47 +254,60 @@
call _DoRealign
pop esi
.endsplit:
- cmp [esi+TSplitRect.pWindow], 0
- je .endresize
+ mov ebx, [esi+TSplitRect.pWindow]
+ test ebx, ebx
+ jz .endresize
mov eax, [esi+TSplitRect.rect.right]
mov ecx, [esi+TSplitRect.rect.bottom]
- mov ebx, [esi+TSplitRect.rect.left]
- mov edx, [esi+TSplitRect.rect.top]
- sub eax, ebx
- sub ecx, edx
-
- set [esi+TSplitRect.pWindow], TWindow:width, eax
- set [esi+TSplitRect.pWindow], TWindow:height, ecx
- set [esi+TSplitRect.pWindow], TWindow:x, ebx
- set [esi+TSplitRect.pWindow], TWindow:y, edx
-
- exec [esi+TSplitRect.pWindow], TWindow:UpdateBounds
+ sub eax, [esi+TSplitRect.rect.left]
+ sub ecx, [esi+TSplitRect.rect.top]
+
+ mov [ebx+TWindow._width], eax
+ mov [ebx+TWindow._height], ecx
+
+ mov eax, [esi+TSplitRect.rect.left]
+ mov ecx, [esi+TSplitRect.rect.top]
+
+ mov [ebx+TWindow._x], eax
+ mov [ebx+TWindow._y], ecx
+
+; mov ebx, [esi+TSplitRect.rect.left]
+; mov edx, [esi+TSplitRect.rect.top]
+; sub eax, ebx
+; sub ecx, edx
+;
+; set [esi+TSplitRect.pWindow], TWindow:width, eax
+; set [esi+TSplitRect.pWindow], TWindow:height, ecx
+; set [esi+TSplitRect.pWindow], TWindow:x, ebx
+; set [esi+TSplitRect.pWindow], TWindow:y, edx
+
+; exec [esi+TSplitRect.pWindow], TWindow:UpdateBounds
exec [esi+TSplitRect.pWindow], TWindow:Refresh
.endresize:
return
endp
-proc DrawSplitters, .context, .ptrSplitters
+proc DrawSplitters, .pImage, .ptrSplitters
begin
pushad
mov esi, [.ptrSplitters]
- mov edi, [.context]
+ mov edi, [.pImage]
call _DoDrawSplitters
popad
return
endp
;esi - pointer to TSplitRect
-; edi - hDC
+; edi - TImage
proc _DoDrawSplitters
begin
mov ebx, esi
add esi, sizeof.TSplitRect
@@ -433,48 +469,7 @@
endp
-
-proc DrawSplitterDefault, .context, .pRect, .type
-begin
- pushad
-
- mov esi, [.pRect]
- mov eax, [esi+RECT.right]
- mov ecx, [esi+RECT.bottom]
- sub eax, [esi+RECT.left]
- sub ecx, [esi+RECT.top]
-
- stdcall DrawFillRect, [.context], [esi+RECT.left], [esi+RECT.top], eax, ecx, [clSplitter]
- popad
- return
-endp
-
-
-proc DrawSplitterDefault2, .context, .pRect, .type
-.bounds TBounds
-begin
- pushad
-
- mov esi, [.pRect]
- mov eax, [esi+RECT.left]
- mov ecx, [esi+RECT.top]
- mov edx, [esi+RECT.right]
- mov ebx, [esi+RECT.bottom]
- sub edx, eax
- sub ebx, ecx
- mov [.bounds.x], eax
- mov [.bounds.y], ecx
- mov [.bounds.width], edx
- mov [.bounds.height], ebx
- lea eax, [.bounds]
-
- stdcall [DrawBox], [.context], eax, [clDialogBk], bxSunken
-
- popad
- return
-endp
-
endmodule
Index: freshlib/gui/TAction.asm
==================================================================
--- freshlib/gui/TAction.asm
+++ freshlib/gui/TAction.asm
@@ -14,66 +14,442 @@
; Different UI elements, such as buttons, menu items etc. can be attached to
; the action object and to use its attributes. When the programmer changes
; something in the action, all UI elements are updated automatically.
;_________________________________________________________________________________________
-struc TAction caption, hint, icon, FastKey, enabled, OnExecute, OnIdle {
-common
- .Text dd caption ; handle or pointer to the caption string.
- .Hint dd hint ; handle or pointer to the Hint text.
- .icon dd icon ; pointer to TImage
- .FastKey dd FastKey ; pointer to keyboard accelerator combination.
- .Enabled dd enabled ; if FALSE, the action is not active.
- .OnExecute dd OnExecute ; pointer to procedure to be executed on activation of the action.
- .OnIdle dd OnIdle ; pointer to procedure that to be executed once, when there is no other events in the queue.
-}
-
-virtual at 0
- TAction TAction ?, ?, ?, ?, ?, ?, ?
-end virtual
-
-
-struc TFastKey flags, key, action {
- .flags dd flags
- .key dd key
- .action dd action
-}
-virtual at 0
- TFastKey TFastKey ?, ?, ?
-end virtual
-
-
-struct TActionList
- .count dd ?
- .accelerators dd ?
- .actions:
+module "TAction"
+
+Ctrl = maskCtrl
+Alt = maskAlt
+Shift = maskShift
+
+
+fkScancode = $80000000
+
+struct TFastKey
+ .flags dd ?
+ .key dd ?
ends
-
-macro ActionList name, [actname, caption, hint, icon, FastKey, OnExecute, OnIdle] {
-common
- local i, count, acclist
- i = 0
- label name dword
- .count dd count
- .accelerators dd acclist
-forward
- local .accitem, txtlbl, hintlbl
-
- txtlbl text caption
- hintlbl text hint
-
- actname TAction txtlbl, hintlbl, icon, accitem, 1, OnExecute, OnIdle
-
- i = i + 1
-common
- count = i
- label acclist dword
-
-forward
- if FastKey eq NONE
- accitem = 0
- else
- .accitem TFastKey FastKey, name#actname
- end if
-}
+object TAction, TObject
+
+ ._caption dd ?
+ ._hint_text dd ?
+ ._icon_index dd ?
+ ._enabled dd ?
+ ._checked dd ?
+
+ ._accel TFastKey
+
+ ._on_execute dd ?
+ ._on_idle dd ?
+
+ ._ctrl_list dd ?
+
+ ._icon_cache_gray dd ?
+ ._icon_cache dd ?
+
+ param .Caption, ._caption, .SetCaption
+ param .HintText, ._hint_text, .SetHintText
+ param .IconIndex, ._icon_index, .SetIconIndex
+ param .Enabled, ._enabled, .SetEnabled
+ param .Checked, ._checked, .SetChecked
+ param .AccelStr, .GetAccelStr, NONE
+ param .Icon, .GetIcon, NONE
+
+ param .OnExecute, ._on_execute, ._on_execute
+ param .OnIdle, ._on_idle, ._on_idle
+
+ method .GetIcon
+ method .GetAccelStr
+
+ method .SetParent, .value
+
+ method .SetCaption, .value
+ method .SetHintText, .value
+ method .SetIconIndex, .value
+ method .SetEnabled, .value
+ method .SetChecked, .value
+
+ method .UpdateControls
+
+ method .SetAccelerator, .flags, .key
+
+ method .Execute, .fromCtrl
+ method .Attach, .ctrl
+ method .Detach, .ctrl
+
+ method .Create, .parent
+ method .Destroy
+
+ method .__clear_cache
+
+endobj
+
+
+
+interface TAction.OnExecute, .Action, .Ctrl
+
+
+
+method TAction.Create
+begin
+ inherited [.parent]
+
+ mov eax, [.self]
+ mov [eax+TAction._enabled], 1
+ return
+endp
+
+
+
+
+method TAction.Destroy
+begin
+ pushad
+
+ mov esi, [.self]
+ exec esi, TAction:__clear_cache
+
+ mov edi, [esi+TAction._ctrl_list]
+ test edi, edi
+ je .finish
+
+ mov ecx, [edi+TArray.count]
+
+.loop:
+ dec ecx
+ js .end_loop
+
+ set [edi+TArray.array+4*ecx], TWindow:Action, 0
+ jmp .loop
+
+.end_loop:
+ stdcall FreeMem, edi
+
+
+.finish:
+ popad
+ inherited
+ return
+endp
+
+
+
+method TAction.SetParent
+begin
+ inherited [.value]
+ exec [.self], TAction:UpdateControls
+ return
+endp
+
+
+
+method TAction.Execute
+begin
+ pushad
+
+ mov esi, [.self]
+
+ cmp [esi+TAction._enabled], 0
+ je .finish
+
+ mov edi, [esi+TAction._on_execute]
+ test edi, edi
+ jz .finish
+
+ stdcall edi, esi, [.fromCtrl]
+
+.finish:
+ popad
+ return
+endp
+
+
+
+
+method TAction.Attach
+begin
+ pushad
+
+ mov esi, [.self]
+ mov edx, [esi+TAction._ctrl_list]
+ test edx, edx
+ jnz @f
+
+ stdcall CreateArray, 4
+ mov edx, eax
+@@:
+
+ stdcall AddArrayItems, edx, 1
+ mov ecx, [.ctrl]
+ mov [eax], ecx
+
+ mov [esi+TAction._ctrl_list], edx
+
+ popad
+ return
+endp
+
+
+
+
+method TAction.Detach
+begin
+ pushad
+
+ mov esi, [.self]
+ mov edx, [esi+TAction._ctrl_list]
+ test edx, edx
+ jz .finish
+
+ stdcall ListIndexOf, edx, [.ctrl]
+ jc .finish ; not found
+
+ stdcall DeleteArrayItems, edx, eax, 1
+
+ cmp [edx+TArray.count], 0
+ jne @f
+
+ stdcall FreeMem, edx
+ xor edx, edx
+
+@@:
+ mov [esi+TAction._ctrl_list], edx
+
+.finish:
+ popad
+ return
+endp
+
+
+
+
+method TAction.GetIcon
+.list dd ?
+begin
+ pushad
+ mov esi, [.self]
+
+ mov edi, [esi+TAction._enabled]
+ and edi, 1
+
+ mov eax, [esi+TAction._icon_cache_gray+4*edi]
+ test eax, eax
+ jnz .finish
+
+ mov edx, [esi+TAction._icon_index]
+ test edx, edx
+ js .finish ; return 0
+
+ get [.list], esi, TAction:Parent
+ get ecx, [.list], TActionList:IconSize
+
+ stdcall CreateImage, ecx, ecx
+ mov [esi+TAction._icon_cache_gray+4*edi], eax
+
+ imul edx, ecx ; x coordinate.
+
+ get ebx, [.list], TActionList:ImgIcons
+ test ebx, ebx
+ jz .finish
+
+ stdcall CopyImageRect, eax, 0, 0, ebx, edx, 0, ecx, ecx
+ test edi, edi
+ jnz .finish
+
+ stdcall FilterDisabled, eax, FALSE
+
+.finish:
+ mov [esp+regEAX*4], eax
+ popad
+ return
+endp
+
+
+method TAction.GetAccelStr
+begin
+ mov eax, [.self]
+ lea eax, [eax+TAction._accel]
+ stdcall AcceleratorToStr, eax
+ return
+endp
+
+
+
+method TAction.__clear_cache
+begin
+ push eax edx
+
+ mov edx, [.self]
+
+ xor eax, eax
+ xchg eax, [edx+TAction._icon_cache]
+ test eax, eax
+ jz .cache_ok1
+
+ stdcall DestroyImage, eax
+
+.cache_ok1:
+ xor eax, eax
+ xchg eax, [edx+TAction._icon_cache_gray]
+ test eax, eax
+ jz .cache_ok2
+
+ stdcall DestroyImage, eax
+
+.cache_ok2:
+
+ pop edx eax
+ return
+endp
+
+
+
+method TAction.UpdateControls
+begin
+ push eax ecx edx
+
+ mov edx, [.self]
+
+ exec edx, TAction:__clear_cache
+
+ mov edx, [edx+TAction._ctrl_list]
+ test edx, edx
+ jz .finish
+
+ mov ecx, [edx+TArray.count]
+
+.loop:
+ dec ecx
+ js .finish
+
+ exec [edx+TArray.array+4*ecx], TWindow:UpdateAction, [.self]
+ jmp .loop
+
+.finish:
+ pop edx ecx eax
+ return
+endp
+
+
+
+
+method TAction.SetCaption ;, .value
+begin
+ pushad
+ mov esi, [.self]
+ mov eax, [.value]
+ cmp eax, [esi+TAction._caption]
+ je .finish
+
+ mov [esi+TAction._caption], eax
+ exec esi, TAction:UpdateControls
+
+.finish:
+ popad
+ return
+endp
+
+
+
+method TAction.SetHintText ;, .value
+begin
+ pushad
+ mov esi, [.self]
+ mov eax, [.value]
+ cmp eax, [esi+TAction._hint_text]
+ je .finish
+
+ mov [esi+TAction._hint_text], eax
+ exec esi, TAction:UpdateControls
+
+.finish:
+ popad
+ return
+endp
+
+
+
+method TAction.SetIconIndex ;, .value
+begin
+ pushad
+ mov esi, [.self]
+ mov eax, [.value]
+ cmp eax, [esi+TAction._icon_index]
+ je .finish
+
+ mov [esi+TAction._icon_index], eax
+ exec esi, TAction:UpdateControls
+
+.finish:
+ popad
+ return
+endp
+
+
+
+method TAction.SetEnabled ;, .value
+begin
+ pushad
+ mov esi, [.self]
+ mov eax, [.value]
+ cmp eax, [esi+TAction._enabled]
+ je .finish
+
+ mov [esi+TAction._enabled], eax
+ exec esi, TAction:UpdateControls
+
+.finish:
+ popad
+ return
+endp
+
+
+
+method TAction.SetChecked ;, .value
+begin
+ pushad
+ mov esi, [.self]
+ mov eax, [.value]
+ cmp eax, [esi+TAction._checked]
+ je .finish
+
+ mov [esi+TAction._checked], eax
+
+ exec esi, TAction:UpdateControls
+
+.finish:
+ popad
+ return
+endp
+
+
+
+method TAction.SetAccelerator
+begin
+ pushad
+
+ mov esi, [.self]
+
+ mov eax, [.flags]
+ mov ecx, [.key]
+
+ test eax, fkScancode
+ jz @f
+
+ or ecx, fkScancode
+
+@@:
+ and eax, not fkScancode
+ mov [esi+TAction._accel.flags], eax
+ mov [esi+TAction._accel.key], ecx
+
+ exec esi, TAction:UpdateControls
+
+ popad
+ return
+endp
+
+
+endmodule
ADDED freshlib/gui/TActionList.asm
Index: freshlib/gui/TActionList.asm
==================================================================
--- /dev/null
+++ freshlib/gui/TActionList.asm
@@ -0,0 +1,118 @@
+; _______________________________________________________________________________________
+;| |
+;| ..::FreshLib::.. Free, open source. Licensed under "BSD 2-clause" license." |
+;|_______________________________________________________________________________________|
+;
+; Description: Actions management library.
+;
+; Target OS: Any
+;
+; Dependencies:
+;
+; Notes: TActionList is set of TAction that provides some common functionality
+; for example the common icons. It is implemented as a parent object for
+; several TAction objects.
+;_________________________________________________________________________________________
+
+module "TActionList"
+
+
+object TActionList, TObject
+
+ ._img_icons dd ?
+ ._icon_size dd ?
+
+ param .ImgIcons, ._img_icons, .SetIcons
+ param .IconSize, ._icon_size, .SetIconSize
+
+ method .Create, .parent
+
+ method .SetIcons, .value
+ method .SetIconSize, .value
+
+ method .UpdateActions
+
+endobj
+
+
+
+method TActionList.Create
+begin
+ inherited [.parent]
+ set [.self], TActionList:IconSize, 16
+ return
+endp
+
+
+method TActionList.SetIconSize
+begin
+ push eax ecx
+
+ mov ecx, [.self]
+ mov eax, [.value]
+ xchg eax, [ecx+TActionList._icon_size]
+ cmp eax, [ecx+TActionList._icon_size]
+ je .finish
+
+ exec ecx, TActionList:UpdateActions
+
+.finish:
+ pop ecx eax
+ return
+endp
+
+
+
+method TActionList.UpdateActions
+begin
+ pushad
+
+ get edx, [.self], TActionList:Children
+ test edx, edx
+ jz .finish
+
+ mov ecx, [edx+TArray.count]
+
+.loop:
+ dec ecx
+ js .finish
+
+ exec [edx+TArray.array+4*ecx], TAction:UpdateControls
+ jmp .loop
+
+.finish:
+ popad
+ return
+endp
+
+
+
+method TActionList.SetIcons
+begin
+ pushad
+
+; the .value parameter points to a PNG image in the memory.
+ mov esi, [.self]
+
+ get ecx, esi, TActionList:ImgIcons
+ jecxz .old_ok
+
+ stdcall DestroyImage, ecx
+
+.old_ok:
+ mov eax, [.value]
+ test eax, eax
+ jz .new_ok
+
+ stdcall CreateImagePNG, eax, [eax-4]
+
+.new_ok:
+ mov [esi+TActionList._img_icons], eax
+
+ exec [.self], TActionList:UpdateActions
+ popad
+ return
+endp
+
+
+endmodule
Index: freshlib/gui/TApplication.asm
==================================================================
--- freshlib/gui/TApplication.asm
+++ freshlib/gui/TApplication.asm
@@ -18,20 +18,46 @@
; The root object in the application.
; every other object will be child on the TApplication.MainWindow.
; only one instance of TApplication should be created.
;
object TApplication, TObject
+
.FMainWindow dd ?
.FAccelerators dd ?
.FOnIdle dd ?
param .MainWindow, .FMainWindow, .FMainWindow
param .Accelerators, .FAccelerators, .FAccelerators
param .OnIdle, .FOnIdle, .FOnIdle
+ method .__create ; OS dependent create handler.
+
method .Create
+
+ method .ProcessIdle ; calls all TAction idle handlers if any.
+
endobj
+
+
+
+method TApplication.Create
+begin
+ inherited 0 ; no parent for the application!
+ exec [.self], TApplication:__create
+ return
+endp
+
+
+
+
+method TApplication.ProcessIdle
+begin
+
+
+ return
+endp
+
include '%TargetOS%/TApplication.asm'
Index: freshlib/gui/TButton.asm
==================================================================
--- freshlib/gui/TButton.asm
+++ freshlib/gui/TButton.asm
@@ -12,46 +12,435 @@
; Notes: Represents GUI button.
;_________________________________________________________________________________________
module "TButton library"
-; Button states for the field TButton.state
-btnNormal = 0
-btnPressed = 1
-btnPointed = 2
-btnChecked = 3
+; Button states for the field TButton._state
+bsNeutral = 0
+bsHovered = 1
+bsPressed = 2
+bsDisabled = 3
+
+; icon positions
+
+iposLeft = 0
+iposRight = 1
+iposTop = 2
+iposBottom = 3
+iposCenter = 4
object TButton, TWindow
- .state dd ?
+
+; private fields
+
+ ._state dd ? ; internal state variable.
+
+ ._textalign dd ?
._icon dd ?
._iconpos dd ?
- ._textalign dd ?
._OnClick dd ?
._ModalResult dd ?
+
+; parameters
param .OnClick, ._OnClick, ._OnClick
- param .TextAlign, ._textalign, .SetTextAlign
- param .Icon, ._icon, .SetIcon
- param .IconPosition, ._iconpos, .SetIconPos
+ param .TextAlign, ._textalign, .SetTextAlign
+ param .Icon, ._icon, .SetIcon
+ param .IconPosition, ._iconpos, .SetIconPos
+
param .ModalResult, ._ModalResult, ._ModalResult
+; methods
+
+ ; parameters handling methods
+
method .SetTextAlign, .value
method .SetIcon, .value
method .SetIconPos, .value
- method .SysEventHandler, .pEvent
+ ; system events methods
+
+ method .Create, .Parent
+
+ method .Paint
+
+ method .EventMouseEnter
+ method .EventMouseLeave
+
+ method .EventButtonPress, .button, .kbdState, .x, .y
+ method .EventButtonRelease, .button, .kbdState, .x, .y
+
+ method .EventKeyPress, .utf8, .scancode, .kbdState
+ method .EventKeyRelease, .scancode, .kbdState
+
endobj
interface TButton.OnClick, .self, .button
+
+
+
+; new
+
+
+method TButton.Create
+begin
+ inherited [.Parent]
+
+ mov eax, [.self]
+ mov [eax+TButton._cursor], mcHand
+ mov [eax+TButton.__want_focus], TRUE
+
+ return
+endp
+
+
+
+
+
+method TButton.Paint
+
+ .bounds TBounds
+ .clTxt dd ?
+ .canvas dd ?
+
+ .caption dd ?
+ .enabled dd ?
+ .icon dd ?
+
+begin
+ pushad
+
+ mov esi, [.self]
+
+ get edx, esi, TButton:Action
+ test edx, edx
+ jz .get_normal
+
+ get [.caption], edx, TAction:Caption
+ get [.icon], edx, TAction:Icon
+ jmp .get_enabled
+
+.get_normal:
+
+ get [.caption], esi, TButton:Caption
+ get [.icon], esi, TButton:Icon
+
+.get_enabled:
+ get [.enabled], esi, TButton:Enabled ; it will return the TAction:Enabled if attached.
+
+.paint_it:
+ get eax, esi, TWindow:Canvas
+ mov [.canvas], eax
+
+ mov eax, [esi+TButton._state]
+ cmp [.enabled], 0
+ jne .state_ok
+
+ mov eax, bsDisabled
+
+.state_ok:
+ mov edi, [GUI.clBtnBk+4*eax] ; background color
+ mov ecx, [GUI.clBtnTxt+4*eax] ; text color
+ mov edx, [GUI.btnBorder+4*eax]
+ cmp [.enabled], 0
+ jne .border_ok
+
+ or edx, bxDisabled
+
+.border_ok:
+ mov [.clTxt], ecx
+
+ mov ecx, [esi+TButton._width]
+ mov eax, [esi+TButton._height]
+
+ mov [.bounds.x], 0
+ mov [.bounds.y], 0
+ mov [.bounds.width], ecx
+ mov [.bounds.height], eax
+ lea eax, [.bounds]
+
+
+
+ stdcall [DrawBox], [.canvas], eax, edi, edx, [GUI.boxBorderWidth]
+
+; first draw the icon and then resize bounds for the text.
+
+ mov ebx, [GUI.btnMarginX]
+ mov edx, [GUI.btnMarginY]
+
+ add [.bounds.x], ebx
+ add [.bounds.y], edx
+ sub [.bounds.width], ebx
+ sub [.bounds.height], edx
+ sub [.bounds.width], ebx
+ sub [.bounds.height], edx
+
+
+ mov edi, [.icon]
+ test edi, edi
+ jz .draw_text
+
+ cmp [esi+TButton._iconpos], iposCenter
+ jne @f
+
+ mov eax, [.bounds.width]
+ sub eax, [edi+TImage.width]
+ sar eax, 1
+ add eax, [.bounds.x]
+
+ mov ecx, [.bounds.height]
+ sub ecx, [edi+TImage.height]
+ sar ecx, 1
+ add ecx, [.bounds.y] ; x coordinate of the icon.
+
+ jmp .draw_icon
+
+@@:
+ cmp [esi+TButton._iconpos], iposLeft
+ jne @f
+
+; align left
+ mov eax, [.bounds.x]
+
+ mov ecx, [.bounds.height]
+ sub ecx, [edi+TImage.height]
+ sar ecx, 1
+ add ecx, [.bounds.y] ; x coordinate of the icon.
+
+ add ebx, [edi+TImage.width]
+ add [.bounds.x], ebx
+ sub [.bounds.width], ebx
+ jmp .draw_icon
+
+@@:
+ cmp [esi+TButton._iconpos], iposRight
+ jne @f
+
+; align right
+ mov eax, [.bounds.x]
+ add eax, [.bounds.width]
+ sub eax, [edi+TImage.width]
+
+ add ebx, [edi+TImage.width]
+ sub [.bounds.width], ebx
+
+ mov ecx, [.bounds.height]
+ sub ecx, [edi+TImage.height]
+ sar ecx, 1
+ add ecx, [.bounds.y]
+ jmp .draw_icon
+
+@@:
+ cmp [esi+TButton._iconpos], iposTop
+ jne @f
+
+; align top
+ mov eax, [.bounds.width]
+ sub eax, [edi+TImage.width]
+ sar eax, 1
+ add eax, [.bounds.x]
+
+ mov ecx, [.bounds.y]
+
+ add edx, [edi+TImage.height]
+
+ add [.bounds.y], edx
+ sub [.bounds.height], edx
+ jmp .draw_icon
+
+@@:
+ cmp [esi+TButton._iconpos], iposBottom
+ jne .draw_text
+
+; align bottom
+ mov ecx, [.bounds.y]
+ add ecx, [.bounds.height]
+ sub ecx, [edi+TImage.height]
+
+ add edx, [edi+TImage.height]
+ sub [.bounds.height], edx
+
+ mov eax, [.bounds.width]
+ sub eax, [edi+TImage.width]
+ sar eax, 1
+ add eax, [.bounds.x]
+
+.draw_icon:
+ cmp [esi+TButton._state], bsPressed
+ jne .blend_icon
+
+ add eax, [GUI.btnPressedOfsX]
+ add ecx, [GUI.btnPressedOfsY]
+
+.blend_icon:
+ stdcall BlendImage, [.canvas], eax, ecx, edi, 0, 0, [edi+TImage.width], [edi+TImage.height]
+
+.draw_text:
+ get edi, esi, TButton:TextAlign
+
+ mov eax, [.caption]
+ test eax, eax
+ jz .textok
+
+ cmp [esi+TButton._state], bsPressed
+ jne .textofsok
+
+ mov ecx, [GUI.btnPressedOfsX]
+ add [.bounds.x], ecx
+ mov ecx, [GUI.btnPressedOfsY]
+ add [.bounds.y], ecx
+
+.textofsok:
+ stdcall DrawTextBox, [.canvas], eax, [.bounds.x], [.bounds.y], [.bounds.width], [.bounds.height], 2, edi, [GUI.DefaultFont], [.clTxt]
+ stdcall StrDel, eax
+
+
+.textok:
+ cmp esi, [__FocusedWindow]
+ jne .not_focused
+
+ mov eax, [esi+TButton._height]
+ mov ecx, [esi+TButton._width]
+ sub eax, 2
+ sub ecx, 4
+ stdcall DrawSolidRect, [.canvas], 0, eax, [esi+TButton._width], 2, [GUI.clBorderFocused]
+
+.not_focused:
+
+ inherited
+
+ popad
+ return
+endp
+
+
+
+
+method TButton.EventMouseEnter
+begin
+ mov eax, [.self]
+ mov [eax+TButton._state], bsHovered
+ exec eax, TButton:Refresh
+
+ inherited
+ return
+endp
+
+
+
+
+method TButton.EventMouseLeave
+begin
+ mov eax, [.self]
+
+ mov [eax+TButton._state], bsNeutral
+ exec eax, TButton:Refresh
+
+ inherited
+ return
+endp
+
+
+
+method TButton.EventButtonPress
+begin
+ mov eax, [.self]
+
+ mov [eax+TButton._state], bsPressed
+ exec eax, TButton:Refresh
+ return
+endp
+
+
+
+method TButton.EventButtonRelease
+begin
+ pushad
+
+ mov esi, [.self]
+
+ cmp [esi+TButton._state], bsPressed
+ jne .finish
+
+ mov [esi+TButton._state], bsHovered
+ exec esi, TButton:Refresh
+
+ cmp [esi+TButton._ModalResult], mrNone
+ je @f
+
+ get eax, esi, TButton:Parent
+
+ istype eax, TForm
+ jne @f
+
+ set eax, TForm:ModalResult, [esi+TButton._ModalResult]
+
+@@:
+ get eax, esi, TButton:OnClick
+ test eax, eax
+ jz .click_ok
+
+ stdcall eax, esi, [.button] ; OnClick event
+
+.click_ok:
+ get eax, esi, TButton:Action
+ test eax, eax
+ jz .finish
+
+ exec eax, TAction:Execute, [.self]
+
+.finish:
+ popad
+ return
+endp
+
+
+
+
+method TButton.EventKeyPress
+begin
+ push ecx
+
+ cmp [.utf8], ' '
+ jne .finish
+
+ mov ecx, [.self]
+ mov [ecx+TButton._state], bsPressed
+
+ exec ecx, TWindow:EventButtonRelease, mbLeft, [.kbdState], 0, 0
+
+ mov [ecx+TButton._state], bsPressed
+ exec ecx, TWindow:Refresh
+
+.finish:
+ inherited [.utf8], [.scancode], [.kbdState]
+ pop ecx
+ return
+endp
+
+
+
+method TButton.EventKeyRelease
+begin
+ push ecx
+ mov ecx, [.self]
+ mov [ecx+TButton._state], bsNeutral
+
+ exec ecx, TWindow:Refresh
+ pop ecx
+
+ return
+endp
+
method TButton.SetTextAlign
begin
push ecx
@@ -62,10 +451,11 @@
exec ecx, TWindow:Refresh
pop ecx
return
endp
+
method TButton.SetIcon
begin
push ecx
@@ -92,220 +482,7 @@
pop ecx
return
endp
-
-method TButton.SysEventHandler
-begin
- pushad
-
- mov esi, [.self]
- mov ebx, [.pEvent]
-
- dispatch [ebx+TSysEvent.event]
-
-.finish:
- popad
- return
-
-;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-
-oncase sePaint
-; PAINT event is very important.
- mov edx, bxFlat
- mov edi, [clButtonBk] ; background
- mov ecx, [clButtonTxt] ; text
-
- cmp [esi+TButton.state], btnNormal
- je .drawit
-
- mov edx, bxRaised
- mov edi, [clButtonHotBk]
- mov ecx, [clButtonHotTxt]
-
- cmp [esi+TButton.state], btnPointed
- je .drawit
-
- mov edx, bxSunken
- mov edi, [clButtonBk]
- mov ecx, [clButtonHotTxt]
-
- cmp [esi+TButton.state], btnPressed
- je .drawit
-
- mov edx, bxFlat
-
-.drawit:
-locals
- .bounds TBounds
- .clTxt dd ?
-endl
- mov [.clTxt], ecx
-
- mov ecx, [esi+TButton._width]
- mov eax, [esi+TButton._height]
- mov [.bounds.x], 0
- mov [.bounds.y], 0
- mov [.bounds.width], ecx
- mov [.bounds.height], eax
- lea eax, [.bounds]
- stdcall [DrawBox], [ebx+TPaintEvent.context], eax, edi, edx
-
-; first draw the icon and then resize bounds for the text.
- mov edi, [esi+TButton._icon]
- test edi, edi
- jz .draw_text
-
- cmp [esi+TButton._iconpos], AlignLeft
- jne @f
-
-; align left
- mov eax, [.bounds.x]
- mov ecx, [.bounds.height]
- add eax, 2
- sub ecx, [edi+TImage.height]
- sar ecx, 1
- add ecx, [.bounds.y]
-
- mov edx, [edi+TImage.width]
- add edx, 4
- add [.bounds.x], edx
- sub [.bounds.width], edx
- jmp .draw_icon
-
-@@:
- cmp [esi+TButton._iconpos], AlignRight
- jne @f
-
-; align right
- mov edx, [edi+TImage.width]
-
- mov eax, [.bounds.x]
- add eax, [.bounds.width]
- sub eax, edx
- sub eax, 2
- sub [.bounds.width], edx
- sub [.bounds.width], 4
-
- mov ecx, [.bounds.height]
- sub ecx, [edi+TImage.height]
- sar ecx, 1
- add ecx, [.bounds.y]
- jmp .draw_icon
-
-@@:
- cmp [esi+TButton._iconpos], AlignTop
- jne @f
-
-; align top
- mov ecx, [.bounds.y]
- add ecx, 2
- mov eax, [.bounds.width]
- sub eax, [edi+TImage.width]
- sar eax, 1
- add eax, [.bounds.x]
-
- mov edx, [edi+TImage.height]
- add edx, 4
- add [.bounds.y], edx
- sub [.bounds.height], edx
- jmp .draw_icon
-
-@@:
- cmp [esi+TButton._iconpos], AlignBottom
- jne .draw_text
-
-; align bottom
- mov edx, [edi+TImage.height]
-
- mov ecx, [.bounds.y]
- add ecx, [.bounds.height]
- sub ecx, edx
- sub ecx, 2
- sub [.bounds.height], edx
- sub [.bounds.height], 4
-
- mov eax, [.bounds.width]
- sub eax, [edi+TImage.width]
- sar eax, 1
- add eax, [.bounds.x]
-
-.draw_icon:
- stdcall DrawImage, [ebx+TPaintEvent.context], [esi+TButton._icon], eax, ecx
-
-.draw_text:
- get eax, esi, TWindow:Caption
- test eax, eax
- jz .finish
-
- push eax eax
- stdcall StrLen, eax
- mov ecx, eax
- pop eax
- lea edx, [.bounds]
- stdcall DrawTextBox, [ebx+TPaintEvent.context], eax, edx, [esi+TButton._textalign], 0, [.clTxt]
- stdcall StrDel ; from the stack
- jmp .finish
-
-
-;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-
-oncase seMouseEnter
-
- mov [esi+TButton.state], btnPointed
- exec esi, TButton:Refresh
- jmp .finish
-
-
-;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-
-
-oncase seMouseLeave
- mov [esi+TButton.state], btnNormal
- exec esi, TButton:Refresh
- jmp .finish
-
-
-;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-
-
-oncase seMouseBtnPress
- mov [esi+TButton.state], btnPressed
- exec esi, TButton:Refresh
- jmp .finish
-
-
-;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-
-
-oncase seMouseBtnRelease
-
- cmp [esi+TButton.state], btnPressed
- jne .finish
-
- mov [esi+TButton.state], btnPointed
- exec esi, TButton:Refresh
-
- cmp [esi+TButton._ModalResult], mrNone
- je @f
-
- get eax, esi, TButton:Parent
-
- istype eax, TForm
- jne @f
-
- set eax, TForm:ModalResult, [esi+TButton._ModalResult]
-
-@@:
- get eax, esi, TButton:OnClick
- test eax, eax
- jz .finish
-
- stdcall eax, esi, [ebx+TMouseButtonEvent.Button]
- jmp .finish
-
- enddispatch
-endp
-
endmodule
ADDED freshlib/gui/TCheckbox.asm
Index: freshlib/gui/TCheckbox.asm
==================================================================
--- /dev/null
+++ freshlib/gui/TCheckbox.asm
@@ -0,0 +1,374 @@
+; _______________________________________________________________________________________
+;| |
+;| ..::FreshLib::.. Free, open source. Licensed under "BSD 2-clause" license." |
+;|_______________________________________________________________________________________|
+;
+; Description: TCheckbox object class
+;
+; Target OS: Any
+;
+; Dependencies:
+;
+; Notes: Represents GUI checkbox.
+;_________________________________________________________________________________________
+module "TCheckbox library"
+
+
+; Button states for the field TCheckbox._state
+
+cbsNeutral = 0
+cbsHovered = 1
+cbsPressed = 2
+
+cbsDisabled = 3
+
+
+object TCheckbox, TWindow
+
+; private fields
+
+ ._state dd ? ; internal state variable.
+
+ ._OnClick dd ?
+
+ ._checked dd ?
+
+; parameters
+
+ param .Checked, .GetChecked, .SetChecked
+ param .OnClick, ._OnClick, ._OnClick
+
+; methods
+
+ ; parameters handling methods
+
+ method .GetChecked
+ method .SetChecked, .value
+
+ ; system events methods
+
+ method .Create, .Parent
+
+ method .Paint
+
+ method .EventMouseEnter
+ method .EventMouseLeave
+
+ method .EventButtonPress, .button, .kbdState, .x, .y
+ method .EventButtonRelease, .button, .kbdState, .x, .y
+
+ method .EventKeyPress, .utf8, .scancode, .kbdState
+ method .EventKeyRelease, .scancode, .kbdState
+
+endobj
+
+
+; new
+
+
+method TCheckbox.Create
+begin
+ inherited [.Parent]
+
+ mov eax, [.self]
+ mov [eax+TCheckbox.__want_focus], TRUE
+ mov [eax+TCheckbox._cursor], mcHand
+ return
+endp
+
+
+
+
+
+method TCheckbox.Paint
+
+ .bounds TBounds
+ .canvas dd ?
+
+ .caption dd ?
+ .enabled dd ?
+ .checked dd ?
+
+begin
+ pushad
+
+ mov esi, [.self]
+
+ get edx, esi, TCheckbox:Action
+ test edx, edx
+ jz .get_normal
+
+ get eax, edx, TAction:Caption
+ stdcall StrDupMem, eax
+ mov [.caption], eax
+
+ get [.checked], edx, TAction:Checked
+ jmp .get_enabled
+
+.get_normal:
+
+ get [.caption], esi, TCheckbox:Caption
+ get [.checked], esi, TCheckbox:Checked
+
+
+.get_enabled:
+ get [.enabled], esi, TCheckbox:Enabled
+
+.paint_it:
+ get eax, esi, TWindow:Canvas
+ mov [.canvas], eax
+
+ mov eax, [esi+TCheckbox._state]
+ cmp [.enabled], 0
+ jne .state_ok
+
+ mov eax, cbsDisabled
+
+.state_ok:
+ mov edi, [GUI.clCheckboxBack+4*eax] ; background color
+
+ get ecx, esi, TCheckbox:height
+ mov edx, [GUI.cbIconSize]
+ sub ecx, edx
+ sar ecx, 1
+
+ mov [.bounds.x], 0
+ mov [.bounds.y], ecx
+ mov [.bounds.width], edx
+ mov [.bounds.height], edx
+
+ mov eax, [GUI.clDialogBk]
+ and eax, $00ffffff
+ or eax, $01000000
+ stdcall DrawSolidRect, [.canvas], 0, 0, [esi+TCheckbox._width], [esi+TCheckbox._height], eax
+
+ lea eax, [.bounds]
+
+ mov ebx, [GUI.borderCheckbox]
+ cmp [.enabled], 0
+ jne .border_ok
+
+ or ebx, bxDisabled
+
+.border_ok:
+ stdcall DrawBoxDefault, [.canvas], eax, edi, ebx, [GUI.boxBorderWidth]
+
+ mov [.bounds.x], 0
+ mov [.bounds.y], ecx
+ mov [.bounds.width], edx
+ mov [.bounds.height], edx
+
+; first draw the icon and then resize bounds for the text.
+
+ cmp [.checked], 0
+ je .icon_ok
+
+ mov eax, [GUI.iconCheckedGray]
+ cmp [.enabled], 0
+ je .draw_icon
+
+ mov eax, [GUI.iconChecked]
+
+.draw_icon:
+
+ stdcall BlendImage, [.canvas], [.bounds.x], [.bounds.y], eax, 0, 0, [eax+TImage.width], [eax+TImage.height]
+
+.icon_ok:
+ mov ecx, [.bounds.width]
+ mov edx, [esi+TCheckbox._width]
+ mov ebx, [esi+TCheckbox._height]
+
+ add ecx, [GUI.cbMargin]
+ sub edx, ecx
+
+ mov eax, [.caption]
+ test eax, eax
+ jz .textok
+
+ mov edi, [GUI.clCheckboxTxt]
+ cmp [.enabled], 0
+ jne .txt_color_ok
+
+ mov edi, [GUI.clCheckboxTxtGray]
+
+.txt_color_ok:
+ stdcall DrawTextBox, [.canvas], eax, ecx, 0, edx, ebx, 0, dtfAlignLeft or dtfAlignMiddle, [GUI.DefaultFont], edi
+ stdcall StrDel, eax
+
+.textok:
+ cmp esi, [__FocusedWindow]
+ jne .not_focused
+
+ mov eax, [.bounds.y]
+ add eax, 15
+ stdcall DrawSolidRect, [.canvas], 0, eax, 13, 2, [GUI.clBorderFocused]
+
+.not_focused:
+
+ inherited
+
+ popad
+ return
+endp
+
+
+
+
+method TCheckbox.EventMouseEnter
+begin
+ mov eax, [.self]
+ mov [eax+TCheckbox._state], cbsHovered
+ exec eax, TCheckbox:Refresh
+
+ inherited
+ return
+endp
+
+
+
+
+method TCheckbox.EventMouseLeave
+begin
+ mov eax, [.self]
+
+ mov [eax+TCheckbox._state], cbsNeutral
+ exec eax, TCheckbox:Refresh
+
+ inherited
+ return
+endp
+
+
+
+
+method TCheckbox.EventButtonPress
+begin
+ push eax
+
+ mov eax, [.self]
+ mov [eax+TCheckbox._state], cbsPressed
+
+ get eax, [.self], TCheckbox:Checked
+ xor eax, 1
+ set [.self], TCheckbox:Checked, eax
+
+ get eax, [.self], TCheckbox:OnClick
+ test eax, eax
+ jz .finish
+
+ stdcall eax, [.self], [.button]
+
+.finish:
+ exec [.self], TCheckbox:Refresh
+ pop eax
+ return
+endp
+
+
+
+method TCheckbox.EventButtonRelease
+begin
+ pushad
+
+ mov esi, [.self]
+ mov [esi+TCheckbox._state], cbsHovered
+ exec esi, TCheckbox:Refresh
+
+ popad
+ return
+endp
+
+
+
+
+method TCheckbox.EventKeyPress
+begin
+ push ecx
+
+ cmp [.utf8], ' '
+ jne .finish
+
+ mov ecx, [.self]
+ cmp [ecx+TCheckbox._state], cbsPressed
+ je .finish
+
+ exec ecx, TWindow:EventButtonPress, mbLeft, [.kbdState], 0, 0
+
+ mov [ecx+TCheckbox._state], cbsPressed
+ exec ecx, TWindow:Refresh
+
+.finish:
+ inherited [.utf8], [.scancode], [.kbdState]
+ pop ecx
+ return
+endp
+
+
+
+
+method TCheckbox.EventKeyRelease
+begin
+ push ecx
+
+ mov ecx, [.self]
+ mov [ecx+TCheckbox._state], cbsNeutral
+
+ exec ecx, TWindow:Refresh
+ pop ecx
+
+ return
+endp
+
+
+
+method TCheckbox.GetChecked
+begin
+ push ecx edx
+
+ mov edx, [.self]
+ mov ecx, [edx+TCheckbox.__action]
+ jecxz .native
+
+ get eax, ecx, TAction:Checked
+ jmp .finish
+
+.native:
+ mov eax, [edx+TCheckbox._checked]
+
+.finish:
+ pop edx ecx
+ return
+endp
+
+
+
+method TCheckbox.SetChecked
+begin
+ pushad
+
+ mov ecx, [.self]
+ mov eax, [.value]
+
+ get edx, ecx, TCheckbox:Checked
+
+ cmp eax, edx
+ je .finish
+
+ cmp [ecx+TCheckbox.__action], 0
+ je .action_ok
+
+ set [ecx+TCheckbox.__action], TAction:Checked, eax
+
+.action_ok:
+ mov [ecx+TCheckbox._checked], eax
+ exec ecx, TWindow:Refresh
+
+.finish:
+ popad
+ return
+endp
+
+
+
+
+endmodule
Index: freshlib/gui/TEdit.asm
==================================================================
--- freshlib/gui/TEdit.asm
+++ freshlib/gui/TEdit.asm
@@ -12,66 +12,91 @@
; Notes: Represents single line edit control.
;_________________________________________________________________________________________
module "TEdit library"
-object TEdit, TBackWindow
+object TEdit, TWindow
._Text dd ?
._Len dd ? ; the length of the string in characters. (UTF-8)
._Start dd ? ; Where the string begins to be displayed in the edit window.
._Pos dd ? ; Position of the caret in the string.
._Sel dd ? ; Position of the selction in the string.
+ ._need_refresh dd ?
+
._MarginLeft dd ?
._MarginRight dd ?
- ._Focused dd ? ; flag
-
param .Text, .GetText, .SetText
- method ._RedrawShadow
+ param .MarginLeft, ._MarginLeft, ._MarginLeft
+ param .MarginRight, ._MarginRight, ._MarginRight
- method .Create
+ param .CaretPos, ._Pos, .SetCaretPos
+
+ method .Create, .parent
method .Destroy
method .GetText
method .SetText, .value
+ method .SetCaretPos, .value
- method .SysEventHandler, .pEvent
+ method .HitTest, .x, .y ; returns the position inside the string.
+
+; system event methods
+
+ method .UpdateCaretPos
+
+ method .Paint
+
+ method .EventKeyPress, .utf8, .scancode, .kbdState
+ method .EventKeyRelease, .scancode, .kbdState
+
+ method .EventFocusIn
+ method .EventFocusOut
+
endobj
+
method TEdit.Create
begin
push ecx eax
+ inherited [.parent]
+
stdcall StrNew
mov ecx, [.self]
mov [ecx+TEdit._Text], eax
mov [ecx+TEdit._cursor], mcText
-
- inherited
+ mov [ecx+TEdit.__want_focus], TRUE
+ mov [ecx+TEdit._need_refresh], TRUE
pop eax ecx
return
endp
+
method TEdit.Destroy
begin
mov eax, [.self]
stdcall StrDel, [eax+TEdit._Text]
return
endp
+
+
method TEdit.GetText
begin
mov eax, [.self]
stdcall StrDup, [eax+TEdit._Text]
return
endp
+
+
method TEdit.SetText
begin
push esi eax
@@ -81,216 +106,174 @@
mov [esi+TEdit._Pos], 0
mov [esi+TEdit._Sel], 0
lea eax, [esi+TEdit._Text]
stdcall SetString, eax, [.value]
+
stdcall StrLenUtf8, [esi+TEdit._Text], -1
mov [esi+TEdit._Len], eax
- mov [esi+TEdit._fShadowReady], 0
-
exec esi, TEdit:Refresh
pop eax esi
return
endp
-method TEdit._RedrawShadow
+method TEdit.Paint
.bounds TBounds
.selbeg dd ?
.selend dd ?
- .ypos dd ?
- .context dd ?
+
+ .clBack dd ?
+ .border dd ?
+
begin
pushad
+
mov esi, [.self]
+ exec esi, TEdit:__UpdateCanvas
- mov eax, [esi+TEdit._pShadow]
- stdcall AllocateContext, [eax+TBackBuffer.raster]
- mov [.context], eax
+ mov eax, [GUI.clEditBk]
+ mov ecx, [GUI.editBorder]
+ cmp esi, [__FocusedWindow]
+ jne @f
+ mov eax, [GUI.clEditBkFocused]
+ mov ecx, [GUI.editBorderFocused]
+@@:
+ mov [.clBack], eax
+ mov [.border], ecx
+
+; selection sort positions.
mov eax, [esi+TEdit._Pos]
mov ecx, [esi+TEdit._Sel]
cmp eax,ecx
jle @f
xchg eax, ecx
@@:
mov [.selbeg], eax
mov [.selend], ecx
+; drawing bounds
mov ecx, [esi+TEdit._width]
mov eax, [esi+TEdit._height]
mov [.bounds.x], 0
mov [.bounds.y], 0
mov [.bounds.width], ecx
mov [.bounds.height], eax
lea eax, [.bounds]
- stdcall [DrawBox], [.context], eax, [clEditBk], bxSunken
+
+ stdcall [DrawBox], [esi+TWindow._canvas], eax, [.clBack], [.border], [GUI.boxBorderWidth]
+
+ mov eax, [GUI.boxBorderWidth]
+ add [.bounds.x], eax
+ add [.bounds.y], eax
+ shl eax, 1
+ sub [.bounds.width], eax
+ sub [.bounds.height], eax
mov eax, [esi+TEdit._MarginLeft]
mov ecx, [esi+TEdit._MarginRight]
add [.bounds.x], eax
sub [.bounds.width], eax
sub [.bounds.width], ecx
cmp [.bounds.width], 0
jle .enddraw
- mov ecx, [esi+TEdit._Start]
-
- stdcall StrOffsUtf8, [esi+TEdit._Text], ecx
+ stdcall StrOffsUtf8, [esi+TEdit._Text], [esi+TEdit._Start]
mov edi, eax
- mov eax, [.bounds.y]
- add eax, [.bounds.height]
- sub eax, 4
- mov [.ypos], eax ; y position of the characters.
-
-.drawloop:
- stdcall DecodeUtf8, [edi]
- jc .enddraw
-
- test eax, eax
- jz .eraseremaining
-
- mov eax, [clEditTxt]
- cmp ecx, [.selbeg]
- jl .colorok
- cmp ecx, [.selend]
- jge .colorok
- mov eax, [clEditSelTxt]
-
-.colorok:
- push eax 0 [.ypos] [.bounds.x] edx edi
-
- push 0 edx edi
- add edi, edx
- stdcall GetTextBounds, [.context] ; remaining from the stack
-
- sub [.bounds.width], eax
- js .nodraw
-
- cmp ecx, [.selbeg]
- jl .drawtxt
- cmp ecx, [.selend]
- jge .drawtxt
-
- mov esi, [.ypos]
- sub esi, edx
- add edx, 2
- stdcall DrawFillRect, [.context], [.bounds.x], [.bounds.y], eax, [.bounds.height], [clEditSel]
-
-.drawtxt:
- add [.bounds.x], eax
- stdcall DrawString, [.context] ; remaining from the stack
-
- inc ecx
- jmp .drawloop
-
-.nodraw:
- add esp, 24 ; 6*4
- jmp .enddraw
-
-.eraseremaining:
- stdcall DrawFillRect, [.context], [.bounds.x], [.bounds.y], [.bounds.width], [.bounds.height], [clEditBk]
+ stdcall DrawTextBox, [esi+TEdit._canvas], edi, [.bounds.x], [.bounds.y], [.bounds.width], [.bounds.height], 0, dtfAlignLeft or dtfAlignMiddle or dtfSingleLine, [GUI.DefaultFont], [GUI.clEditTxt]
+
+; determine the selection
+
+ mov eax, [.selbeg]
+ mov ecx, [esi+TEdit._MarginLeft]
+
+ sub eax, [esi+TEdit._Start]
+ jle .xsel_ok
+
+ stdcall StrOffsUtf8, edi, eax
+ sub eax, edi
+
+ stdcall GetTextBounds, edi, eax, [GUI.DefaultFont]
+ mov ecx, eax
+
+.xsel_ok:
+ mov eax, [.selend]
+ sub eax, [esi+TEdit._Start]
+ jle .enddraw
+
+ stdcall StrOffsUtf8, edi, eax
+ sub eax, edi
+
+ stdcall GetTextBounds, edi, eax, [GUI.DefaultFont]
+
+ mov edx, [.bounds.width]
+ add edx, [.bounds.x]
+
+ cmp eax, edx
+ cmovg eax, edx
+ sub eax, ecx
+
+ add ecx, [.bounds.x]
+ stdcall BlendSolidRect, [esi+TWindow._canvas], ecx, [.bounds.y], eax, [.bounds.height], [GUI.clEditSel]
.enddraw:
- stdcall ReleaseContext, [.context]
-
- stc
+ inherited
popad
return
endp
-
-method TEdit.SysEventHandler
-.changes dd ?
-.prevpos dd ?
-.PosChanged = 1
-.NeedRefresh = 2
-.ShowCaret = 4
+method TEdit.EventKeyPress ;, .utf8, .scancode, .kbdState
+.time dd ?
begin
- push eax ebx ecx edx esi edi
+ pushad
- mov [.changes], 0
+ stdcall GetTimestamp
+ mov [.time], eax
+
mov esi, [.self]
- mov ebx, [.pEvent]
- mov eax, [ebx+TSysEvent.event]
-
- cmp eax, seKbdKeyPress
- je .keypress
-
- cmp eax, seFocusIn
- je .focusin
-
- cmp eax, seFocusOut
- je .focusout
-
- inherited [.pEvent]
-
-.finish:
- pop edi esi edx ecx ebx eax
- return
-
-;............................................................................................
-
-.focusin:
- mov [esi+TEdit._Focused], TRUE
- stdcall CaretAttach, esi
- or [.changes], .PosChanged or .ShowCaret
- jmp .endmove
-
-.focusout:
- stdcall CaretShow, FALSE
- mov [esi+TEdit._Focused], FALSE
- or [.changes], .PosChanged
- jmp .endmove
-
-;............................................................................................
-
-.keypress:
-; mov eax, [ebx+TKeyboardEvent.kbdStatus]
-; OutputRegister regEAX, 16
-
- mov eax, [esi+TEdit._Pos]
- mov [.prevpos], eax
-
- mov eax, [ebx+TKeyboardEvent.key]
+ get ebx, esi, TEdit:CaretPos
+
+ mov eax, [.utf8]
test eax, eax
jz .no_char
cmp eax, $20
jb .no_char
cmp eax, $7f
je .no_char
+
push eax
call .ClearSelection
stdcall StrPtr, [esi+TEdit._Text]
mov ecx, eax
- stdcall StrOffsUtf8, eax, [esi+TEdit._Pos]
+ stdcall StrOffsUtf8, eax, ebx
sub ecx, eax
neg ecx
pop eax
stdcall StrCharInsert, [esi+TEdit._Text], eax, ecx
inc [esi+TEdit._Len]
- mov [ebx+TKeyboardEvent.kbdStatus], 0
- or [.changes], .NeedRefresh
+ mov [.kbdState], 0
+ inc [esi+TEdit._need_refresh]
jmp .right
.no_char:
- mov eax, [ebx+TKeyboardEvent.scancode]
+ mov eax, [.scancode]
cmp eax, keyLeftNumpad
je .left
cmp eax, keyLeft
je .left
@@ -319,60 +302,53 @@
je .backdel
jmp .finish
.left:
- cmp [esi+TEdit._Pos], 0
+ cmp ebx, 0
jle .endmove
- or [.changes], .PosChanged
- dec [esi+TEdit._Pos]
+ dec ebx
jmp .endmove
.right:
- mov eax, [esi+TEdit._Pos]
- cmp eax, [esi+TEdit._Len]
- jae .finish
+ cmp ebx, [esi+TEdit._Len]
+ jae .endmove
- or [.changes], .PosChanged
- inc [esi+TEdit._Pos]
+ inc ebx
jmp .endmove
.home:
- mov [esi+TEdit._Pos], 0
- mov [esi+TEdit._Start], 0
- mov [.changes], .PosChanged or .NeedRefresh
+ xor ebx, ebx
jmp .endmove
+
.end:
- mov eax, [esi+TEdit._Len]
- mov [esi+TEdit._Pos], eax
- or [.changes], .PosChanged
+ mov ebx, [esi+TEdit._Len]
jmp .endmove
+
.backdel:
call .ClearSelection
jnc .endmove
- cmp [esi+TEdit._Pos], 0
+ cmp ebx, 0
jle .endmove
- or [.changes], .PosChanged
- dec [esi+TEdit._Pos]
+ dec ebx
.del:
call .ClearSelection
jnc .endmove
- mov eax, [esi+TEdit._Pos]
- cmp eax, [esi+TEdit._Len]
- jae .finish ; can't delete after the end of string.
+ cmp ebx, [esi+TEdit._Len]
+ jge .finish ; can't delete after the end of string.
stdcall StrPtr, [esi+TEdit._Text]
-
mov ecx, eax
- stdcall StrOffsUtf8, eax, [esi+TEdit._Pos]
+
+ stdcall StrOffsUtf8, eax, ebx
sub eax, ecx
stdcall StrSplit, [esi+TEdit._Text], eax
mov ebx, eax
@@ -382,131 +358,53 @@
stdcall StrCopyPart, ebx, ebx, edx, -1
stdcall StrCat, [esi+TEdit._Text], ebx
stdcall StrDel, ebx
dec [esi+TEdit._Len]
- or [.changes], .NeedRefresh
.endmove:
- mov ebx, [.pEvent]
mov eax, [esi+TEdit._Pos]
- cmp [ebx+TSysEvent.event], seKbdKeyPress
- jne .setselection
-
- test [ebx+TKeyboardEvent.kbdStatus], maskShift
- jnz .refresh
-
-.setselection:
- mov ecx, [.prevpos]
- cmp ecx, [esi+TEdit._Sel]
- je @f
- or [.changes], .NeedRefresh
-@@:
- mov [esi+TEdit._Sel], eax
-
- test [.changes], .NeedRefresh
- jz .caretmove
-
-.refresh:
- mov [esi+TEdit._fShadowReady], 0
- exec [.self], TEdit:Refresh
-
-.caretmove:
- cmp [esi+TEdit._Focused], 0
+
+ test [.kbdState], maskShift
+ jnz .set_pos
+
+ mov [esi+TEdit._Sel], ebx
+
+.set_pos:
+ set esi, TEdit:CaretPos, ebx
+
+ cmp [esi+TEdit._need_refresh], 0
je .finish
- test [.changes], .PosChanged
- jz .showcaret
-
- mov eax, [esi+TEdit._Pos]
- cmp eax, [esi+TEdit._Start]
- jl .scroll
-
- stdcall StrPtr, [esi+TEdit._Text]
- mov edi, eax
-
- stdcall StrOffsUtf8, edi, [esi+TEdit._Pos]
- mov ecx, eax
-
- stdcall StrOffsUtf8, edi, [esi+TEdit._Start]
- sub ecx, eax ; offset to char under cursor.
- jns .leftok
-
-.scroll:
- mov eax, [esi+TEdit._Start]
- sub eax, 8
- test eax, eax
- jns @f
- xor eax, eax
-@@:
- mov [esi+TEdit._Start], eax
- mov [.changes], .PosChanged or .NeedRefresh
- jmp .endmove
-
-.leftok:
- mov edi, eax ; pointer to start of the text.
-
- stdcall AllocateContext, [esi+TEdit.handle]
- push eax
-
- stdcall GetTextBounds, eax, edi, ecx, 0
- lea ecx, [eax+2] ; x coordinate of the cursor.
- add ecx, [esi+TEdit._MarginLeft]
-
- stdcall ReleaseContext ; from the stack.
-
- mov eax, [esi+TEdit._width]
- sub eax, [esi+TEdit._MarginRight]
- sub eax, ecx
- cmp eax, 2
- jge .caretok
-
- mov eax, [esi+TEdit._Start]
- add eax, 8
- cmp eax, [esi+TEdit._Len]
- jle @f
- mov eax, [esi+TEdit._Len]
-@@:
- mov [esi+TEdit._Start], eax
-
- mov [.changes], .PosChanged or .NeedRefresh
- jmp .endmove
-
-
-.caretok:
- mov edx, [esi+TEdit._height]
- sub edx, 4
-
- stdcall CaretChange, ecx, 2, 1, edx
-
-.showcaret:
- test [.changes], .ShowCaret
- jz .finish
-
- stdcall CaretShow, TRUE
- jmp .finish
-
-;............................................................................................
+ exec esi, TEdit:Update
+ mov [esi+TEdit._need_refresh], 0
+
+.finish:
+ stdcall GetTimestamp
+ sub eax, [.time]
+
+ OutputValue "Key press:", eax, 10, 4
+
+ popad
+ return
.ClearSelection:
- mov eax, [esi+TEdit._Pos]
mov ecx, [esi+TEdit._Sel]
- cmp eax, [esi+TEdit._Sel]
+ cmp ebx, [esi+TEdit._Sel]
je .noselection ; there is no selection.
- jg @f
- xchg eax, ecx ; eax=end_selection; ecx=beg_selection
+ jl @f
+ xchg ebx, ecx ; ebx=beg_selection; ecx=end_selection
@@:
- add [esi+TEdit._Len], ecx
- sub [esi+TEdit._Len], eax
- mov [esi+TEdit._Pos], ecx
- mov [esi+TEdit._Sel], ecx
+ add [esi+TEdit._Len], ebx
+ sub [esi+TEdit._Len], ecx
+ mov [esi+TEdit._Sel], ebx
push -1
- stdcall StrOffsUtf8, [esi+TEdit._Text], eax
+ stdcall StrOffsUtf8, [esi+TEdit._Text], ecx
push eax
- stdcall StrOffsUtf8, [esi+TEdit._Text], ecx
+ stdcall StrOffsUtf8, [esi+TEdit._Text], ebx
push eax
stdcall StrPtr, [esi+TEdit._Text]
sub [esp], eax ; begin of the selection
sub [esp+4], eax
mov eax, [esp]
@@ -516,19 +414,471 @@
mov ecx, eax
stdcall StrCopyPart, ecx, ecx ; pos and length from the stack.
stdcall StrCat, [esi+TEdit._Text], ecx
stdcall StrDel, ecx
- or [.changes], .PosChanged or .NeedRefresh
clc
retn
.noselection:
stc
retn
+
+endp
+
+
+
+method TEdit.EventKeyRelease ;, .scancode, .kbdState
+begin
+
+ return
+endp
+
+
+
+method TEdit.SetCaretPos
+begin
+ pushad
+
+ mov ecx, [.self]
+ mov eax, [.value]
+ cmp eax, [ecx+TEdit._Pos]
+ je .finish
+
+ mov [ecx+TEdit._Pos], eax
+ exec ecx, TEdit:UpdateCaretPos
+
+.finish:
+ popad
+ return
+endp
+
+
+
+method TEdit.UpdateCaretPos
+.refresh dd ?
+begin
+ pushad
+ mov esi, [.self]
+
+ xor eax, eax
+ mov [.refresh], eax
+
+ mov eax, [esi+TEdit._Pos]
+ cmp eax, [esi+TEdit._Start]
+ jge .compute_x
+
+; scroll the text
+ and eax, $fffffff8
+ mov [esi+TEdit._Start], eax
+ inc [.refresh]
+
+.compute_x:
+ stdcall StrPtr, [esi+TEdit._Text]
+ mov edi, eax
+
+ stdcall StrOffsUtf8, edi, [esi+TEdit._Pos]
+ mov ecx, eax
+
+ stdcall StrOffsUtf8, edi, [esi+TEdit._Start]
+ sub ecx, eax ; offset to char under cursor.
+
+.leftok:
+ mov edi, eax ; StrOffsUtf8 returns pointer to start of the text.
+
+ mov eax, ecx
+ jecxz @f
+
+ stdcall GetTextBounds, edi, ecx, [GUI.DefaultFont]
+
+@@:
+ lea ecx, [eax+1] ; x coordinate of the cursor.
+ add ecx, [esi+TEdit._MarginLeft]
+
+ mov eax, [esi+TEdit._width]
+ sub eax, [esi+TEdit._MarginRight]
+ sub eax, ecx
+ cmp eax, 1
+ jge .caretok
+
+ mov eax, [esi+TEdit._Start]
+ add eax, 8
+ cmp eax, [esi+TEdit._Len]
+ jle @f
+ mov eax, [esi+TEdit._Len]
+@@:
+ mov [esi+TEdit._Start], eax
+ inc [.refresh]
+ jmp .compute_x
+
+.caretok:
+ cmp [.refresh], 0
+ je .canvas_ok
+
+ exec esi, TEdit:Paint
+ inc [esi+TEdit._need_refresh]
+
+.canvas_ok:
+ mov edx, [esi+TEdit._height]
+ sub edx, 4
+
+ add ecx, [GUI.boxBorderWidth]
+ stdcall CaretChange, ecx, 2, 1, edx
+
+ popad
+ return
+endp
+
+
+
+method TEdit.HitTest
+begin
+
+
+ return
+endp
+
+
+
+method TEdit.EventFocusIn
+begin
+ stdcall CaretAttach, [.self]
+ stdcall CaretShow, TRUE
+ exec [.self], TEdit:UpdateCaretPos
+ return
+endp
+
+
+method TEdit.EventFocusOut
+begin
+ stdcall CaretShow, FALSE
+
+ inherited
+ return
endp
+
+;method TEdit.SysEventHandler
+;.changes dd ?
+;.prevpos dd ?
+;.PosChanged = 1
+;.NeedRefresh = 2
+;.ShowCaret = 4
+;begin
+; push eax ebx ecx edx esi edi
+;
+; mov [.changes], 0
+; mov esi, [.self]
+; mov ebx, [.pEvent]
+; mov eax, [ebx+TSysEvent.event]
+;
+; cmp eax, seKbdKeyPress
+; je .keypress
+;
+; cmp eax, seFocusIn
+; je .focusin
+;
+; cmp eax, seFocusOut
+; je .focusout
+;
+; inherited [.pEvent]
+;
+;.finish:
+; pop edi esi edx ecx ebx eax
+; return
+;
+;;............................................................................................
+;
+;.focusin:
+; mov [esi+TEdit._Focused], TRUE
+; stdcall CaretAttach, esi
+; or [.changes], .PosChanged or .ShowCaret
+; jmp .endmove
+;
+;.focusout:
+; stdcall CaretShow, FALSE
+; mov [esi+TEdit._Focused], FALSE
+; or [.changes], .PosChanged
+; jmp .endmove
+;
+;;............................................................................................
+;
+;.keypress:
+;; mov eax, [ebx+TKeyboardEvent.kbdStatus]
+;; OutputRegister regEAX, 16
+;
+; mov eax, [esi+TEdit._Pos]
+; mov [.prevpos], eax
+;
+; mov eax, [ebx+TKeyboardEvent.key]
+; test eax, eax
+; jz .no_char
+;
+; cmp eax, $20
+; jb .no_char
+;
+; cmp eax, $7f
+; je .no_char
+;
+; push eax
+;
+; call .ClearSelection
+;
+; stdcall StrPtr, [esi+TEdit._Text]
+; mov ecx, eax
+; stdcall StrOffsUtf8, eax, [esi+TEdit._Pos]
+; sub ecx, eax
+; neg ecx
+;
+; pop eax
+; stdcall StrCharInsert, [esi+TEdit._Text], eax, ecx
+; inc [esi+TEdit._Len]
+;
+; mov [ebx+TKeyboardEvent.kbdStatus], 0
+; or [.changes], .NeedRefresh
+; jmp .right
+;
+;.no_char:
+; mov eax, [ebx+TKeyboardEvent.scancode]
+;
+; cmp eax, keyLeftNumpad
+; je .left
+; cmp eax, keyLeft
+; je .left
+;
+; cmp eax, keyRightNumpad
+; je .right
+; cmp eax, keyRight
+; je .right
+;
+; cmp eax, keyHomeNumpad
+; je .home
+; cmp eax, keyHome
+; je .home
+;
+; cmp eax, keyEndNumpad
+; je .end
+; cmp eax, keyEnd
+; je .end
+;
+; cmp eax, keyDelNumpad
+; je .del
+; cmp eax, keyDelete
+; je .del
+;
+; cmp eax, keyBackSpace
+; je .backdel
+;
+; jmp .finish
+;
+;.left:
+; cmp [esi+TEdit._Pos], 0
+; jle .endmove
+;
+; or [.changes], .PosChanged
+; dec [esi+TEdit._Pos]
+; jmp .endmove
+;
+;.right:
+; mov eax, [esi+TEdit._Pos]
+; cmp eax, [esi+TEdit._Len]
+; jae .finish
+;
+; or [.changes], .PosChanged
+; inc [esi+TEdit._Pos]
+; jmp .endmove
+;
+;.home:
+; mov [esi+TEdit._Pos], 0
+; mov [esi+TEdit._Start], 0
+; mov [.changes], .PosChanged or .NeedRefresh
+; jmp .endmove
+;
+;.end:
+; mov eax, [esi+TEdit._Len]
+; mov [esi+TEdit._Pos], eax
+; or [.changes], .PosChanged
+; jmp .endmove
+;
+;.backdel:
+; call .ClearSelection
+; jnc .endmove
+;
+; cmp [esi+TEdit._Pos], 0
+; jle .endmove
+;
+; or [.changes], .PosChanged
+; dec [esi+TEdit._Pos]
+;
+;.del:
+; call .ClearSelection
+; jnc .endmove
+;
+; mov eax, [esi+TEdit._Pos]
+; cmp eax, [esi+TEdit._Len]
+; jae .finish ; can't delete after the end of string.
+;
+; stdcall StrPtr, [esi+TEdit._Text]
+;
+; mov ecx, eax
+; stdcall StrOffsUtf8, eax, [esi+TEdit._Pos]
+; sub eax, ecx
+;
+; stdcall StrSplit, [esi+TEdit._Text], eax
+; mov ebx, eax
+;
+; stdcall StrPtr, ebx
+; stdcall DecodeUtf8, [eax]
+;
+; stdcall StrCopyPart, ebx, ebx, edx, -1
+; stdcall StrCat, [esi+TEdit._Text], ebx
+; stdcall StrDel, ebx
+;
+; dec [esi+TEdit._Len]
+; or [.changes], .NeedRefresh
+;
+;.endmove:
+; mov ebx, [.pEvent]
+; mov eax, [esi+TEdit._Pos]
+; cmp [ebx+TSysEvent.event], seKbdKeyPress
+; jne .setselection
+;
+; test [ebx+TKeyboardEvent.kbdStatus], maskShift
+; jnz .refresh
+;
+;.setselection:
+; mov ecx, [.prevpos]
+; cmp ecx, [esi+TEdit._Sel]
+; je @f
+; or [.changes], .NeedRefresh
+;@@:
+; mov [esi+TEdit._Sel], eax
+;
+; test [.changes], .NeedRefresh
+; jz .caretmove
+;
+;.refresh:
+; mov [esi+TEdit._fShadowReady], 0
+; exec [.self], TEdit:Refresh
+;
+;.caretmove:
+; cmp [esi+TEdit._Focused], 0
+; je .finish
+;
+; test [.changes], .PosChanged
+; jz .showcaret
+;
+; mov eax, [esi+TEdit._Pos]
+; cmp eax, [esi+TEdit._Start]
+; jl .scroll
+;
+; stdcall StrPtr, [esi+TEdit._Text]
+; mov edi, eax
+;
+; stdcall StrOffsUtf8, edi, [esi+TEdit._Pos]
+; mov ecx, eax
+;
+; stdcall StrOffsUtf8, edi, [esi+TEdit._Start]
+; sub ecx, eax ; offset to char under cursor.
+; jns .leftok
+;
+;.scroll:
+; mov eax, [esi+TEdit._Start]
+; sub eax, 8
+; test eax, eax
+; jns @f
+; xor eax, eax
+;@@:
+; mov [esi+TEdit._Start], eax
+; mov [.changes], .PosChanged or .NeedRefresh
+; jmp .endmove
+;
+;.leftok:
+; mov edi, eax ; pointer to start of the text.
+;
+; stdcall AllocateContext, [esi+TEdit.handle]
+; push eax
+;
+; stdcall GetTextBounds, eax, edi, ecx, 0
+; lea ecx, [eax+2] ; x coordinate of the cursor.
+; add ecx, [esi+TEdit._MarginLeft]
+;
+; stdcall ReleaseContext ; from the stack.
+;
+; mov eax, [esi+TEdit._width]
+; sub eax, [esi+TEdit._MarginRight]
+; sub eax, ecx
+; cmp eax, 2
+; jge .caretok
+;
+; mov eax, [esi+TEdit._Start]
+; add eax, 8
+; cmp eax, [esi+TEdit._Len]
+; jle @f
+; mov eax, [esi+TEdit._Len]
+;@@:
+; mov [esi+TEdit._Start], eax
+;
+; mov [.changes], .PosChanged or .NeedRefresh
+; jmp .endmove
+;
+;
+;.caretok:
+; mov edx, [esi+TEdit._height]
+; sub edx, 4
+;
+; stdcall CaretChange, ecx, 2, 1, edx
+;
+;.showcaret:
+; test [.changes], .ShowCaret
+; jz .finish
+;
+; stdcall CaretShow, TRUE
+; jmp .finish
+;
+;;............................................................................................
+;
+;
+;.ClearSelection:
+; mov eax, [esi+TEdit._Pos]
+; mov ecx, [esi+TEdit._Sel]
+; cmp eax, [esi+TEdit._Sel]
+; je .noselection ; there is no selection.
+; jg @f
+; xchg eax, ecx ; eax=end_selection; ecx=beg_selection
+;@@:
+; add [esi+TEdit._Len], ecx
+; sub [esi+TEdit._Len], eax
+; mov [esi+TEdit._Pos], ecx
+; mov [esi+TEdit._Sel], ecx
+;
+; push -1
+; stdcall StrOffsUtf8, [esi+TEdit._Text], eax
+; push eax
+; stdcall StrOffsUtf8, [esi+TEdit._Text], ecx
+; push eax
+; stdcall StrPtr, [esi+TEdit._Text]
+; sub [esp], eax ; begin of the selection
+; sub [esp+4], eax
+; mov eax, [esp]
+; sub [esp+4], eax ; length of the selection
+;
+; stdcall StrSplit, [esi+TEdit._Text] ; position from the stack
+; mov ecx, eax
+; stdcall StrCopyPart, ecx, ecx ; pos and length from the stack.
+; stdcall StrCat, [esi+TEdit._Text], ecx
+; stdcall StrDel, ecx
+;
+; or [.changes], .PosChanged or .NeedRefresh
+; clc
+; retn
+;
+;.noselection:
+; stc
+; retn
+;endp
+
endmodule
; stdcall DecodeUtf8, [edi]
Index: freshlib/gui/TForm.asm
==================================================================
--- freshlib/gui/TForm.asm
+++ freshlib/gui/TForm.asm
@@ -9,10 +9,11 @@
;
; Dependencies:
;
; Notes: Represents form window that to serve as parent window for other controls.
;_________________________________________________________________________________________
+
module "TForm library"
mrNone = 0
mrOK = 1
@@ -27,74 +28,373 @@
object TForm, TWindow
._modal_result dd ?
._OnClose dd ? ; On close window event handler.
+
+ ._p_split_grid dd ?
+ ._p_split_template dd ?
+ ._drag_splitter dd ?
param .ModalResult, ._modal_result, ._modal_result
param .OnClose, ._OnClose, ._OnClose
- method .SysEventHandler, .pEvent
+ param .SplitGrid, ._p_split_grid, .SetSplitGrid
+
+ method .__RealignSplitGrid
+
+ method .SetSplitGrid, .value
+ method .AttachControlToCell, .pWindow, .idCell
+
+ method .SetWidth, .value
+ method .SetHeight, .value
+
+ method .EventMouseMove, .x, .y, .kbdState
+ method .EventButtonPress, .button, .kbdState, .x, .y
+ method .EventButtonRelease, .button, .kbdState, .x, .y
+
+ method .EventResize, .newWidth, .newHeight
+
+ method .CloseRequest, .reason
+ method .Paint
+
endobj
+
+
+;----------------------------------------------------------------------
+; Interface for TForm.OnClose user handler.
+; Arguments:
+; .self - pointer to the TForm object
+; .reason - the reason for the close request.
+;
+; Returns:
+; CF = 1 - Ignore the request. The form will not be closed.
+; CF = 0 - Destroy the object.
+;
+; If the OnClose event handler is not set, the form will be destroyed.
+;----------------------------------------------------------------------
+interface TForm.OnClose, .self, .reason
+
; OS independent code.
-method TForm.SysEventHandler
+
+method TForm.Paint
begin
- push ebx esi
-
- mov ebx, [.pEvent]
- cmp [ebx+TSysEvent.event], sePaint
- je .onpaint
-
- cmp [ebx+TSysEvent.event], seCloseRequest
- je .close_request
-
- ; call the inherited event handler...
-.inherited:
- inherited [.pEvent]
-
-.finish:
- pop esi ebx
- return
-
-.onpaint:
+ pushad
+
mov esi, [.self]
-
- mov eax, [ebx+TPaintEvent.rect.right]
- mov ecx, [ebx+TPaintEvent.rect.bottom]
- sub eax, [ebx+TPaintEvent.rect.left]
- sub ecx, [ebx+TPaintEvent.rect.top]
-
- stdcall DrawFillRect, [ebx+TPaintEvent.context], [ebx+TPaintEvent.rect.left], [ebx+TPaintEvent.rect.top], eax, ecx, [clDialogBk]
-
- if defined options.DebugMode & options.DebugMode
- stdcall DrawLine, [ebx+TPaintEvent.context], 0, 0, [esi+TWindow._width], [esi+TWindow._height]
- stdcall DrawLine, [ebx+TPaintEvent.context], [esi+TWindow._width], 0, 0, [esi+TWindow._height]
- end if
-
- DebugMsg "Window OnPaing event."
-
- jmp .inherited
-
-.close_request:
-; DebugMsg "Close request"
-
- get eax, esi, TForm:OnClose
+ get edi, esi, TWindow:Canvas
+
+ stdcall DrawSolidRect, edi, 0, 0, [esi+TWindow._width], [esi+TWindow._height], [GUI.clDialogBk]
+
+ mov ebx, [esi+TForm._p_split_grid]
+ test ebx, ebx
+ jz .finish
+
+ lea ebx, [ebx+TArray.array]
+ stdcall DrawSplitters, edi, ebx
+
+.finish:
+ inherited
+ popad
+ return
+endp
+
+
+
+
+method TForm.EventResize ;, .newWidth, .newHeight
+begin
+ inherited [.newWidth], [.newHeight]
+ exec [.self], TForm:__RealignSplitGrid
+ return
+endp
+
+
+
+
+method TForm.SetWidth
+begin
+ inherited [.value]
+ exec [.self], TForm:__RealignSplitGrid
+ return
+endp
+
+
+
+method TForm.SetHeight
+begin
+ inherited [.value]
+ exec [.self], TForm:__RealignSplitGrid
+ return
+endp
+
+
+
+
+method TForm.CloseRequest ;, .reason
+begin
+ push eax
+
+ get eax, [.self], TForm:OnClose
+
test eax, eax
- jz @f
+ jz .destroy
- stdcall eax, esi, [ebx+TCloseEvent.reason] ; if OnClose return CF=0 the form is destroyed. Else, the form is not destroyed.
+ stdcall eax, [.self], [.reason]
jc .finish
-@@:
- set esi, TForm:Visible, FALSE
- destroy esi
+.destroy:
+ destroy [.self]
+
+.finish:
+ pop eax
+ return
+endp
+
+
+
+; sets the splitgrid from a template.
+
+method TForm.SetSplitGrid
+begin
+ pushad
+ mov esi, [.self]
+ mov edx, [.value]
+ cmp edx, [esi+TForm._p_split_template]
+ je .finish
+
+ mov [esi+TForm._p_split_template], edx
+
+ mov ecx, [esi+TForm._p_split_grid]
+ test ecx, ecx
+ jz .old_ok
+
+ stdcall FreeMem, ecx
+
+.old_ok:
+ test edx, edx
+ jz .finish
+
+ stdcall ReadSplitGridTemplate, edx
+ mov [esi+TForm._p_split_grid], eax
+
+ exec esi, TForm:__RealignSplitGrid
+
+.finish:
+ popad
+ return
+endp
+
+
+
+
+
+method TForm.AttachControlToCell;, .pWindow, .idCell
+begin
+ pushad
+ mov esi, [.self]
+ mov edi, [esi+TForm._p_split_grid]
+ test edi, edi
+ jz .finish
+
+ mov eax, [.idCell]
+ cmp eax, [edi+TArray.count]
+ jae .finish
+
+ imul eax, sizeof.TSplitRect
+ lea edi, [edi+TArray.array+eax]
+
+ push [.pWindow]
+ pop [edi+TSplitRect.pWindow]
+
+ exec [.self], TForm:__RealignSplitGrid
+
+.finish:
+ popad
+ return
+endp
+
+
+
+method TForm.__RealignSplitGrid
+.rect RECT
+begin
+ pushad
+
+ mov esi, [.self]
+ mov ebx, [esi+TForm._p_split_grid]
+ test ebx, ebx
+ jz .finish
+
+ lea ebx, [ebx+TArray.array]
+
+ xor eax, eax
+ get ecx, esi, TWindow:width
+ get edx, esi, TWindow:height
+
+ mov [.rect.left], eax
+ mov [.rect.top], eax
+ mov [.rect.right], ecx
+ mov [.rect.bottom], edx
+
+ lea eax, [.rect]
+ stdcall RealignGrid, ebx, eax
+
+ exec esi, TWindow:Refresh
+
+.finish:
+ popad
+ return
+endp
+
+
+
+
+
+
+method TForm.EventMouseMove ;, .x, .y, .kbdState
+begin
+ pushad
+
+ mov ebx, [.self]
+
+ mov esi, [ebx+TForm._drag_splitter]
+ test esi, esi
+ jz .find_splitter
+
+ mov ecx, [esi+TSplitRect.type]
+ and ecx, stVert
+ mov eax, [.x+ecx] ; the respective coordinate.
+
+ sub eax, [esi+TSplitRect.rect.left+ecx]
+
+ test [esi+TSplitRect.type], stOriginBR
+ jz .sizeok
+
+ mov edx, [esi+TSplitRect.rect.right+ecx]
+ sub edx, [esi+TSplitRect.rect.left+ecx]
+ sub eax, edx
+ neg eax
+
+ sub eax, [esi+TSplitRect.spWidth]
+
+.sizeok:
+ test [esi+TSplitRect.type], stRelative
+ jz .posok
+
+ cdq
+ mov ebx, $8000
+ imul ebx
+
+ mov ebx, [esi+ecx+TSplitRect.rect.right]
+ sub ebx, [esi+ecx+TSplitRect.rect.left] ; size of rect (x or y depending on type)
+
+ idiv ebx
+
+.posok:
+ mov [esi+TSplitRect.pos], eax
+ stdcall RealignGrid, esi, esi
+
+ exec [.self], TWindow:RectChanged, esi
+ exec [.self], TWindow:Refresh
+
+.finish:
+ popad
+ inherited [.x], [.y], [.kbdState]
+ return
+
+
+.find_splitter:
+ mov edi, [ebx+TForm._p_split_grid]
+ test edi, edi
+ jnz .found
+
+.set_default:
+ mov ecx, [ebx+TForm._cursor]
+ jmp .setit
+
+.found:
+ lea edi, [edi+TArray.array]
+
+ lea eax, [.x]
+ stdcall FindSplitter, edi, eax
+ jnc .set_default
+
+ test [eax+TSplitRect.type], stJustGap
+ jnz .finish
+
+ mov ecx, mcSizeH
+ test [eax+TSplitRect.type], stVert
+ jz .setit
+ mov ecx, mcSizeV
+
+.setit:
+ stdcall GetStockCursor, ecx
+
+ get edx, ebx, TWindow:OSWindow
+ stdcall SetMouseCursor, [edx+TWindow.handle], eax
+ jmp .finish
+
+endp
+
+
+
+method TForm.EventButtonPress ;, .button, .kbdState, .x, .y
+ .pnt POINT
+ .cliprect RECT
+begin
+ pushad
+
+ mov esi, [.self]
+ mov ebx, [esi+TForm._p_split_grid]
+ test ebx, ebx
+ jz .finish
+
+ lea ebx, [ebx+TArray.array]
+
+ mov eax, [.x]
+ mov ecx, [.y]
+ mov [.pnt.x], eax
+ mov [.pnt.y], ecx
+
+ lea eax, [.pnt]
+ stdcall FindSplitter, ebx, eax
+ jnc .finish
+
+ test [eax+TSplitRect.type], stJustGap
+ jnz .finish
+
+ mov [esi+TForm._drag_splitter], eax
+
+ stdcall SetMouseCapture, esi
+
+.finish:
+ popad
+ inherited [.button], [.kbdState], [.x], [.y]
+ return
+endp
+
+
+
+method TForm.EventButtonRelease ;, .button, .kbdState, .x, .y
+begin
+ push eax
+
+ mov eax, [.self]
+ mov [eax+TForm._drag_splitter], 0
+ stdcall SetMouseCapture, 0
- DebugMsg "Form destroyed"
- jmp .finish
+.finish:
+ pop eax
+ inherited [.button], [.kbdState], [.x], [.y]
+ return
endp
+
+
endmodule
+
Index: freshlib/gui/TImageLabel.asm
==================================================================
--- freshlib/gui/TImageLabel.asm
+++ freshlib/gui/TImageLabel.asm
@@ -21,27 +21,23 @@
iaTop = $0
iaBottom = $100
iaMiddle = $200
iaStrechV = $300
+
object TImageLabel, TWindow
._ImageAlign dd ?
._Image dd ?
- ._Mask dd ?
- ._Background dd ?
param .ImageAlign, ._ImageAlign, .SetImageAlign ; image align flags.
param .Image, ._Image, .SetImage ; TImage object
- param .Mask, ._Mask, .SetMask
- param .Background, ._Background, ._Background
method .SetImageAlign, .value
method .SetImage, .value
- method .SetMask, .value
- method .SysEventHandler, .pEvent
+ method .Paint
endobj
method TImageLabel.SetImageAlign
begin
@@ -54,10 +50,11 @@
exec eax, TWindow:Refresh
pop eax
return
endp
+
method TImageLabel.SetImage
begin
push eax
@@ -69,89 +66,73 @@
pop eax
return
endp
-method TImageLabel.SetMask
-begin
- push eax
-
- mov eax, [.self]
- push [.value]
- pop [eax+TImageLabel._Mask]
-
- exec eax, TWindow:Refresh
- pop eax
- return
-endp
-
-
-
-
-method TImageLabel.SysEventHandler
-begin
- push eax ebx ecx edx esi
+
+method TImageLabel.Paint
+begin
+ pushad
mov esi, [.self]
- mov ebx, [.pEvent]
- mov eax, [ebx+TSysEvent.event]
-
- cmp eax, sePaint
- je .onpaint
-
-.finish:
- stc
- pop esi edx ecx ebx eax
- return
-
-.onpaint:
- locals
- .bounds TBounds
- endl
+
+ exec esi, TWindow:__UpdateCanvas
+ mov edi, [esi+TWindow._canvas]
+
mov ecx, [esi+TImageLabel._width]
- mov eax, [esi+TImageLabel._height]
- mov [.bounds.x], 0
- mov [.bounds.y], 0
- mov [.bounds.width], ecx
- mov [.bounds.height], eax
-
- stdcall SetDrawMode, [ebx+TPaintEvent.context], cmCopy
- stdcall DrawFillRect, [ebx+TPaintEvent.context], [.bounds.x], [.bounds.y], [.bounds.width], [.bounds.height], [clDialogBk]
-
- mov eax, [esi+TImageLabel._Image]
- mov ecx, [.bounds.width]
- mov edx, [.bounds.height]
- sub ecx, [eax+TImage.width]
- sub edx, [eax+TImage.height]
+ mov edx, [esi+TImageLabel._height]
+ xor eax, eax
+
+ stdcall DrawSolidRect, edi, eax, eax, ecx, edx, eax ; clear with transparency.
mov eax, [esi+TImageLabel._ImageAlign]
+ mov esi, [esi+TImageLabel._Image]
+
+ test esi, esi
+ jz .finish
+
+ sub ecx, [esi+TImage.width]
+ sub edx, [esi+TImage.height]
cmp al, iaRight
je .x_ok
+
cmp al, iaCenter
je .x_center
+
xor ecx, ecx
jmp .x_ok
+
.x_center:
sar ecx, 1
+
.x_ok:
cmp ah, iaBottom /256
je .y_ok
+
cmp ah, iaMiddle / 256
je .y_center
+
xor edx, edx
jmp .y_ok
+
.y_center:
sar edx, 1
+
.y_ok:
- stdcall DrawMaskedImage, [ebx+TPaintEvent.context], [esi+TImageLabel._Mask], [esi+TImageLabel._Image], ecx, edx
- jmp .finish
-endp
+
+ xor eax, eax
+; stdcall BlendImage, edi, ecx, edx, esi, eax, eax, [esi+TImage.width], [esi+TImage.height]
+ stdcall CopyImageRect, edi, ecx, edx, esi, eax, eax, [esi+TImage.width], [esi+TImage.height]
+.finish:
+ popad
+ return
+endp
endmodule
Index: freshlib/gui/TLabel.asm
==================================================================
--- freshlib/gui/TLabel.asm
+++ freshlib/gui/TLabel.asm
@@ -11,22 +11,45 @@
;
; Notes: Not finished.
;_________________________________________________________________________________________
module "TLabel library"
+
object TLabel, TWindow
- ._textalign dd ?
+
+; private fields
+ ._textalign dd ?
+; parameters
param .TextAlign, ._textalign, .SetTextAlign ; text align flags.
-
+; parameter methods
method .SetTextAlign, .value
- method .SysEventHandler, .pEvent
+; other methods
+ method .Create, .parent
+
+ method .Paint
+
endobj
+
+
+method TLabel.Create
+begin
+ push eax ecx
+
+ inherited [.parent]
+
+ mov eax, [.self]
+ mov [eax+TLabel._textalign], dtfAlignLeft or dtfAlignMiddle or dtfCRLF or dtfWordWrap
+
+ pop ecx eax
+ return
+endp
+
method TLabel.SetTextAlign
begin
push eax
@@ -39,57 +62,58 @@
return
endp
-
-method TLabel.SysEventHandler
+method TLabel.Paint
+ .bounds TBounds
begin
pushad
mov esi, [.self]
- mov ebx, [.pEvent]
- mov eax, [ebx+TSysEvent.event]
-
- cmp eax, sePaint
- je .onpaint
-
-.finish:
- stc
- popad
- return
-
-.onpaint:
- locals
- .bounds TBounds
- endl
-
+ exec esi, TWindow:__UpdateCanvas
+
+ xor edx, edx
mov ecx, [esi+TLabel._width]
mov eax, [esi+TLabel._height]
- mov [.bounds.x], 0
- mov [.bounds.y], 0
+ mov [.bounds.x], edx
+ mov [.bounds.y], edx
mov [.bounds.width], ecx
mov [.bounds.height], eax
+
lea eax, [.bounds]
- stdcall [DrawBox], [ebx+TPaintEvent.context], eax, [clDialogBk], bxNone
+ stdcall [DrawBox], [esi+TWindow._canvas], eax, [GUI.clLabelBk], bxNone, [GUI.boxBorderWidth]
+
+ mov eax, [GUI.btnMarginX]
+ mov ecx, [GUI.btnMarginY]
+
+ add [.bounds.x], eax
+ add [.bounds.y], ecx
+
+ shl eax, 1
+ shl ecx, 1
+
+ sub [.bounds.width], eax
+ sub [.bounds.height], ecx
get eax, esi, TWindow:Caption
test eax, eax
jz .finish
- push eax eax
- stdcall StrLen, eax
- mov ecx, eax
- pop eax
- lea edx, [.bounds]
- stdcall DrawTextBox, [ebx+TPaintEvent.context], eax, edx, [esi+TLabel._textalign], 0, [clDialogTxt]
- stdcall StrDel ; from the stack
- jmp .finish
+ stdcall DrawTextBox, [esi+TWindow._canvas], eax, [.bounds.x], [.bounds.y], [.bounds.width], [.bounds.height], 2, [esi+TLabel._textalign], [GUI.DefaultFont], [GUI.clLabelTxt]
+ stdcall StrDel, eax
+
+
+.finish:
+ inherited
+
+ popad
+ return
endp
endmodule
Index: freshlib/gui/TMenu.asm
==================================================================
--- freshlib/gui/TMenu.asm
+++ freshlib/gui/TMenu.asm
@@ -11,89 +11,891 @@
;
; Notes: Represents main menu or popup menu objects.
;_________________________________________________________________________________________
module "TMenu library"
-;ObjectClass Menu, \
-; Window, \
-; TMenu.Create, \
-; TMenu.Destroy,\
-; TMenu.Get, \
-; TMenu.Set, \
-; TMenu.ExecCmd,\
-; TMenu.SysEventHandler
-
-; The inherited TWindow.caption serves as a menu item caption in the parent menu.
-; The children TMenu objects are reparent to the root, and their pointers are stored in the
-; list of TMenuItem elements.
+
+mitSeparator = 0
+mitAction = 1
+mitSubmenu = 2
+mitString = 3 ; contains simple text string can't have accelerator and icons.
+
+
+struct TMenuItem
+ .type dd ?
+ .item dd ? ; different for the different types of items: NULL, pointer to TAction, pointer to TMenu, handle of string.
+ends
+
+
+
object TMenu, TWindow
- .pForm dd ? ; pointer to TForm object. If NULL, the menu is popup menu.
- .pItems dd ? ;
+ ._p_items dd ?
+ ._selected dd ?
+ .__caller dd ?
- method .Show, .parent, .kind
+ .__icon_size dd ?
+
+ param .Selected, ._selected, .SetSelected
+ param .Items, ._p_items, .SetItems
+ param .LineHeight, .GetLineHeight, NONE
+
+ method .GetLineHeight
+
+ method .SetSelected, .value
+ method .SetItems, .menu_template
+ method .SetVisible, .value
+
+ method .AddItem, .Type, .Item
+
+ method .Paint
+
+ method .Create, .Parent
+ method .Destroy
+
+ method .Show, .parent, .x, .y
+
+ method .EventButtonPress, .button, .kbdState, .x, .y
+ method .EventMouseMove, .x, .y, .kbdState
+
endobj
-
-
-
-proc TMenu.Create, .obj
-begin
- return
-endp
-
-
-proc TMenu.Destroy, .obj
-begin
- return
-endp
-
-
-proc TMenu.Get, .obj, .param
-begin
- return
-endp
-
-
-proc TMenu.Set, .obj, .param
-begin
-
- return
-endp
-
-
-proc TMenu.ExecCmd, .obj, .method
-begin
- cmp [.method], TMenu.Show
- je .show
-
- stc
- return
-
-; Method show
-.show:
-virtual at esi
- .parent dd ?
- .kind dd ?
-end virtual
-
- mov ebx, [.obj]
-; First check item count and set proper size of the menu window.
-
-
-
-
- return
-endp
-
-
-proc TMenu.SysEventHandler, .obj, .event
-begin
-
- return
-endp
+method TMenu.Create
+begin
+ stdcall CreateArray, 8
+ push eax
+
+ mov eax, [.self]
+ pop [eax+TMenu._p_items]
+
+ mov [eax+TMenu.__want_focus], 0
+ mov [eax+TMenu._selected], -1
+
+ inherited 0
+
+ set [.self], TWindow:border, borderNone
+ return
+endp
+
+
+
+
+method TMenu.Destroy
+begin
+ mov eax, [.self]
+ stdcall FreeMem, [eax+TMenu._p_items]
+ return
+endp
+
+
+
+method TMenu.GetLineHeight
+begin
+ pushad
+ mov esi, [.self]
+
+ stdcall GetFontMetrics, [GUI.DefaultFont]
+
+ mov ecx, [esi+TMenu.__icon_size]
+ mov edx, [GUI.menuIconMargin]
+ add ecx, edx
+
+ cmp eax, ecx
+ cmovb eax, ecx
+
+ mov [esp+4*regEAX], eax
+ popad
+ return
+endp
+
+
+
+method TMenu.SetItems
+begin
+ pushad
+
+
+
+
+ popad
+ return
+endp
+
+
+method TMenu.AddItem
+begin
+ pushad
+
+ mov esi, [.self]
+ mov edx, [esi+TMenu._p_items]
+
+ stdcall AddArrayItems, edx, 1
+
+ pushd [.Type]
+ pushd [.Item]
+ popd [eax+TMenuItem.item]
+ popd [eax+TMenuItem.type]
+
+ mov [esi+TMenu._p_items], edx
+
+ popad
+ return
+endp
+
+
+
+
+method TMenu.SetVisible ;
+.max dd ?
+.str dd ?
+begin
+ pushad
+
+ mov esi, [.self]
+
+ cmp [.value], FALSE
+ je .switch_off
+
+ get edx, esi, TMenu:Items
+
+ mov ecx, [edx+TArray.count]
+ test ecx, ecx
+ jnz .compute_width
+
+ stdcall GetTextBounds, "Empty menu", 10, [GUI.DefaultFont]
+ add eax, 20
+ jmp .set_width
+
+
+.compute_width:
+
+ mov [.max], 0
+ mov [esi+TMenu.__icon_size], 0
+
+.loop:
+ dec ecx
+ js .end_width
+
+ lea ebx, [edx+TArray.array+8*ecx] ; pointer to TMenuItem
+
+ cmp [ebx+TMenuItem.type], mitSeparator
+ je .loop
+
+ cmp [ebx+TMenuItem.type], mitAction
+ je .action
+
+ cmp [ebx+TMenuItem.type], mitSubmenu
+ je .submenu
+
+; it is string.
+
+ stdcall StrDup, [ebx+TMenuItem.item]
+ push eax
+ jmp .str_width
+
+.submenu:
+ get eax, [ebx+TMenuItem.item], TMenu:Caption
+ push eax
+
+ stdcall StrCat, eax, txt " >"
+ jmp .str_width
+
+.action:
+ get eax, [ebx+TMenuItem.item], TAction:Icon
+ test eax, eax
+ jz .icon_ok
+
+ mov eax, [eax+TImage.height]
+
+ cmp eax, [esi+TMenu.__icon_size]
+ jbe .icon_ok
+ mov [esi+TMenu.__icon_size], eax
+
+.icon_ok:
+
+ get eax, [ebx+TMenuItem.item], TAction:AccelStr
+ push eax
+
+ get edi, [ebx+TMenuItem.item], TAction:Caption
+ stdcall StrCat, eax, edi
+
+
+.str_width:
+ stdcall StrPtr, eax
+ push edx
+ stdcall GetTextBounds, eax, [eax+string.len], [GUI.DefaultFont]
+ pop edx
+
+ stdcall StrDel ; from the stack
+
+ cmp eax, [.max]
+ jbe .loop
+
+ mov [.max], eax
+
+ jmp .loop
+
+.end_width:
+
+
+; here compute the size of the menu and set .width and .height fields.
+
+ mov edx, [GUI.iconMenuChecked]
+ mov eax, [edx+TImage.width]
+ add eax, [esi+TMenu.__icon_size]
+
+ add eax, [.max]
+ add eax, [GUI.menuMinTextDist]
+
+ mov edx, [GUI.menuIconMargin]
+ lea edx, [3*edx]
+ add eax, edx
+ mov edx, [GUI.boxBorderWidth]
+ lea eax, [eax+2*edx]
+
+
+.set_width:
+ set esi, TWindow:width, eax
+
+ get ecx, esi, TMenu:LineHeight
+ get edx, esi, TMenu:Items
+
+ mov eax, [edx+TArray.count]
+ imul eax, ecx
+
+ test eax, eax
+ jnz @f
+ add eax, ecx
+@@:
+
+ mov ecx, [GUI.boxBorderWidth]
+ lea eax, [eax+2*ecx]
+
+ mov ecx, [GUI.menuIconMargin]
+ lea eax, [eax+2*ecx]
+
+ set esi, TWindow:height, eax
+
+
+.finish:
+ popad
+
+ inherited [.value]
+ return
+
+
+.switch_off:
+ xor ecx, ecx
+
+ mov eax, [esi+TMenu.__caller]
+ test eax, eax
+ jz .set_active
+
+ istype eax, TMenu
+ cmove ecx, eax
+ je .set_active
+
+; remove capture.
+ stdcall SetMouseCapture, ecx ; ecx is 0 here!!!
+
+.set_active:
+ mov [__ActiveMenu], ecx
+ jmp .finish
+
+endp
+
+
+
+method TMenu.Paint
+
+.bounds TBounds
+
+.y dd ?
+.yTxt dd ?
+.xTxt dd ?
+.clTxt dd ?
+
+.line dd ?
+
+.canvas dd ?
+
+; item parameters, depend on the item type.
+
+.text dd ?
+.accel dd ?
+.icon dd ?
+.check dd ?
+.enabled dd ?
+.subicon dd ?
+
+begin
+ pushad
+ mov esi, [.self]
+
+ get ebx, esi, TWindow:Canvas
+ mov [.canvas], ebx
+
+ xor eax, eax
+ mov [.bounds.x], eax
+ mov [.bounds.y], eax
+
+ mov eax, [ebx+TImage.width]
+ mov ecx, [ebx+TImage.height]
+ mov [.bounds.width], eax
+ mov [.bounds.height], ecx
+
+ get eax, esi, TMenu:LineHeight
+ mov [.line], eax
+
+ lea eax, [.bounds]
+ stdcall [DrawBox], [.canvas], eax, [GUI.clMenuBack], [GUI.borderMenu], [GUI.boxBorderWidth]
+
+ get edi, esi, TMenu:Items
+ test edi, edi
+ jz .end_loop
+
+
+; compute the text base line.
+
+ stdcall GetFontMetrics, [GUI.DefaultFont]
+
+ mov ecx, [.line]
+ sub ecx, eax
+ lea ecx, [ecx+2*ebx]
+ sar ecx, 1
+ mov [.yTxt], ecx
+
+ mov ecx, [GUI.boxBorderWidth]
+ add ecx, [GUI.menuIconMargin]
+ mov [.y], ecx
+ add [.yTxt], ecx
+
+ mov ecx, [GUI.menuIconMargin]
+ lea ecx, [3*ecx]
+ mov eax, [esi+TMenu.__icon_size]
+
+ add ecx, eax
+ add ecx, [GUI.boxBorderWidth]
+
+ mov eax, [GUI.iconMenuChecked]
+ add ecx, [eax+TImage.width]
+
+ mov [.xTxt], ecx
+
+ xor ecx, ecx
+ cmp [edi+TArray.count], ecx
+ je .empty_menu
+
+.loop:
+ cmp ecx, [edi+TArray.count]
+ jae .end_loop
+
+ lea edx, [edi+TArray.array + 8*ecx] ; pointer to TMenuItem
+
+ mov eax, [edx+TMenuItem.type]
+
+ cmp eax, mitSeparator
+ je .draw_separator
+
+ cmp eax, mitAction
+ je .action
+
+ cmp eax, mitSubmenu
+ je .submenu
+
+ cmp eax, mitString
+ jne .next_item
+
+.string:
+ stdcall StrDup, [edx+TMenuItem.item]
+ mov [.text], eax
+
+ xor eax, eax
+ mov [.accel], eax
+ mov [.icon], eax
+ mov [.check], eax
+ mov [.subicon], eax
+ inc eax
+ mov [.enabled], eax
+ jmp .draw_background
+
+.submenu:
+ get eax, [edx+TMenuItem.item], TMenu:Caption
+ mov [.text], eax
+
+ get eax, [edx+TMenuItem.item], TMenu:Enabled
+ mov [.enabled], eax
+
+ mov ebx, [GUI.menuSubIconGray]
+ test eax, eax
+ jz @f
+
+ mov ebx, [GUI.menuSubIcon]
+
+ cmp ecx, [esi+TMenu._selected]
+ jne @f
+ mov ebx, [GUI.menuSubIconSel]
+
+@@:
+ mov [.subicon], ebx
+
+ xor eax, eax
+ mov [.icon], eax
+ mov [.check], eax
+ mov [.accel], eax
+ jmp .draw_background
+
+
+.action:
+ mov [.subicon], 0
+
+ get eax, [edx+TMenuItem.item], TAction:Caption
+ mov [.text], eax
+
+ get eax, [edx+TMenuItem.item], TAction:AccelStr
+ mov [.accel], eax
+
+ get eax, [edx+TMenuItem.item], TAction:Enabled
+ mov [.enabled], eax
+
+ get eax, [edx+TMenuItem.item], TAction:Icon
+ mov [.icon], eax
+
+ get eax, [edx+TMenuItem.item], TAction:Checked
+ mov [.check], eax
+ jmp .draw_background
+
+
+.draw_separator:
+ mov eax, [.bounds.x]
+ mov ebx, [.bounds.width]
+ mov edx, [GUI.menuIconMargin]
+ add eax, edx
+ sub ebx, edx
+ sub ebx, edx
+
+; stdcall DrawSolidRect, [.canvas], eax, [.y], ebx, 1, $ffff0000
+;
+; mov edx, [.line]
+; add edx, [.y]
+; dec edx
+;
+; stdcall DrawSolidRect, [.canvas], eax, edx, ebx, 1, $ffff0000
+
+ mov edx, [.line]
+ add edx, [.y]
+ add edx, [.y]
+ sar edx, 1
+
+ stdcall DrawSolidRect, [.canvas], eax, edx, ebx, 1, [GUI.clBorderDark]
+ inc edx
+ stdcall DrawSolidRect, [.canvas], eax, edx, ebx, 1, [GUI.clBorderLight]
+ jmp .next_item
+
+
+; draw the background
+.draw_background:
+ cmp ecx, [esi+TMenu._selected]
+ jne .selected_ok
+
+ cmp [.enabled], 0
+ je .selected_ok
+
+ stdcall DrawSolidRect, [.canvas], [.bounds.x], [.y], [.bounds.width], [.line], [GUI.clEditSel]
+
+.selected_ok:
+
+; draw the icon
+
+ cmp [.icon], 0
+ je .icon_ok
+
+ mov ebx, [GUI.iconMenuChecked]
+ mov eax, [ebx+TImage.width]
+
+ add eax, [GUI.menuIconMargin]
+ add eax, [GUI.menuIconMargin]
+ add eax, [GUI.boxBorderWidth] ; x-coordinate
+
+ mov ebx, [.icon]
+ test ebx, ebx
+ jz .icon_ok
+
+ mov edx, [.line]
+ sub edx, [ebx+TImage.height]
+ add edx, [.y]
+ add edx, [.y]
+ sar edx, 1
+
+ stdcall BlendImage, [.canvas], eax, edx, ebx, 0, 0, [ebx+TImage.width], [ebx+TImage.height]
+
+.icon_ok:
+
+; draw the checkbox
+
+ cmp [.check], 0
+ je .draw_text
+
+ mov eax, [GUI.menuIconMargin]
+ add eax, [GUI.boxBorderWidth]
+
+ mov ebx, [GUI.iconMenuChecked]
+
+ cmp [.enabled], 0
+ jne .check_ok
+
+ mov ebx, [GUI.iconMenuCheckedGray]
+
+.check_ok:
+ mov edx, [.line]
+ sub edx, [ebx+TImage.height]
+ add edx, [.y]
+ add edx, [.y]
+ sar edx, 1
+
+ stdcall BlendImage, [.canvas], eax, edx, ebx, 0, 0, [ebx+TImage.width], [ebx+TImage.height]
+
+
+.draw_text:
+
+ mov eax, [GUI.clMenuTextGray]
+
+ cmp [.enabled], 0
+ je .txt_color_ok
+
+ mov eax, [GUI.clMenuText]
+
+ cmp ecx, [esi+TMenu._selected]
+ jne .txt_color_ok
+
+ mov eax, [GUI.clEditSelTxt]
+
+.txt_color_ok:
+ mov [.clTxt], eax
+
+ push eax
+ push [GUI.DefaultFont]
+ push [.yTxt]
+ pushd [.xTxt]
+
+ stdcall StrLen, [.text]
+ push eax
+
+ stdcall StrPtr, [.text]
+
+ stdcall DrawString, [.canvas], eax ; remaining from the stack
+
+ stdcall StrDel, [.text]
+
+; draw the submenu arrow
+ mov ebx, [.subicon]
+ test ebx, ebx
+ jz .draw_accelerator
+
+ mov eax, [.bounds.width]
+ sub eax, [ebx+TImage.width]
+ sub eax, [GUI.menuIconMargin]
+
+ mov edx, [.line]
+ sub edx, [ebx+TImage.height]
+ add edx, [.y]
+ add edx, [.y]
+ sar edx, 1
+
+ stdcall BlendImage, [.canvas], eax, edx, ebx, 0, 0, [ebx+TImage.width], [ebx+TImage.height]
+ jmp .next_item
+
+; draw the accelerator
+.draw_accelerator:
+ cmp [.accel], 0
+ je .next_item
+
+ stdcall StrPtr, [.accel]
+ push eax
+
+ stdcall GetTextBounds, eax, [eax+string.len], [GUI.DefaultFont]
+
+ mov edx, [.bounds.width]
+ sub edx, [GUI.boxBorderWidth]
+ sub edx, [GUI.menuIconMargin]
+ sub edx, eax
+
+ pop eax
+ stdcall DrawString, [.canvas], eax, [eax+string.len], edx, [.yTxt], [GUI.DefaultFont], [.clTxt]
+
+ stdcall StrDel, [.accel]
+
+
+.next_item:
+ mov eax, [.line]
+ add [.y], eax
+ add [.yTxt], eax
+
+ inc ecx
+ jmp .loop
+
+
+.end_loop:
+
+ popad
+ return
+
+.empty_menu:
+ stdcall DrawString, [.canvas], "Empty menu", 10, 10, 14, [GUI.DefaultFont], [GUI.clMenuText]
+ stdcall FilterDisabled, [.canvas], FALSE
+ jmp .end_loop
+
+endp
+
+
+
+
+method TMenu.Show
+begin
+ pushad
+
+ mov esi, [.self]
+ mov edi, [.parent]
+
+ istype edi, TMenu
+ je .capture_ok
+
+ stdcall SetMouseCapture, edi
+
+.capture_ok:
+ exec edi, TWindow:ClientToScreenXY, [.x], [.y]
+
+ mov [esi+TWindow._x], ecx
+ mov [esi+TWindow._y], edx
+ mov [esi+TMenu._selected], 0
+
+ mov [esi+TMenu.__caller], edi
+ mov [__ActiveMenu], esi
+ set esi, TMenu:Visible, TRUE
+
+ popad
+ return
+endp
+
+
+
+
+proc AcceleratorToStr, .pFastKey
+begin
+ push ecx edx
+
+ mov edx, [.pFastKey]
+ test edx, edx
+ jz .empty
+
+ mov eax, [edx+TFastKey.key] ; scan code
+ xor ecx, ecx ; utf8
+
+ test eax, eax
+ js @f
+ xchg ecx, eax
+@@:
+ and eax, $7fffffff
+ stdcall CreateKeyName, ecx, eax, [edx+TFastKey.flags]
+ jnc .finish
+
+.empty:
+ stdcall StrNew
+ stc
+
+.finish:
+ pop edx ecx
+ return
+endp
+
+
+
+method TMenu.SetSelected
+begin
+ pushad
+
+ mov esi, [.self]
+ mov ecx, [.value]
+ cmp ecx, [esi+TMenu._selected]
+ je .finish
+
+ get edi, esi, TMenu:Items
+ test edi, edi
+ jz .finish
+
+ cmp ecx, [edi+TArray.count]
+ jae .finish
+
+ mov [esi+TMenu._selected], ecx
+ exec esi, TWindow:Refresh
+
+ lea edx, [edi+TArray.array+8*ecx]
+ cmp [edx+TMenuItem.type], mitSubmenu
+ jne .hide_old
+
+ get eax, [edx+TMenuItem.item], TMenu:Enabled
+ test eax, eax
+ jz .finish
+
+ get ebx, esi, TMenu:LineHeight
+ imul ebx, ecx
+
+ mov eax, [esi+TMenu._width]
+ sub eax, [GUI.menuIconMargin]
+
+ exec [edx+TMenuItem.item], TMenu:Show, esi, eax, ebx
+
+ jmp .finish
+
+.hide_old:
+ cmp [__ActiveMenu], esi
+ je .finish
+
+ set [__ActiveMenu], TWindow:Visible, FALSE
+ mov [__ActiveMenu], esi
+
+.finish:
+ popad
+ return
+endp
+
+
+
+method TMenu.EventMouseMove
+begin
+ pushad
+
+ mov esi, [.self]
+
+ mov ecx, [.x]
+ mov edx, [.y]
+ sub ecx, [esi+TMenu._x]
+ js .check_caller
+ sub edx, [esi+TMenu._y]
+ js .check_caller
+
+ cmp ecx, [esi+TMenu._width]
+ jge .check_caller
+
+ cmp edx, [esi+TMenu._height]
+ jge .check_caller
+
+ sub edx, [GUI.boxBorderWidth]
+ js .exit
+
+ sub edx, [GUI.menuIconMargin]
+ js .exit
+
+ get ecx, esi, TMenu:LineHeight
+
+ mov eax, edx
+ cdq
+ idiv ecx
+
+ set esi, TMenu:Selected, eax
+
+.exit:
+ popad
+ return
+
+.check_caller:
+ mov esi, [esi+TMenu.__caller]
+ test esi, esi
+ jz .exit
+
+ istype esi, TMenu
+ jne .exit
+
+ exec esi, TMenu:EventMouseMove, [.x], [.y], [.kbdState]
+ jmp .exit
+endp
+
+
+
+
+
+method TMenu.EventButtonPress
+begin
+ pushad
+ mov esi, [.self]
+
+ mov ecx, [.x]
+ mov edx, [.y]
+
+ sub ecx, [esi+TMenu._x]
+ js .check_caller
+ sub edx, [esi+TMenu._y]
+ js .check_caller
+ cmp ecx, [esi+TMenu._width]
+ jge .check_caller
+ cmp edx, [esi+TMenu._height]
+ jge .check_caller
+
+ mov ecx, [esi+TMenu._selected]
+ mov edx, [esi+TMenu._p_items]
+
+ cmp ecx, [edx+TArray.count]
+ jae .finish
+
+ lea edi, [edx+TArray.array+8*ecx]
+
+ cmp [edi+TMenuItem.type], mitSeparator
+ je .finish
+
+ cmp [edi+TMenuItem.type], mitString
+ je .finish ; temporary, until I decide what to do with the string items.
+
+ cmp [edi+TMenuItem.type], mitSubmenu
+ je .finish
+
+ cmp [edi+TMenuItem.type], mitAction
+ jne .finish
+
+ get eax, [edi+TMenuItem.item], TAction:Enabled
+ test eax, eax
+ jz .finish
+
+ call .hideall
+ exec [edi+TMenuItem.item], TAction:Execute, [.self] ; execute the action.
+
+.finish:
+ popad
+ return
+
+
+.check_caller:
+ set esi, TMenu:Visible, FALSE ; hide the menu
+
+ mov esi, [esi+TMenu.__caller]
+ test esi, esi
+ jz .finish
+
+ istype esi, TMenu
+ jne .finish
+
+ mov [esi+TMenu._selected], -1
+ exec esi, TMenu:EventMouseMove, [.x], [.y], [.kbdState]
+ exec esi, TMenu:EventButtonPress, [.button], [.kbdState], [.x], [.y]
+ jmp .finish
+
+
+.hideall:
+ cmp [__ActiveMenu], 0
+ jne @f
+
+ retn
+
+@@:
+ set [__ActiveMenu], TMenu:Visible, FALSE ; hide the menu
+ jmp .hideall
+
+
+
+
+endp
+
endmodule
DELETED freshlib/gui/TMenuItem.asm
Index: freshlib/gui/TMenuItem.asm
==================================================================
--- freshlib/gui/TMenuItem.asm
+++ /dev/null
@@ -1,40 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "BSD 2-clause" license." |
-;|_______________________________________________________________________________________|
-;
-; Description: TMenuItem object class
-;
-; Target OS: Any
-;
-; Dependencies:
-;
-; Notes: TMenuItems are the items of the GUI menu objects.
-;_________________________________________________________________________________________
-module "TMenuItem library"
-
-;ObjectClass MenuItem, \
-; Object, \
-; TMenuItem.Create, \
-; TMenuItem.Destroy,\
-; TMenuItem.Get, \
-; TMenuItem.Set, \
-; TMenuItem.ExecCmd,\
-; 0
-
-mikCommand = 0
-mikSubmenu = 1
-mikSeparator = 2
-
-
-object TMenuItem, TObject
- .parent dd ? ; pointer to TMenu object.
- .kind dd ? ; mikCommand, mikSubmenu or mikSeparator
- .pAction dd ? ; depending on the kind. Pointer to TAction or handle of string with the text.
- .child dd ? ; pointer to the child TMenu object
-
- method Paint, .context, .x, .y, .width, .height
-endobj
-
-
-endmodule
Index: freshlib/gui/TObject.asm
==================================================================
--- freshlib/gui/TObject.asm
+++ freshlib/gui/TObject.asm
@@ -24,50 +24,41 @@
._OnCreate dd ?
._OnDestroy dd ?
._ptrVar dd ?
+ .__Parent dd ?
+ .__pChildren dd ? ; pointer to TArray of pointers to children windows.
+
; parameters
+
+ param .Parent, .__Parent, .SetParent
+ param .Children, .__pChildren, NONE
param .OnCreate, ._OnCreate, ._OnCreate
param .OnDestroy, ._OnDestroy, ._OnDestroy
param .ptrVar, ._ptrVar, ._ptrVar
; methods
- method .Create
+ method .Create, .parent
method .Destroy
- abstract .AddChild, .objchild ; this method is not implemented in TObject, but every descendent can implement it's own parent/child system.
+ method .SetParent, .value
+
+ method .AddChild, .objchild
+ method .RemoveChild, .objchild
endobj
-method TObject.Destroy
-begin
- push ecx
-
- get ecx, [.self], TObject:OnDestroy
- jecxz .event_ok
-
- stdcall dword ecx, [.self]
-
-.event_ok:
- get ecx, [.self], TObject:ptrVar
- jecxz .varok
-
- mov dword [ecx], 0
-
-.varok:
-if defined options.Threads & options.Threads
- mov ecx, [.self]
- lea ecx, [eax+TObject._mxAccess]
- stdcall MutexDestroy, eax
-end if
- pop ecx
- return
-endp
+
+interface TObject.OnCreate, .self
+interface TObject.OnDestroy, .self
+
+
+
method TObject.Create
begin
if defined options.Threads & options.Threads
@@ -76,12 +67,170 @@
lea eax, [eax+TObject._mxAccess]
stdcall MutexCreate, 0, eax
stdcall MutexRelease, eax
pop eax
end if
+ set [.self], TWindow:Parent, [.parent]
+ return
+endp
+
+
+
+
+method TObject.Destroy
+begin
+ pushad
+
+ mov esi, [.self]
+
+ get ecx, esi, TObject:OnDestroy
+ jecxz .event_ok
+
+ push esi
+ stdcall dword ecx, [.self]
+ pop esi
+
+.event_ok:
+ get ecx, esi, TObject:ptrVar
+ jecxz .varok
+ mov dword [ecx], 0
+.varok:
+
+; destroy all children
+ get ebx, esi, TWindow:Children
+ test ebx, ebx
+ jz .end_children
+
+ mov ecx, [ebx+TArray.count]
+
+.loop:
+ dec ecx
+ js .end_children
+
+ destroy [ebx+TArray.array+4*ecx]
+ jmp .loop
+
+.end_children:
+
+if defined options.Threads & options.Threads
+ lea ecx, [esi+TObject._mxAccess]
+ stdcall MutexDestroy, ecx
+end if
+ popad
+ return
+endp
+
+
+
+
+
+;_________________________________________________________________________________________
+
+
+
+method TObject.AddChild
+begin
+ pushad
+
+ mov esi, [.self]
+ mov ebx, [.objchild]
+
+ istype ebx, TObject
+ jne .not_window
+
+ mov edx, [esi+TObject.__pChildren]
+ test edx, edx
+ jnz .array_ok
+
+ stdcall CreateArray, 4
+ mov edx, eax
+
+.array_ok:
+
+ stdcall AddArrayItems, edx, 1
+ mov [eax], ebx
+ mov [esi+TObject.__pChildren], edx
+
+ clc
+ popad
+ return
+
+
+.not_window:
+ stc
+ popad
+ return
+endp
+
+
+;_________________________________________________________________________________________
+
+
+;----------------------------------------------------------------------
+; Returns:
+; CF = 1 - if the object specified was not found as a window child.
+; CF = 0 - the child was removed from the list of childrens.
+;----------------------------------------------------------------------
+
+method TObject.RemoveChild
+begin
+ push edx esi
+
+ mov esi, [.self]
+ mov edx, [esi+TObject.__pChildren]
+
+ stdcall ListIndexOf, edx, [.objchild]
+ jc .finish
+
+ stdcall DeleteArrayItems, edx, eax, 1
+
+ cmp [edx+TArray.count], 0
+ jne .store
+
+ stdcall FreeMem, edx
+ xor edx, edx
+
+.store:
+ mov [esi+TObject.__pChildren], edx
+ clc
+
+.finish:
+ pop esi edx
return
endp
+
+;_________________________________________________________________________________________
+
+
+
+method TObject.SetParent
+begin
+ pushad
+
+ mov esi, [.self]
+ mov edi, [.value]
+ cmp edi, [esi+TObject.__Parent] ; if the parent is already set to the same value, ignore.
+ je .finish
+
+ cmp [esi+TWindow.__Parent], 0
+ je .parent_ok
+
+ exec [esi+TObject.__Parent], TObject:RemoveChild, esi ; remove the window from the old parent.
+ mov [esi+TObject.__Parent], edi ; store the new parent.
+
+.parent_ok:
+ test edi, edi
+ jz .finish
+
+ exec edi, TObject:AddChild, esi
+
+.finish:
+ mov [esi+TObject.__Parent], edi
+ popad
+ return
+endp
+
endmodule
Index: freshlib/gui/TProgressbar.asm
==================================================================
--- freshlib/gui/TProgressbar.asm
+++ freshlib/gui/TProgressbar.asm
@@ -19,20 +19,31 @@
._Max dd ?
._Color dd ?
param .Pos, ._Pos, .SetPos
param .Max, ._Max, .SetMax
- param .Color, ._Color, .SetColor
method .Step
method .SetPos, .value
method .SetMax, .value
- method .SetColor, .value
+
+ method .Create, .pParent
- method .SysEventHandler, .pEvent
+ method .Paint
endobj
+
+
+method TProgress.Create
+begin
+ mov eax, [.self]
+ mov [eax+TProgress.__want_focus], FALSE
+
+ inherited [.pParent]
+ return
+endp
+
method TProgress.Step
begin
push eax ecx
@@ -85,64 +96,30 @@
pop ecx eax
return
endp
-method TProgress.SetColor
-begin
- push eax ecx
- mov ecx, [.self]
- mov eax, [.value]
-
- xchg eax, [ecx+TProgress._Color]
- cmp eax, [ecx+TProgress._Color]
- je .finish
-
- exec ecx, TWindow:Refresh
-
-.finish:
- pop ecx eax
- return
-endp
-
-
-
-method TProgress.SysEventHandler
-begin
- push eax ebx ecx esi
+
+
+method TProgress.Paint
+ .bounds TBounds
+begin
+ pushad
mov esi, [.self]
- mov ebx, [.pEvent]
- cmp [ebx+TSysEvent.event], sePaint
- je .paint
-
-.finish:
- stc
- pop esi ecx ebx eax
- return
-
-.paint:
-locals
- .bounds TBounds
- .style TLineStyle
-endl
+
+ exec esi, TWindow:__UpdateCanvas
+
mov [.bounds.x], 0
mov [.bounds.y], 0
mov eax, [esi+TProgress._width]
mov ecx, [esi+TProgress._height]
mov [.bounds.width], eax
mov [.bounds.height], ecx
lea eax, [.bounds]
- stdcall [DrawBox], [ebx+TPaintEvent.context], eax, 0, bxSunken or bxNoFill
-
- stdcall DrawRectangle, [ebx+TPaintEvent.context], eax, [clDialogBk]
-
- inc [.bounds.x]
- inc [.bounds.y]
- sub [.bounds.width], 2
- sub [.bounds.height], 2
+ stdcall [DrawBox], [esi+TProgress._canvas], eax, [GUI.clProgressBk], [GUI.progressBorder], [GUI.boxBorderWidth]
mov eax, [esi+TProgress._Pos]
mov ecx, [esi+TProgress._Max]
test ecx, ecx
jnz @f
@@ -154,17 +131,15 @@
@@:
imul eax, [.bounds.width]
cdq
idiv ecx
- stdcall DrawFillRect, [ebx+TPaintEvent.context], [.bounds.x], [.bounds.y], eax, [.bounds.height], [esi+TProgress._Color]
- sub [.bounds.width], eax
- inc eax
- inc [.bounds.width]
- stdcall DrawFillRect, [ebx+TPaintEvent.context], eax, [.bounds.y], [.bounds.width], [.bounds.height], [clDialogBk]
+ stdcall DrawSolidRect, [esi+TProgress._canvas], [.bounds.x], [.bounds.y], eax, [.bounds.height], [GUI.clProgressBar]
- jmp .finish
+ inherited
+ popad
+ return
endp
endmodule
Index: freshlib/gui/TScrollWindow.asm
==================================================================
--- freshlib/gui/TScrollWindow.asm
+++ freshlib/gui/TScrollWindow.asm
@@ -22,64 +22,210 @@
._Drag dd ?
ends
-object TScrollWindow, TBackWindow
+object TScrollbar, TWindow
._HScroller TScrollbar
._VScroller TScrollbar
- method .HScrollSet, .Pos, .Max, .Page ; only params >=0 are set. If<0 ignored.
- method .VScrollSet, .Pos, .Max, .Page
+ param .HMax, ._HScroller.Max, ._HScroller.Max
+ param .HPos, ._HScroller.Pos, ._HScroller.Pos
+ param .HPage, ._HScroller.Page, ._HScroller.Page
- method ._RedrawShadow
- method .GetFreeArea
+ param .VMax, ._VScroller.Max, ._VScroller.Max
+ param .VPos, ._VScroller.Pos, ._VScroller.Pos
+ param .VPage, ._VScroller.Page, ._VScroller.Page
- method .SysEventHandler, .pEvent
+ method .Paint
+
+ method .EventMouseMove, .x, .y, .kbdState
+
+ method .EventButtonPress, .button, .kbdState, .x, .y
+ method .EventButtonRelease, .button, .kbdState, .x, .y
endobj
-ScrollBarWidth = 12
-MinScrollBarWidth = 12
;_________________________________________________________________________________________
-method TScrollWindow.SysEventHandler
- .event TScrollEvent
+
+method TScrollWindow.Paint
+.canvas dd ?
+.recth TBounds
+.rectv TBounds
+.rectx TBounds
+begin
+ pushad
+ mov esi, [.self]
+
+ exec esi, TWindow:__UpdateCanvas
+
+ mov eax, [esi+TWindow._canvas]
+ mov [.canvas], eax
+
+ xor eax, eax
+ mov [.recth.x], eax
+ mov [.rectv.y], eax
+
+ mov eax, [esi+TWindow._width]
+ mov edx, [esi+TWindow._height]
+ sub eax, [scrollWidth]
+ sub edx, [scrollWidth]
+ mov [.rectv.x], eax
+ mov [.recth.y], edx
+
+ inc edx
+ inc eax
+ mov [.rectx.y], edx
+ mov [.rectx.x], eax
+
+ mov eax, [scrollWidth]
+ mov [.recth.height], eax
+ mov [.rectv.width], eax
+ dec eax
+ mov [.rectx.width], eax
+ mov [.rectx.height], eax
+
+ mov eax, [esi+TWindow._width]
+ mov edx, [esi+TWindow._height]
+ sub eax, [scrollWidth]
+ sub edx, [scrollWidth]
+ mov [.recth.width], eax
+ mov [.rectv.height], edx
+
+ lea eax, [.rectx]
+ stdcall DrawBoxDefault, [.canvas], eax, [clDialogBk], bxNone, 0
+
+ lea eax, [.recth]
+ stdcall DrawBoxDefault, [.canvas], eax, [clScrollBk], bxSunken or bxNoFill, 0
+
+ lea eax, [.rectv]
+ stdcall DrawBoxDefault, [.canvas], eax, [clScrollBk], bxSunken or bxNoFill, 0
+
+ lea eax, [esi+TScrollWindow._HScroller]
+ stdcall _SliderPixels, eax, [.recth.width]
+
+ push esi
+ stdcall DrawSolidRect, [.canvas], [.recth.x], [.recth.y], eax, [.recth.height], [clScrollBk]
+ mov esi, [.recth.width]
+ sub esi, eax
+ sub esi, edx
+
+ add eax, [.recth.x]
+ lea edi, [eax+edx]
+ stdcall DrawSolidRect, [.canvas], edi, [.recth.y], esi, [.recth.height], [clScrollBk]
+ pop esi
+
+ mov [.rectx.x], eax
+
+ mov [.rectx.width], edx
+ push [.recth.y] [.recth.height]
+ pop [.rectx.height] [.rectx.y]
+
+ lea eax, [.rectx]
+ stdcall [DrawSlider], [.canvas], eax, [clScrollSlider], sliderHorizontal
+
+ lea eax, [esi+TScrollWindow._VScroller]
+ stdcall _SliderPixels, eax, [.rectv.height]
+
+ push esi
+ stdcall DrawSolidRect, [.canvas], [.rectv.x], [.rectv.y], [.rectv.width], eax, [clScrollBk]
+ mov esi, [.rectv.height]
+ sub esi, eax
+ sub esi, edx
+
+ add eax, [.rectv.y]
+ lea edi, [eax+edx]
+ stdcall DrawSolidRect, [.canvas], [.rectv.x], edi, [.rectv.width], esi, [clScrollBk]
+ pop esi
+
+ mov [.rectx.y], eax
+
+ mov [.rectx.height], edx
+ push [.rectv.x] [.rectv.width]
+ pop [.rectx.width] [.rectx.x]
+
+ lea eax, [.rectx]
+ stdcall [DrawSlider], [.canvas], eax, [clScrollSlider], sliderVertical
+
+ inherited
+
+ popad
+ return
+
+endp
+
+
+
+
+
+
+method TScrollWindow.EventMouseMove
begin
- push eax ebx edx esi edi
+ pushad
+
mov esi, [.self]
- mov ecx, [.pEvent]
-
- cmp [ecx+TSysEvent.event], seMouseBtnPress
- je .btnpress
-
- cmp [ecx+TSysEvent.event], seMouseBtnRelease
- je .btnrelease
-
- cmp [ecx+TSysEvent.event], seMouseMove
- je .mousemove
+
+ stdcall __ScrollSetCursor, esi, [.x], [.y]
+
+ lea edi, [esi+TScrollWindow._HScroller]
+
+ mov eax, [.x]
+ mov ecx, [esi+TScrollWindow._width]
+ mov edx, scrollX
+
+ cmp [edi+TScrollbar._Drag], 0
+ jne .found
+
+
+ lea edi, [esi+TScrollWindow._VScroller]
+
+ mov eax, [.y]
+ mov ecx, [esi+TScrollWindow._height]
+ mov edx, scrollY
+
+ cmp [edi+TScrollbar._Drag], 0
+
+ je .continue
+
+.found:
+ sub ecx, [scrollWidth]
+ sub eax, 2
+ sub eax, [edi+TScrollbar._Drag]
+
+ stdcall _SetSliderPos, edi, eax, ecx
+ jc .finish
+
+ exec [.self], TWindow:EventScroll, edx, scTrack, [edi+TScrollbar.Pos] ;method .EventScroll, .direction, .command, .value
+
+ exec [.self], TWindow:Refresh
.continue:
- inherited [.pEvent]
.finish:
- pop edi esi edx ebx eax
+ inherited [.x], [.y], [.kbdState]
+
+ popad
return
+endp
-;.........................................................................................
-
-.btnpress:
- stdcall __ScrollSetCursor, esi, [ecx+TMouseButtonEvent.x], [ecx+TMouseButtonEvent.y]
-
- cmp [ecx+TMouseButtonEvent.Button], mbLeft
- jne .continue
-
- stdcall _WhatScrollbar, esi, [ecx+TMouseButtonEvent.x], [ecx+TMouseButtonEvent.y]
- jc .continue ; not found
+method TScrollWindow.EventButtonPress
+begin
+ pushad
+
+ mov esi, [.self]
+
+ stdcall __ScrollSetCursor, esi, [.x], [.y]
+
+ cmp [.button], mbLeft
+ jne .finish
+
+ stdcall _WhatScrollbar, esi, [.x], [.y]
+ jc .finish ; not found
; here ecx=height of the scrollbar
; edi= ptr to TScrollbar structure
; ebx= coordinate of the mouse in the scrollbar
@@ -89,209 +235,134 @@
cmp ebx, edx
jg .after
; inside the slider - capture the mouse.
mov [edi+TScrollbar._Drag], ebx
- stdcall MouseCapture, [esi+TWindow.handle]
- jmp .continue
+
+ stdcall SetMouseCapture, esi
+
+.finish:
+
+ inherited [.button], [.kbdState], [.x], [.y]
+
+ popad
+ return
.before:
.after:
- jmp .continue
+ popad
+ return
+endp
+
+
+
+method TScrollWindow.EventButtonRelease
+begin
+ pushad
-;.........................................................................................
+ mov esi, [.self]
-.btnrelease:
- stdcall __ScrollSetCursor, esi, [ecx+TMouseButtonEvent.x], [ecx+TMouseButtonEvent.y]
+ stdcall __ScrollSetCursor, esi, [.x], [.y]
xor eax, eax
mov [esi+TScrollWindow._HScroller._Drag], eax
mov [esi+TScrollWindow._VScroller._Drag], eax
- stdcall MouseCapture, eax
- jmp .continue
-
-;.........................................................................................
-
-.mousemove:
- mov ecx, [.pEvent]
- stdcall __ScrollSetCursor, esi, [ecx+TMouseMoveEvent.x], [ecx+TMouseMoveEvent.y]
-
- mov ecx, [.pEvent]
- lea edi, [esi+TScrollWindow._HScroller]
- mov eax, [ecx+TMouseMoveEvent.x]
- mov ecx, [esi+TScrollWindow._width]
- mov [.event.ScrollBar], scrollX
- cmp [edi+TScrollbar._Drag], 0
- jne .found
-
- mov ecx, [.pEvent]
- lea edi, [esi+TScrollWindow._VScroller]
- mov eax, [ecx+TMouseMoveEvent.y]
- mov ecx, [esi+TScrollWindow._height]
- mov [.event.ScrollBar], scrollY
- cmp [edi+TScrollbar._Drag], 0
-
- je .continue
-
-
-.found:
- mov [.event.event], seScroll
- mov [.event.ScrollCmd], scTrack
-
- sub ecx, ScrollBarWidth
- sub eax, 2
- sub eax, [edi+TScrollbar._Drag]
- stdcall _SetSliderPos, edi, eax, ecx
- jc .endmove
-
- mov eax, [edi+TScrollbar.Pos]
- mov [.event.Value], eax
-
- lea eax, [.event]
-
- exec esi, TWindow:SysEventHandler, eax
- jnc .finish
-
-; ?????? Do we need this?
-; execute esi, TScrollWindow.Refresh
-
-.endmove:
- clc
- jmp .finish
-
+ stdcall SetMouseCapture, eax
+
+ popad
+ return
+endp
+
+
+
+
+
+
+
+
+
+
+; returns:
+; eax - position in pixels
+; edx - size in pixels
+
+
+proc _SliderPixels, .pScrollbar, .length
+begin
+ push ecx esi
+
+ mov ecx, [.pScrollbar]
+
+; page size in pixels.
+ mov esi, [ecx+TScrollbar.Max]
+ mov eax, [.length]
+ add esi, [ecx+TScrollbar.Page]
+ test esi, esi
+ jz .lengthok
+
+ imul [ecx+TScrollbar.Page]
+ idiv esi
+
+.lengthok:
+ cmp eax, [minSliderHeight]
+ jge @f
+ mov eax, [minSliderHeight]
+@@:
+ cmp eax, [.length]
+ jle @f
+ mov eax, [.length]
+@@:
+ push eax
+
+; position in pixels
+
+ sub eax, [.length]
+ mov esi, [ecx+TScrollbar.Max]
+ test esi, esi
+ jnz @f
+ inc esi
+@@:
+ neg eax
+ mul [ecx+TScrollbar.Pos]
+ div esi
+
+ pop edx ; width
+
+ pop esi ecx
+ return
endp
-;_________________________________________________________________________________________
-method TScrollWindow._RedrawShadow
- .recth TBounds
- .rectv TBounds
- .rectx TBounds
-
- .context dd ?
+proc __ScrollSetCursor, .window, .x, .y
begin
pushad
- mov esi, [.self]
-
- get ebx, esi, TScrollWindow:FreeArea
-
- mov eax, [esi+TScrollWindow._pShadow]
- stdcall AllocateContext, [eax+TBackBuffer.raster]
- mov [.context], eax
-
- mov eax, [ebx+TBounds.x]
- mov edx, [ebx+TBounds.y]
- mov [.recth.x], eax
- mov [.rectv.y], edx
-
- add eax, [ebx+TBounds.width]
- add edx, [ebx+TBounds.height]
- mov [.rectv.x], eax
- mov [.recth.y], edx
-
- inc edx
- inc eax
- mov [.rectx.y], edx
- mov [.rectx.x], eax
-
- mov [.recth.height], ScrollBarWidth
- mov [.rectv.width], ScrollBarWidth
- mov [.rectx.width], ScrollBarWidth-1
- mov [.rectx.height], ScrollBarWidth-1
-
- mov eax, [ebx+TBounds.width]
- mov edx, [ebx+TBounds.height]
- inc eax
- inc edx
- mov [.recth.width], eax
- mov [.rectv.height], edx
-
- lea eax, [.rectx]
- stdcall [DrawBox], [.context], eax, [clDialogBk], bxNone
-
- lea eax, [.recth]
- stdcall [DrawBox], [.context], eax, [clScrollBk], bxSunken or bxNoFill
-
- lea eax, [.rectv]
- stdcall [DrawBox], [.context], eax, [clScrollBk], bxSunken or bxNoFill
-
- lea eax, [esi+TScrollWindow._HScroller]
- stdcall _SliderPixels, eax, [.recth.width]
-
- push esi
- stdcall DrawFillRect, [.context], [.recth.x], [.recth.y], eax, [.recth.height], [clScrollBk]
- mov esi, [.recth.width]
- sub esi, eax
- sub esi, edx
-
- add eax, [.recth.x]
- lea edi, [eax+edx]
- stdcall DrawFillRect, [.context], edi, [.recth.y], esi, [.recth.height], [clScrollBk]
- pop esi
-
- mov [.rectx.x], eax
-
- mov [.rectx.width], edx
- push [.recth.y] [.recth.height]
- pop [.rectx.height] [.rectx.y]
-
- lea eax, [.rectx]
- stdcall [DrawSlider], [.context], eax, [clScrollSlider], sliderHorizontal
-
- lea eax, [esi+TScrollWindow._VScroller]
- stdcall _SliderPixels, eax, [.rectv.height]
-
- push esi
- stdcall DrawFillRect, [.context], [.rectv.x], [.rectv.y], [.rectv.width], eax, [clScrollBk]
- mov esi, [.rectv.height]
- sub esi, eax
- sub esi, edx
-
- add eax, [.rectv.y]
- lea edi, [eax+edx]
- stdcall DrawFillRect, [.context], [.rectv.x], edi, [.rectv.width], esi, [clScrollBk]
- pop esi
-
- mov [.rectx.y], eax
-
- mov [.rectx.height], edx
- push [.rectv.x] [.rectv.width]
- pop [.rectx.width] [.rectx.x]
-
- lea eax, [.rectx]
- stdcall [DrawSlider], [.context], eax, [clScrollSlider], sliderVertical
-
- stdcall ReleaseContext, [.context]
- stc
+
+ mov esi, [.window]
+ mov eax, [esi+TWindow._cursor]
+
+ stdcall _WhatScrollbar, esi, [.x], [.y]
+ jc @f
+
+ mov eax, mcArrow
+@@:
+ mov [esi+TWindow._cursor], eax
+ test eax, $ffffff00
+ jnz @f
+ stdcall GetStockCursor, eax
+@@:
+ get edx, esi, TWindow:OSWindow
+
+ stdcall SetMouseCursor, edx, eax
+
popad
return
endp
-
-
-method TScrollWindow.GetFreeArea
-begin
- inherited
-
- sub [eax+TBounds.width], ScrollBarWidth
- jns @f
- mov [eax+TBounds.width], 0
-@@:
- sub [eax+TBounds.height], ScrollBarWidth
- jns @f
- mov [eax+TBounds.height], 0
-@@:
- return
-endp
-
-
-;_________________________________________________________________________________________
-
proc _SetSliderPos, .pScrollbar, .x, .lengthpx
begin
push eax ecx edx
@@ -327,83 +398,10 @@
xor eax, eax
jmp .ok2
endp
-
-; returns:
-; eax - position in pixels
-; edx - size in pixels
-
-proc _SliderPixels, .pScrollbar, .length
-begin
- push ecx esi
-
- mov ecx, [.pScrollbar]
-
-; page size in pixels.
- mov esi, [ecx+TScrollbar.Max]
- mov eax, [.length]
- add esi, [ecx+TScrollbar.Page]
- test esi, esi
- jz .lengthok
-
- imul [ecx+TScrollbar.Page]
- idiv esi
-
-.lengthok:
- cmp eax, MinScrollBarWidth
- jge @f
- mov eax, MinScrollBarWidth
-@@:
- cmp eax, [.length]
- jle @f
- mov eax, [.length]
-@@:
- push eax
-
-; position in pixels
-
- sub eax, [.length]
- mov esi, [ecx+TScrollbar.Max]
- test esi, esi
- jnz @f
- inc esi
-@@:
- neg eax
- mul [ecx+TScrollbar.Pos]
- div esi
-
- pop edx ; width
-
- pop esi ecx
- return
-endp
-
-
-proc __ScrollSetCursor, .window, .x, .y
-begin
- pushad
-
- mov esi, [.window]
- mov eax, [esi+TWindow._cursor]
- stdcall _WhatScrollbar, esi, [.x], [.y]
- jc @f
-
- mov eax, mcArrow
-@@:
- mov [esi+TWindow._cursor], eax
- test eax, $ffffff00
- jnz @f
- stdcall GetStockCursor, eax
-@@:
- stdcall SetMouseCursor, eax
-
- popad
- return
-endp
-
; returns:
; ecx = height of the scrollbar
; edi = ptr to TScrollbar structure
@@ -415,19 +413,15 @@
begin
push eax edx esi
mov esi, [.window]
-
- mov eax, [.x]
- mov edx, [.y]
-
mov eax, [esi+TWindow._width]
mov edx, [esi+TWindow._height]
- sub eax, ScrollBarWidth
- sub edx, ScrollBarWidth
+ sub eax, [scrollWidth]
+ sub edx, [scrollWidth]
cmp [.x], eax
jl .checkh
cmp [.y], edx
@@ -457,11 +451,430 @@
stc
pop esi edx eax
return
endp
+
+;;_________________________________________________________________________________________
+;
+;
+;method TScrollWindow.SysEventHandler
+; .event TScrollEvent
+;begin
+; push eax ebx edx esi edi
+; mov esi, [.self]
+; mov ecx, [.pEvent]
+;
+; cmp [ecx+TSysEvent.event], seMouseBtnPress
+; je .btnpress
+;
+; cmp [ecx+TSysEvent.event], seMouseBtnRelease
+; je .btnrelease
+;
+; cmp [ecx+TSysEvent.event], seMouseMove
+; je .mousemove
+;
+;.continue:
+; inherited [.pEvent]
+;
+;.finish:
+; pop edi esi edx ebx eax
+; return
+;
+;
+;;.........................................................................................
+;
+;.btnpress:
+; stdcall __ScrollSetCursor, esi, [ecx+TMouseButtonEvent.x], [ecx+TMouseButtonEvent.y]
+;
+; cmp [ecx+TMouseButtonEvent.Button], mbLeft
+; jne .continue
+;
+; stdcall _WhatScrollbar, esi, [ecx+TMouseButtonEvent.x], [ecx+TMouseButtonEvent.y]
+; jc .continue ; not found
+;
+;; here ecx=height of the scrollbar
+;; edi= ptr to TScrollbar structure
+;; ebx= coordinate of the mouse in the scrollbar
+;
+; stdcall _SliderPixels, edi, ecx
+; sub ebx, eax
+; jl .before
+; cmp ebx, edx
+; jg .after
+;
+;; inside the slider - capture the mouse.
+; mov [edi+TScrollbar._Drag], ebx
+; stdcall MouseCapture, [esi+TWindow.handle]
+; jmp .continue
+;
+;.before:
+;.after:
+; jmp .continue
+;
+;;.........................................................................................
+;
+;.btnrelease:
+; stdcall __ScrollSetCursor, esi, [ecx+TMouseButtonEvent.x], [ecx+TMouseButtonEvent.y]
+;
+; xor eax, eax
+; mov [esi+TScrollWindow._HScroller._Drag], eax
+; mov [esi+TScrollWindow._VScroller._Drag], eax
+;
+; stdcall MouseCapture, eax
+; jmp .continue
+;
+;;.........................................................................................
+;
+;.mousemove:
+; mov ecx, [.pEvent]
+; stdcall __ScrollSetCursor, esi, [ecx+TMouseMoveEvent.x], [ecx+TMouseMoveEvent.y]
+;
+; mov ecx, [.pEvent]
+; lea edi, [esi+TScrollWindow._HScroller]
+; mov eax, [ecx+TMouseMoveEvent.x]
+; mov ecx, [esi+TScrollWindow._width]
+; mov [.event.ScrollBar], scrollX
+; cmp [edi+TScrollbar._Drag], 0
+; jne .found
+;
+; mov ecx, [.pEvent]
+; lea edi, [esi+TScrollWindow._VScroller]
+; mov eax, [ecx+TMouseMoveEvent.y]
+; mov ecx, [esi+TScrollWindow._height]
+; mov [.event.ScrollBar], scrollY
+; cmp [edi+TScrollbar._Drag], 0
+;
+; je .continue
+;
+;
+;.found:
+; mov [.event.event], seScroll
+; mov [.event.ScrollCmd], scTrack
+;
+; sub ecx, ScrollBarWidth
+; sub eax, 2
+; sub eax, [edi+TScrollbar._Drag]
+; stdcall _SetSliderPos, edi, eax, ecx
+; jc .endmove
+;
+; mov eax, [edi+TScrollbar.Pos]
+; mov [.event.Value], eax
+;
+; lea eax, [.event]
+;
+; exec esi, TWindow:SysEventHandler, eax
+; jnc .finish
+;
+;; ?????? Do we need this?
+;; execute esi, TScrollWindow.Refresh
+;
+;.endmove:
+; clc
+; jmp .finish
+;
+;endp
+;
+;
+;;_________________________________________________________________________________________
+;
+;
+;method TScrollWindow._RedrawShadow
+; .recth TBounds
+; .rectv TBounds
+; .rectx TBounds
+;
+; .context dd ?
+;begin
+; pushad
+; mov esi, [.self]
+;
+; get ebx, esi, TScrollWindow:FreeArea
+;
+; mov eax, [esi+TScrollWindow._pShadow]
+; stdcall AllocateContext, [eax+TBackBuffer.raster]
+; mov [.context], eax
+;
+; mov eax, [ebx+TBounds.x]
+; mov edx, [ebx+TBounds.y]
+; mov [.recth.x], eax
+; mov [.rectv.y], edx
+;
+; add eax, [ebx+TBounds.width]
+; add edx, [ebx+TBounds.height]
+; mov [.rectv.x], eax
+; mov [.recth.y], edx
+;
+; inc edx
+; inc eax
+; mov [.rectx.y], edx
+; mov [.rectx.x], eax
+;
+; mov [.recth.height], ScrollBarWidth
+; mov [.rectv.width], ScrollBarWidth
+; mov [.rectx.width], ScrollBarWidth-1
+; mov [.rectx.height], ScrollBarWidth-1
+;
+; mov eax, [ebx+TBounds.width]
+; mov edx, [ebx+TBounds.height]
+; inc eax
+; inc edx
+; mov [.recth.width], eax
+; mov [.rectv.height], edx
+;
+; lea eax, [.rectx]
+; stdcall DrawBoxDefault, [.context], eax, [clDialogBk], bxNone
+;
+; lea eax, [.recth]
+; stdcall [DrawBox], [.context], eax, [clScrollBk], bxSunken or bxNoFill
+;
+; lea eax, [.rectv]
+; stdcall [DrawBox], [.context], eax, [clScrollBk], bxSunken or bxNoFill
+;
+; lea eax, [esi+TScrollWindow._HScroller]
+; stdcall _SliderPixels, eax, [.recth.width]
+;
+; push esi
+; stdcall DrawFillRect, [.context], [.recth.x], [.recth.y], eax, [.recth.height], [clScrollBk]
+; mov esi, [.recth.width]
+; sub esi, eax
+; sub esi, edx
+;
+; add eax, [.recth.x]
+; lea edi, [eax+edx]
+; stdcall DrawFillRect, [.context], edi, [.recth.y], esi, [.recth.height], [clScrollBk]
+; pop esi
+;
+; mov [.rectx.x], eax
+;
+; mov [.rectx.width], edx
+; push [.recth.y] [.recth.height]
+; pop [.rectx.height] [.rectx.y]
+;
+; lea eax, [.rectx]
+; stdcall [DrawSlider], [.context], eax, [clScrollSlider], sliderHorizontal
+;
+; lea eax, [esi+TScrollWindow._VScroller]
+; stdcall _SliderPixels, eax, [.rectv.height]
+;
+; push esi
+; stdcall DrawFillRect, [.context], [.rectv.x], [.rectv.y], [.rectv.width], eax, [clScrollBk]
+; mov esi, [.rectv.height]
+; sub esi, eax
+; sub esi, edx
+;
+; add eax, [.rectv.y]
+; lea edi, [eax+edx]
+; stdcall DrawFillRect, [.context], [.rectv.x], edi, [.rectv.width], esi, [clScrollBk]
+; pop esi
+;
+; mov [.rectx.y], eax
+;
+; mov [.rectx.height], edx
+; push [.rectv.x] [.rectv.width]
+; pop [.rectx.width] [.rectx.x]
+;
+; lea eax, [.rectx]
+; stdcall [DrawSlider], [.context], eax, [clScrollSlider], sliderVertical
+;
+; stdcall ReleaseContext, [.context]
+; stc
+; popad
+; return
+;endp
+;
+;
+;
+;
+;method TScrollWindow.GetFreeArea
+;begin
+; inherited
+;
+; sub [eax+TBounds.width], ScrollBarWidth
+; jns @f
+; mov [eax+TBounds.width], 0
+;@@:
+; sub [eax+TBounds.height], ScrollBarWidth
+; jns @f
+; mov [eax+TBounds.height], 0
+;@@:
+; return
+;endp
+;
+;
+;;_________________________________________________________________________________________
+;
+;
+;
+;proc _SetSliderPos, .pScrollbar, .x, .lengthpx
+;begin
+; push eax ecx edx
+;
+; mov ecx, [.pScrollbar]
+; stdcall _SliderPixels, [.pScrollbar], [.lengthpx]
+;
+; sub [.lengthpx], edx
+; jz .zero
+;
+; mov eax, [ecx+TScrollbar.Max]
+; imul [.x]
+; idiv [.lengthpx]
+;
+; cmp eax, 0
+; jge .ok
+; mov eax, 0
+;.ok:
+; cmp eax, [ecx+TScrollbar.Max]
+; jle .ok2
+; mov eax, [ecx+TScrollbar.Max]
+;.ok2:
+; cmp [ecx+TScrollbar.Pos], eax
+; stc
+; je @f
+; clc
+;@@:
+; mov [ecx+TScrollbar.Pos], eax
+; pop edx ecx eax
+; return
+;
+;.zero:
+; xor eax, eax
+; jmp .ok2
+;endp
+;
+;
+;
+;; returns:
+;; eax - position in pixels
+;; edx - size in pixels
+;
+;proc _SliderPixels, .pScrollbar, .length
+;begin
+; push ecx esi
+;
+; mov ecx, [.pScrollbar]
+;
+;; page size in pixels.
+; mov esi, [ecx+TScrollbar.Max]
+; mov eax, [.length]
+; add esi, [ecx+TScrollbar.Page]
+; test esi, esi
+; jz .lengthok
+;
+; imul [ecx+TScrollbar.Page]
+; idiv esi
+;
+;.lengthok:
+; cmp eax, MinScrollBarWidth
+; jge @f
+; mov eax, MinScrollBarWidth
+;@@:
+; cmp eax, [.length]
+; jle @f
+; mov eax, [.length]
+;@@:
+; push eax
+;
+;; position in pixels
+;
+; sub eax, [.length]
+; mov esi, [ecx+TScrollbar.Max]
+; test esi, esi
+; jnz @f
+; inc esi
+;@@:
+; neg eax
+; mul [ecx+TScrollbar.Pos]
+; div esi
+;
+; pop edx ; width
+;
+; pop esi ecx
+; return
+;endp
+;
+;
+;proc __ScrollSetCursor, .window, .x, .y
+;begin
+; pushad
+;
+; mov esi, [.window]
+; mov eax, [esi+TWindow._cursor]
+; stdcall _WhatScrollbar, esi, [.x], [.y]
+; jc @f
+;
+; mov eax, mcArrow
+;@@:
+; mov [esi+TWindow._cursor], eax
+; test eax, $ffffff00
+; jnz @f
+; stdcall GetStockCursor, eax
+;@@:
+; stdcall SetMouseCursor, eax
+;
+; popad
+; return
+;endp
+;
+;
+;
+;; returns:
+;; ecx = height of the scrollbar
+;; edi = ptr to TScrollbar structure
+;; ebx = coordinate of the mouse in the scrollbar
+;;
+;; CF=1 if the cursor is not in scrollbar
+;
+;proc _WhatScrollbar, .window, .x, .y
+;begin
+; push eax edx esi
+;
+; mov esi, [.window]
+;
+;
+; mov eax, [.x]
+; mov edx, [.y]
+;
+; mov eax, [esi+TWindow._width]
+; mov edx, [esi+TWindow._height]
+;
+; sub eax, ScrollBarWidth
+; sub edx, ScrollBarWidth
+;
+; cmp [.x], eax
+; jl .checkh
+;
+; cmp [.y], edx
+; jg .notfound ; we are in the dead square.
+;
+;; mouse in vscrollbar
+; mov ebx, [.y]
+; mov ecx, edx
+; lea edi, [esi+TScrollWindow._VScroller]
+; jmp .found
+;
+;.checkh:
+; cmp [.y], edx
+; jl .notfound ; in the client area
+;
+;; mouse in hscrollbar
+; mov ebx, [.x]
+; mov ecx, eax
+; lea edi, [esi+TScrollWindow._HScroller]
+;
+;.found:
+; clc
+; pop esi edx eax
+; return
+;
+;.notfound:
+; stc
+; pop esi edx eax
+; return
+;endp
+
endmodule
ADDED freshlib/gui/TScrollbar.asm
Index: freshlib/gui/TScrollbar.asm
==================================================================
--- /dev/null
+++ freshlib/gui/TScrollbar.asm
@@ -0,0 +1,402 @@
+; _______________________________________________________________________________________
+;| |
+;| ..::FreshLib::.. Free, open source. Licensed under "BSD 2-clause" license." |
+;|_______________________________________________________________________________________|
+;
+; Description: TScrollWindow object class
+;
+; Target OS: Any
+;
+; Dependencies:
+;
+; Notes: TScrollWindow is window that may have scrollers to scroll the client area.
+;_________________________________________________________________________________________
+module "TScrollWindow library"
+
+
+sbkHorizontal = 0
+sbkVertical = 1
+
+
+object TScrollbar, TWindow
+
+ ._pos dd ?
+ ._page dd ?
+ ._max dd ?
+
+ ._kind dd ?
+
+ ._drag_ofs dd ?
+
+ ._state dd ?
+
+ param .Kind, ._kind, .SetKind
+
+ param .Pos, ._pos, .SetPos
+ param .Page, ._page, .SetPage
+ param .Max, ._max, .SetMax
+
+ method .SetKind, .value
+
+ method .SetPos, .value
+ method .SetPage, .value
+ method .SetMax, .value
+
+ method .Paint
+
+ method .EventMouseMove, .x, .y, .kbdState
+
+ method .EventButtonPress, .button, .kbdState, .x, .y
+ method .EventButtonRelease, .button, .kbdState, .x, .y
+
+ method .EventMouseEnter
+ method .EventMouseLeave
+endobj
+
+
+
+;_________________________________________________________________________________________
+
+
+method TScrollbar.SetKind ;, .value
+begin
+ mov eax, [.self]
+ push [.value]
+ pop [eax+TScrollbar._kind]
+
+ exec eax, TScrollbar:Refresh
+ return
+endp
+
+;_________________________________________________________________________________________
+
+method TScrollbar.SetPos ;, .value
+begin
+ push eax ecx
+
+ mov ecx, [.self]
+
+ mov eax, [.value]
+ cmp eax, [ecx+TScrollbar._pos]
+ je .finish
+
+ mov [ecx+TScrollbar._pos], eax
+ exec ecx, TScrollbar:Refresh
+
+.finish:
+ pop ecx eax
+ return
+endp
+
+;_________________________________________________________________________________________
+
+
+method TScrollbar.SetPage ;, .value
+begin
+ push eax ecx
+
+ mov ecx, [.self]
+
+ mov eax, [.value]
+ cmp eax, [ecx+TScrollbar._page]
+ je .finish
+
+ mov [ecx+TScrollbar._page], eax
+ exec ecx, TScrollbar:Refresh
+
+.finish:
+ pop ecx eax
+ return
+endp
+
+
+;_________________________________________________________________________________________
+
+
+method TScrollbar.SetMax ;, .value
+begin
+ push eax ecx
+
+ mov ecx, [.self]
+
+ mov eax, [.value]
+ cmp eax, [ecx+TScrollbar._max]
+ je .finish
+
+ mov [ecx+TScrollbar._max], eax
+ exec ecx, TScrollbar:Refresh
+
+.finish:
+ pop ecx eax
+ return
+endp
+
+
+
+;_________________________________________________________________________________________
+
+
+method TScrollbar.Paint
+.canvas dd ?
+.rect TBounds
+begin
+ pushad
+ mov esi, [.self]
+
+ get ebx, esi, TScrollbar:Canvas
+
+ xor eax, eax
+ mov ecx, [ebx+TImage.width]
+ mov edx, [ebx+TImage.height]
+
+ mov [.rect.x], eax
+ mov [.rect.y], eax
+ mov [.rect.width], ecx
+ mov [.rect.height], edx
+
+ mov edi, [esi+TScrollbar._state]
+
+ stdcall DrawSolidRect, ebx, eax, eax, [ebx+TImage.width], [ebx+TImage.height], [GUI.clScrollBk+4*edi]
+
+ mov ecx, [esi+TScrollbar._kind]
+ mov edx, [esi+TScrollbar._width + 4*ecx] ; sbkHorizontal = 0; sbkVertical = 1
+
+ stdcall _SliderPixels, esi, edx
+
+ mov [.rect.x + 4*ecx], eax
+ mov [.rect.width + 4*ecx], edx
+
+ lea eax, [.rect]
+ stdcall DrawBoxDefault, ebx, eax, [GUI.clScrollSlider+4*edi], [GUI.borderScroll], [GUI.boxBorderWidth]
+
+ inherited
+
+ popad
+ return
+
+endp
+
+
+
+
+
+
+method TScrollbar.EventMouseMove
+begin
+ pushad
+
+ mov esi, [.self]
+ mov edx, [esi+TScrollbar._kind]
+
+ cmp [esi+TScrollbar._drag_ofs], 0
+ je .finish
+
+ mov eax, [.x + 4*edx]
+ mov ecx, [esi+TScrollbar._width + 4*edx]
+
+ sub eax, [edi+TScrollbar._drag_ofs]
+
+ stdcall _SetSliderPos, edi, eax, ecx
+ jc .finish
+
+ get eax, esi, TWindow:Parent
+ exec eax, TWindow:EventScroll, edx, scTrack, [edi+TScrollbar._pos] ;method .EventScroll, .direction, .command, .value
+
+ exec esi, TWindow:Refresh
+
+.finish:
+ inherited [.x], [.y], [.kbdState]
+ popad
+ return
+endp
+
+
+method TScrollbar.EventButtonPress
+begin
+ pushad
+
+ cmp [.button], mbLeft
+ jne .finish
+
+ mov esi, [.self]
+ mov ebx, [esi+TScrollbar._kind]
+
+ stdcall _SliderPixels, esi, [esi+TScrollbar._width + 4*ebx]
+
+ mov edi, [.x+ 4*ebx]
+
+ sub edi, eax
+ jl .before
+
+ cmp edi, edx
+ jg .after
+
+; inside the slider - capture the mouse.
+
+ mov [esi+TScrollbar._drag_ofs], edi
+
+ stdcall SetMouseCapture, esi
+
+.finish:
+ inherited [.button], [.kbdState], [.x], [.y]
+
+ popad
+ return
+
+.before:
+.after:
+ jmp .finish
+endp
+
+
+
+
+method TScrollbar.EventButtonRelease
+begin
+ pushad
+
+ mov esi, [.self]
+
+ xor eax, eax
+ mov [esi+TScrollbar._drag_ofs], eax
+ stdcall SetMouseCapture, eax
+
+ popad
+ return
+endp
+
+
+
+
+
+
+
+
+
+; returns:
+; eax - position in pixels
+; edx - size in pixels
+
+
+proc _SliderPixels, .pScrollbar, .length
+begin
+ push ecx esi
+
+ mov ecx, [.pScrollbar]
+
+; page size in pixels.
+ mov esi, [ecx+TScrollbar._max]
+ mov eax, [.length]
+ add esi, [ecx+TScrollbar._page]
+ test esi, esi
+ jz .lengthok
+
+ imul [ecx+TScrollbar._page]
+ idiv esi
+
+.lengthok:
+ cmp eax, [GUI.minSliderHeight]
+ jge @f
+ mov eax, [GUI.minSliderHeight]
+@@:
+ cmp eax, [.length]
+ jle @f
+ mov eax, [.length]
+@@:
+ push eax
+
+; position in pixels
+
+ sub eax, [.length]
+ mov esi, [ecx+TScrollbar._max]
+ test esi, esi
+ jnz @f
+ inc esi
+@@:
+ neg eax
+ mul [ecx+TScrollbar._pos]
+ div esi
+
+ pop edx ; width
+
+ pop esi ecx
+ return
+endp
+
+
+
+
+
+proc _SetSliderPos, .pScrollbar, .x, .lengthpx
+begin
+ push eax ecx edx
+
+ mov ecx, [.pScrollbar]
+ stdcall _SliderPixels, [.pScrollbar], [.lengthpx]
+
+ sub [.lengthpx], edx
+ jz .zero
+
+ mov eax, [ecx+TScrollbar._max]
+ imul [.x]
+ idiv [.lengthpx]
+
+ cmp eax, 0
+ jge .ok
+ mov eax, 0
+.ok:
+ cmp eax, [ecx+TScrollbar._max]
+ jle .ok2
+ mov eax, [ecx+TScrollbar._max]
+.ok2:
+ cmp [ecx+TScrollbar._pos], eax
+ stc
+ je @f
+ clc
+@@:
+ mov [ecx+TScrollbar._pos], eax
+ pop edx ecx eax
+ return
+
+.zero:
+ xor eax, eax
+ jmp .ok2
+endp
+
+
+
+
+
+
+method TScrollbar.EventMouseEnter
+begin
+ mov eax, [.self]
+ mov [eax+TScrollbar._state], 1
+ exec eax, TWindow:Refresh
+
+ inherited
+ return
+endp
+
+
+
+
+method TScrollbar.EventMouseLeave
+begin
+ mov eax, [.self]
+ mov [eax+TScrollbar._state], 0
+
+ exec eax, TWindow:Refresh
+
+ inherited
+ return
+endp
+
+
+
+
+
+endmodule
+
+
+
Index: freshlib/gui/TTreeView.asm
==================================================================
--- freshlib/gui/TTreeView.asm
+++ freshlib/gui/TTreeView.asm
@@ -10,128 +10,909 @@
; Dependencies:
; Notes:
;_________________________________________________________________________________________
module "TreeView library"
-;ObjectClass TreeView, \
-; ScrollWindow, \
-; TTreeView.Create, \
-; TTreeView.Destroy, \
-; TTreeView.Get, \
-; TTreeView.Set, \
-; TTreeView.ExecCmd, \
-; TTreeView.SysEventHandler
; tree-view item state flags.
tvisExpanded = 1
tvisSelected = 2
-tvisFocused = 4
+
+; iterate visible items flags
+
+iifViewport = 1 ; iterate only items that are in the viewport of the control.
+ ; if not set, the items that are "visible" because of the expanded parent items
+ ; will cause callback call as well.
+
+
+; TTreeView:HitTest return flags
+
+tvhtNone = 0
+tvhtExpandIcon = 1
+tvhtItemIcon = 2
+tvhtItemText = 3
struct TTreeViewItem
+
.level dd ? ; the level of the element in the tree.
.caption dd ? ; hString of the name.
.state dd ? ; one or more state flags.
- .imgNormal dd ? ; index to the icon for normal state
- .iSelected dd ? ; index to the icon for selected state
-
- .pObject dd ? ; the object attached to the item
- align 32
- .shift = 5
-ends
-
-
-object TTreeView, TScrollWindow
- ._items dd ? ; TArray with TTreeViewItem elements.
- ._first dd ? ; index of the first visible item.
-
- .OnItemDelete dd ? ; procedure to be call when the item is deleted. It should free the objects attached to the item.
-
- param .Focused
-
- method .AddItem, .iParent
- method .DelItem, .iItem ;deletes the item and all children.
- method .GetItem, .index
-endobj
-
-
-proc TTreeView.Create, .pobj
-begin
- mov ebx, [.pobj]
-
- stdcall CreateArray, sizeof.TTreeViewItem
- mov [ebx+TTreeView._items], eax
-
- clc
- return
-endp
-
-
-proc TTreeView.Destroy, .pobj
-begin
- mov ebx, [.pobj]
-
- execute ebx, TTreeView.DelItem, -1
- stdcall FreeMem, [ebx+TTreeView._items]
-
- clc
- return
-endp
-
-
-proc TTreeView.Get, .pobj, .paramID
-begin
- stc
- return
-endp
-
-
-proc TTreeView.Set, .pobj, .paramID, .value
-begin
- stc
- return
-endp
-
-
-proc TTreeView.ExecCmd, .self, .method
-begin
- cmp [.method], TTreeView._RedrawShadow
- je .redraw
-
- stc
- return
-
-.redraw:
-locals
- .context dd ?
-endl
-
- pushad
- mov esi, [.self]
-
- mov edi, [esi+TTreeView._pShadow]
- stdcall AllocateContext, [edi+TBackBuffer.raster]
- mov [.context], eax
-
- stdcall DrawFillRect, [.context], 0, 0, [esi+TWindow._width], [esi+TWindow._height], [clEditBk]
-
-
-
-
- stdcall ReleaseContext, [.context]
-
- popad
- stc
- return
-
-endp
-
-
-proc TTreeView.SysEventHandler, .pobj, .pEvent
-begin
- stc
- return
-endp
+
+ .imgNormal dd ? ; index to the icon for normal state
+ .iSelected dd ? ; index to the icon for selected state
+
+ .UserData dd ? ; the user data attached to the item.
+
+ align 32
+ .shift = 5
+
+ends
+
+
+
+
+object TTreeView, TWindow
+
+ ._items dd ? ; TArray with TTreeViewItem elements.
+ ._index dd ? ; TArray with dword index to the displayable items of ._items array.
+
+ ._start_view dd ? ; in the index array.
+ ._focused dd ?
+
+ ._line_height dd ?
+ ._text_offset dd ?
+ ._margin_top dd ?
+ ._margin_left dd ?
+
+ .YScroller dd ?
+
+ ._on_focused_change dd ?
+
+ param .StartView, ._start_view, .SetStartView
+ param .OnFocusItem, ._on_focused_change, ._on_focused_change
+ param .FocusedItem, ._focused, .SetFocused
+
+ method .SetStartView, .value
+ method .SetFocused, .value
+
+ method .Create, .parent
+ method .Destroy
+
+ method .ClearSelection, .mask
+ method .IterateVisibleItems, .start_item, .flags, .callback, .user
+ method .HitTest, .x, .y
+
+ method .__UpdateCanvas
+ method .__RebuildIndex
+
+ method .Paint
+
+ method .EventKeyPress, .utf8, .scancode, .kbdState
+ method .EventButtonPress, .button, .kbdState, .x, .y
+ method .EventScroll, .direction, .command, .value
+
+endobj
+
+
+
+interface TTreeView.IterateCallback, .pTreeView, .pItem, .yItem, .user
+
+interface TTreeView.OnFocusItem, .pTreeView, .pItem
+
+
+
+
+method TTreeView.Create ; .parent
+begin
+ pushad
+ mov esi, [.self]
+
+ stdcall CreateArray, sizeof.TTreeViewItem
+ mov [esi+TTreeView._items], eax
+
+ stdcall CreateArray, 4
+ mov [esi+TTreeView._index], eax
+
+ mov [esi+TTreeView._margin_top], 4
+ mov [esi+TTreeView._margin_left], 4
+
+ stdcall GetFontMetrics, [GUI.DefaultFont]
+ add eax, 4
+ add ebx, 2
+ mov [esi+TTreeView._line_height], eax
+ mov [esi+TTreeView._text_offset], ebx
+
+ create edi, TScrollbar, [.self]
+ set edi, TScrollbar:Kind, sbkVertical
+ set edi, TScrollbar:width, [GUI.scrollWidth]
+
+ mov [esi+TTreeView.YScroller], edi
+
+ mov [esi+TTreeView.__want_focus], 1
+
+ inherited [.parent]
+ popad
+ return
+endp
+
+
+
+method TTreeView.Destroy
+begin
+ push ebx
+
+ mov ebx, [.self]
+
+ set ebx, TTreeView:Visible, FALSE ; in order to not try to update the view.
+
+ stdcall FreeMem, [ebx+TTreeView._index]
+ stdcall FreeMem, [ebx+TTreeView._items]
+
+ pop ebx
+ inherited
+ return
+endp
+
+
+
+
+method TTreeView.__UpdateCanvas
+.count dd ?
+begin
+ inherited
+
+ pushad
+
+; now update the scroller size and position.
+
+ mov esi, [.self]
+ mov ecx, [esi+TTreeView._width]
+ mov edx, [esi+TTreeView._height]
+
+ mov eax, ecx
+ sub eax, [GUI.scrollWidth]
+ sub eax, [GUI.boxBorderWidth]
+
+ sub edx, [GUI.boxBorderWidth]
+ sub edx, [GUI.boxBorderWidth]
+ js .finish
+
+ set [esi+TTreeView.YScroller], TScrollbar:x, eax
+ set [esi+TTreeView.YScroller], TScrollbar:y, [GUI.boxBorderWidth]
+ set [esi+TTreeView.YScroller], TScrollbar:height, edx
+
+
+ mov eax, [esi+TTreeView._height]
+ mov ecx, [esi+TTreeView._line_height]
+
+ cdq
+
+ div ecx
+ test eax, eax
+ jz @f
+
+ inc eax
+@@:
+ mov ebx, [esi+TTreeView._index]
+ test ebx, ebx
+ jz .finish
+
+ mov ebx, [ebx+TArray.count]
+ sub ebx, eax
+ inc ebx
+
+ set [esi+TTreeView.YScroller], TScrollbar:Page, eax
+ set [esi+TTreeView.YScroller], TScrollbar:Max, ebx
+
+ cmp eax, ebx
+ setl al
+ movzx eax, al
+
+ set [esi+TTreeView.YScroller], TScrollbar:Visible, eax
+
+.finish:
+ popad
+ return
+endp
+
+
+
+
+
+method TTreeView.__RebuildIndex
+begin
+ pushad
+
+ mov esi, [.self]
+
+ mov ecx, [esi+TTreeView._index]
+ jecxz @f
+
+ stdcall FreeMem, ecx
+
+@@:
+ stdcall CreateArray, 4
+ mov [esi+TTreeView._index], eax
+
+ xor eax, eax
+ lea edx, [esi+TTreeView._index]
+ exec esi, TTreeView:IterateVisibleItems, eax, eax, TTreeView.__AddIndex, edx
+
+ popad
+ return
+endp
+
+
+
+proc TTreeView.__AddIndex as TTreeView.IterateCallback
+begin
+ mov esi, [.pTreeView]
+ mov esi, [esi+TTreeView._items]
+ lea esi, [esi+TArray.array]
+
+ mov edi, [.user]
+ mov ebx, [.pItem]
+ sub ebx, esi
+ shr ebx, TTreeViewItem.shift
+
+ stdcall AddArrayItems, [edi], 1
+ mov [edi], edx
+ mov [eax], ebx
+
+ clc
+ return
+endp
+
+
+
+
+method TTreeView.Paint
+.bounds TBounds
+.end_item dd ?
+begin
+ pushad
+
+ mov esi, [.self]
+ get ebx, esi, TWindow:Canvas
+
+ xor eax, eax
+
+ mov [.bounds.x], eax
+ mov [.bounds.y], eax
+
+ mov ecx, [esi+TTreeView._width]
+ mov edx, [esi+TTreeView._height]
+
+ mov [.bounds.width], ecx
+ mov [.bounds.height], edx
+
+ lea eax, [.bounds]
+ stdcall [DrawBox], [esi+TTreeView._canvas], eax, [GUI.clTreeViewBack], bxNone, 0
+
+ mov eax, [esi+TTreeView._items]
+ mov ebx, [eax+TArray.count]
+ shl ebx, TTreeViewItem.shift
+ lea ebx, [eax+TArray.array+ebx]
+ mov [.end_item], ebx
+
+ mov edi, [esi+TTreeView._index]
+ mov ecx, [esi+TTreeView._start_view]
+ mov edx, [esi+TTreeView._margin_top]
+
+.loop:
+ cmp ecx, [edi+TArray.count]
+ jae .end_paint
+
+ mov eax, [edi+TArray.array + 4*ecx]
+ shl eax, TTreeViewItem.shift
+ add eax, [esi+TTreeView._items]
+ add eax, TArray.array
+
+ xor ebx, ebx
+ cmp ecx, [esi+TTreeView._focused]
+ sete bl
+ push ebx ; .focused argument
+
+ lea ebx, [eax+sizeof.TTreeViewItem]
+ cmp ebx, [.end_item]
+ jb @f
+
+ xor ebx, ebx
+
+@@:
+ stdcall TTreeView.__PaintOneItem, esi, eax, ebx, [esi+TTreeView._line_height], [esi+TTreeView._line_height], edx ; the last argument from the stack.
+
+ inc ecx
+ add edx, [esi+TTreeView._line_height]
+ cmp edx, [esi+TTreeView._height]
+ jb .loop
+
+.end_paint:
+ lea eax, [.bounds]
+ mov ecx, [GUI.tvBorder]
+ or ecx, bxNoFill
+ stdcall [DrawBox], [esi+TTreeView._canvas], eax, [GUI.clTreeViewBack], ecx, [GUI.boxBorderWidth]
+
+ inherited
+
+ popad
+ return
+endp
+
+
+proc TTreeView.__PaintOneItem, .pTreeView, .pItem, .pNextItem, .hsize, .vsize, .y, .focused
+.back dd ?
+.text dd ?
+begin
+ pushad
+
+ mov edx, [.y]
+ mov esi, [.pItem]
+ mov edi, [.pTreeView]
+
+ mov ecx, [esi+TTreeViewItem.level]
+ imul ecx, [.hsize]
+
+ add ecx, [edi+TTreeView._margin_left] ; left margin.
+
+ mov eax, [GUI.clTreeViewText]
+ mov ebx, [GUI.clTreeViewBack]
+
+ test [esi+TTreeViewItem.state], tvisSelected
+ jz @f
+ mov eax, [GUI.clTreeSelectedTxt]
+ mov ebx, [GUI.clTreeSelected]
+@@:
+ cmp [.focused], 0
+ je @f
+ mov eax, [GUI.clTreeFocusedTxt]
+ mov ebx, [GUI.clTreeFocused]
+@@:
+ mov [.text], eax
+ mov [.back], ebx
+
+; draw state icon
+ mov eax, [.pNextItem]
+ test eax, eax
+ jz .state_icon_ok
+
+ mov eax, [eax+TTreeViewItem.level]
+ cmp eax, [esi+TTreeViewItem.level]
+ jle .state_icon_ok
+
+ mov ebx, [esi+TTreeViewItem.state]
+ and ebx, tvisExpanded
+ mov ebx, [GUI.tvIcons+8*ebx] ; TImage with the expand/collapse icon
+
+ push ecx edx
+
+; center the icon
+ mov eax, [edi+TTreeView._line_height]
+ sub eax, [ebx+TImage.width]
+ sar eax, 1
+
+ add ecx, eax
+
+ mov eax, [edi+TTreeView._line_height]
+ sub eax, [ebx+TImage.height]
+ sar eax, 1
+
+ add edx, eax
+
+;.draw_state:
+ stdcall BlendImage, [edi+TTreeView._canvas], ecx, edx, ebx, 0, 0, [ebx+TImage.width], [ebx+TImage.height]
+ pop edx ecx
+
+.state_icon_ok:
+ add ecx, [.hsize]
+
+; draw item icon
+ mov ebx, [esi+TTreeViewItem.imgNormal]
+ test ebx, ebx
+ jz .icon_ok
+
+ push ecx edx
+
+; center the icon
+ mov eax, [edi+TTreeView._line_height]
+ sub eax, [ebx+TImage.width]
+ sar eax, 1
+
+ add ecx, eax
+
+ mov eax, [edi+TTreeView._line_height]
+ sub eax, [ebx+TImage.height]
+ sar eax, 1
+
+ add edx, eax
+
+ stdcall BlendImage, [edi+TTreeView._canvas], ecx, edx, ebx, 0, 0, [ebx+TImage.width], [ebx+TImage.height]
+
+ pop edx ecx
+
+ add ecx, [edi+TTreeView._line_height]
+
+.icon_ok:
+ push edx
+
+ stdcall StrPtr, [esi+TTreeViewItem.caption]
+ stdcall GetTextBounds, eax, [eax+string.len], [GUI.DefaultFont]
+
+ pop edx
+ add eax, 4
+
+ stdcall DrawSolidRect, [edi+TTreeView._canvas], ecx, edx, eax, [.vsize], [.back]
+
+ add edx, [edi+TTreeView._text_offset]
+ add ecx, 2
+
+ stdcall StrPtr, [esi+TTreeViewItem.caption]
+ stdcall DrawString, [edi+TTreeView._canvas], eax, [eax+string.len], ecx, edx, [GUI.DefaultFont], [.text]
+
+ popad
+ return
+endp
+
+
+
+
+method TTreeView.EventKeyPress ;, .utf8, .scancode, .kbdState
+begin
+ pushad
+
+ mov esi, [.self]
+
+ mov eax, [.utf8]
+ test eax, eax
+ jz .no_char
+
+; search the treeview???
+
+ popad
+ return
+
+.no_char:
+ mov eax, [.scancode]
+
+ cmp eax, keyUpNumpad
+ je .up
+ cmp eax, keyUp
+ je .up
+
+ cmp eax, keyDownNumpad
+ je .down
+ cmp eax, keyDown
+ je .down
+
+ cmp eax, keyPgUpNumpad
+ je .pgup
+ cmp eax, keyPgUp
+ je .pgup
+
+ cmp eax, keyPgDnNumpad
+ je .pgdn
+ cmp eax, keyPgDown
+ je .pgdn
+
+ popad
+ return
+
+.up:
+ mov edx, 1
+ jmp .moveup
+
+.pgup:
+ get edx, [esi+TTreeView.YScroller], TScrollbar:Page
+ dec edx
+
+
+.moveup:
+ mov ebx, [esi+TTreeView._focused]
+
+ test [.kbdState], maskShift
+ jnz .sel_up_ok
+
+ exec esi, TTreeView:ClearSelection, not tvisSelected
+
+.sel_up_ok:
+ sub ebx, edx
+ jns @f
+
+ xor ebx, ebx
+@@:
+ set esi, TTreeView:FocusedItem, ebx
+
+ cmp ebx, [esi+TTreeView._start_view]
+ jae .refresh
+
+ set esi, TTreeView:StartView, ebx
+ jmp .finish
+
+.refresh:
+ exec esi, TTreeView:Refresh
+
+.finish:
+ popad
+ return
+
+
+.down:
+ mov edx, 1
+ jmp .move_down
+
+.pgdn:
+ get edx, [esi+TTreeView.YScroller], TScrollbar:Page
+ dec edx
+
+
+.move_down:
+ mov edi, [esi+TTreeView._index]
+ mov ebx, [esi+TTreeView._focused]
+
+ add ebx, edx
+
+ cmp ebx, [edi+TArray.count]
+ jb .posok
+
+ mov ebx, [edi+TArray.count]
+ dec ebx
+
+.posok:
+ test [.kbdState], maskShift
+ jnz .sel_dn_ok
+
+ exec esi, TTreeView:ClearSelection, not tvisSelected
+
+.sel_dn_ok:
+ set esi, TTreeView:FocusedItem, ebx
+
+ get ecx, [esi+TTreeView.YScroller], TScrollbar:Page
+
+ sub ecx, 2
+ sub ebx, ecx
+
+ cmp ebx, [esi+TTreeView._start_view]
+ jle .refresh
+
+ set esi, TTreeView:StartView, ebx
+ jmp .finish
+
+endp
+
+
+
+method TTreeView.EventButtonPress ;, .button, .kbdState, .x, .y
+begin
+ pushad
+
+ mov esi, [.self]
+
+ exec esi, TTreeView:HitTest, [.x], [.y]
+
+ cmp eax, tvhtNone
+ je .finish2
+
+ cmp eax, tvhtExpandIcon
+ je .expand_collapse
+
+ test [.kbdState], maskCtrl
+ jnz @f
+ exec esi, TTreeView:ClearSelection, not tvisSelected
+@@:
+ set esi, TTreeView:FocusedItem, ecx
+ jmp .finish
+
+.expand_collapse:
+
+ xor [edx+TTreeViewItem.state], tvisExpanded
+ exec esi, TTreeView:__RebuildIndex
+
+.finish:
+ exec [.self], TWindow:Refresh
+
+.finish2:
+ popad
+ return
+endp
+
+
+
+method TTreeView.EventScroll
+begin
+ pushad
+
+ mov esi, [.self]
+
+ cmp [.command], scWheelUp
+ je .scrollup
+
+ cmp [.command], scWheelDn
+ je .scrolldn
+
+ cmp [.command], scTrack
+ jne .finish
+
+ set esi, TTreeView:StartView, [.value]
+
+.finish:
+ popad
+ return
+
+.scrollup:
+ get eax, esi, TTreeView:StartView
+ dec eax
+ jns @f
+ xor eax, eax
+@@:
+ set esi, TTreeView:StartView, eax
+ jmp .finish
+
+
+.scrolldn:
+ get ecx, [esi+TTreeView.YScroller], TScrollbar:Max
+ get eax, esi, TTreeView:StartView
+ inc eax
+ cmp eax, ecx
+ jbe @f
+ dec eax
+@@:
+ set [.self], TTreeView:StartView, eax
+ jmp .finish
+
+ return
+endp
+
+
+
+
+method TTreeView.SetStartView ;, .value
+begin
+ pushad
+
+ mov esi, [.self]
+ mov ebx, [.value]
+ mov [esi+TTreeView._start_view], ebx
+
+ set [esi+TTreeView.YScroller], TScrollbar:Pos, ebx
+ exec [.self], TWindow:Refresh
+
+ popad
+ return
+
+endp
+
+
+
+method TTreeView.IterateVisibleItems
+.end dd ?
+
+.min_item dd ?
+.maxy dd ?
+begin
+ pushad
+
+ mov esi, [.self]
+
+ mov eax, [esi+TTreeView._height]
+ mov [.maxy], eax
+
+ mov eax, [esi+TTreeView._items]
+ mov eax, [eax+TArray.count]
+
+ mov ecx, [.start_item]
+ mov edx, [esi+TTreeView._start_view]
+
+ shl eax, TTreeViewItem.shift
+ shl ecx, TTreeViewItem.shift
+ shl edx, TTreeViewItem.shift
+
+ add eax, [esi+TTreeView._items]
+ add ecx, [esi+TTreeView._items]
+ add edx, [esi+TTreeView._items]
+
+ lea eax, [eax+TArray.array]
+ lea ecx, [ecx+TArray.array]
+ lea edx, [edx+TArray.array]
+
+ mov [.end], eax
+ mov [.min_item], edx
+
+ xor edx, edx
+ dec edx ; current level = $ffffffff - unsigned cmp
+
+ xor edi, edi ; current Y coordinate.
+ add edi, [esi+TTreeView._margin_top] ; top margin.
+
+.item_loop:
+ cmp ecx, [.end]
+ jae .end_items
+
+ cmp [ecx+TTreeViewItem.level], edx
+ ja .next_item
+ je .equal
+
+; below
+ mov edx, [ecx+TTreeViewItem.level]
+
+.equal:
+ test [ecx+TTreeViewItem.state], tvisExpanded
+ jz .visible
+
+ inc edx
+
+.visible:
+ test [.flags], iifViewport
+ jz .yes
+
+ cmp ecx, [.min_item]
+ jb .next_item
+
+ cmp edi, [.maxy]
+ ja .end_items
+
+.yes:
+ pushad
+ stdcall [.callback], esi, ecx, edi, [.user]
+ popad
+ jc .found
+
+ add edi, [esi+TTreeView._line_height]
+
+.next_item:
+ add ecx, sizeof.TTreeViewItem
+ jmp .item_loop
+
+.end_items:
+ clc
+ popad
+ return
+
+.found:
+ mov [esp+regEAX*4], ecx
+ popad
+ return
+endp
+
+
+
+
+method TTreeView.HitTest
+.index dd ?
+begin
+ pushad
+
+ mov esi, [.self]
+
+ mov eax, [.y]
+ sub eax, [esi+TTreeView._margin_top]
+ xor edx, edx
+ mov ecx, [esi+TTreeView._line_height]
+
+ mov [.index], edx
+
+ div ecx
+
+ add eax, [esi+TTreeView._start_view]
+ mov ebx, [esi+TTreeView._index]
+
+ cmp eax, [ebx+TArray.count]
+ jae .not_found
+
+ mov [.index], eax
+
+ mov edi, [ebx+4*eax+TArray.array] ; index
+
+ mov ebx, [esi+TTreeView._items]
+
+ cmp edi, [ebx+TArray.count]
+ jae .not_found
+
+ shl edi, TTreeViewItem.shift
+ lea edi, [ebx+TArray.array + edi] ; edi - pointer to the pointed item.
+
+ mov edx, [edi+TTreeViewItem.level]
+ imul edx, [esi+TTreeView._line_height]
+ add edx, [esi+TTreeView._margin_left]
+
+ cmp [.x], edx
+ jb .finish
+
+ add edx, [esi+TTreeView._line_height]
+
+ mov eax, tvhtExpandIcon
+
+ cmp [.x], edx
+ jb .finish
+
+ add edx, [esi+TTreeView._line_height]
+
+ mov eax, tvhtItemIcon
+
+ cmp [.x], edx
+ jb .finish
+
+ mov eax, tvhtItemText
+
+.finish:
+ mov [esp+regEDX*4], edi
+ mov [esp+regEAX*4], eax
+ mov eax, [.index]
+ mov [esp+regECX*4], eax
+ popad
+ return
+
+.not_found:
+ xor edi, edi
+ mov eax, tvhtNone
+ jmp .finish
+
+endp
+
+
+
+method TTreeView.ClearSelection
+begin
+ pushad
+
+ mov esi, [.self]
+ mov esi, [esi+TTreeView._items]
+ lea edi, [esi+TArray.array]
+ mov ecx, [esi+TArray.count]
+ mov ebx, [.mask]
+
+.loop:
+ dec ecx
+ js .finish
+
+ and [edi+TTreeViewItem.state], ebx
+ add edi, sizeof.TTreeViewItem
+ jmp .loop
+
+
+.finish:
+ popad
+ return
+endp
+
+
+
+
+method TTreeView.SetFocused ;, .value
+begin
+ pushad
+ mov esi, [.self]
+ mov edi, [esi+TTreeView._items]
+ mov ecx, [.value]
+
+ cmp [esi+TTreeView._focused], ecx
+ je .finish
+
+ mov [esi+TTreeView._focused], ecx
+
+ xor ebx, ebx
+
+ cmp ecx, [edi+TArray.count]
+ jae .no_selection
+
+ shl ecx, TTreeViewItem.shift
+ lea ebx, [edi+TArray.array+ecx]
+
+ or [ebx+TTreeViewItem.state], tvisSelected
+
+.no_selection:
+ mov eax, [esi+TTreeView._on_focused_change]
+ test eax, eax
+ jz .finish
+
+ stdcall eax, esi, ebx ; interface TTreeView.OnFocusItem, .pTreeView, .pItem
+
+.finish:
+ popad
+ return
+endp
+
+
endmodule
Index: freshlib/gui/TWindow.asm
==================================================================
--- freshlib/gui/TWindow.asm
+++ freshlib/gui/TWindow.asm
@@ -13,17 +13,66 @@
; This file contains only OS independent part of the library and includes
; the OS dependent files.
;_________________________________________________________________________________________
module "TWindow library"
+; Interfaces for the OS dependent procedures
-; The elements of the array returned by .Children param
-; if handle<>0 and pWindow=0 - it is a native window, not added by FreshLib
-struct TWinArrayItem
- .handle dd ? ; The native OS handle of the window.
- .pWindow dd ? ; pointer to TWindow descendent structure.
-ends
+; NOTICE: Some of them are not needed, so can be removed.
+
+
+;-----------------------------------------------------------------------------------------
+; Creates OS window, according to the content of TWindow structure [.pWindow]
+;
+; Notice, that this OS windows are created ONLY for the visible top level windows.
+;
+;-----------------------------------------------------------------------------------------
+interface _CreateWindow, .pWindow
+
+;-----------------------------------------------------------------------------------------
+; Destroy the OS window. The OS windows are actually destroyed when invisible and then
+; recreated when needed.
+;-----------------------------------------------------------------------------------------
+interface _DestroyWindow, .hwnd
+
+;-----------------------------------------------------------------------------------------
+; Converts the client coordinates to screen coordinates.
+;-----------------------------------------------------------------------------------------
+interface _ClientToScreen, .hwnd, .x, .y
+
+;-----------------------------------------------------------------------------------------
+; Changes the visibility of the window.
+;-----------------------------------------------------------------------------------------
+interface _ShowWindow, .hwnd, .flag
+
+
+interface _RefreshWindowRect, .hwnd, .x, .y, .width, .height
+interface _SetWindowTextUtf8, .hwnd, .ptrUtf8
+interface _SetModalTowards, .hwnd, .hwndParent
+interface _FinalizeModal, .hwnd, .hwndParent
+interface _GetWindowStruct, .hwin
+interface _SetWindowStruct, .hwin, .value
+
+
+; probably not needed, but will keep them for some time.
+
+;interface _SetWindowBorder, .hwnd, .brdType
+;interface _GetWindowBounds, .hwnd, .pBounds
+;interface _SetWindowBounds, .hwnd, .pBounds
+;interface _CreateNullWindow
+;interface _GetParent, .hwnd
+;interface _GetChildren, .hwnd
+;interface _GetVisible, .hwnd
+;interface _SetFocus, .hwnd
+;interface _AddChild, .hwnd, .child
+;interface _GetWindowTextUtf8, .hwnd, .ptrUtf8
+;interface _EnableWindow, .hwnd, .flag
+;interface _SetTransientTowards, .hwnd, .hwndParent
+
+
+include '%TargetOS%/windows.asm'
+
; Border kind of window.
borderNone = 0
borderFull = 1
@@ -31,114 +80,195 @@
borderToolbox = 3
object TWindow, TObject
- .handle dd ? ; it is handle to the system provided window.
-
- ._x dd ?
- ._y dd ?
- ._width dd ?
- ._height dd ?
-
- ._visible dd ?
-
- ._border dd ?
-
- ._pSplitGrid dd ? ; pointer to array of TSplitRect that devide the window on a layout grid.
- ._dragSplitter dd ?
-
- ._FreeArea TBounds ; the window area that remains free after all children aligned. [1]
-
- ._caption dd ? ; string handle with window caption.
- ._cursor dd ? ; it is a handle to the mouse cursor.
-
- .___counter dd ?
+ .handle dd ? ; it is handle to the system provided window.
+
+ ._x dd ?
+ ._y dd ?
+ ._width dd ?
+ ._height dd ?
+
+ ._border dd ? ; has meaning only for the top level windows!
+
+ ._visible dd ?
+
+ ._cursor dd ? ; mouse cursor.
+
+ ._caption dd ? ; string handle with window caption.
+
+ ._enabled dd ?
+
+ .__want_focus dd ?
+
+ .__action dd ?
+
+ .__main dd ? ; this is the window that is main for this window. has meaning only for top level windows.
+
+; window canvas
+
+ ._screen dd ? ; TImage containing the image of the window with all children composited.
+ ._invalid_rect RECT ; the rectangle that need to be repainted.
+
+ ._canvas dd ? ; TImage containing the image of the window only.
+
+ ._screen_invalid dd ?
+ ._canvas_invalid dd ?
+
+; window user event handlers
+
+ ._OnPaint dd ?
+ ._OnScroll dd ?
+ ._OnKeyPressed dd ?
; parameters
+ param .OSWindow, .GetOSWindow, NONE ; the first window down the tree, that has window handle.
+
+ param .Action, .__action, .SetAction
+
param .x, ._x, ._x
param .y, ._y, ._y
- param .width, ._width, ._width
- param .height, ._height, ._height
-
- param .FreeArea, .GetFreeArea, NONE ; read only.
-
- param .borderKind, ._border, .SetBorder
- param .ZOrder, .GetZ, .SetZ
-
- param .Visible, ._visible, .SetVisible
+ param .width, ._width, .SetWidth
+ param .height, ._height, .SetHeight
+
+ param .border, ._border, ._border
+
+ param ._MainWindow, .__main, .__main
+
+ param .Cursor, ._cursor, ._cursor
+
+ param .Visible, ._visible, .SetVisible
param .Caption, .GetCaption, .SetCaption
- param .Parent, .GetParent, .SetParent
- param .Cursor, ._cursor, .SetCursor
- param .Children, .GetChildren, NONE
- param .SplitGrid, ._pSplitGrid, .SetSplitGrid
- param .SplitCell, .GetSplitCell, .SetSplitCell
+ param .Enabled, .GetEnabled, .SetEnabled
+ param .GlobalEnabled, .GetGlobalEnabled, NONE
+
+ param .WantFocus, .__want_focus, NONE
+
+ param .ImgScreen, .GetImgScreen, NONE
+ param .Canvas, .GetCanvas, NONE
+
+ param .OnPaint, ._OnPaint, .SetOnPaint
+ param .OnScroll, ._OnScroll, ._OnScroll
+
+ param .OnKeyPressed, ._OnKeyPressed, ._OnKeyPressed
+
+ param .SplitCell, NONE, .SetSplitCell
+
+; private methods
+
+ method .__UpdateHandle
+ method .__UpdateFocus
+ method .__UpdateCanvas
+ method .__UpdateScreen
+
; parameter methods
- method .GetFreeArea
- method .GetZ
+ method .SetParent, .value
+
+ method .SetAction, .value
+
+ method .UpdateAction, .action ; to be defined only for controls that can be attached to TAction
+
+ method .SetWidth, .value
+ method .SetHeight, .value
+
+ method .GetEnabled
+ method .SetEnabled, .value
+
+ method .GetGlobalEnabled
+
method .GetCaption
- method .GetParent
- method .GetChildren
- method .GetSplitCell
-
- method .SetBorder, .value
- method .SetZ, .value
- method .SetVisible, .value
method .SetCaption, .value
- method .SetParent, .value
- method .SetCursor, .value
- method .SetSplitGrid, .value
+
+ method .SetVisible, .value
+
+ method .SetOnPaint, .value
+
method .SetSplitCell, .value
+
+ method .GetImgScreen
+ method .GetCanvas
+
+ method .GetOSWindow
; other methods
- method .Create
+ method .Create, .parent
method .Destroy
+
+; Parent/child methods definitions of abstract methods, inherited from TObject
+
+ method .ChildByXY, .x, .y, .onlyenabled
+
+ method .RectChanged, .pRect ; invalidates the rectangle, so all children windows in this rectangle are
+ ; to be redrawn. Called from the children window on any visual changes.
+ ; notice, that if the child changed the size ot position, it needs special
+ ; processing of the rectangle. Actually the changed rectangle is the
+ ; bounding rectangle of the new and old rectangles.
+
+ method .ClientToScreenXY, .x, .y
+
+
+; Painting methods
+
+ method .Paint ; Paints itself on the .Canvas TImage
method .Refresh
- method .Focus
- method .UpdateBounds
+ method .Update
- method .AddChild, .child
- method .AlignChildren
+ method .RefreshAll
- method .SysEventHandler, .pEvent
+; System event methods
+
+ method .EventFocusIn
+ method .EventFocusOut
+
+ method .EventResize, .newWidth, .newHeight
+ method .EventMove, .newX, .newY
+
+ method .EventMouseEnter
+ method .EventMouseLeave
+
+ method .EventMouseMove, .x, .y, .kbdState
+
+ method .EventButtonPress, .button, .kbdState, .x, .y
+ method .EventButtonRelease, .button, .kbdState, .x, .y
+
+ method .EventScroll, .direction, .command, .value
+
+ method .EventKeyPress, .utf8, .scancode, .kbdState
+ method .EventKeyRelease, .scancode, .kbdState
+
+ method .CloseRequest, .reason
endobj
-; NOTES:
-; [1] FreeArea field
-;
-; [2] The param .children returns an array of TWinArrayItem filled with information about
-; all children of the given window.
-; This array is allocated with CreateArray and needs to be free with FreeMem after use.
-; TArray.lparam of the array contains a pointer to the element containing current window
+
+interface TWindow.OnPaint, .self, .canvas
+
+interface TWindow.OnScroll, .self, .direction, .command, .value
+
+interface TWindow.OnKeyPressed, .self, .utf8, .scancode, .kbdState
-; OS dependend code
-include '%TargetOS%/windows.asm'
; OS independent code.
-
;_________________________________________________________________________________________
+
method TWindow.Create
begin
- push ebx
-
- stdcall _CreateNullWindow
-
- mov ebx, [.self]
- mov [ebx+TWindow.handle], eax
- stdcall _SetWindowStruct, eax, ebx
-
- pop ebx
+ inherited [.parent]
+
+ set [.self], TWindow:Enabled, TRUE
+ set [.self], TWindow:Cursor, mcArrow
+ set [.self], TWindow:border, borderFull
return
endp
;_________________________________________________________________________________________
@@ -145,94 +275,138 @@
method TWindow.Destroy
begin
- push eax
-
- set [.self], TWindow:SplitGrid, 0
-
- mov eax, [.self]
- cmp [eax+TWindow.handle], 0
- je @f
-
- stdcall _DestroyWindow, [eax+TWindow.handle]
+ pushad
+
+ mov esi, [.self]
+
+; hide the window, destroy the handle and remove the focus.
+ mov [esi+TWindow._visible], 0
+ exec esi, TWindow:__UpdateHandle
+ exec esi, TWindow:__UpdateFocus
+
+ cmp esi, [__LastPointedWindow]
+ jne @f
+ mov [__LastPointedWindow], 0
+@@:
+
+; detach from action if any
+
+ mov ecx, [esi+TWindow.__action]
+ jecxz @f
+
+ exec ecx, TAction:Detach, esi
+
@@:
+; destroy the canvas and screen images if any.
+
+ mov ecx, [esi+TWindow._canvas]
+ jecxz .canvas_ok
+
+ stdcall DestroyImage, ecx
+
+.canvas_ok:
+
+ mov ecx, [esi+TWindow._screen]
+ jecxz .screen_ok
+
+ stdcall DestroyImage, ecx
+
+.screen_ok:
+
+; free the string handles
+
+ stdcall StrDel, [esi+TWindow._caption]
+
+ popad
+
inherited
- pop eax
- return
-endp
-
-
-
-;_________________________________________________________________________________________
-
-
-method TWindow.GetParent
-begin
- mov eax, [.self]
-
- stdcall _GetParent, [eax+TWindow.handle]
- test eax, eax
- jz .finish
-
- stdcall _GetWindowStruct, eax
-
-.finish:
return
endp
;_________________________________________________________________________________________
-method TWindow.GetChildren
+
+
+method TWindow.SetAction
begin
- mov eax, [.self]
- stdcall _GetChildren, [eax+TWindow.handle]
+ pushad
+
+ mov esi, [.self]
+ mov ecx, [.value]
+ mov edx, [esi+TWindow.__action]
+
+ cmp ecx, edx
+ je .finish
+
+ mov [esi+TWindow.__action], ecx
+
+ test edx, edx
+ jz .old_ok
+
+ exec edx, TAction:Detach, esi
+
+.old_ok:
+ test ecx, ecx
+ jz .new_ok
+
+ exec ecx, TAction:Attach, esi
+
+.new_ok:
+ getm eax, esi, TWindow:UpdateAction
test eax, eax
jz .finish
- push ecx ebx edi
-
- mov ebx, eax
- mov ecx, [ebx+TArray.count]
-
-.loop:
- jecxz .endloop
- dec ecx
-
- stdcall _GetWindowStruct, [ebx+TArray.array+8*ecx+TWinArrayItem.handle]
-
- mov [ebx+TArray.array+8*ecx+TWinArrayItem.pWindow], eax
- jmp .loop
-
-.endloop:
- mov eax, ebx
+ stdcall eax, esi, ecx
.finish:
- pop edi ebx ecx
+ popad
return
endp
;_________________________________________________________________________________________
-method TWindow.GetFreeArea
+
+method TWindow.SetWidth
+begin
+ push ecx eax
+
+ mov ecx, [.self]
+
+ mov eax, [.value]
+ xchg eax, [ecx+TWindow._width]
+ cmp eax, [ecx+TWindow._width]
+ je .finish
+
+ exec ecx, TWindow:Paint
+
+.finish:
+ pop eax ecx
+ return
+endp
+
+
+
+method TWindow.SetHeight
begin
- push ecx esi
- mov esi, [.self]
-
- xor eax, eax
- mov [esi+TWindow._FreeArea.x], eax
- mov [esi+TWindow._FreeArea.y], eax
- mov eax, [esi+TWindow._width]
- mov ecx, [esi+TWindow._height]
- mov [esi+TWindow._FreeArea.width], eax
- mov [esi+TWindow._FreeArea.height], ecx
- lea eax, [esi+TWindow._FreeArea]
-
- pop esi ecx
+ push ecx eax
+
+ mov ecx, [.self]
+
+ mov eax, [.value]
+ xchg eax, [ecx+TWindow._height]
+ cmp eax, [ecx+TWindow._height]
+ je .finish
+
+ exec ecx, TWindow:Paint
+
+.finish:
+ pop eax ecx
return
endp
;_________________________________________________________________________________________
@@ -251,42 +425,28 @@
;_________________________________________________________________________________________
-method TWindow.SetBorder
-begin
- push eax esi
-
- mov esi, [.self]
- mov eax, [.value]
- xchg eax, [esi+TWindow._border]
- cmp eax, [esi+TWindow._border]
- je .finish ; not changed
-
- stdcall _SetWindowBorder, [esi+TWindow.handle], [esi+TWindow._border]
-
-.finish:
- pop esi eax
- return
-endp
-
-
-;_________________________________________________________________________________________
-
method TWindow.SetCaption
begin
push eax esi
mov esi, [.self]
lea eax, [esi+TWindow._caption]
stdcall SetString, eax, [.value]
stdcall StrPtr, [eax]
+
+ cmp [esi+TWindow.handle], 0
+ je @f
stdcall _SetWindowTextUtf8, [esi+TWindow.handle], eax
+@@:
+ exec esi, TWindow:Refresh
+
pop esi eax
return
endp
@@ -301,425 +461,979 @@
mov eax, [.value]
xchg [esi+TWindow._visible], eax
cmp [esi+TWindow._visible], eax
je .finish
- stdcall _ShowWindow, [esi+TWindow.handle], [esi+TWindow._visible]
+ exec esi, TWindow:__UpdateFocus
+ exec esi, TWindow:__UpdateHandle
+ exec esi, TWindow:Refresh
.finish:
pop esi eax
return
endp
;_________________________________________________________________________________________
-method TWindow.SetSplitGrid
+method TWindow.SetOnPaint
begin
push eax esi
mov esi, [.self]
- mov eax, [esi+TWindow._pSplitGrid]
- test eax, eax
- jz @f
-
- sub eax, TArray.array
- stdcall FreeMem, eax
- mov [esi+TWindow._pSplitGrid], 0
-
-@@:
- cmp [.value], 0
+ mov eax, [.value]
+ xchg [esi+TWindow._OnPaint], eax
+ cmp [esi+TWindow._OnPaint], eax
je .finish
- stdcall ReadSplitGridTemplate, [.value]
- test eax, eax
- jz .finish
-
- add eax, TArray.array
- mov [esi+TWindow._pSplitGrid], eax
-
- exec esi, TWindow:AlignChildren
+ exec esi, TWindow:Refresh
.finish:
pop esi eax
return
endp
-
;_________________________________________________________________________________________
+
method TWindow.SetSplitCell
begin
- pushad
-
- mov esi, [.self]
- get edi, esi, TWindow:Parent
- get edx, edi, TWindow:SplitGrid
- test edx, edx
- jz .finish ; there is no splitgrid set on the parent
-
- mov ecx, 1
- mov ebx, [.value]
-
-.search_loop:
- test [edx+TSplitRect.type], stNone
- jnz .check
-
- inc ecx
- add edx, sizeof.TSplitRect
- jmp .search_loop
-
-.check:
- cmp [edx+TSplitRect.id], ebx
- je .found
-
- add edx, sizeof.TSplitRect
- dec ecx
- jnz .search_loop
+ push eax
+
+ get eax, [.self], TWindow:Parent
+ istype eax, TForm
+ jne .finish
+
+ exec eax, TForm:AttachControlToCell, [.self], [.value]
+
+.finish:
+ pop eax
+ return
+endp
+
+
+;_________________________________________________________________________________________
+
+
+method TWindow.GetGlobalEnabled
+begin
+ push ecx
+
+ mov ecx, [.self]
+
+ get eax, ecx, TWindow:Action
+ test eax, eax
+ jz .action_ok
+
+ get eax, eax, TAction:Enabled
+ jmp .check_parent
+
+.action_ok:
+ mov eax, [ecx+TWindow._enabled]
+
+.check_parent:
+ test eax, eax
+ jz .finish
+
+ get ecx, [.self], TWindow:Parent
+ jecxz .finish
+
+ get eax, ecx, TWindow:GlobalEnabled
+
+.finish:
+ pop ecx
+ return
+endp
+
+
+
+;_________________________________________________________________________________________
+
+
+
+method TWindow.GetEnabled
+begin
+ push ecx
+
+ mov ecx, [.self]
+
+ get eax, ecx, TWindow:Action
+ test eax, eax
+ jz .action_ok
+
+ get eax, eax, TAction:Enabled
jmp .finish
-.found:
- mov [edx+TSplitRect.pWindow], esi
+.action_ok:
+ mov eax, [ecx+TWindow._enabled]
- exec edi, TWindow:AlignChildren
+.finish:
+ pop ecx
+ return
+endp
+
+
+
+
+method TWindow.SetEnabled
+begin
+ push ecx
+ mov ecx, [.self]
+ push [.value]
+ pop [ecx+TWindow._enabled]
+
+ exec ecx, TWindow:__UpdateFocus
+ exec ecx, TWindow:Refresh
+
+ pop ecx
+ return
+endp
+
+
+
+
+;_________________________________________________________________________________________
+;
+; returns the pointer of the image TWindow.ImgScreen but only after ensuring that the
+; contained image is valid.
+
+method TWindow.GetImgScreen
+.dest RECT
+.xSrc dd ?
+.ySrc dd ?
+begin
+ pushad
+
+ mov esi, [.self]
+
+ exec esi, TWindow:__UpdateScreen
+ mov edx, [esi+TWindow._screen]
+ test edx, edx
+ jnz .process_screen
+
+ mov edx, [esi+TWindow._canvas]
+ jmp .end_loop
+
+.process_screen:
+ mov eax, [esi+TWindow._invalid_rect.right]
+ mov ecx, [esi+TWindow._invalid_rect.bottom]
+
+ sub eax, [esi+TWindow._invalid_rect.left]
+ jz .finish
+
+ sub ecx, [esi+TWindow._invalid_rect.top]
+ jz .finish
+
+ get ebx, esi, TWindow:Canvas
+
+; start with the background.
+
+ stdcall CopyImageRect, edx, [esi+TWindow._invalid_rect.left], [esi+TWindow._invalid_rect.top], ebx, [esi+TWindow._invalid_rect.left], [esi+TWindow._invalid_rect.top], eax, ecx
+
+; then blend the children windows
+
+ lea edi, [esi+TWindow._invalid_rect] ; EDI = invalid rect.
+
+ get ebx, esi, TObject:Children
+ test ebx, ebx
+ jz .end_loop
+
+ xor ecx, ecx
+ cmp ecx, [ebx+TArray.count]
+ je .end_loop
+
+.children_loop:
+ mov esi, [ebx+4*ecx+TArray.array]
+
+ istype esi, TWindow
+ jne .next_child
+
+ get eax, esi, TWindow:Visible
+ test eax, eax
+ jz .next_child
+
+ push [esi+TWindow._x] [esi+TWindow._y] [esi+TWindow._width] [esi+TWindow._height]
+ pop [.dest.bottom] [.dest.right] [.dest.top] [.dest.left]
+
+ mov eax, [.dest.left]
+ add [.dest.right], eax
+
+ mov eax, [.dest.top]
+ add [.dest.bottom], eax
+
+ lea eax, [.dest]
+ stdcall RectIntersect, eax, eax, edi
+ jc .next_child ; the rectangles does not intersect, so the child should not to be painted.
+
+ mov eax, [.dest.left]
+ sub [.dest.right], eax
+
+ sub eax, [esi+TWindow._x]
+ mov [.xSrc], eax
+
+ mov eax, [.dest.top]
+ sub [.dest.bottom], eax
+ sub eax, [esi+TWindow._y]
+ mov [.ySrc], eax
+
+ get eax, esi, TWindow:ImgScreen
+
+
+ stdcall BlendImage, edx, [.dest.left], [.dest.top], eax, [.xSrc], [.ySrc], [.dest.right], [.dest.bottom]
+
+.next_child:
+ inc ecx
+ cmp ecx, [ebx+TArray.count]
+ jne .children_loop
+
+.end_loop:
+ mov esi, [.self]
+
+ get eax, esi, TWindow:Enabled
+ test eax, eax
+ jnz .dis_ok
+
+; stdcall FilterDisabled, edx, [esi+TWindow.handle]
+
+.dis_ok:
+ xor eax, eax
+ mov [esi+TWindow._invalid_rect.left], eax
+ mov [esi+TWindow._invalid_rect.top], eax
+ mov [esi+TWindow._invalid_rect.right], eax
+ mov [esi+TWindow._invalid_rect.bottom], eax
+
+.finish:
+ mov [esp+4*regEAX], edx
+ popad
+ return
+endp
+
+
+
+;_________________________________________________________________________________________
+
+
+method TWindow.GetCanvas
+begin
+
+ exec [.self], TWindow:__UpdateCanvas
+
+ mov eax, [.self]
+ mov eax, [eax+TWindow._canvas]
+ return
+endp
+
+
+
+;_________________________________________________________________________________________
+
+
+method TWindow.GetOSWindow
+begin
+ push esi
+
+ mov esi, [.self]
+
+.loop:
+ cmp [esi+TWindow.handle], 0
+ jne .finish
+
+ get esi, esi, TWindow:Parent
+ test esi, esi
+ jnz .loop
+
+.finish:
+ mov eax, esi
+ pop esi
+ return
+endp
+
+
+;_________________________________________________________________________________________
+
+
+method TWindow.Paint
+.rect RECT
+begin
+ pushad
+
+ mov esi, [.self]
+
+ get eax, esi, TWindow:OnPaint
+ test eax, eax
+ jz .user_paint_ok
+
+ get ecx, esi, TWindow:Canvas
+ stdcall eax, esi, ecx ; user OnPaint handler.
+
+.user_paint_ok:
+
+ xor ecx, ecx
+ mov eax, [esi+TWindow._width]
+ mov edx, [esi+TWindow._height]
+
+ mov [.rect.left], ecx
+ mov [.rect.top], ecx
+ mov [.rect.right], eax
+ mov [.rect.bottom], edx
+ lea eax, [.rect]
+ exec esi, TWindow:RectChanged, eax
+
+ popad
+ return
+endp
+
+
+;_________________________________________________________________________________________
+
+method TWindow.Refresh
+.rect RECT
+begin
+ exec [.self], TWindow:Paint
+ exec [.self], TWindow:Update
+ return
+endp
+
+
+
+method TWindow.RefreshAll
+begin
+ pushad
+ get esi, [.self], TObject:Children
+ test esi, esi
+ jz .end_loop
+
+ mov ecx, [esi+TArray.count]
+
+.loop:
+ dec ecx
+ js .end_loop
+
+ istype [esi+TArray.array+4*ecx], TWindow
+ jne .loop
+
+ exec [esi+TArray.array+4*ecx], TWindow:RefreshAll
+ jmp .loop
+
+.end_loop:
+ exec [.self], TWindow:Refresh
+
+ popad
+ return
+endp
+
+
+
+
+method TWindow.Update
+.rect RECT
+begin
+ pushad
+
+ mov esi, [.self]
+
+ xor ecx, ecx
+ mov eax, [esi+TWindow._width]
+ mov edx, [esi+TWindow._height]
+
+ mov [.rect.left], ecx
+ mov [.rect.top], ecx
+
+ mov [.rect.right], eax
+ mov [.rect.bottom], edx
+
+
+.loop:
+ lea eax, [.rect]
+ exec esi, TWindow:RectChanged, eax
+
+ mov eax, [esi+TWindow._x]
+ mov edx, [esi+TWindow._y]
+
+ add [.rect.left], eax
+ add [.rect.top], edx
+ add [.rect.right], eax
+ add [.rect.bottom], edx
+
+ get ecx, esi, TWindow:Parent
+
+ jecxz .refresh
+
+ mov esi, ecx
+ jmp .loop
+
+
+.refresh:
+ cmp [esi+TWindow.handle], 0
+ je .finish
+
+ mov eax, [esi+TWindow._invalid_rect.right]
+ mov edx, [esi+TWindow._invalid_rect.bottom]
+
+ sub eax, [esi+TWindow._invalid_rect.left]
+ sub edx, [esi+TWindow._invalid_rect.top]
+
+ stdcall _RefreshWindowRect, [esi+TWindow.handle], [esi+TWindow._invalid_rect.left], [esi+TWindow._invalid_rect.top], eax, edx
+
+.finish:
+ popad
+ return
+endp
+
+
+
+;_________________________________________________________________________________________
+
+
+;---------------------------------------------------------------------------------
+; Arguments:
+; .self
+; .x
+; .y
+;
+; Returns:
+; eax - pointer to TWindow
+; ecx - X coordinates, translated to the client coordinates of the child.
+; edx - Y coordinates, translated to the client coordinates of the child.
+;
+; If children window was not found, the method returns:
+; eax = [.self]
+; ecx = [.x]
+; edx = [.y]
+;---------------------------------------------------------------------------------
+
+method TWindow.ChildByXY
+begin
+ push ebx esi edi
+
+ mov eax, [.self]
+ mov ecx, [.x]
+ mov edx, [.y]
+
+ mov esi, [eax+TObject.__pChildren]
+ test esi, esi
+ jz .finish
+
+ mov edi, [esi+TArray.count]
+ lea esi, [esi+TArray.array]
+
+
+.loop:
+ dec edi
+ js .finish
+
+ mov ebx, [esi+4*edi]
+
+ istype ebx, TWindow
+ jne .loop
+
+ sub ecx, [ebx+TWindow._x]
+ jl .no2
+
+ sub edx, [ebx+TWindow._y]
+ jl .no
+
+ cmp ecx, [ebx+TWindow._width]
+ jge .no
+
+ cmp edx, [ebx+TWindow._height]
+ jge .no
+
+ cmp [.onlyenabled], FALSE
+ je .enabled_ok
+
+ push eax
+ get eax, ebx, TWindow:GlobalEnabled
+ test eax, eax
+ pop eax
+ jz .no
+
+
+.enabled_ok:
+ pushad
+
+ get esi, ebx, TWindow:Canvas
+
+ mov eax, edx
+ imul eax, [esi+TImage.width]
+ shl eax, 2
+ add eax, [esi+TImage.pPixels]
+
+ cmp byte [eax+4*ecx+3], 0 ; the alpha value under the pointer
+ popad
+ jne .yes
+
+
+.no:
+ add edx, [ebx+TWindow._y]
+
+.no2:
+ add ecx, [ebx+TWindow._x]
+ jmp .loop
+
+
+.yes:
+ mov eax, ebx
+ exec eax, TWindow:ChildByXY, ecx, edx, [.onlyenabled]
.finish:
- popad
+ pop edi esi ebx
return
+
endp
+
+
+
;_________________________________________________________________________________________
+;
+; Includes the passed rectangle in the invalid rectangle. Later this rectangle will need
+; to be repainted, but only when the screen image is required.
+;
-
-method TWindow.UpdateBounds
+method TWindow.RectChanged ;, .pRect
+.client RECT
begin
push eax ecx
- mov ecx, [.self]
- lea eax, [ecx+TWindow._x]
- stdcall _SetWindowBounds, [ecx+TWindow.handle], eax
+
+ xor eax, eax
+ mov [.client.left], eax
+ mov [.client.top], eax
+
+ mov eax, [.self]
+
+ push [eax+TWindow._height] [eax+TWindow._width]
+ pop [.client.right] [.client.bottom]
+
+ mov ecx, [eax+TWindow._invalid_rect.right]
+ sub ecx, [eax+TWindow._invalid_rect.left]
+ jz .copy
+
+ mov ecx, [eax+TWindow._invalid_rect.bottom]
+ sub ecx, [eax+TWindow._invalid_rect.top]
+ jnz .add
+
+.copy:
+ lea eax, [eax+TWindow._invalid_rect]
+ stdcall RectCopy, eax, [.pRect]
+ jmp .intersect
+
+.add:
+ lea eax, [eax+TWindow._invalid_rect]
+ stdcall RectBounding, eax, eax, [.pRect]
+
+.intersect:
+ lea ecx, [.client]
+ stdcall RectIntersect, eax, eax, ecx
+
pop ecx eax
return
endp
;_________________________________________________________________________________________
-
-method TWindow.Refresh
-begin
- push eax
-
- mov eax, [.self]
- cmp [eax+TWindow._visible], 0
- je .finish
-
- stdcall _RefreshWindow, [eax+TWindow.handle]
-
-.finish:
- pop eax
- return
-endp
-
-;_________________________________________________________________________________________
-
-method TWindow.AddChild
-begin
- push eax ebx
-
- istype [.child], TWindow
- jne .add_not_window
-
- mov ebx, [.child]
- mov eax, [.self]
-
- stdcall _AddChild, [eax+TWindow.handle], [ebx+TWindow.handle]
-
- clc
- pop ebx eax
- return
-
-
-.add_not_window: ; this is possible, but not implemented for now.
- stc
- pop ebx eax
- return
-endp
-
method TWindow.SetParent
begin
- exec [.value], TWindow:AddChild, [.self]
- return
-endp
-
-
-;_________________________________________________________________________________________
-
-method TWindow.AlignChildren
- .winrect RECT
-begin
- pushad
-
- mov esi, [.self]
-
- cmp [esi+TWindow._pSplitGrid], 0
- je .endalign
-
- xor eax, eax
- mov [.winrect.left], eax
- mov [.winrect.top], eax
-
- get eax, esi, TWindow:width
- get edx, esi, TWindow:height
-
- mov [.winrect.right], eax
- mov [.winrect.bottom], edx
-
- lea eax, [.winrect]
- get edx, esi, TWindow:SplitGrid
-
- stdcall RealignGrid, edx, eax
-
- exec esi, TWindow:Refresh
-
-.endalign:
- pop edi esi
- return
-endp
-
-
-;_________________________________________________________________________________________
-
-method TWindow.Focus
-begin
- push eax
- mov eax, [.self]
- stdcall _SetFocus, [eax+TWindow.handle]
- pop eax
+ inherited [.value]
+ exec [.self], TWindow:__UpdateHandle ; create/destroy handle of the OS window, according to the window state.
return
endp
;_________________________________________________________________________________________
-method TWindow.SysEventHandler
-begin
- pushad
-
- mov esi, [.self]
- mov ebx, [.pEvent]
- mov eax, [ebx+TSysEvent.event]
-
- cmp eax, seMouseEnter
- je .mouseenter
-
- cmp eax, seMouseLeave
- je .mouseleave
-
- cmp eax, seMouseBtnPress
- je .mouse_btnpress
-
- cmp eax, seMouseBtnRelease
- je .mouse_btnrelease
-
- cmp eax, seResize
- je .resize
-
- cmp eax, seMouseMove
- je .mousemove
-
- cmp eax, sePaint
- je .paint
-
-.no_action:
- stc
- popad
- return
-
-.finish:
- clc
- popad
- return
-
-;.........................................................................................
-.paint:
- get eax, esi, TWindow:SplitGrid
- test eax, eax
- jz .no_action
-
- stdcall DrawSplitters, [ebx+TPaintEvent.context], eax
-
- clc
- jmp .finish
-
-;.........................................................................................
-.move:
- mov eax, [ebx+TMoveEvent.newX]
- mov ecx, [ebx+TMoveEvent.newY]
- mov [esi+TWindow._x], eax
- mov [esi+TWindow._y], ecx
- jmp .finish
-
-;.........................................................................................
-.resize:
- mov eax, [ebx+TResizeEvent.newWidth]
- mov ecx, [ebx+TResizeEvent.newHeight]
+
+method TWindow.__UpdateHandle
+begin
+ pushad
+
+ mov esi, [.self]
+ xor ecx, ecx
+
+ cmp [esi+TWindow._visible], ecx
+ je .no_handle
+
+ get eax, esi, TWindow:Parent
+
+ test eax, eax
+ jnz .no_handle
+
+; need handle
+
+ cmp [esi+TWindow.handle], ecx
+ jne .finish ; the window needs OS handle and has one.
+
+; The window has no handle, but needs it.
+
+ stdcall _CreateWindow, esi
+ mov [esi+TWindow.handle], eax
+
+; stdcall _CreateNullWindow
+; mov [esi+TWindow.handle], eax
+; mov ebx, eax
+
+; stdcall _SetWindowStruct, ebx, esi
+
+; stdcall StrPtr, [esi+TWindow._caption]
+; stdcall _SetWindowTextUtf8, ebx, eax
+
+; lea eax, [esi+TWindow._x]
+; stdcall _SetWindowBounds, ebx, eax
+
+; stdcall _SetWindowBorder, ebx, [esi+TWindow._border]
+
+ stdcall _ShowWindow, eax, TRUE
+
+
+.finish:
+ popad
+ return
+
+
+.no_handle:
+
+ cmp [esi+TWindow.handle], ecx
+ je .finish ; no need for handle and there is no such.
+
+ ; stdcall _ShowWindow, [esi+TWindow.handle], 0
+ stdcall _DestroyWindow, [esi+TWindow.handle] ; destroy not needed window handle.
+
+ mov [esi+TWindow.handle], ecx
+ jmp .finish
+
+endp
+
+
+
+
+method TWindow.__UpdateFocus
+begin
+ mov eax, [.self]
+ cmp eax, [__FocusedWindow]
+ jne .finish
+
+ get eax, [.self], TWindow:Visible
+ test eax, eax
+ jz .clear
+
+ get eax, [.self], TWindow:Enabled
+ test eax, eax
+ jz .clear
+
+ get eax, [.self], TWindow:WantFocus
+ test eax, eax
+ jz .clear
+
+.finish:
+ return
+
+.clear:
+ mov [__FocusedWindow], 0
+ exec [.self], TWindow:EventFocusOut
+ return
+endp
+
+
+
+
+
+method TWindow.__UpdateCanvas
+begin
+ pushad
+ mov esi, [.self]
+ mov edi, [esi+TWindow._canvas]
+ mov ecx, [esi+TWindow._width]
+ mov edx, [esi+TWindow._height]
+
+ test edi, edi
+ jz .create_new
+
+ cmp [edi+TImage.width], ecx
+ jne .destroy_img
+
+ cmp [edi+TImage.height], edx
+ je .imageok
+
+
+.destroy_img:
+
+ stdcall DestroyImage, edi
+
+.create_new:
+ stdcall CreateImage, ecx, edx
+ mov [esi+TWindow._canvas], eax
+
+.imageok:
+ popad
+ return
+endp
+
+
+
+
+
+method TWindow.__UpdateScreen
+begin
+ pushad
+ mov esi, [.self]
+ mov edi, [esi+TWindow._screen]
+ mov ecx, [esi+TWindow._width]
+ mov edx, [esi+TWindow._height]
+
+ test edi, edi
+ jz .create_new
+
+ cmp [edi+TImage.width], ecx
+ jne .destroy_img
+
+ cmp [edi+TImage.height], edx
+ je .imageok
+
+
+.destroy_img:
+
+ stdcall DestroyImage, edi
+
+.create_new:
+ mov eax, [esi+TWindow.__pChildren]
+ test eax, eax
+ jz .imageok
+ cmp [eax+TArray.count], 0
+ je .imageok
+
+ stdcall CreateImage, ecx, edx
+
+ mov [esi+TWindow._screen], eax
+
+ xor eax, eax
+ mov [esi+TWindow._invalid_rect.left], eax
+ mov [esi+TWindow._invalid_rect.top], eax
+ mov [esi+TWindow._invalid_rect.right], ecx
+ mov [esi+TWindow._invalid_rect.bottom], edx
+
+.imageok:
+ popad
+ return
+endp
+
+
+
+
+
+
+; System events methods
+
+
+
+
+method TWindow.EventResize ;, .newWidth, .newHeight
+begin
+ pushad
+ mov esi, [.self]
+
+ mov eax, [.newWidth]
+ mov ecx, [.newHeight]
+
+ cmp eax, [esi+TWindow._width]
+ jne .update
+
+ cmp ecx, [esi+TWindow._height]
+ je .finish
+
+.update:
mov [esi+TWindow._width], eax
mov [esi+TWindow._height], ecx
- exec esi, TWindow:AlignChildren
- jmp .finish
-
-;.........................................................................................
-
-.mouse_btnpress:
- exec esi, TWindow:Focus
-
- get ecx, esi, TWindow:SplitGrid
- test ecx, ecx
- jz .finish
-
- cmp [ebx+TMouseButtonEvent.Button], mbLeft
- jne .finish
-
- lea eax, [ebx+TMouseButtonEvent.x]
- stdcall FindSplitter, ecx, eax
- jnc .finish
-
- test [eax+TSplitRect.type], stJustGap
- jnz .finish
-
- mov [esi+TWindow._dragSplitter], eax
-
- stdcall MouseCapture, [esi+TWindow.handle]
- jmp .finish
-
-;.........................................................................................
-.mousemove:
- cmp [esi+TWindow._dragSplitter], 0
- je .set_mouse_cursor
-
- mov edi, [esi+TWindow._dragSplitter] ; splitter to resize
-
- mov ecx, [edi+TSplitRect.type]
- and ecx, stVert
- mov eax, [ebx+TMouseMoveEvent.x+ecx] ; the respective coordinate.
-
- sub eax, [edi+TSplitRect.rect.left+ecx]
-
- test [edi+TSplitRect.type], stOriginBR
- jz .sizeok
-
- mov edx, [edi+TSplitRect.rect.right+ecx]
- sub eax, edx
- neg eax
-
- sub eax, [edi+TSplitRect.spWidth]
-
-.sizeok:
- test [edi+TSplitRect.type], stRelative
- jz .posok
-
- cdq
- mov ebx, $8000
- imul ebx
-
- mov ebx, [edi+TSplitRect.rect.right+ecx]
- sub ebx, [edi+TSplitRect.rect.left+ecx] ; size of rect (x or y depending on type)
-
- idiv ebx
-
-.posok:
- cmp eax, [edi+TSplitRect.min]
- jge @f
- mov eax, [edi+TSplitRect.min]
-@@:
- cmp [edi+TSplitRect.max], 0
- je @f
-
- cmp eax, [edi+TSplitRect.max]
- jle @f
- mov eax, [edi+TSplitRect.max]
-@@:
- mov edx, $8000 ;==100%
-
- test [edi+TSplitRect.type], stRelative
- jnz @f
-
- mov edx, [edi+TSplitRect.rect.right+ecx]
- sub edx, [edi+TSplitRect.rect.left+ecx]
- sub edx, [edi+TSplitRect.spWidth]
-
-@@:
- cmp eax, edx
- jle @f
- mov eax, edx
-@@:
- mov [edi+TSplitRect.pos], eax
- stdcall RealignGrid, edi, edi
-
-; In order to avoid flicker, [.hwnd] must have WS_CLIPCHILDREN set.
-
- exec esi, TWindow:Refresh
- jmp .finish
-
-.set_mouse_cursor:
- mov ecx, [esi+TWindow._cursor]
-
- get edx, esi, TWindow:SplitGrid
- test edx, edx
- jz .cursor_ok
-
- lea eax, [ebx+TMouseMoveEvent.x]
- stdcall FindSplitter, edx, eax
- jnc .cursor_ok
-
- test [eax+TSplitRect.type], stJustGap
- jnz .finish
-
- mov ecx, mcSizeH
- test [eax+TSplitRect.type], stVert
- jz .cursor_ok
- mov ecx, mcSizeV
-
-.cursor_ok:
- stdcall GetStockCursor, ecx
- stdcall SetMouseCursor, eax
- jmp .finish
-
-;.........................................................................................
-
-.mouse_btnrelease:
- cmp [esi+TWindow._dragSplitter], 0
+ exec esi, TWindow:Paint
+
+.finish:
+ popad
+ return
+endp
+
+
+
+
+method TWindow.EventMove ;, .newX, .newY
+begin
+ push esi
+ mov esi, [.self]
+
+ push [.newX] [.newY]
+ pop [esi+TWindow._y] [esi+TWindow._x]
+
+ pop esi
+ return
+endp
+
+
+
+
+method TWindow.EventMouseEnter
+begin
+ push esi edx
+
+ mov esi, [.self]
+ get edx, esi, TWindow:OSWindow
+
+ stdcall GetStockCursor, [esi+TWindow._cursor]
+ stdcall SetMouseCursor, [edx+TWindow.handle], eax
+
+ pop edx esi
+ return
+endp
+
+
+
+
+method TWindow.EventMouseLeave
+begin
+
+ return
+endp
+
+
+
+
+method TWindow.EventMouseMove ;, .x, .y, .kbdState
+begin
+
+ return
+endp
+
+
+
+
+method TWindow.EventButtonPress ;, .button, .kbdState, .x, .y
+begin
+
+ return
+endp
+
+
+
+method TWindow.EventButtonRelease ;, .button, .kbdState, .x, .y
+begin
+
+ return
+endp
+
+
+
+
+method TWindow.EventScroll ;, .direction, .command, .value
+begin
+ mov eax, [.self]
+ cmp [eax+TWindow._OnScroll], 0
+ je .finish
+
+ pushad
+ stdcall [eax+TWindow._OnScroll], [.self], [.direction], [.command], [.value]
+ popad
+
+.finish:
+ return
+endp
+
+
+
+
+method TWindow.CloseRequest ;, .reason
+begin
+
+ return
+endp
+
+
+
+
+method TWindow.EventKeyPress ;, .utf8, .scancode, .kbdState
+begin
+ mov eax, [.self]
+ cmp [eax+TWindow._OnKeyPressed], 0
je .finish
- cmp [ebx+TMouseButtonEvent.Button], mbLeft
- jne .finish
-
- stdcall MouseCapture, NULL
- mov [esi+TWindow._dragSplitter], 0
- jmp .finish
-
-;.........................................................................................
-
-.mouseenter:
- mov eax, [esi+TWindow._cursor]
- test eax, $ffffff00
- jnz @f
- stdcall GetStockCursor, eax
-@@:
- stdcall SetMouseCursor, eax
- jmp .finish
-
-;.........................................................................................
-.mouseleave:
- stdcall GetStockCursor, mcArrow
- stdcall SetMouseCursor, eax
- jmp .finish
-
+ pushad
+ stdcall [eax+TWindow._OnKeyPressed], [.self], [.utf8], [.scancode], [.kbdState]
+ popad
+
+.finish:
+ return
+endp
+
+
+
+method TWindow.EventKeyRelease ;, .kbdState
+begin
+
+ return
+endp
+
+
+
+method TWindow.EventFocusIn
+begin
+ exec [.self], TWindow:Refresh
+ return
+endp
+
+
+
+method TWindow.EventFocusOut
+begin
+ exec [.self], TWindow:Refresh
+ return
+endp
+
+
+
+
+; Utility procedures.
+
+
+method TWindow.ClientToScreenXY; , .window, .x, .y
+begin
+ push eax esi
+
+ mov ecx, [.x]
+ mov edx, [.y]
+ mov esi, [.self]
+
+.loop:
+ get eax, esi, TWindow:Parent
+ test eax, eax
+ jz .os_win
+
+ add ecx, [esi+TWindow._x]
+ add edx, [esi+TWindow._y]
+
+ mov esi, eax
+ jmp .loop
+
+.os_win:
+ mov eax, [esi+TWindow.handle]
+ test eax, eax
+ jz .finish
+
+
+ stdcall _ClientToScreen, eax, ecx, edx
+
+.finish:
+ pop esi eax
+ return
+endp
+
+
+
+method TWindow.UpdateAction
+begin
+ exec [.self], TWindow:Refresh
+ return
endp
endmodule
DELETED freshlib/gui/ThemeGUI.asm
Index: freshlib/gui/ThemeGUI.asm
==================================================================
--- freshlib/gui/ThemeGUI.asm
+++ /dev/null
@@ -1,200 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "BSD 2-clause" license." |
-;|_______________________________________________________________________________________|
-;
-; Description: This file contains procedures and data, that form the appearance of the
-; FreshLib GUI application. Colors, control borders, backgrownd drawing etc.
-;
-; Target OS: Any
-;
-; Dependencies:
-;
-; Notes: The user should be able to change these settings and if he uses external
-; procedures, then the code from this library should not be compiled.
-;_________________________________________________________________________________________
-module "GUI theme data and code library"
-
-; Box border type
-bxNone = 0
-bxRaised = 1
-bxSunken = 2
-bxFlat = 3
-bxNoFill = $80000000
-
-; Default colors
-iglobal
- var clBorderLight = $ffffffff
- var clBorderDark = $ff606060 ; soft shadow
- var clBorderNeutral = $ffa0a0a8
-
-; edit colors
- var clEditBk = $fffffff0
- var clEditTxt = $ff000000
- var clEditSel = $ff0000a0
- var clEditSelTxt = $ffffffff
-
-; button colors
- var clButtonBk = $ffd0d0d8
- var clButtonTxt = $ff000000
-
- var clButtonHotBk = $ffe0e0e8
- var clButtonHotTxt = $ff0000ff
-
-; dialog box colors.
- var clDialogBk = $ffd0d0d8
- var clDialogTxt = $ff000000
-
-; scrollbar colors
- var clScrollBk = $ffa0a0a0
- var clScrollSlider = $ffd0d0d8
-
-; splitter colors
- var clSplitter = $ff80a0a0
-
-; grid colors.
- var clGridCellBk = $ffffffff ; normal data cell background
- var clGridCellText = $ff000000 ; normal cell text color
-
- var clGridSelBk = $ff000080 ; selected cell background
- var clGridSelText = $ffffffff ; selected cell text color
-
- var clGridFixedBk = $ffd0d0d8 ; fixed cell background
- var clGridFixedText = $ff000000 ; fixed cell text color
-
- var clGridLines = $ff000000
-
- var clGridMarked = $ff0000a0 ; background for the cells that are selected in the moment.
-
-; drawing functions.
-
- if ~defined DrawBox | defined ___DrawBox
- var DrawBox = DrawBoxDefault
- ___DrawBox = 1
- end if
-
- if ~defined DrawSlider | defined ___DrawSlider
- var DrawSlider = DrawSliderDefault
- ___DrawSlider = 1
- end if
-
- if ~defined DrawSplitter | defined ___DrawSplitter
- var DrawSplitter = DrawSplitterDefault2
- ___DrawSplitter = 1
- end if
-
-
-endg
-
-
-
-
-
-; Midnight colors
-;iglobal
-; var clBorderLight = $0000ff
-; var clBorderDark = $000000
-; var clBorderNeutral = $808080
-;
-; var clEditBk = $0000c0
-; var clEditTxt = $ffffff
-; var clEditSel = $0000ff
-; var clEditSelTxt = $000000
-;
-; var clButtonBk = $000080
-; var clButtonTxt = $ffffff
-;
-; var clButtonHotBk = $0000a0
-; var clButtonHotTxt = $ffffff
-;
-; var clDialogBk = $000080
-; var clDialogTxt = $ffffff
-;endg
-
-
-
-
-proc DrawBoxDefault, .context, .pBounds, .bkground, .border
- .brd RECT
-begin
- push eax ecx edx esi
-
-
- stdcall SetDrawMode, [.context], cmCopy
-
- mov esi, [.pBounds]
-
- mov edx, [.border]
- and edx, $ff
- jz .borderok
-
- mov eax, [esi+TBounds.x]
- mov ecx, [esi+TBounds.y]
- mov [.brd.left], eax
- mov [.brd.top], ecx
-
- add eax, [esi+TBounds.width]
- add ecx, [esi+TBounds.height]
- dec eax
- dec ecx
- mov [.brd.right], eax
- mov [.brd.bottom], ecx
-
- sub [esi+TBounds.width], 2
- sub [esi+TBounds.height], 2
- inc [esi+TBounds.x]
- inc [esi+TBounds.y]
-
- mov eax, [clBorderLight]
- mov ecx, [clBorderDark]
-
- cmp edx, bxRaised
- je .colorok
-
- xchg eax, ecx
-
- cmp edx, bxSunken
- je .colorok
-
- mov eax, [clBorderNeutral]
- mov ecx, eax
-
-.colorok:
- stdcall SetSimpleLine, [.context], eax
- stdcall DrawLine, [.context], [.brd.left], [.brd.top], [.brd.left], [.brd.bottom]
- stdcall DrawLine, [.context], [.brd.left], [.brd.top], [.brd.right], [.brd.top]
-
- stdcall SetSimpleLine, [.context], ecx
- stdcall DrawLine, [.context], [.brd.left], [.brd.bottom], [.brd.right], [.brd.bottom]
- inc [.brd.bottom]
- stdcall DrawLine, [.context], [.brd.right], [.brd.top], [.brd.right], [.brd.bottom]
-
-.borderok:
- bt [.border], 31
- jc .fillok
- stdcall DrawFillRect, [.context], [esi+TBounds.x], [esi+TBounds.y], [esi+TBounds.width], [esi+TBounds.height], [.bkground]
-
-; additional 1px margin
- sub [esi+TBounds.width], 2
- sub [esi+TBounds.height], 2
- inc [esi+TBounds.x]
- inc [esi+TBounds.y]
-
-.fillok:
- pop esi edx ecx eax
- return
-endp
-
-
-sliderHorizontal = 0
-sliderVertical = 1
-
-proc DrawSliderDefault, .context, .pBounds, .bkground, .type
-begin
- stdcall [DrawBox], [.context], [.pBounds], [.bkground], bxRaised
- return
-endp
-
-
-
-endmodule
Index: freshlib/gui/Win32/Main.asm
==================================================================
--- freshlib/gui/Win32/Main.asm
+++ freshlib/gui/Win32/Main.asm
@@ -10,51 +10,100 @@
; Dependencies:
;
; Notes: Organize the main message/event loop needed by every GUI engine.
;_________________________________________________________________________________________
-proc ProcessSystemEvents
+
+
+
+
+body ProcessSystemEvents
.msg MSG
+.msg2 MSG
begin
- push ecx edx esi
+ push ecx edx esi edi
.msgloop:
lea esi, [.msg]
xor eax, eax
invoke PeekMessageW, esi, eax, eax, eax, PM_REMOVE
test eax, eax
jz .exitok
- cmp [.msg.message], WM_TIMER
- je .translate ; express dispatching of the timer messages.
-
cmp [.msg.message], WM_QUIT
je .terminate
- stdcall __ProcessOneSystemEvent, [esi+MSG.hwnd], [esi+MSG.message], [esi+MSG.wParam], [esi+MSG.lParam]
- jnc .msgloop ; the message is translated to system event and the event is executed by the object SysEvent handler.
+ cmp [.msg.message], WM_TIMER
+ jne .timer_ok
-; the message is for window that is not an FreshLib object, so process with standard windows behaviour.
+ xor eax, eax
+ stdcall __TimerProc, eax, eax, eax, eax
+ jmp .msgloop
+
+.timer_ok:
+ cmp [.msg.message], WM_MOUSEMOVE
+ jne .move_ok
+
+.loop:
+ invoke PeekMessageW, esi, [.msg.hwnd], WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE
+ test eax, eax
+ jnz .loop
+ jmp .processit
+
+
+.move_ok:
+ cmp [.msg.message], WM_KEYDOWN
+ jne .processit
+
+; cleaning the message queue from the keyboard autorepeat messages.
+
+ lea edi, [.msg2]
+
+.loop2:
+ invoke PeekMessageW, edi, [.msg.hwnd], WM_KEYDOWN, WM_KEYDOWN, PM_NOREMOVE
+ test eax, eax
+ jz .processit
+
+ mov eax, [.msg2.wParam]
+ mov ecx, [.msg2.lParam]
+
+ cmp eax, [.msg.wParam]
+ jne .processit
+
+ cmp ecx, [.msg.lParam]
+ jne .processit
+
+ invoke PeekMessageW, edi, [.msg.hwnd], WM_KEYDOWN, WM_KEYDOWN, PM_REMOVE
+ jmp .loop2
+
+
+.processit:
+ stdcall __ProcessOneSystemEvent, [.msg.hwnd], [.msg.message], [.msg.wParam], [.msg.lParam]
+ jnc .msgloop
+
+ invoke DefWindowProcW, [.msg.hwnd], [.msg.message], [.msg.wParam], [.msg.lParam]
+
; invoke TranslateMessage, esi
-.translate:
- invoke DispatchMessageW, esi
+; invoke DispatchMessageW, esi
+
jmp .msgloop
.exitok:
clc
- pop esi edx ecx
+ pop edi esi edx ecx
return
.terminate:
mov eax, [.msg.wParam]
stc
- pop esi edx ecx
+ pop edi esi edx ecx
return
endp
+
proc WaitForSystemEvent
begin
@@ -65,107 +114,105 @@
endp
-;proc EventsQueued, .pWin
-;.msg MSG
-;begin
-; push eax ecx edx
-; mov eax, [.pWin]
-; mov ecx, [eax+TWindow.handle]
-; lea eax, [.msg]
-; invoke PeekMessage, eax, ecx, 0, 0, PM_NOREMOVE
-; test eax, eax
-; clc
-; jz @f
-; stc
-;@@:
-; pop edx ecx eax
-; return
-;endp
-;
-
;----------------------------------------------------------------------------------------------------------
; This procedure makes following:
; 1. Takes as arguments one windows message
-; 2. Converts this message to FreshLib system event (or not, depending on the message)
-; 3. Calls SysEventHandler procedures for the given object (if any) with the created event structure.
+; 2. Analizes the message and finds the target child window for it (only top level windows receive messages)
+; 3. Calls the respective event handling method of the target window object.
; 4. returns CF=0 if the event was properly processed.
; 5. returns CF=1 if the event was not processed.
;
; The event can be not processed in the following cases:
; 1. The window that receives the message is not FreshLib object.
-; 2. TObjectClass.procSysEventHandler = 0 for the given class and all parents.
-; 3. All procSysEventHandler procedures refuse to process the event (CF=1)
+; 2. The respective event handler refuse to process the event (return CF=1)
;----------------------------------------------------------------------------------------------------------
-uglobal
- if used __LatestPointedObj
- __LatestPointedObj dd ?
- end if
-endg
-
proc __ProcessOneSystemEvent, .hwnd, .wmsg, .wparam, .lparam
-.event rb 32
begin
pushad
stdcall _GetWindowStruct, [.hwnd]
test eax, eax
- jz .not_processed
+ jz .ondefault
mov esi, eax
- lea edi, [.event]
dispatch [.wmsg]
.ondefault:
- invoke DefWindowProcW, [.hwnd], [.wmsg], [.wparam], [.lparam]
+ popad
+ stc
+ return
-.finish:
+
+.ret_null:
+ xor eax, eax
+
+.processed:
mov [esp+4*regEAX], eax
popad
clc
return
-.not_processed:
- popad
- stc
- return
-
;.........................................................................................
-.exec_event:
- exec esi, TWindow:SysEventHandler, edi
- jc .ondefault
- jmp .finish
+oncase WM_ACTIVATE
+oncase WM_CANCELMODE
+
+ cmp [__ActiveMenu], 0
+ je .ondefault
+
+.hideall:
+ set [__ActiveMenu], TWindow:Visible, FALSE
+ cmp [__ActiveMenu], 0
+ jne .hideall
+
+ jmp .ret_null
;.........................................................................................
oncase WM_MOUSEWHEEL
-
- mov eax, [.wparam]
- sar eax, 16
- mov ecx, scWheelUp
- test eax, eax
- jns @f
- mov ecx, scWheelDn
- neg eax
+locals
+ .point POINT
+endl
+ movsx ecx, word [.lparam]
+ movsx edx, word [.lparam+2]
+ mov [.point.x], ecx
+ mov [.point.y], edx
+
+ lea eax, [.point]
+ invoke ScreenToClient, [.hwnd], eax
+
+ mov ecx, [.point.y]
+ shl ecx, 16
+ mov cx, word [.point.x]
+
+ mov [.lparam], ecx
+
+ movsx ecx, word [.lparam]
+ movsx edx, word [.lparam+2]
+ call .get_mouse_target
+
+ mov eax, [.wparam]
+ sar eax, 16
+ mov ecx, scWheelUp
+ test eax, eax
+ jns @f
+ mov ecx, scWheelDn
+ neg eax
@@:
- mov [edi+TScrollEvent.event], seScroll
- mov [edi+TScrollEvent.ScrollBar], scrollY
- mov [edi+TScrollEvent.ScrollCmd], ecx
-
- xor edx, edx
- mov ecx, 120
- idiv ecx
- mov [edi+TScrollEvent.Value], eax
-
- jmp .exec_event
+ mov ebx, 120
+ cdq
+ div ebx
+
+ exec edi, TWindow:EventScroll, scrollY, ecx, eax
+ jmp .ret_null
;.........................................................................................
oncase WM_WINDOWPOSCHANGED
@@ -175,87 +222,70 @@
mov ebx, [.lparam]
test [ebx+WINDOWPOS.flags], SWP_NOMOVE
jnz .move_ok
- mov eax, [ebx+WINDOWPOS.x]
- mov ecx, [ebx+WINDOWPOS.y]
- mov [edi+TMoveEvent.newX], eax
- mov [edi+TMoveEvent.newY], ecx
-
- mov [edi+TMoveEvent.event], seMove
-
- exec esi, TWindow:SysEventHandler, edi
+ exec esi, TWindow:EventMove, [ebx+WINDOWPOS.x], [ebx+WINDOWPOS.y]
.move_ok:
test [ebx+WINDOWPOS.flags], SWP_NOSIZE
- jnz .not_processed
+ jnz .ret_null
lea eax, [.rect]
- invoke GetClientRect, [.hwnd], eax
-
- mov eax, [.rect.right]
- mov ecx, [.rect.bottom]
- mov [edi+TResizeEvent.newWidth], eax
- mov [edi+TResizeEvent.newHeight], ecx
- mov [edi+TResizeEvent.event], seResize
-
- jmp .exec_event
+ invoke GetClientRect, [esi+TWindow.handle], eax
+
+ exec esi, TWindow:EventResize, [.rect.right], [.rect.bottom]
+ jmp .ret_null
;.........................................................................................
oncase WM_SYSKEYDOWN
oncase WM_SYSKEYUP
oncase WM_KEYDOWN
oncase WM_KEYUP
+
locals
.keyboard rb 256
- .unicode rw 16
- .utf8 rb 16
+ .unicode rw 16
+ .utf8buff rb 16
+ .scancode dd ?
endl
+
lea ebx, [.keyboard]
invoke GetKeyboardState, ebx
+
mov eax, [.lparam]
mov ecx, eax
shr eax, 16
and ecx, $80000000
and eax, $ff
- mov [edi+TKeyboardEvent.scancode], eax
+ mov [.scancode], eax
+
+ mov dword [.utf8buff], 0
+
or eax, ecx
lea edx, [.unicode]
invoke ToUnicode, [.wparam], eax, ebx, edx, 16, 0
xor ecx, ecx
test eax, eax
jz .key_translated ; the key can not be translated.
js .key_translated ; it is a dead key. What we have to do???
- lea edx, [.utf8]
+ lea edx, [.utf8buff]
xor ecx, ecx
mov [edx], ecx
mov [edx+4], ecx
lea ecx, [.unicode]
invoke WideCharToMultiByte, CP_UTF8, 0, ecx, eax, edx, 8, 0, 0
- xor ecx, ecx
- test eax, eax
- jz .key_translated
-
- mov ecx, dword [.utf8]
.key_translated:
- mov [edi+TKeyboardEvent.key], ecx
-
- mov ecx, seKbdKeyPress
- cmp [.wmsg], WM_KEYDOWN
- je @f
- cmp [.wmsg], WM_SYSKEYDOWN
- je @f
- mov ecx, seKbdKeyRelease
-@@:
- mov [edi+TKeyboardEvent.event], ecx
-
xor eax, eax
+
+ cmp [__FocusedWindow], eax
+ jz .ondefault
+
test [.keyboard+VK_CONTROL], $80
jz @f
or eax, maskCtrl
@@:
test [.keyboard+VK_SHIFT], $80
@@ -272,229 +302,272 @@
@@:
test [.keyboard+VK_CAPITAL], $01
jz @f
or eax, maskCapsLock
@@:
+ test [.keyboard+VK_LBUTTON], $80
+ jz @f
+ or eax, maskBtnLeft
+@@:
+ test [.keyboard+VK_RBUTTON], $80
+ jz @f
+ or eax, maskBtnRight
+@@:
+ test [.keyboard+VK_MBUTTON], $80
+ jz @f
+ or eax, maskBtnMiddle
+@@:
-; or eax, [__MouseButtonMask]
-; OutputRegister regEAX, 16
+ cmp [.wmsg], WM_KEYUP
+ je .key_up
+ cmp [.wmsg], WM_SYSKEYUP
+ je .key_up
- mov [edi+TKeyboardEvent.kbdStatus], eax
- jmp .exec_event
+;.key_down:
+ exec [__FocusedWindow], TWindow:EventKeyPress, dword [.utf8buff], [.scancode], eax
+ jmp .end_key_msg
+
+.key_up:
+ exec [__FocusedWindow], TWindow:EventKeyRelease, [.scancode], eax
+
+.end_key_msg:
+ cmp [.wmsg], WM_SYSKEYDOWN
+ je .ondefault
+
+ cmp [.wmsg], WM_SYSKEYUP
+ je .ondefault
+
+ jmp .ret_null
;.........................................................................................
oncase WM_SETFOCUS
- mov [edi+TFocusInEvent.event], seFocusIn
- jmp .exec_event
+
+ stdcall __SearchWindowToFocus, esi
+
+ mov [__FocusedWindow], eax
+
+ test eax, eax
+ jz .ret_null
+
+ exec eax, TWindow:EventFocusIn
+ jmp .ret_null
;.........................................................................................
oncase WM_KILLFOCUS
- mov [edi+TFocusOutEvent.event], seFocusOut
- jmp .exec_event
-
-
-;.........................................................................................
-
-
-oncase WM_SETCURSOR
-
- movzx eax, word [.lparam]
- cmp eax, HTCLIENT
- jne .ondefault
-
- mov eax, [esi+TWindow._cursor]
- test eax, $ffffff00
- jnz .customcursor
-
- stdcall GetStockCursor, eax
-
-.customcursor:
- stdcall SetMouseCursor, eax
- jmp .finish
-
+
+ xor ebx, ebx
+ xchg [__FocusedWindow], ebx
+ test ebx, ebx
+ jz .ret_null
+
+ exec ebx, TWindow:EventFocusOut
+ jmp .ret_null
;.........................................................................................
oncase WM_MOUSEMOVE
- cmp esi, [__LatestPointedObj]
- je .normal_mouse_move
-
- mov [edi+TMouseEnterEvent.event], seMouseLeave
- xchg esi, [__LatestPointedObj]
- test esi, esi
- jz .leaveok
-
- exec esi, TWindow:SysEventHandler, edi
-
-.leaveok:
- mov esi, [__LatestPointedObj]
- mov [edi+TMouseEnterEvent.event], seMouseEnter
-
- exec esi, TWindow:SysEventHandler, edi
-
-.normal_mouse_move:
- mov [edi+TMouseMoveEvent.event], seMouseMove
- movsx eax, word [.lparam]
- movsx ecx, word [.lparam+2]
- mov [edi+TMouseMoveEvent.x], eax
- mov [edi+TMouseMoveEvent.y], ecx
- jmp .exec_event
-
+
+ movsx ecx, word [.lparam]
+ movsx edx, word [.lparam+2]
+
+ stdcall ServeMenuMouseMove, [.hwnd], ecx, edx, 0
+ jc .ret_null
+
+ call .get_mouse_target
+
+ get eax, edi, TWindow:Enabled
+ test eax, eax
+ jz .ret_null
+
+ cmp edi, [__LastPointedWindow]
+ je .move_event
+
+ cmp [__LastPointedWindow], 0
+ je .leave_ok
+
+ exec [__LastPointedWindow], TWindow:EventMouseLeave
+
+.leave_ok:
+
+ mov [__LastPointedWindow], edi
+ exec edi, TWindow:EventMouseEnter
+
+.move_event:
+
+ exec edi, TWindow:EventMouseMove, ecx, edx, 0
+ jmp .ret_null
;.........................................................................................
+
oncase WM_PAINT
+
locals
- .ps PAINTSTRUCT
- .context TContext
- .caret dd ?
- .rect2 RECT
+ .ps PAINTSTRUCT
+ .hdc dd ?
endl
- lea eax, [.rect2]
- invoke GetUpdateRect, [.hwnd], eax, FALSE
- test eax, eax
- jz .endpaint
+ get edi, esi, TWindow:ImgScreen
lea eax, [.ps]
invoke BeginPaint, [.hwnd], eax
-
-if defined Caret
- mov [.caret], -1
- cmp esi, [Caret.pWindow]
- jne @f
-
- stdcall CaretShow, FALSE
- mov [.caret], eax
-@@:
-end if
-
- mov [edi+TPaintEvent.event], sePaint
- push [.ps.hdc]
- pop [.context.handle]
- push [.hwnd]
- pop [.context.raster]
-
- lea eax, [.context]
- mov [edi+TPaintEvent.context], eax
-
-; ?????????????????????????????
-; push [.ps.rcPaint.left] [.ps.rcPaint.top]
- push [.rect2.left] [.rect2.top]
- pop [edi+TPaintEvent.rect.top] [edi+TPaintEvent.rect.left]
-; push [.ps.rcPaint.right] [.ps.rcPaint.bottom]
- push [.rect2.right] [.rect2.bottom]
- pop [edi+TPaintEvent.rect.bottom] [edi+TPaintEvent.rect.right]
-
- exec esi, TWindow:SysEventHandler, edi
+ mov [.hdc], eax
+
+ mov ecx, [.ps.rcPaint.right]
+ mov edx, [.ps.rcPaint.bottom]
+ sub ecx, [.ps.rcPaint.left]
+ sub edx, [.ps.rcPaint.top]
+
+ stdcall DrawImageRect, [.hdc], edi, [.ps.rcPaint.left], [.ps.rcPaint.top], [.ps.rcPaint.left], [.ps.rcPaint.top], ecx, edx
lea eax, [.ps]
invoke EndPaint, [.hwnd], eax
-if defined Caret
- cmp [.caret], -1
- je @f
- stdcall CaretShow, [.caret]
-@@:
-end if
-
-.endpaint:
- pop edi esi edx ecx ebx eax
- clc
- return
+ jmp .ret_null
;.........................................................................................
oncase WM_CLOSE
+
+ DebugMsg "Close request."
get eax, [pApplication], TApplication:MainWindow
test eax, eax
jz @f
+
cmp [eax], esi
jne @f
DebugMsg "Quit message posted."
invoke PostQuitMessage, 0
@@:
- mov [edi+TCloseEvent.event], seCloseRequest
- mov [edi+TCloseEvent.reason], cerFromUser
- jmp .exec_event
+ exec esi, TWindow:CloseRequest, cerFromUser
+ jmp .ret_null
+
oncase WM_DESTROY
- cmp esi, [__LatestPointedObj]
- jne .ondefault
-
- mov [__LatestPointedObj], 0
+ mov [esi+TWindow.handle], 0
jmp .ondefault
;.........................................................................................
oncase WM_LBUTTONUP
oncase WM_RBUTTONUP
oncase WM_MBUTTONUP
+ movsx ecx, word [.lparam]
+ movsx edx, word [.lparam+2]
+ call .get_mouse_target
+
+ get eax, edi, TWindow:Enabled
+ test eax, eax
+ jz .ret_null
+
+ mov ebx, [.wmsg]
+ sub ebx, WM_LBUTTONDOWN
+ movzx ebx, byte [.__mouse_button_table+ebx]
+
+ stdcall __KeyStatus, [.wparam]
+
+ exec edi, TWindow:EventButtonRelease, ebx, eax, ecx, edx
+ jmp .ret_null
+
+
oncase WM_LBUTTONDOWN
oncase WM_RBUTTONDOWN
oncase WM_MBUTTONDOWN
-oncase WM_LBUTTONDBLCLK
-oncase WM_RBUTTONDBLCLK
-oncase WM_MBUTTONDBLCLK
+
+locals
+ .kbdState dd ?
+endl
+
+ movsx ecx, word [.lparam]
+ movsx edx, word [.lparam+2]
- stdcall __MouseButton, [.wmsg]
- mov [edi+TMouseButtonEvent.event], ecx
- mov [edi+TMouseButtonEvent.Button], eax
+ mov ebx, [.wmsg]
+ sub ebx, WM_LBUTTONDOWN
+ movzx ebx, byte [.__mouse_button_table+ebx]
+
stdcall __KeyStatus, [.wparam]
- mov [edi+TMouseButtonEvent.kbdStatus], eax
-
- movsx eax, word [.lparam]
- movsx ecx, word [.lparam+2]
- mov [edi+TMouseButtonEvent.x], eax
- mov [edi+TMouseButtonEvent.y], ecx
-
-
- jmp .exec_event
+ mov [.kbdState], eax
+
+ stdcall ServeMenuButtonPress, [.hwnd], ebx, eax, ecx, edx
+ jc .ret_null
+
+ call .get_mouse_target
+
+ get eax, edi, TWindow:Enabled
+ test eax, eax
+ jz .ret_null
+
+; deal with focus
+
+ cmp edi, [__FocusedWindow]
+ je .focusok
+
+ get eax, edi, TWindow:WantFocus
+ test eax, eax
+ jz .focusok
+
+ mov eax, [__FocusedWindow]
+ mov [__FocusedWindow], edi
+
+
+ test eax, eax
+ jz @f
+ exec eax, TWindow:EventFocusOut
+@@:
+
+ exec edi, TWindow:EventFocusIn
+
+.focusok:
+ exec edi, TWindow:EventButtonPress, ebx, [.kbdState], ecx, edx
+ jmp .ret_null
+
+
+; Double clicks are not supported for now...
+
+;oncase WM_LBUTTONDBLCLK
+;oncase WM_RBUTTONDBLCLK
+;oncase WM_MBUTTONDBLCLK
+
enddispatch
-endp
-
-
-
-proc __MouseButton, .msg
-begin
- mov eax, [.msg]
- sub eax, WM_LBUTTONDOWN
- movzx ecx, byte [__mouse_event_table+eax]
- movzx eax, byte [__mouse_button_table+eax]
- return
-endp
-
-
-iglobal
- if used __mouse_button_table
- __mouse_button_table db mbLeft, mbLeft, mbLeft
- db mbRight, mbRight, mbRight
- db mbMiddle, mbMiddle, mbMiddle
- end if
-
- if used __mouse_event_table
- __mouse_event_table db seMouseBtnPress, seMouseBtnRelease, seMouseBtnDblClick
- db seMouseBtnPress, seMouseBtnRelease, seMouseBtnDblClick
- db seMouseBtnPress, seMouseBtnRelease, seMouseBtnDblClick
- end if
-endg
+
+
+.get_mouse_target:
+ mov edi, [__MouseTarget]
+ test edi, edi
+ jz .search_target_move
+
+ stdcall __GetRelativeXY, edi, ecx, edx
+ jmp .target_move
+
+.search_target_move:
+ exec esi, TWindow:ChildByXY, ecx, edx, FALSE
+ mov edi, eax
+
+.target_move:
+ retn
+
+
+ .__mouse_button_table db mbLeft, mbLeft, mbLeft
+ db mbRight, mbRight, mbRight
+ db mbMiddle, mbMiddle, mbMiddle
+endp
;.........................................................................................
@@ -514,13 +587,14 @@
jz @f
or eax, maskBtnMiddle
@@:
test [.status], MK_SHIFT
jz @f
- or eax, maskCtrl
+ or eax, maskShift
@@:
test [.status], MK_CONTROL
jz @f
or eax, maskCtrl
@@:
return
-endp
+endp
+
Index: freshlib/gui/Win32/TApplication.asm
==================================================================
--- freshlib/gui/Win32/TApplication.asm
+++ freshlib/gui/Win32/TApplication.asm
@@ -18,18 +18,15 @@
hInstance dd ?
end if
endg
-method TApplication.Create
+method TApplication.__create
begin
- push eax ecx edx
invoke GetModuleHandleW, 0
mov [hInstance], eax
-
clc
- pop edx ecx eax
return
endp
Index: freshlib/gui/Win32/mouse.asm
==================================================================
--- freshlib/gui/Win32/mouse.asm
+++ freshlib/gui/Win32/mouse.asm
@@ -13,11 +13,11 @@
;_________________________________________________________________________________________
; ToDo: Arbitrary mouse cursors, B&W for the begining.
-proc SetMouseCursor, .hCursor
+proc SetMouseCursor, .hWindow, .hCursor
begin
push ecx edx
invoke SetCursor, [.hCursor]
pop edx ecx
return
@@ -27,29 +27,33 @@
proc GetStockCursor, .index
begin
push ecx edx
mov eax, [.index]
- and eax, 7
+ cmp eax, mcCount
+ jb @f
+ xor eax, eax
+@@:
movzx eax, [_cursors+2*eax]
invoke LoadCursorW, 0, eax
pop edx ecx
return
endp
if used _cursors
- _cursors dw IDC_ARROW, IDC_IBEAM, IDC_CROSS, IDC_SIZEWE, IDC_SIZENS, IDC_SIZENWSE, IDC_SIZENESW, IDC_WAIT
+ _cursors dw IDC_ARROW, IDC_IBEAM, IDC_CROSS, IDC_SIZEWE, IDC_SIZENS, IDC_SIZENWSE, IDC_SIZENESW, IDC_WAIT, IDC_HAND, IDC_HAND, IDC_ARROW
end if
-proc MouseCapture, .hwnd
+proc __MouseCapture, .hwnd
begin
push eax ecx edx
cmp [.hwnd], 0
je .release
+ DebugMsg "Mouse captured!"
invoke SetCapture, [.hwnd]
.finish:
pop edx ecx eax
return
Index: freshlib/gui/Win32/windows.asm
==================================================================
--- freshlib/gui/Win32/windows.asm
+++ freshlib/gui/Win32/windows.asm
@@ -25,11 +25,11 @@
;
; Registers common window class
; Call only once
;_________________________________________________________________________________________
-if used _CreateNullWindow
+if used _CreateWindow
initialize __RegisterWindowClass
.wc WNDCLASS
begin
@@ -36,17 +36,14 @@
xor eax, eax
lea edi, [.wc]
mov ecx, sizeof.WNDCLASS / 4
rep stosd
- mov [.wc.style], CS_OWNDC or CS_DBLCLKS or CS_VREDRAW or CS_HREDRAW
+ mov [.wc.style], CS_PARENTDC; or CS_DBLCLKS ;or CS_VREDRAW or CS_HREDRAW
mov [.wc.lpfnWndProc], __CommonWindowProc
mov [.wc.cbWndExtra], nWindowExtraBytes
-; invoke CreateSolidBrush, $0000ff
-; mov [.wc.hbrBackground], eax
-
mov eax,[hInstance]
mov [.wc.hInstance],eax
mov [.wc.lpszClassName], cWindowClassName
lea eax, [.wc]
@@ -59,24 +56,107 @@
;_________________________________________________________________________________________
-proc _CreateNullWindow
+
+body _CreateWindow
+
+.pwc dd ?
+.charlen dd ?
+
+.style dd ?
+.exstyle dd ?
+
+.rect RECT
+
begin
- push ecx edx
- xor ecx, ecx
- invoke CreateWindowExW, ecx, cWindowClassName, ecx, WS_CLIPSIBLINGS or WS_CLIPCHILDREN, ecx, ecx, ecx, ecx, ecx, ecx, ecx, ecx
- pop edx ecx
+ pushad
+ mov esi, [.pWindow]
+
+ mov [.pwc], 0
+
+ cmp [esi+TWindow._caption], 0
+ je .caption_ok
+
+ stdcall StrLen, [esi+TWindow._caption]
+ lea ecx, [eax*4]
+
+ stdcall GetMem, ecx
+ mov [.pwc], eax
+
+ stdcall StrPtr, [esi+TWindow._caption]
+
+ invoke MultiByteToWideChar, CP_UTF8, 0, eax, -1, [.pwc], ecx
+ mov [.charlen], eax
+
+.caption_ok:
+
+; now styles
+ mov eax, [esi+TWindow._border]
+ and eax, $3
+
+ mov ecx, [.styles+4*eax]
+ mov edx, [.exstyles+4*eax]
+
+ mov [.style], ecx
+ mov [.exstyle], edx
+
+; the coordinates and size
+
+ xor eax, eax
+ mov [.rect.left], eax
+ mov [.rect.top], eax
+ mov ecx, [esi+TWindow._width]
+ mov edx, [esi+TWindow._height]
+ mov [.rect.right], ecx
+ mov [.rect.bottom], edx
+
+ lea eax, [.rect]
+ invoke AdjustWindowRectEx, eax, [.style], 0, [.exstyle]
+
+ mov ecx, [.rect.right]
+ mov edx, [.rect.bottom]
+ sub ecx, [.rect.left]
+ sub edx, [.rect.top]
+
+; the owner
+ mov eax, [esi+TWindow.__main]
+ test eax, eax
+ jz .owner_ok
+
+ mov eax, [eax+TWindow.handle]
+.owner_ok:
+ invoke CreateWindowExW, [.exstyle], cWindowClassName, [.pwc], [.style], [esi+TWindow._x], [esi+TWindow._y], ecx, edx, eax, 0, [hInstance], 0
+ mov [esp+4*regEAX], eax
+
+ invoke SetWindowLongW, eax, ofsWindowStruct, esi
+
+ stdcall FreeMem, [.pwc]
+
+ popad
return
+
+
+.styles dd WS_POPUP
+ dd WS_BORDER or WS_CAPTION or WS_SYSMENU or WS_SIZEBOX or WS_MINIMIZEBOX or WS_MAXIMIZEBOX
+ dd WS_CAPTION or WS_SYSMENU
+ dd WS_BORDER or WS_CAPTION or WS_SYSMENU or WS_SIZEBOX
+
+.exstyles dd WS_EX_TOPMOST or WS_EX_TOOLWINDOW or WS_EX_NOACTIVATE
+ dd WS_EX_APPWINDOW
+ dd WS_EX_DLGMODALFRAME
+ dd WS_EX_TOOLWINDOW
endp
+
+
;_________________________________________________________________________________________
-proc _DestroyWindow, .hwnd
+body _DestroyWindow
begin
push eax ecx edx
invoke DestroyWindow, [.hwnd]
pop edx ecx eax
return
@@ -84,248 +164,110 @@
;_________________________________________________________________________________________
-proc _GetParent, .hwnd
-begin
- push ecx edx
-; invoke GetParent, [.hwnd]
- invoke GetWindowLongW, [.hwnd], GWL_HWNDPARENT
- pop edx ecx
- return
-endp
-
-;_________________________________________________________________________________________
-
-
-proc _GetChildren, .hwnd
-begin
- push ebx ecx edx
-
- xor ebx, ebx
-
- invoke GetWindow, [.hwnd], GW_CHILD
- mov ecx, eax
- jecxz .endchildren
-
- stdcall CreateArray, sizeof.TWinArrayItem
- mov ebx, eax
-
-.loophwnd:
- stdcall AddArrayItems, ebx, 1
- mov ebx, edx
-
- mov [eax+TWinArrayItem.handle], ecx
-
- invoke GetWindow, ecx, GW_HWNDNEXT
- mov ecx, eax
- jecxz .endchildren
- jmp .loophwnd
-
-.endchildren:
- mov eax, ebx
- pop edx ecx ebx
- return
-endp
-
-
-;_________________________________________________________________________________________
-
-
-
-proc _GetVisible, .hwnd
-begin
- push ecx edx
- invoke IsWindowVisible, [.hwnd]
- pop edx ecx
- return
-endp
-
-
-;_________________________________________________________________________________________
-
-
-
-proc _GetWindowBounds, .hwnd, .pBounds
-begin
- push eax ecx edx
-
- invoke GetClientRect, [.hwnd], [.pBounds]
- invoke GetParent, [.hwnd]
- invoke MapWindowPoints, [.hwnd], eax, [.pBounds], 2
-
- mov edx, [.pBounds]
- mov eax, [edx+TBounds.width]
- mov ecx, [edx+TBounds.height]
- sub eax, [edx+TBounds.x]
- sub ecx, [edx+TBounds.y]
- mov [edx+TBounds.width], eax
- mov [edx+TBounds.height], ecx
-
- pop edx ecx eax
- return
-endp
-
-
-
-;_________________________________________________________________________________________
-
-
-proc _SetWindowBounds, .hwnd, .pBounds
-.rect RECT
-begin
- push eax ecx edx
-
- mov eax, [.pBounds]
- push [eax+TBounds.width] [eax+TBounds.height]
- pop [.rect.bottom] [.rect.right]
- mov [.rect.left], 0
- mov [.rect.top], 0
-
- invoke GetWindowLongW, [.hwnd], GWL_EXSTYLE
- push eax
- push FALSE
- invoke GetWindowLongW, [.hwnd], GWL_STYLE
- push eax
-
- lea eax, [.rect]
- invoke AdjustWindowRectEx, eax ; and from the stack
-
- mov eax, [.rect.right]
- mov ecx, [.rect.bottom]
- sub eax, [.rect.left]
- sub ecx, [.rect.top]
-
- mov edx, [.pBounds]
- invoke SetWindowPos, [.hwnd], 0, [edx+TBounds.x], [edx+TBounds.y], eax, ecx, SWP_NOZORDER; or SWP_NOREDRAW
-
- pop edx ecx eax
- return
-endp
-
-
-
-
-
-;_________________________________________________________________________________________
-
-wsNoneWindowBorder = WS_POPUP
-wsFullWindowBorder = WS_BORDER or WS_CAPTION or WS_SYSMENU or WS_SIZEBOX or WS_MINIMIZEBOX or WS_MAXIMIZEBOX
-wsModalWindowBorder = WS_CAPTION or WS_SYSMENU
-wsToolboxWindowBorder = WS_BORDER or WS_CAPTION or WS_SYSMENU or WS_SIZEBOX
-
-wsAllWindowBorder = wsNoneWindowBorder or wsFullWindowBorder or wsModalWindowBorder or wsToolboxWindowBorder
-
-proc _SetWindowBorder, .hwnd, .brdType
-.bounds TBounds
-begin
- push eax ebx ecx edx esi
-
- invoke GetWindowLongW, [.hwnd], GWL_STYLE
- mov ebx, eax
-
- mov esi, [.brdType]
- and esi, 3
-
- mov ecx, [.styles+4*esi]
- mov edx, [.exstyles+4*esi]
-
- and ebx, not wsAllWindowBorder
- test ebx, WS_CHILD
- jz @f
- and ecx, not (WS_CAPTION or WS_SYSMENU or WS_SIZEBOX)
- and edx, not (WS_EX_APPWINDOW or WS_EX_DLGMODALFRAME or WS_EX_TOOLWINDOW)
-@@:
- or ebx, ecx
- invoke SetWindowLongW, [.hwnd], GWL_EXSTYLE, edx
- invoke SetWindowLongW, [.hwnd], GWL_STYLE, ebx
-
- lea esi, [.bounds]
- stdcall _GetWindowBounds, [.hwnd], esi
- stdcall _SetWindowBounds, [.hwnd], esi
-
- pop esi edx ecx ebx eax
- return
-
-.styles dd wsNoneWindowBorder
- dd wsFullWindowBorder
- dd wsModalWindowBorder
- dd wsToolboxWindowBorder
-
-.exstyles dd 0
- dd WS_EX_APPWINDOW
- dd WS_EX_DLGMODALFRAME
- dd WS_EX_TOOLWINDOW
-
-endp
-
-;_________________________________________________________________________________________
-
-proc _ShowWindow, .hwnd, .flag
-begin
- push eax ecx edx
- invoke ShowWindow, [.hwnd], [.flag]
- pop edx ecx eax
- return
-endp
-
-
-;_________________________________________________________________________________________
-
-
-proc _RefreshWindow, .hwnd
-begin
- push eax ecx edx
- xor eax, eax
- invoke InvalidateRect, [.hwnd], eax, eax
-; invoke RedrawWindow, [.hwnd], eax, eax, RDW_INVALIDATE or RDW_UPDATENOW or RDW_ERASENOW
-
- pop edx ecx eax
- return
-endp
-
-
-;_________________________________________________________________________________________
-
-
-proc _SetFocus, .hwnd
-begin
- push eax ecx edx
- invoke SetFocus, [.hwnd]
- pop edx ecx eax
- return
-endp
-
-;_________________________________________________________________________________________
-
-proc _AddChild, .hwnd, .child
-begin
- push eax ecx edx
-
- invoke GetWindowLongW, [.child], GWL_STYLE
- or eax, WS_CHILD
- and eax, not (WS_DLGFRAME or WS_BORDER)
- invoke SetWindowLongW, [.child], GWL_STYLE, eax
- invoke SetParent, [.child], [.hwnd]
-
- pop edx ecx eax
- return
-endp
-
-;_________________________________________________________________________________________
-
-
-; Common utility procedures.
+
+body _ClientToScreen
+begin
+ push eax
+
+ lea eax, [.x]
+
+ invoke ClientToScreen, [.hwnd], eax
+ mov ecx, [.x]
+ mov edx, [.y]
+ pop eax
+ return
+endp
+
+
+
+
+;_________________________________________________________________________________________
+
+
+body _ShowWindow
+begin
+ pushad
+
+ mov ebx, SW_HIDE
+ cmp [.flag], 0
+ je .com_ok
+
+ mov ebx, SW_SHOWNOACTIVATE
+
+ invoke GetWindowLongW, [.hwnd], GWL_STYLE
+ test eax, WS_POPUP
+ jnz .com_ok
+
+ mov ebx, SW_SHOWNORMAL
+
+.com_ok:
+ invoke ShowWindow, [.hwnd], ebx
+
+ popad
+ return
+endp
+
+
+;_________________________________________________________________________________________
+
+
+body _RefreshWindowRect
+;.rect RECT
+begin
+ push eax ecx edx ebx
+
+; WAY 1 - direct paint on the window surface, without sending any messages.
+
+ invoke GetDC, [.hwnd]
+ mov ebx, eax
+
+ stdcall _GetWindowStruct, [.hwnd]
+ get eax, eax, TWindow:ImgScreen
+
+ stdcall DrawImageRect, ebx, eax, [.x], [.y], [.x], [.y], [.width], [.height]
+
+ invoke ReleaseDC, [.hwnd], ebx
+
+;; Needed for WAY2 and WAY3
+;
+; mov eax, [.x]
+; mov ecx, [.y]
+; mov [.rect.left], eax
+; mov [.rect.top], ecx
+; add eax, [.width]
+; add ecx, [.height]
+; mov [.rect.right], eax
+; mov [.rect.bottom], ecx
+
+
+;; WAY2 - generates messages before returning.
+;
+; lea eax, [.rect]
+; xor ecx, ecx
+; invoke RedrawWindow, [.hwnd], eax, ecx, RDW_UPDATENOW or RDW_INVALIDATE or RDW_NOERASE
+
+;; WAY3 - returns immediately and posts messages to the queue
+
+; lea eax, [.rect]
+; xor ecx, ecx
+; invoke InvalidateRect, [.hwnd], eax, ecx
+
+ pop ebx edx ecx eax
+ return
+endp
+
;_________________________________________________________________________________________
;
; Returns the window TObject structure, from the window handle.
;_________________________________________________________________________________________
-proc _GetWindowStruct, .hwin
+body _GetWindowStruct
begin
push ecx edx
invoke GetWindowLongW, [.hwin], ofsWindowStruct
pop edx ecx
return
@@ -335,11 +277,11 @@
;_________________________________________________________________________________________
-proc _SetWindowStruct, .hwin, .value
+body _SetWindowStruct
begin
push eax ecx edx
invoke SetWindowLongW, [.hwin], ofsWindowStruct, [.value]
pop edx ecx eax
return
@@ -348,15 +290,19 @@
;_________________________________________________________________________________________
-proc _SetWindowTextUtf8, .hwnd, .ptrUtf8
+body _SetWindowTextUtf8
.pwc dd ?
.charlen dd ?
begin
push eax ecx edx
+
+ cmp [.ptrUtf8], 0
+ je .finish
+
stdcall StrLen, [.ptrUtf8]
lea ecx, [eax*4]
stdcall GetMem, ecx
mov [.pwc], eax
@@ -364,80 +310,42 @@
invoke MultiByteToWideChar, CP_UTF8, 0, [.ptrUtf8], -1, [.pwc], ecx
mov [.charlen], eax
invoke SendMessageW, [.hwnd], WM_SETTEXT, 0, [.pwc]
stdcall FreeMem, [.pwc]
+
+.finish:
pop edx ecx eax
return
endp
;_________________________________________________________________________________________
-
-proc _GetWindowTextUtf8, .hwnd, .ptrUtf8
-.pwc dd ?
-.charlen dd ?
-begin
- push ebx ecx edx edi
- stdcall StrNew
- mov ebx, eax
-
- invoke SendMessage, [.hwnd], WM_GETTEXTLENGTH, 0, 0
- mov [.charlen], eax
- lea ecx, [eax*4]
-
- stdcall StrSetCapacity, ebx, ecx
- mov edi, eax
-
- stdcall GetMem, ecx
- mov [.pwc], eax
-
- invoke SendMessage, [.hwnd], WM_GETTEXT, [.charlen], [.pwc]
- invoke WideCharToMultiByte, CP_UTF8, 0, [.pwc], -1, edi, [edi+string.capacity], 0, 0
- stdcall FreeMem, [.pwc]
- stdcall StrFixLen, ebx
- mov eax, ebx
- pop edi edx ecx ebx
- return
-endp
-
-
-
-;_________________________________________________________________________________________
-
-
-proc _EnableWindow, .hwnd, .flag
-begin
- push eax ecx edx
- invoke EnableWindow, [.hwnd], [.flag]
- pop edx ecx eax
- return
-endp
-
-
-;_________________________________________________________________________________________
-
-
-proc _SetModalTowards, .hwnd, .hwndParent
-begin
- push eax ecx edx
- stdcall _SetWindowBorder, [.hwnd], borderModal
- invoke SetWindowLongW, [.hwnd], GWL_HWNDPARENT, [.hwndParent]
+body _SetModalTowards
+begin
+ push eax ecx edx
+
+ invoke SetWindowLongW, [.hwnd], GWL_HWNDPARENT, [.hwndParent]
+ invoke EnableWindow, [.hwndParent], FALSE
pop edx ecx eax
return
endp
;_________________________________________________________________________________________
-proc _FinalizeModal, .hwnd, .hwndParent
+body _FinalizeModal
begin
+ push eax ecx edx
+ invoke EnableWindow, [.hwndParent], TRUE
+ invoke SetFocus, [.hwndParent]
+ pop edx ecx eax
return
endp
;_________________________________________________________________________________________
@@ -446,11 +354,11 @@
proc __CommonWindowProc, .hwnd, .wmsg, .wparam, .lparam
begin
stdcall __ProcessOneSystemEvent, [.hwnd], [.wmsg], [.wparam], [.lparam] ; sometimes windows calls winproc directly instead of using postmessage.
jnc .finish
-; invoke DefWindowProcW, [.hwnd], [.wmsg], [.wparam], [.lparam]
+ invoke DefWindowProcW, [.hwnd], [.wmsg], [.wparam], [.lparam]
.finish:
return
endp
Index: freshlib/gui/all.asm
==================================================================
--- freshlib/gui/all.asm
+++ freshlib/gui/all.asm
@@ -21,44 +21,50 @@
include 'mouse.asm'
include 'textcaret.asm'
; OS independent support code
-include 'realobjects.inc'
-
-;include 'TAction.asm'
; Limited support for the old visual editor. Contains only macro definitions.
;include 'OldTemplates.inc'
; OS independent components
include 'TObject.asm'
include 'TApplication.asm'
+include 'TAction.asm'
+include 'TActionList.asm'
+
include 'TWindow.asm'
-include 'TBackWindow.asm'
-include 'TScrollWindow.asm'
+include 'TScrollbar.asm'
include 'TForm.asm'
include 'TButton.asm'
+include 'TCheckbox.asm'
include 'TEdit.asm'
include 'TLabel.asm'
include 'TImageLabel.asm'
-;include 'TMenuItem.asm'
-;include 'TMenu.asm'
+include 'TMenu.asm'
include 'TProgressbar.asm'
-;include 'TTreeView.asm'
+include 'TTreeView.asm'
;include 'TGrid.asm'
include 'dialogs.asm'
-
-include 'ThemeGUI.asm'
include 'SplitGrid.asm'
; OS independent main procedures.
include 'Main.asm'
; OS independent template engine.
include 'ObjTemplates.asm'
+; Way to change the GUI themes in Runtime.
+include 'themes.asm'
+
+match theme, ThemeGUI {
+ include 'themes/'#`theme#'.asm'
+}
+
+;include 'themes/flat_gui.asm'
+;include 'themes/win_gui.asm'
Index: freshlib/gui/dialogs.asm
==================================================================
--- freshlib/gui/dialogs.asm
+++ freshlib/gui/dialogs.asm
@@ -13,31 +13,30 @@
;_________________________________________________________________________________________
module "Common dialogs library"
iglobal
- getfile _DlgIconError, '%lib%/gui/images/error.gif'
- getfile _DlgIconInformation, '%lib%/gui/images/information.gif'
- getfile _DlgIconQuestion, '%lib%/gui/images/question.gif'
- getfile _DlgIconWarning, '%lib%/gui/images/warning.gif'
- getfile _DlgMaskDialogIcons, '%lib%/gui/images/icon_mask.gif'
+ getfile _DlgIconError, '%lib%/gui/images/error.png'
+ getfile _DlgIconInformation, '%lib%/gui/images/information.png'
+ getfile _DlgIconQuestion, '%lib%/gui/images/question.png'
+ getfile _DlgIconWarning, '%lib%/gui/images/warning.png'
if used _CommonDialogTemplate
_CommonDialogTemplate:
- ObjTemplate tfParent or tfEnd, TForm, frmCommonDialog, x, 200, y, 100, width, 480, height, 100
- ObjTemplate tfChild, TImageLabel, .imgIcon, x, 4, y, 4, width, 50, height, 50, Visible, TRUE, ImageAlign, iaCenter or iaMiddle
- ObjTemplate tfChild, TLabel, .LblText, x,58, y, 4, width, 10, height, 10, TextAlign, dtfAlignLeft or dtfAlignMiddle or dtfWordWrap or dtfCRLF, Visible, TRUE
-
- ObjTemplate tfChild, TButton, .btnOK, x, 0, y, 0, width, 64, height, 24, TextAlign, dtfAlignCenter or dtfAlignMiddle, Caption, 'OK', ModalResult, mrOK
- ObjTemplate tfChild, TButton, .btnCancel, x, 0, y, 0, width, 64, height, 24, TextAlign, dtfAlignCenter or dtfAlignMiddle, Caption, 'Cancel', ModalResult, mrCancel
- ObjTemplate tfChild, TButton, .btnAbort, x, 0, y, 0, width, 64, height, 24, TextAlign, dtfAlignCenter or dtfAlignMiddle, Caption, 'Abort', ModalResult, mrAbort
- ObjTemplate tfChild, TButton, .btnRetry, x, 0, y, 0, width, 64, height, 24, TextAlign, dtfAlignCenter or dtfAlignMiddle, Caption, 'Retry', ModalResult, mrRetry
- ObjTemplate tfChild, TButton, .btnIgnore, x, 0, y, 0, width, 64, height, 24, TextAlign, dtfAlignCenter or dtfAlignMiddle, Caption, 'Ignore', ModalResult, mrIgnore
- ObjTemplate tfChild, TButton, .btnYes, x, 0, y, 0, width, 64, height, 24, TextAlign, dtfAlignCenter or dtfAlignMiddle, Caption, 'Yes', ModalResult, mrYes
- ObjTemplate tfChild, TButton, .btnNo, x, 0, y, 0, width, 64, height, 24, TextAlign, dtfAlignCenter or dtfAlignMiddle, Caption, 'No', ModalResult, mrNo
- ObjTemplate tfChild, TButton, .btnMaybe, x, 0, y, 0, width, 64, height, 24, TextAlign, dtfAlignCenter or dtfAlignMiddle, Caption, 'Maybe', ModalResult, mrMaybe
- ObjTemplate tfEnd, TButton, .btnHelp, x, 0, y, 0, width, 64, height, 24, TextAlign, dtfAlignCenter or dtfAlignMiddle, Caption, 'Help', ModalResult, mrNone
+ ObjTemplate tfParent or tfEnd, TForm, frmCommonDialog, x = 200, y = 100, width = 480, height = 100, border = borderModal
+ ObjTemplate tfChild, TImageLabel, .imgIcon, x = 4, y = 4, width = 70, height = 70, Visible = TRUE, ImageAlign = iaCenter or iaMiddle
+ ObjTemplate tfChild, TLabel, .LblText, x = 74, y = 4, width = 10, height = 10, TextAlign = dtfAlignLeft or dtfAlignMiddle or dtfWordWrap or dtfCRLF, Visible = TRUE
+
+ ObjTemplate tfChild, TButton, .btnOK, x = 0, y = 0, width = 64, height = 24, TextAlign = dtfAlignCenter or dtfAlignMiddle, Caption = 'OK', ModalResult = mrOK
+ ObjTemplate tfChild, TButton, .btnCancel, x = 0, y = 0, width = 64, height = 24, TextAlign = dtfAlignCenter or dtfAlignMiddle, Caption = 'Cancel', ModalResult = mrCancel
+ ObjTemplate tfChild, TButton, .btnAbort, x = 0, y = 0, width = 64, height = 24, TextAlign = dtfAlignCenter or dtfAlignMiddle, Caption = 'Abort', ModalResult = mrAbort
+ ObjTemplate tfChild, TButton, .btnRetry, x = 0, y = 0, width = 64, height = 24, TextAlign = dtfAlignCenter or dtfAlignMiddle, Caption = 'Retry', ModalResult = mrRetry
+ ObjTemplate tfChild, TButton, .btnIgnore, x = 0, y = 0, width = 64, height = 24, TextAlign = dtfAlignCenter or dtfAlignMiddle, Caption = 'Ignore', ModalResult = mrIgnore
+ ObjTemplate tfChild, TButton, .btnYes, x = 0, y = 0, width = 64, height = 24, TextAlign = dtfAlignCenter or dtfAlignMiddle, Caption = 'Yes', ModalResult = mrYes
+ ObjTemplate tfChild, TButton, .btnNo, x = 0, y = 0, width = 64, height = 24, TextAlign = dtfAlignCenter or dtfAlignMiddle, Caption = 'No', ModalResult = mrNo
+ ObjTemplate tfChild, TButton, .btnMaybe, x = 0, y = 0, width = 64, height = 24, TextAlign = dtfAlignCenter or dtfAlignMiddle, Caption = 'Maybe', ModalResult = mrMaybe
+ ObjTemplate tfEnd, TButton, .btnHelp, x = 0, y = 0, width = 64, height = 24, TextAlign = dtfAlignCenter or dtfAlignMiddle, Caption = 'Help', ModalResult = mrNone
end if
endg
; buttons flags used:
@@ -61,14 +60,15 @@
proc ShowMessage, .parent, .icon, .hTitle, .hMessage, .maskButtons
.xrow dd ?
.yrow dd ?
.hicon dd ?
-.hmask dd ?
begin
push ebx ecx edx esi
stdcall CreateFromTemplate, _CommonDialogTemplate, 0
+
+ set [frmCommonDialog], TWindow:_MainWindow, [.parent]
; First set the position and size of the dialog box, depending on the flags, and the size of the message.
; Set the message text:
set [frmCommonDialog.LblText], TLabel:Caption, [.hMessage]
@@ -97,11 +97,10 @@
cmp eax, edx
jge .widthok
lea eax, [edx+32]
set ebx, TForm:width, eax
- exec ebx, TWindow:UpdateBounds
.widthok:
sub eax, edx
sar eax, 1 ; eax is the begin X coordinate of the row
@@ -120,11 +119,10 @@
mov esi, [edx]
set [esi], TButton:x, [.xrow]
set [esi], TButton:y, [.yrow]
- exec [esi], TWindow:UpdateBounds
set [esi], TButton:Visible, TRUE
add [.xrow], 64+16
@@:
@@ -137,40 +135,37 @@
mov eax, [.icon]
cmp eax, .iconCount
jb @f
xor eax, eax
@@:
- stdcall CreateImageGIF, [.iconTable+4*eax], [.iconSizes+4*eax]
- OutputRegister regEAX, 16
+ stdcall CreateImagePNG, [.iconTable+4*eax], [.iconSizes+4*eax]
+
mov [.hicon], eax
set [frmCommonDialog.imgIcon], TImageLabel:Image, eax
- stdcall CreateImageGIF, _DlgMaskDialogIcons, _DlgMaskDialogIcons.size
- OutputRegister regEAX, 16
- mov [.hmask], eax
- set [frmCommonDialog.imgIcon], TImageLabel:Mask, eax
-
; set the text position and size.
mov ecx, [.yrow]
sub ecx, 8
set [frmCommonDialog.LblText], TLabel:height, ecx
set [frmCommonDialog.imgIcon], TImageLabel:height, ecx
- exec [frmCommonDialog.imgIcon], TWindow:UpdateBounds
get eax, [frmCommonDialog], TForm:width
- sub eax, 66
+ get ecx, [frmCommonDialog.LblText], TLabel:x
+
+ sub eax, ecx
set [frmCommonDialog.LblText], TLabel:width, eax
- exec [frmCommonDialog.LblText], TWindow:UpdateBounds
+
+; exec [frmCommonDialog.LblText], TWindow:Refresh
+; exec [frmCommonDialog.imgIcon], TWindow:Refresh
stdcall ShowModal, ebx, [.parent]
destroy ebx
stdcall DestroyImage, [.hicon]
- stdcall DestroyImage, [.hmask]
pop esi edx ecx ebx
return
.btnTable dd frmCommonDialog.btnOK, \
@@ -183,10 +178,11 @@
frmCommonDialog.btnMaybe, \
frmCommonDialog.btnHelp
.iconTable dd _DlgIconError, _DlgIconInformation, _DlgIconQuestion, _DlgIconWarning
.iconCount = ($ - .iconTable)/4
+
.iconSizes dd _DlgIconError.size, _DlgIconInformation.size, _DlgIconQuestion.size, _DlgIconWarning.size
endp
ADDED freshlib/gui/images/_theme_circle/error.png
Index: freshlib/gui/images/_theme_circle/error.png
==================================================================
--- /dev/null
+++ freshlib/gui/images/_theme_circle/error.png
cannot compute difference between binary files
ADDED freshlib/gui/images/_theme_circle/information.png
Index: freshlib/gui/images/_theme_circle/information.png
==================================================================
--- /dev/null
+++ freshlib/gui/images/_theme_circle/information.png
cannot compute difference between binary files
ADDED freshlib/gui/images/_theme_circle/question.png
Index: freshlib/gui/images/_theme_circle/question.png
==================================================================
--- /dev/null
+++ freshlib/gui/images/_theme_circle/question.png
cannot compute difference between binary files
ADDED freshlib/gui/images/_theme_circle/warning.png
Index: freshlib/gui/images/_theme_circle/warning.png
==================================================================
--- /dev/null
+++ freshlib/gui/images/_theme_circle/warning.png
cannot compute difference between binary files
Index: freshlib/gui/images/_theme_rhomb/Icons.odg
==================================================================
--- freshlib/gui/images/_theme_rhomb/Icons.odg
+++ freshlib/gui/images/_theme_rhomb/Icons.odg
cannot compute difference between binary files
ADDED freshlib/gui/images/checkbox/check.png
Index: freshlib/gui/images/checkbox/check.png
==================================================================
--- /dev/null
+++ freshlib/gui/images/checkbox/check.png
cannot compute difference between binary files
ADDED freshlib/gui/images/checkbox/check.svg
Index: freshlib/gui/images/checkbox/check.svg
==================================================================
--- /dev/null
+++ freshlib/gui/images/checkbox/check.svg
@@ -0,0 +1,83 @@
+
+
+
+
ADDED freshlib/gui/images/checkbox/check_flat.png
Index: freshlib/gui/images/checkbox/check_flat.png
==================================================================
--- /dev/null
+++ freshlib/gui/images/checkbox/check_flat.png
cannot compute difference between binary files
ADDED freshlib/gui/images/checkbox/check_flat.svg
Index: freshlib/gui/images/checkbox/check_flat.svg
==================================================================
--- /dev/null
+++ freshlib/gui/images/checkbox/check_flat.svg
@@ -0,0 +1,80 @@
+
+
+
+
ADDED freshlib/gui/images/checkbox/check_flat_gray.png
Index: freshlib/gui/images/checkbox/check_flat_gray.png
==================================================================
--- /dev/null
+++ freshlib/gui/images/checkbox/check_flat_gray.png
cannot compute difference between binary files
ADDED freshlib/gui/images/checkbox/check_flat_gray.svg
Index: freshlib/gui/images/checkbox/check_flat_gray.svg
==================================================================
--- /dev/null
+++ freshlib/gui/images/checkbox/check_flat_gray.svg
@@ -0,0 +1,80 @@
+
+
+
+
ADDED freshlib/gui/images/checkbox/check_gray.png
Index: freshlib/gui/images/checkbox/check_gray.png
==================================================================
--- /dev/null
+++ freshlib/gui/images/checkbox/check_gray.png
cannot compute difference between binary files
ADDED freshlib/gui/images/checkbox/check_gray.svg
Index: freshlib/gui/images/checkbox/check_gray.svg
==================================================================
--- /dev/null
+++ freshlib/gui/images/checkbox/check_gray.svg
@@ -0,0 +1,83 @@
+
+
+
+
DELETED freshlib/gui/images/error.gif
Index: freshlib/gui/images/error.gif
==================================================================
--- freshlib/gui/images/error.gif
+++ /dev/null
cannot compute difference between binary files
ADDED freshlib/gui/images/error.png
Index: freshlib/gui/images/error.png
==================================================================
--- /dev/null
+++ freshlib/gui/images/error.png
cannot compute difference between binary files
DELETED freshlib/gui/images/icon_mask.gif
Index: freshlib/gui/images/icon_mask.gif
==================================================================
--- freshlib/gui/images/icon_mask.gif
+++ /dev/null
cannot compute difference between binary files
DELETED freshlib/gui/images/information.gif
Index: freshlib/gui/images/information.gif
==================================================================
--- freshlib/gui/images/information.gif
+++ /dev/null
cannot compute difference between binary files
ADDED freshlib/gui/images/information.png
Index: freshlib/gui/images/information.png
==================================================================
--- /dev/null
+++ freshlib/gui/images/information.png
cannot compute difference between binary files
ADDED freshlib/gui/images/menu/check.png
Index: freshlib/gui/images/menu/check.png
==================================================================
--- /dev/null
+++ freshlib/gui/images/menu/check.png
cannot compute difference between binary files
ADDED freshlib/gui/images/menu/check.svg
Index: freshlib/gui/images/menu/check.svg
==================================================================
--- /dev/null
+++ freshlib/gui/images/menu/check.svg
@@ -0,0 +1,84 @@
+
+
+
+
ADDED freshlib/gui/images/menu/check_flat.png
Index: freshlib/gui/images/menu/check_flat.png
==================================================================
--- /dev/null
+++ freshlib/gui/images/menu/check_flat.png
cannot compute difference between binary files
ADDED freshlib/gui/images/menu/check_flat.svg
Index: freshlib/gui/images/menu/check_flat.svg
==================================================================
--- /dev/null
+++ freshlib/gui/images/menu/check_flat.svg
@@ -0,0 +1,86 @@
+
+
+
+
ADDED freshlib/gui/images/menu/check_flat_gray.png
Index: freshlib/gui/images/menu/check_flat_gray.png
==================================================================
--- /dev/null
+++ freshlib/gui/images/menu/check_flat_gray.png
cannot compute difference between binary files
ADDED freshlib/gui/images/menu/check_flat_gray.svg
Index: freshlib/gui/images/menu/check_flat_gray.svg
==================================================================
--- /dev/null
+++ freshlib/gui/images/menu/check_flat_gray.svg
@@ -0,0 +1,86 @@
+
+
+
+
ADDED freshlib/gui/images/menu/check_gray.png
Index: freshlib/gui/images/menu/check_gray.png
==================================================================
--- /dev/null
+++ freshlib/gui/images/menu/check_gray.png
cannot compute difference between binary files
ADDED freshlib/gui/images/menu/check_gray.svg
Index: freshlib/gui/images/menu/check_gray.svg
==================================================================
--- /dev/null
+++ freshlib/gui/images/menu/check_gray.svg
@@ -0,0 +1,84 @@
+
+
+
+
ADDED freshlib/gui/images/menu/submenu.png
Index: freshlib/gui/images/menu/submenu.png
==================================================================
--- /dev/null
+++ freshlib/gui/images/menu/submenu.png
cannot compute difference between binary files
ADDED freshlib/gui/images/menu/submenu.svg
Index: freshlib/gui/images/menu/submenu.svg
==================================================================
--- /dev/null
+++ freshlib/gui/images/menu/submenu.svg
@@ -0,0 +1,89 @@
+
+
+
+
ADDED freshlib/gui/images/menu/submenugray.png
Index: freshlib/gui/images/menu/submenugray.png
==================================================================
--- /dev/null
+++ freshlib/gui/images/menu/submenugray.png
cannot compute difference between binary files
ADDED freshlib/gui/images/menu/submenugray.svg
Index: freshlib/gui/images/menu/submenugray.svg
==================================================================
--- /dev/null
+++ freshlib/gui/images/menu/submenugray.svg
@@ -0,0 +1,89 @@
+
+
+
+
ADDED freshlib/gui/images/menu/submenusel.png
Index: freshlib/gui/images/menu/submenusel.png
==================================================================
--- /dev/null
+++ freshlib/gui/images/menu/submenusel.png
cannot compute difference between binary files
ADDED freshlib/gui/images/menu/submenusel.svg
Index: freshlib/gui/images/menu/submenusel.svg
==================================================================
--- /dev/null
+++ freshlib/gui/images/menu/submenusel.svg
@@ -0,0 +1,89 @@
+
+
+
+
DELETED freshlib/gui/images/question.gif
Index: freshlib/gui/images/question.gif
==================================================================
--- freshlib/gui/images/question.gif
+++ /dev/null
cannot compute difference between binary files
ADDED freshlib/gui/images/question.png
Index: freshlib/gui/images/question.png
==================================================================
--- /dev/null
+++ freshlib/gui/images/question.png
cannot compute difference between binary files
ADDED freshlib/gui/images/svg/error.svg
Index: freshlib/gui/images/svg/error.svg
==================================================================
--- /dev/null
+++ freshlib/gui/images/svg/error.svg
@@ -0,0 +1,67 @@
+
+
+
+
ADDED freshlib/gui/images/svg/information.svg
Index: freshlib/gui/images/svg/information.svg
==================================================================
--- /dev/null
+++ freshlib/gui/images/svg/information.svg
@@ -0,0 +1,67 @@
+
+
+
+
ADDED freshlib/gui/images/svg/question.svg
Index: freshlib/gui/images/svg/question.svg
==================================================================
--- /dev/null
+++ freshlib/gui/images/svg/question.svg
@@ -0,0 +1,63 @@
+
+
+
+
ADDED freshlib/gui/images/svg/warning.svg
Index: freshlib/gui/images/svg/warning.svg
==================================================================
--- /dev/null
+++ freshlib/gui/images/svg/warning.svg
@@ -0,0 +1,65 @@
+
+
+
+
ADDED freshlib/gui/images/treeview/down.png
Index: freshlib/gui/images/treeview/down.png
==================================================================
--- /dev/null
+++ freshlib/gui/images/treeview/down.png
cannot compute difference between binary files
ADDED freshlib/gui/images/treeview/minus.png
Index: freshlib/gui/images/treeview/minus.png
==================================================================
--- /dev/null
+++ freshlib/gui/images/treeview/minus.png
cannot compute difference between binary files
ADDED freshlib/gui/images/treeview/plus.png
Index: freshlib/gui/images/treeview/plus.png
==================================================================
--- /dev/null
+++ freshlib/gui/images/treeview/plus.png
cannot compute difference between binary files
ADDED freshlib/gui/images/treeview/right.png
Index: freshlib/gui/images/treeview/right.png
==================================================================
--- /dev/null
+++ freshlib/gui/images/treeview/right.png
cannot compute difference between binary files
ADDED freshlib/gui/images/treeview/svg/down.svg
Index: freshlib/gui/images/treeview/svg/down.svg
==================================================================
--- /dev/null
+++ freshlib/gui/images/treeview/svg/down.svg
@@ -0,0 +1,89 @@
+
+
+
+
ADDED freshlib/gui/images/treeview/svg/right.svg
Index: freshlib/gui/images/treeview/svg/right.svg
==================================================================
--- /dev/null
+++ freshlib/gui/images/treeview/svg/right.svg
@@ -0,0 +1,89 @@
+
+
+
+
DELETED freshlib/gui/images/warning.gif
Index: freshlib/gui/images/warning.gif
==================================================================
--- freshlib/gui/images/warning.gif
+++ /dev/null
cannot compute difference between binary files
ADDED freshlib/gui/images/warning.png
Index: freshlib/gui/images/warning.png
==================================================================
--- /dev/null
+++ freshlib/gui/images/warning.png
cannot compute difference between binary files
Index: freshlib/gui/mouse.asm
==================================================================
--- freshlib/gui/mouse.asm
+++ freshlib/gui/mouse.asm
@@ -19,11 +19,40 @@
mcSizeH = 3
mcSizeV = 4
mcSizeUL_LR = 5
mcSizeLL_UR = 6
mcWait = 7
+mcHand = 8
+mcDragHand = 9
+mcPencil = 10
+
+
+mcCount = 11
+
+
+
+proc SetMouseCapture, .window
+begin
+ pushad
+
+ xor edi, edi
+
+ mov esi, [.window]
+ cmp [.window], edi
+ je .setit
+
+ get edi, esi, TWindow:OSWindow
+ mov edi, [edi+TWindow.handle]
+
+.setit:
+ mov [__MouseTarget], esi
+ stdcall __MouseCapture, edi
+
+ popad
+ return
+endp
-mcCount = 8
+
include '%TargetOS%/mouse.asm'
endmodule
DELETED freshlib/gui/realobjects.asm
Index: freshlib/gui/realobjects.asm
==================================================================
--- freshlib/gui/realobjects.asm
+++ /dev/null
DELETED freshlib/gui/realobjects.inc
Index: freshlib/gui/realobjects.inc
==================================================================
--- freshlib/gui/realobjects.inc
+++ /dev/null
@@ -1,406 +0,0 @@
-cParamMask = $fffe0000
-cMethodMask = $ffff0000
-
-
-macro __search_method flag, num, count, list, cname, method {
- define flag FALSE
- rept count i:1 \{ match mname, method \\{ match class | name , list\\#i \\\{ match =mname, name \\\\{
- define flag TRUE
- num equ i
- \\\\} \\\} \\} \}
-}
-
-
-macro object name, parent {
- obj@name equ name
- obj@parent equ parent
-
- name#.param?num = 0
-
- name#@count equ 0
-
- match any, parent \{
- name#@count equ parent#@count
- rept parent\#@count i:1 \\{
- name\\#@method\\#i equ parent\\#@method\\#i
- match class | mname, parent\\#i \\\{
- name\\\#mname = i or cMethodMask
-; display 3, "Copy:", \\\`name,\\\`mname, ' = ', \\\`i, 13, 10
- \\\}
- \\}
- \}
-
- macro param paramname*, getval*, setval* \{
- paramname = name#.param?num or cParamMask
- name#.param?num = name#.param?num + 1
-
- if getval eq NONE
- paramname\#.get = -1
- else
- paramname\#.get = getval
- end if
-
- if setval eq NONE ; read only
- paramname\#.set = -1
- else
- paramname\#.set = setval
- end if
- \}
-
- macro method mname, [marg] \{
- \common
- \local f1, n1
- name\#mname\#.arguments equ marg
- define f1 FALSE
- __search_method f1, n1, name\#@count, name\#@method, parent, mname
- match =FALSE, f1 \\{
- rept 1 x:name\\#@count+1 \\\{
- name\\\#@count equ x
- name\\\#@method\\\#x equ name | mname
-; display 3,'New method:', \\\`name,\\\`mname, ' = ', \\\`x, 13, 10
- methods.\\\#name\\\#mname\\\#.inherited equ NONE
- \\\}
- \\}
- match =TRUE, f1 \\{
- match num, n1 \\\{
- match class | mmname, name\\\#@method\\\#num \\\\{
- methods.\\\\#name\\\\#mname\\\\#.inherited equ methods.\\\\#class\\\\#mmname
- \\\\}
- name\\\#@method\\\#num equ name | mname
-; display 3,'Redefinition:', \\\`name,\\\`mname, ' = ', \\\`num, 13, 10
- \\\}
- \\}
- \}
-
- macro abstract mname, [marg] \{
- \common
- method mname, marg
- methods.\#name\#mname = 0
- \}
-
-
- macro name#@members \{
- macro method mname, [marg] \\{ \\}
- macro abstract mname, [marg] \\{ \\}
- match any, parent \\{
- parent\\#@members
- \\}
- purge method, abstract
-}
-
-
-endobj fix } obj_helper
-
-
-macro obj_helper {
- match name, obj@name \{
-
- virtual at 0
- name dd ? ; pointer to the methods table.
- name\#@members
-
- rept name\#@count i:1 \\{
- match class | meth, name\\#@method\\#i \\\{
- name\\\#meth = (i-1) or cMethodMask
-; display 1, "Method constant", \\\`name,\\\`meth, " = ", \\\`i, 13, 10
- \\\}
- \\}
-
- sizeof.\#name = $
- end virtual
-
- label vtables.\#name dword
-
- if used vtables.\#name\#.parent | used vtables.\#name
- .parent dd 0
- end if
-
- match parent, obj@parent \\{
- if defined vtables.\\#parent\\#.parent ; in order to not use the address vtables.#parent
- store dword vtables.\\#parent\\#.parent at .parent
- end if
- \\}
-
- if used vtables.\#name
- .mcount dd name\#@count ; methods count
-; display 2, \`name, " methods list ----------------------------------", 13, 10
- rept name\#@count i:1 \\{
- match class | meth, name\\#@method\\#i \\\{
-; display 1, \\\`class, \\\`meth, 13, 10
- if defined methods.\\\#class\\\#meth
- dd methods.\\\#class\\\#meth
- else
- dd 0
- end if
- \\\}
- \\}
- end if
- \}
- purge method, param
- restore obj@name, obj@parent
-}
-
-
-macro method name {
- local f1, f2
- define f1 TRUE
- if used methods.#name
- match =NONE, methods.#name#.inherited \{
- define f1 FALSE
- dd 0
- \}
- match =TRUE, f1 \{
- dd methods.\#name\#.inherited
- \}
- end if
- match =name#.arguments, name#.arguments \{
- "Error! Method not defined in any object."
- \}
-
- f2 equ FALSE
- match arguments, name#.arguments \{
- f2 equ TRUE
- proc methods.\#name, .self, arguments
- \}
- match =FALSE, f2 \{
- proc methods.\#name, .self
- \}
-}
-
-
-
-; Object manipulation macros. They all generate some assembly code and its syntax is
-; designed to resemble the usual assembly language syntax. These macros are some
-; kind of quasiinstructions.
-
-; These macros uses FreshLib in order to allocate/deallocate dynamic memory.
-
-
-
-macro create target, class {
- if ~target eq eax
- push eax
- end if
-
- stdcall GetMem, sizeof.#class
- mov dword [eax], vtables.#class
-
- if ~target eq eax
- mov target, eax
- end if
-
- if defined class#.Create & (class#.Create and $ffff0000) = cMethodMask
- exec eax, class#:Create
- end if
-
- if ~target eq eax
- pop eax
- end if
-}
-
-
-macro destroy ptrObj {
- if defined TObject.Destroy & (TObject.Destroy and $ffff0000) = cMethodMask
- push eax
- exec ptrObj, TObject:Destroy
- pop eax
- end if
- stdcall FreeMem, ptrObj
-}
-
-
-macro exec ptrobj, method, [arg] {
-common
- local ind
- ind equ NONE
- match class:meth, method \{
- ind equ class\#.\#meth
- \}
-
- match =NONE, ind \{
- disp 2, "Error! Invalid syntax. Use class:method.", 13, 10
- err
- \}
-
- if defined ind & ~(ind and $ffff0000) = cMethodMask
- match meth, ind \{
- disp 2, 'Error! ', \`meth, ' is not a method.', 13, 10
- err
- \}
- end if
-
-reverse
- if ~arg eq
- pushx arg
- end if
-common
- local ..end
-
- if ptrobj eqtype 1
- pushd [ptrobj]
- else
- pushd ptrobj ; push .self argument
- end if
-
- if ptrobj eqtype eax
- mov eax, [ptrobj]
- else
- if ptrobj eqtype 1
- mov eax, [ptrobj]
- mov eax, [eax]
- else
- mov eax, ptrobj
- mov eax, [eax]
- end if
- end if
-
- call dword [eax+8+4*(ind and $ffff)]
-}
-
-
-
-macro inherited [arg] {
-common
- if ~arg eq
-reverse
- pushx arg
-common
- end if
- push [.self]
- call dword [.__info.start-4]
-}
-
-
-
-macro get target, obj, param {
-local flag
-
- flag equ FALSE
-
- match class:par, param \{
- flag equ TRUE
- \}
-
- match =FALSE, flag \{
- disp 2, "Error! Invalid syntax. Use class:method.", 13, 10
- err
- \}
-
- match class:par, param \{
-
- if class\#.\#par\#.get < sizeof.\#class ; field
- if obj eqtype eax
- if target eqtype eax
- mov target, [obj+class\#.\#par\#.get]
- else
- pushd [obj+class\#.\#par\#.get]
- popd target
- end if
- else
- if ~target eq eax
- push eax
- end if
- if obj eqtype 1
- mov eax, [obj]
- else
- mov eax, obj
- end if
- if target eqtype eax
- mov target, [eax+class\#.\#par\#.get]
- else
- pushd [eax+class\#.\#par\#.get]
- popd target
- end if
- if ~target eq eax
- pop eax
- end if
- end if
- else ; by method
- if ~target eq eax
- push eax
- end if
- exec obj, class\#:\#par\#.get
- if ~target eq eax
- mov target, eax
- pop eax
- end if
- end if
- \}
-}
-
-
-macro set obj, param, value {
-local flag
-
- flag equ FALSE
-
- match class:par, param \{
- flag equ TRUE
- \}
-
- match =FALSE, flag \{
- disp 2, "Error! Invalid syntax. Use class:method.", 13, 10
- err
- \}
-
- match class:par, param \{
-
- if class\#.\#par\#.set < sizeof.\#class ; field
- if obj eqtype eax
- if value eqtype eax
- mov [obj+class\#.\#par\#.set], value
- else
- pushd value
- popd [obj+class\#.\#par\#.set]
- end if
- else
- if value eq eax
- push ecx
- mov ecx, obj
- mov [ecx+class\#.\#par\#.set], value
- pop ecx
- else
- push eax
- mov eax, obj
- if value eqtype eax
- mov [eax+class\#.\#par\#.set], value
- else
- pushd value
- popd [eax+class\#.\#par\#.set]
- end if
- pop eax
- end if
- end if
- else ; by method
- push eax
- exec obj, class\#:\#par\#.set, value
- pop eax
- end if
- \}
-}
-
-
-; returns ZF = 1 if the type matches
-; returns ZF = 0 if the type does not matches.
-
-macro istype ptrobj, class {
- local ..itis, ..loop
- push ecx
-
- if ptrobj eqtype eax ; register
- if ~ptrobj eq ecx
- mov ecx, ptrobj
- end if
- else
- mov ecx, ptrobj
- end if
-
-..loop:
- mov ecx, [ecx] ; get vtable, or the parent vtable
- jecxz ..itis ; if jump, ZF=0
- cmp ecx, vtables.#class
- jne ..loop
-; here ZF = 1
-..itis:
- pop ecx
-}
Index: freshlib/gui/sysevents.asm
==================================================================
--- freshlib/gui/sysevents.asm
+++ freshlib/gui/sysevents.asm
@@ -11,50 +11,19 @@
;
; Notes:
;_________________________________________________________________________________________
module "System events library"
-seMouseMove = $0001
-seMouseEnter = $0002
-seMouseLeave = $0003
-seMouseBtnPress = $0004
-seMouseBtnRelease = $0005
-seMouseBtnClick = $0006
-seMouseBtnDblClick = $0007
-seTimer = $0008
-seKbdKeyPress = $0009
-seKbdKeyRelease = $000a
-seKbdStatusChanged = $000b
-seKbdChar = $000c
-
-seScroll = $000d
-
-
-sePaint = $0100
-seCloseRequest = $0101
-
-seFocusIn = $0102
-seFocusOut = $0103
-
-seMove = $0104
-seResize = $0105
-
-
-struct TSysEvent
- .event dd ?
-ends
-
-
-struct TMouseMoveEvent
- . TSysEvent
- .x dd ?
- .y dd ?
-ends
-
-mbLeft = 0
-mbMiddle = 1
-mbRight = 2
+
+mbLeft = 1
+mbMiddle = 2
+mbRight = 3
+
+
+mbScrollUp = 4
+mbScrollDn = 5
+
maskBtnLeft = $0100
maskBtnMiddle = $0200
maskBtnRight = $0400
maskShift = $1
@@ -61,37 +30,15 @@
maskCapsLock = $2
maskCtrl = $4
maskAlt = $8
maskScrLk = $10
-
-struct TMouseButtonEvent
- . TSysEvent
- .Button dd ?
- .kbdStatus dd ?
- .x dd ? ; coordinates of the mouse pointer in the client
- .y dd ?
-ends
-
-
-struct TMouseEnterEvent
- . TSysEvent
-ends
-
; These are scan codes for the non character keys. They are OS dependent and should be used by
; their names.
include '%TargetOS%/keycodes.inc'
-
-struct TKeyboardEvent
- . TSysEvent
- .key dd ? ; 1..4 bytes UTF-8 character typed by the keyboard, or 0 if non character key is pressed/released.
- .scancode dd ? ; scan code of the pressed key.
- .kbdStatus dd ? ; same as mouse button event - contains mouse buttons and Ctrl, Shift and Alt keys status.
-ends
-
scTrack = 1
scUp = 2
scDown = 3
scWheelUp = 4
@@ -98,90 +45,42 @@
scWheelDn = 5
scrollX = 0
scrollY = 1
-
-struct TScrollEvent
- . TSysEvent
- .ScrollBar dd ? ; 0
- .ScrollCmd dd ? ;
- .Value dd ? ; Distance for scUp and scDown and position for scTrack
-ends
-
-
-struct TTimerEvent
- . TSysEvent
- .timer dd ?
-ends
-
-
-struct TPaintEvent
- . TSysEvent
-
- .context dd ? ; pointer to TContext structure, properly initialized.
- .rect RECT
-ends
-
-
-struct TCloseEvent
- . TSysEvent
- .reason dd ? ; how the close was requested?
-ends
-
cerFromUser = 0 ; user pressed X button on the window header, pressed alt+F4 from the keyboard, or choose "Close" from the title menu.
cerFromProgram = 1 ; Method Close was executed from the program.
-struct TFocusInEvent
- . TSysEvent
-ends
-
-struct TFocusOutEvent
- . TSysEvent
-ends
-
-
-struct TMoveEvent
- . TSysEvent
- .newX dd ?
- .newY dd ?
-ends
-
-
-struct TResizeEvent
- . TSysEvent
- .newWidth dd ?
- .newHeight dd ?
-ends
+
; creates and returns a string with the textual identifier of the pressed/released key.
-proc CreateKeyName, .pKeyEvent
+
+proc CreateKeyName, .utf8, .scancode, .kbdStatus
begin
push ebx ecx esi edi
- stdcall StrDup, .strkey
+ stdcall StrNew
mov ebx, eax
- mov edi, [.pKeyEvent]
- test [edi+TKeyboardEvent.kbdStatus], maskCtrl
+ test [.kbdStatus], maskCtrl
jz @f
stdcall StrCharCat, ebx, 'Ctrl'
stdcall StrCharCat, ebx, '+'
@@:
- test [edi+TKeyboardEvent.kbdStatus], maskAlt
+ test [.kbdStatus], maskAlt
jz @f
stdcall StrCharCat, ebx, 'Alt+'
@@:
- test [edi+TKeyboardEvent.kbdStatus], maskShift
+ test [.kbdStatus], maskShift
jz @f
stdcall StrCharCat, ebx, 'Shif'
stdcall StrCharCat, ebx, 't+'
@@:
- mov ecx, [edi+TKeyboardEvent.key]
+ mov ecx, [.utf8]
jecxz .searchlist
cmp ecx, ' '
jne @f
mov ecx, 'Spc'
@@ -210,11 +109,11 @@
mov esi, __FunctionalKeyNames
.loop:
movzx ecx, word [esi]
jecxz .notfound
- cmp ecx, [edi+TKeyboardEvent.scancode]
+ cmp ecx, [.scancode]
je .found
add esi, 4
jmp .loop
.found:
@@ -227,11 +126,11 @@
stdcall StrDel, ebx
xor eax, eax
stc
jmp .finish
-.strkey db 'key', 0
+;.strkey db 'key', 0
endp
macro keynames lbl, [scancode, name] {
common
@@ -287,16 +186,16 @@
keyF10, 'F10', \
keyF11, 'F11', \
keyF12, 'F12', \
keyCapsLock, 'CapsLock', \
keyShiftLeft, 'ShiftL', \
- keyCtrlLeft, 'CtrlL', \
- keyAltLeft, 'AltL', \
- keyAltRight, 'AltR', \
+ keyCtrlLeft, 'LeftCtrl', \
+ keyAltLeft, 'LeftAlt', \
+ keyAltRight, 'RightAlt', \
keyPopupMenu, 'PopupMenu', \
- keyShiftRight, 'ShiftR', \
- keyCtrlRight, 'CtrlR', \
- keyBackSpace, 'BackSp'
+ keyShiftRight, 'RightShift', \
+ keyCtrlRight, 'RightCtrl', \
+ keyBackSpace, 'BkSp'
end if
endg
endmodule
Index: freshlib/gui/textcaret.asm
==================================================================
--- freshlib/gui/textcaret.asm
+++ freshlib/gui/textcaret.asm
@@ -181,11 +181,11 @@
proc __CaretTimerProc, .timer
begin
cmp [Caret.pWindow], 0
je .exit
- mov eax, -1
+ or eax, -1
xchg [Caret.sync], eax
test eax, eax
jnz .exit ; don't wait for lock.
cmp [Caret.visible], 0
@@ -211,53 +211,43 @@
je .exit
cmp [Caret.pWindow], 0
je .exit
- push $ffffffff
-
xor eax, 1
mov [Caret.state], eax
mov ecx, [Caret.timer]
- mov eax, [Caret.state]
mov eax, [CaretTimes+4*eax]
mov [ecx+TTimer.interval], eax
mov [ecx+TTimer.value], 0
- test eax, eax
- jnz .draw
-; clear
- push [Caret.OldPos.height]
- push [Caret.OldPos.width]
- push [Caret.OldPos.y]
- push [Caret.OldPos.x]
- jmp .drawit
-
-.draw:
+ jz .clean
+
+ push $ffFF0000
push [Caret.Pos.height] [Caret.Pos.width] [Caret.Pos.y] [Caret.Pos.x]
push [Caret.Pos.height] [Caret.Pos.width] [Caret.Pos.y] [Caret.Pos.x]
pop [Caret.OldPos.x] [Caret.OldPos.y] [Caret.OldPos.width] [Caret.OldPos.height]
-.drawit:
mov eax, [Caret.pWindow]
- stdcall AllocateContext, [eax+TWindow.handle]
- test eax, eax
- jz .exit
-
- mov esi, eax
-
- stdcall SetDrawMode, esi, cmXor
- stdcall DrawFillRect, esi ; arguments from the stack
- stdcall ReleaseContext, esi
+ get esi, [Caret.pWindow], TWindow:Canvas
+
+ stdcall DrawSolidRect, esi ; arguments from the stack
+
+ exec [Caret.pWindow], TWindow:Update
.exit:
pop esi ecx
return
+
+.clean:
+ exec [Caret.pWindow], TWindow:Refresh ; cleans the caret by repainting the whole window? - not good solution, actually!!!
+ jmp .exit
+
endp
endmodule
ADDED freshlib/gui/themes.asm
Index: freshlib/gui/themes.asm
==================================================================
--- /dev/null
+++ freshlib/gui/themes.asm
@@ -0,0 +1,879 @@
+; _______________________________________________________________________________________
+;| |
+;| ..::FreshLib::.. Free, open source. Licensed under "BSD 2-clause" license." |
+;|_______________________________________________________________________________________|
+;
+; Description: This file contains procedures and data, that form the appearance of the
+; FreshLib GUI application. Colors, control borders, backgrownd drawing etc.
+;
+; Target OS: Any
+;
+; Dependencies:
+;
+; Notes: The user should be able to change these settings and if he uses external
+; procedures, then the code from this library should not be compiled.
+;_________________________________________________________________________________________
+
+module "Runtime GUI themes support"
+
+
+; Box border type
+bxNone = 0
+bxRaised = 1
+bxSunken = 2
+bxFlat = 3
+bxFocused = 4
+bxNoFill = $80000000
+bxDisabled = $40000000
+
+
+
+
+struct TMetaHeader
+ .pData dd ? ; pointer to the NamedArray data fields.
+ .length dd ? ; total length of the NamedArray structure: fields+static data+meta data.
+ .count dd ? ; count of the TMetaFields following.
+ends
+
+struct TMetaField
+ .pName dd ?
+ .type dw ?
+ .len dw ? ; length of the field in dwords
+ .offset dd ? ; offset of the field, relative to the start of the array.
+ends
+
+
+;
+; The NamedArray is a type of structure that contains
+; the fields names together with the field values.
+; This way, the values of the array can be write to
+; text files and then restored in runtime, based not
+; on the fields offsets (that can differ) but based on
+; field names.
+;
+
+
+___natNUM = 0 ; NUM, Stored as decimal, signed.
+___natHEX = 1 ; HEX, Stored as hex, unsigned.
+___natTXT = 2 ; TXT, Stored as string. Needs postprocessing.
+___natFONT = 3 ; FONT, Stored as multivalue: face, size, flags, etc.
+___natPNG = 4 ; PNG, Stored as a hex array. Need postprocessing.
+___natFILE = 5 ; FILE, Stored as a hex array.
+
+
+macro NamedArray lbl, [name, type, value] {
+common
+ local ..fake_lbl
+
+ label ..fake_lbl dword
+ label lbl dword
+
+; data fields
+
+forward
+ local ..len, ..fake_name
+
+ ..len = 0
+
+ label ..fake_name dword
+
+ if used lbl#.#name | (defined options.WholeTheme & options.WholeTheme)
+ label lbl#.#name dword
+ irp val, value \{
+
+ ..len = ..len + 1
+
+ if (type eq NUM)|(type eq HEX)
+ dd val
+ else
+ if type eq TXT
+ if val eqtype 1
+ dd val
+ else
+ dd 0 ; will be changed later in the macro
+ end if
+ else
+ if (type eq FONT) | (type eq PNG)
+ dd 0 ; will be changed later in the macro.
+ dd 0
+ else
+ if type eq FILE
+ dd 0 ; pointer to data
+ else
+ Error! Unknown `type type.
+ end if
+ end if
+ end if
+ end if
+ \}
+ end if
+
+; data for the strings, images, files, etc.
+forward
+local ..index
+
+ ..index = 0
+
+ irp val, value \{
+ \local ..dta, ..len
+
+ if used lbl\#.\#name | (defined options.WholeTheme & options.WholeTheme)
+ if type eq TXT
+ if ~ val eqtype 1
+ ..dta db val
+ db 0
+ end if
+ end if
+
+ if type eq FONT
+ match face : size : weight : flags, val \\{ ; For the Linux port, this structure is enough and not need FontCreate call.
+ \\local ..font_face
+
+ ..dta dd ..font_face ; font face string
+ dd size ; NUM
+ dd weight ; NUM
+ dd flags ; HEX
+
+ ..font_face db face, 0
+ \\}
+
+ ..index = ..index + 4
+ end if
+
+ if type eq PNG
+ dd ..len
+ ..dta file val
+ ..len = $ - ..dta
+
+ ..index = ..index + 4
+ end if
+
+ if type eq FILE
+ dd ..len
+ ..dta file val
+ ..len = $ - ..dta
+ end if
+
+ if defined ..dta
+ store dword ..dta at ..fake_name + ..index
+ end if
+ end if
+
+ ..index = ..index + 4
+ \}
+
+; Header of the meta data.
+common
+ local ..cnt, ..total, ..fake_meta
+ ..cnt = 0
+
+ if used lbl#.#meta | (defined options.WholeTheme & options.WholeTheme)
+
+ label lbl#.#meta dword
+ label ..fake_meta dword
+
+ dd ..fake_lbl
+ dd lbl#.#size
+ dd ..total
+
+; metadata
+forward
+ local ..namestr
+
+; array with the fields names and offsets.
+ if defined lbl#.#name
+
+ dd ..namestr
+ dw ___nat#type
+ dw ..len ; dwords
+ dd ..fake_name - ..fake_lbl
+
+ ..cnt = ..cnt + 1
+
+ end if
+
+; field names
+forward
+
+ if used ..namestr | (defined options.WholeTheme & options.WholeTheme)
+ ..namestr db `name, 0
+ end if
+
+; Initialization code
+common
+ end if
+
+ if used lbl#.#Init | (defined options.WholeTheme & options.WholeTheme)
+ lbl#.#Init:
+
+forward
+
+local ..index
+
+ ..index = 0
+
+ irp val, value \{
+ if used lbl\#.\#name | (defined options.WholeTheme & options.WholeTheme)
+ if type eq FONT
+ mov eax, [..fake_name+..index+4]
+ stdcall FontCreate, [eax+__TFont.hFontFace], [eax+__TFont.height], [eax+__TFont.weight], [eax+__TFont.flags]
+ mov [..fake_name+..index], eax
+
+ ..index = ..index + 4
+ end if
+
+ if (type eq PNG)
+ mov eax, [..fake_name+..index+4]
+ stdcall CreateImagePNG, eax, [eax-4]
+ mov [..fake_name+..index], eax
+
+ ..index = ..index + 4
+ end if
+ end if
+
+ ..index = ..index + 4
+ \}
+
+common
+ retn
+ end if
+common
+ lbl#.#size = $ - ..fake_lbl
+
+ ..total = ..cnt
+}
+
+
+
+; Serializes the NamedArray to a string.
+; .pMeta - poitner to the meta data of the named array structure.
+
+proc NamedArrayToString, .pMeta
+.array dd ?
+.data2string dd ?
+.datalen dd ?
+begin
+ pushad
+
+ mov esi, [.pMeta]
+ stdcall StrNew
+ mov edi, eax
+
+ lodsd
+ mov [.array], eax
+
+ lodsd ; TMetaHeader.length
+
+ lodsd
+ mov ecx, eax ; count of the meta records.
+
+.loop:
+ dec ecx
+ js .end_loop
+
+ lodsd ; pointer to the field name.
+
+ stdcall StrCat, edi, eax
+ stdcall StrCharCat, edi, " = "
+
+ lodsw ; data type
+ movzx eax, ax
+ push [.data_handlers+4*eax]
+ push [.data_len+4*eax]
+
+ pop [.datalen]
+ pop [.data2string]
+
+ lodsw
+ movzx edx, ax ; number of sub values
+
+ lodsd ; offset, relative to [.array]
+ mov ebx, eax
+ add ebx, [.array] ; pointer to the values
+
+.loop2:
+ dec edx
+ js .end_loop2
+
+ stdcall [.data2string], ebx
+ push eax
+
+ stdcall StrCat, edi, eax
+ stdcall StrDel ; from the stack
+
+ add ebx, [.datalen]
+
+ test edx, edx
+ jz .loop2
+
+ stdcall StrCharCat, edi, ", "
+ jmp .loop2
+
+.end_loop2:
+ stdcall StrCharCat, edi, $0a0d
+ jmp .loop
+
+.end_loop:
+ mov [esp+regEAX*4], edi
+ popad
+ return
+
+
+.data_handlers dd __DataToNum, __DataToHex, __DataToTxt, __DataToFont, __DataToPng, __DataToFile
+.data_len dd 4, 4, 4, 8, 8, 4
+
+endp
+
+
+proc __DataToNum, .pData
+begin
+ mov eax, [.pData]
+ stdcall NumToStr, [eax], ntsDec or ntsSigned
+ return
+endp
+
+
+
+proc __DataToHex, .pData
+begin
+ mov eax, [.pData]
+ stdcall NumToStr, [eax], ntsHex or ntsUnsigned
+ stdcall StrCharInsert, eax, '$', 0
+ return
+endp
+
+
+
+proc __DataToTxt, .pData
+begin
+ mov eax, [.pData]
+ stdcall StrDupMem, [eax]
+ stdcall StrSetQuotes, eax, 0
+ return
+endp
+
+
+
+proc __DataToFont, .pData
+begin
+ push esi ebx
+
+ mov esi, [.pData]
+ mov esi, [esi+4]
+
+ stdcall StrDup, [esi+__TFont.hFontFace] ; face name
+ stdcall StrSetQuotes, eax, 0
+ mov ebx, eax
+
+ stdcall StrCharCat, ebx, " : "
+
+ stdcall NumToStr, [esi+__TFont.height], ntsDec or ntsUnsigned ; size
+ stdcall StrCat, ebx, eax
+ stdcall StrDel, eax
+
+ stdcall StrCharCat, ebx, " : "
+
+ stdcall NumToStr, [esi+__TFont.weight], ntsDec or ntsUnsigned ; weight
+ stdcall StrCat, ebx, eax
+ stdcall StrDel, eax
+
+ stdcall StrCharCat, ebx, " : $"
+
+ stdcall NumToStr, [esi+__TFont.flags], ntsHex or ntsUnsigned ; flags
+ stdcall StrCat, ebx, eax
+ stdcall StrDel, eax
+
+ mov eax, ebx
+
+ pop ebx esi
+ return
+endp
+
+
+
+proc __DataToPng, .pData
+begin
+ pushad
+
+ mov esi, [.pData]
+ mov esi, [esi+4] ; pointer to the compressed file.
+ mov ecx, [esi-4] ; length
+ jmp __DataToFile.convert_file
+endp
+
+
+
+proc __DataToFile, .pData
+begin
+ pushad
+
+ mov esi, [.pData]
+ mov esi, [esi] ; pointer to the compressed file.
+ mov ecx, [esi-4] ; length
+
+.convert_file:
+ stdcall NumToStr, ecx, ntsDec or ntsUnsigned
+ mov ebx, eax
+
+ stdcall StrCharCat, ebx, ":"
+
+ stdcall EncodeBase64, esi, ecx
+ push eax
+
+ stdcall StrCat, ebx, eax
+ stdcall StrDel ; from the stack
+
+ mov [esp+regEAX*4], ebx
+ popad
+ return
+endp
+
+
+
+
+proc StringToNamedArray, .pMeta, .hString
+.string2data dd ?
+.free_data dd ?
+.data_start dd ?
+.data_end dd ?
+begin
+ pushad
+
+ mov esi, [.pMeta]
+ mov eax, [esi+TMetaHeader.pData]
+ mov [.data_start], eax
+ add eax, [esi+TMetaHeader.length]
+ mov [.data_end], eax
+
+ stdcall StrSplitList, [.hString], $0a, FALSE
+ mov esi, eax
+
+ xor ecx, ecx
+
+.loop:
+ cmp ecx, [esi+TArray.count]
+ jae .end_loop
+
+ stdcall StrSplitList, [esi+TArray.array+4*ecx], "=", FALSE
+ mov edi, eax
+
+ cmp [edi+TArray.count], 2
+ jne .next_line
+
+ stdcall __SearchName, [.pMeta], [edi+TArray.array]
+ test eax, eax
+ jz .free1
+
+ push esi ecx
+
+ mov ebx, eax
+
+ stdcall StrSplitList, [edi+TArray.array+4], ',', FALSE
+ mov edx, eax
+
+ movzx ecx, [ebx+TMetaField.len]
+ cmp ecx, [edx+TArray.count]
+ jb .free2 ; there is no place to restore this parameter.
+
+ movzx eax, [ebx+TMetaField.type]
+ push [.data_handlers+4*eax]
+ push [.free_handlers+4*eax]
+
+ pop [.free_data]
+ pop [.string2data]
+
+ mov esi, [ebx+TMetaField.offset]
+ add esi, [.data_start] ; pointer to the data field.
+
+ xor ecx, ecx
+
+.loop2:
+ cmp ecx, [edx+TArray.count]
+ jae .free2
+
+ call [.free_data]
+ stdcall [.string2data], [edx+TArray.array+4*ecx]
+
+ inc ecx
+ jmp .loop2
+
+
+.free2:
+ stdcall ListFree, edx, StrDel
+
+ pop ecx esi
+
+.free1:
+ stdcall ListFree, edi, StrDel
+
+.next_line:
+ inc ecx
+ jmp .loop
+
+.end_loop:
+ stdcall ListFree, esi, StrDel
+ popad
+ return
+
+.data_handlers dd __NumToData, __NumToData, __TxtToData, __FontToData, __PngToData, __FileToData
+.free_handlers dd .end_free, .end_free, .free_txt, .free_font, .free_png, .free_file
+
+
+.check_ptr:
+ test eax, eax
+ jz .out
+
+ cmp eax, [.data_start]
+ jb .out
+ cmp eax, [.data_end]
+ ja .out
+;in
+ stc
+ retn
+
+.out:
+ clc
+ retn
+
+.free_txt:
+ stdcall StrDel, [esi]
+ retn
+
+.free_font:
+ stdcall FontDestroy, [esi]
+ mov eax, [esi+4]
+ call .check_ptr
+ jc .end_free
+
+ stdcall StrDel, [eax+__TFont.hFontFace]
+ retn
+
+.free_png:
+ stdcall DestroyImage, [esi]
+ mov eax, [esi+4]
+
+.free_ptr:
+ sub eax, 4
+ call .check_ptr
+ jc .end_free
+
+ stdcall FreeMem, eax
+
+.end_free:
+ retn
+
+
+.free_file:
+ mov eax, [esi]
+ jmp .free_ptr
+
+endp
+
+
+
+proc __NumToData, .hString
+begin
+ stdcall StrToNumEx, [.hString]
+ mov [esi], eax
+ add esi, 4
+ return
+endp
+
+
+proc __TxtToData, .hString
+begin
+ stdcall StrDup, [.hString]
+ stdcall StrClipQuotes, eax
+ mov [esi], eax
+ add esi, 4
+ return
+endp
+
+
+
+proc __FontToData, .hString
+begin
+ push ebx ecx edx edi
+
+ xor eax, eax
+ mov [esi], eax
+
+ mov edi, [esi+4] ; pointer to the font parameters.
+
+ stdcall StrSplitList, [.hString], ":", FALSE
+ mov edx, eax
+
+ cmp [edx+TArray.count], 4
+ jne .finish
+
+ stdcall StrClipQuotes, [edx+TArray.array]
+ stdcall StrDup, [edx+TArray.array]
+ mov [edi+__TFont.hFontFace], eax
+
+ stdcall StrToNumEx, [edx+TArray.array+4] ; size
+ mov [edi+__TFont.height], eax
+ mov ebx, eax
+
+ stdcall StrToNumEx, [edx+TArray.array+8] ; weight
+ mov [edi+__TFont.weight], eax
+ mov ecx, eax
+
+ stdcall StrToNumEx, [edx+TArray.array+12] ; flags
+ mov [edi+__TFont.flags], eax
+ mov edi, eax
+
+ stdcall StrPtr, [edx+TArray.array]
+ stdcall FontCreate, eax, ebx, ecx, edi
+
+ stdcall ListFree, edx, StrDel
+
+ mov [esi], eax
+ add esi, 8
+
+.finish:
+ pop edi edx ecx ebx
+ return
+endp
+
+
+
+proc __PngToData, .hString
+begin
+ push edx
+
+ stdcall StrSplitList, [.hString], ":", FALSE
+ mov edx, eax
+
+ cmp [edx+TArray.count], 2
+ jne .finish
+
+ stdcall DecodeBase64, [edx+TArray.array+4]
+
+ mov [esi+4], eax
+
+ stdcall CreateImagePNG, eax, [eax-4]
+ mov [esi], eax
+
+.finish:
+ add esi, 8
+ pop edx
+ return
+endp
+
+
+
+proc __FileToData, .hString
+begin
+ push edx
+
+ stdcall StrSplitList, [.hString], ":", FALSE
+ mov edx, eax
+
+ cmp [edx+TArray.count], 2
+ jne .finish
+
+ stdcall DecodeBase64, [edx+TArray.array+4]
+
+ mov [esi], eax
+
+.finish:
+ add esi, 4
+ pop edx
+ return
+endp
+
+
+
+; returns a pointer to the parameter description block: name, count, offset.
+
+proc __SearchName, .pMeta, .hName
+begin
+ push esi ecx
+
+ mov esi, [.pMeta]
+
+ mov ecx, [esi+TMetaHeader.count]
+ add esi, sizeof.TMetaHeader
+
+.search:
+ dec ecx
+ js .not_found
+
+ stdcall StrCompCase, [esi+TMetaField.pName], [.hName]
+ jc .found
+
+ add esi, sizeof.TMetaField
+ jmp .search
+
+.not_found:
+ xor esi, esi
+
+.found:
+ mov eax, esi
+ pop ecx esi
+ return
+endp
+
+
+
+
+iglobal
+; drawing functions.
+
+ var DrawBox = DrawBoxDefault
+ var DrawSlider = DrawSliderDefault
+
+ var DrawSplitter = DrawSplitterDefault
+endg
+
+
+
+proc DrawBoxDefault, .pImage, .pBounds, .bkground, .border, .brd_width
+begin
+ pushad
+
+ mov esi, [.pBounds]
+
+ mov edx, [.border]
+ and edx, $ff
+ jz .borderok
+
+ mov eax, [GUI.clBorderLight]
+ mov ecx, [GUI.clBorderDark]
+
+ test [.border], bxDisabled
+ jz .enabled_ok
+
+ mov eax, [GUI.clBorderLightGray]
+ mov ecx, [GUI.clBorderDarkGray]
+
+.enabled_ok:
+ cmp edx, bxRaised
+ je .colorok
+
+ xchg eax, ecx
+
+ cmp edx, bxSunken
+ je .colorok
+
+ mov eax, [GUI.clBorderNeutralGray]
+
+ test [.border], bxDisabled
+ jnz .flat_ok
+
+ mov eax, [GUI.clBorderNeutral]
+
+.flat_ok:
+ mov ecx, eax
+ cmp edx, bxFlat
+ je .colorok
+
+ mov eax, [GUI.clBorderFocused]
+ mov ecx, eax
+
+.colorok:
+ mov ebx, [.brd_width]
+
+; left border line
+ stdcall DrawSolidRect, [.pImage], [esi+TBounds.x],[esi+TBounds.y], ebx, [esi+TBounds.height], eax
+
+; top
+ add [esi+TBounds.x], ebx
+ sub [esi+TBounds.width], ebx
+
+ stdcall DrawSolidRect, [.pImage], [esi+TBounds.x], [esi+TBounds.y], [esi+TBounds.width], ebx, eax
+
+; right
+ sub [esi+TBounds.width], ebx
+ add [esi+TBounds.y], ebx
+ sub [esi+TBounds.height], ebx
+
+ mov edx, [esi+TBounds.width]
+ add edx, [esi+TBounds.x]
+ stdcall DrawSolidRect, [.pImage], edx, [esi+TBounds.y], ebx, [esi+TBounds.height], ecx
+
+; bottom
+ sub [esi+TBounds.height], ebx
+
+ mov edx, [esi+TBounds.y]
+ add edx, [esi+TBounds.height]
+ stdcall DrawSolidRect, [.pImage], [esi+TBounds.x], edx, [esi+TBounds.width], ebx, ecx
+
+.borderok:
+ bt [.border], 31
+ jc .fillok
+
+ stdcall DrawSolidRect, [.pImage], [esi+TBounds.x], [esi+TBounds.y], [esi+TBounds.width], [esi+TBounds.height], [.bkground]
+
+.fillok:
+
+ popad
+ return
+endp
+
+
+
+sliderHorizontal = 0
+sliderVertical = 1
+
+proc DrawSliderDefault, .pImage, .pBounds, .bkground, .type
+begin
+ stdcall DrawBoxDefault, [.pImage], [.pBounds], [.bkground], [scrollBorder], 2
+ return
+endp
+
+
+
+
+
+proc DrawSplitterDefault, .pImage, .pRect, .type
+begin
+ pushad
+
+ mov esi, [.pRect]
+ mov eax, [esi+RECT.right]
+ mov ecx, [esi+RECT.bottom]
+ sub eax, [esi+RECT.left]
+ sub ecx, [esi+RECT.top]
+
+ stdcall DrawSolidRect, [.pImage], [esi+RECT.left], [esi+RECT.top], eax, ecx, [GUI.clSplitter]
+ popad
+ return
+endp
+
+
+proc DrawSplitterDefault2, .pImage, .pRect, .type
+.bounds TBounds
+begin
+ pushad
+
+ mov esi, [.pRect]
+ mov eax, [esi+RECT.left]
+ mov ecx, [esi+RECT.top]
+ mov edx, [esi+RECT.right]
+ mov ebx, [esi+RECT.bottom]
+ sub edx, eax
+ sub ebx, ecx
+ mov [.bounds.x], eax
+ mov [.bounds.y], ecx
+ mov [.bounds.width], edx
+ mov [.bounds.height], ebx
+ lea eax, [.bounds]
+
+ stdcall DrawBoxDefault, [.pImage], eax, [GUI.clDialogBk], bxSunken, [GUI.boxBorderWidth]
+
+ popad
+ return
+endp
+
+
+
+
+
+
+endmodule
+
+
+
+
+
ADDED freshlib/gui/themes/flat_gui.asm
Index: freshlib/gui/themes/flat_gui.asm
==================================================================
--- /dev/null
+++ freshlib/gui/themes/flat_gui.asm
@@ -0,0 +1,181 @@
+; _______________________________________________________________________________________
+;| |
+;| ..::FreshLib::.. Free, open source. Licensed under "BSD 2-clause" license." |
+;|_______________________________________________________________________________________|
+;
+; Description: This file contains procedures and data, that form the appearance of the
+; FreshLib GUI application. Colors, control borders, backgrownd drawing etc.
+;
+; Target OS: Any
+;
+; Dependencies:
+;
+; Notes: The user should be able to change these settings and if he uses external
+; procedures, then the code from this library should not be compiled.
+;_________________________________________________________________________________________
+module "GUI theme data and code library"
+
+; Named theme colors
+
+; cyan
+clTurquoise = $ff1abc9c
+clGreenSea = $ff16A085
+
+; green
+clEmerald = $ff2ecc71
+clNephritis = $ff27ae60
+
+; blue
+
+clPetermann = $ff3498db
+clBelizeHole = $ff2980b9
+
+; purple
+
+clAmethyst = $ff9b59b6
+clWisteria = $ff8e44ad
+
+; black
+
+clWetAsphalt = $ff34495e
+clMidnight = $ff2c3e50
+
+; gray
+
+clConcrete = $ff95a5a6
+clAsbestos = $ff7f8c8d
+
+; light gray / white
+
+clClouds = $ffecf0f1
+clSilver = $ffbdc3c7
+clWhite = $ffffffff
+
+; Yellow / orange
+
+clSunflower = $fff1c40f
+clOrange = $fff39c12
+
+; Brown / orange
+
+clCarrot = $ffe67e22
+clPumpkin = $ffd35400
+
+; Red
+
+clAlizarin = $ffe74c3c
+clPomegranate = $ffc0392b
+
+iglobal
+
+ NamedArray GUI, \
+\
+\ ; Widgets border colors and width
+ clBorderNeutral, HEX, clTurquoise, \
+ clBorderLight, HEX, clTurquoise, \
+ clBorderDark, HEX, clTurquoise, \
+ clBorderNeutralGray, HEX, $ff606060, \
+ clBorderLightGray, HEX, $ff606060, \
+ clBorderDarkGray, HEX, $ff606060, \
+ clBorderFocused, HEX, clAlizarin, \
+\
+ boxBorderWidth, NUM, 2, \
+\
+\ ; TButton colors and styles. The multivalue fields are for Neutral, Hovered and Pressed states.
+\
+ clBtnBk, HEX, , \
+ clBtnTxt, HEX, , \
+ btnBorder, NUM, , \
+ btnPressedOfsX, NUM, 0, \
+ btnPressedOfsY, NUM, 0, \
+ btnMarginX, NUM, 8, \
+ btnMarginY, NUM, 8, \
+\
+\ ; TEdit colors and styles.
+\
+ clEditBk, HEX, clClouds, \
+ clEditBkFocused, HEX, clClouds, \
+ clEditTxt, HEX, $ff000000, \
+ clEditSel, HEX, clBelizeHole and $00ffffff or $60000000, \
+ clEditSelTxt, HEX, $ffffffff, \
+ editBorder, NUM, bxFlat, \
+ editBorderFocused, NUM, bxFlat, \
+\
+\ ; Dialog boxes and TForm color and styles
+\
+ clDialogBk, HEX, clClouds, \
+ clDialogTxt, HEX, $ff000000, \
+ clSplitter, HEX, clWetAsphalt, \
+\
+\ ; TProgress colors and styles
+\
+ clProgressBk, HEX, clClouds, \
+ clProgressBar, HEX, clTurquoise, \
+ progressBorder, NUM, bxFlat, \
+\
+\ ; TScrollbar colors and styles
+\
+ clScrollBk, HEX, , \
+ clScrollSlider, HEX, , \
+ borderScroll, NUM, bxNone, \
+ scrollWidth, NUM, 12, \
+ minSliderHeight, NUM, 12, \
+\
+\ ; TLabel colors and styles
+\
+ clLabelBk, HEX, $00000000, \
+ clLabelTxt, HEX, $ff000000, \
+\
+\ ; TTreeView colors and styles.
+\
+ clTreeViewBack, HEX, clClouds, \
+ clTreeViewText, HEX, $ff000000, \
+ clTreeSelected, HEX, clBelizeHole, \
+ clTreeSelectedTxt, HEX, clWhite, \
+ clTreeFocused, HEX, clPumpkin, \
+ clTreeFocusedTxt, HEX, clWhite, \
+\
+ tvBorder, NUM, bxFlat, \
+\
+ tvIcons, PNG, <"%lib%/gui/images/treeview/right.png", "%lib%/gui/images/treeview/down.png">, \
+\
+\ ; TMenu colors and styles
+\
+ clMenuBack, HEX, clClouds, \
+ clMenuText, HEX, $ff000000, \
+ clMenuTextGray, HEX, $90000000, \
+ borderMenu, NUM, bxFlat, \
+ menuIconMargin, NUM, 4, \
+ menuMinTextDist, NUM, 32, \
+ menuSubIcon, PNG, "%lib%/gui/images/menu/submenu.png", \
+ menuSubIconSel, PNG, "%lib%/gui/images/menu/submenusel.png", \
+ menuSubIconGray, PNG, "%lib%/gui/images/menu/submenugray.png", \
+\
+\ ; Menu graphics
+\
+ iconMenuChecked, PNG, "%lib%/gui/images/menu/check_flat.png", \
+ iconMenuCheckedGray, PNG, "%lib%/gui/images/menu/check_flat_gray.png", \
+\
+\ ; Checkbox colors
+\
+ clCheckboxBack, HEX, <$ffe0e0e0, $ffffffff, $ffc0c0c0, $80c0c0c0>, \
+ clCheckboxTxt, HEX, $ff000000, \
+ clCheckboxTxtGray, HEX, $ff606060, \
+ cbIconSize, NUM, 13, \
+ cbMargin, NUM, 2, \
+ borderCheckbox, NUM, bxFlat, \
+ iconChecked, PNG, "%lib%/gui/images/checkbox/check_flat.png", \
+ iconCheckedGray, PNG, "%lib%/gui/images/checkbox/check_flat_gray.png", \
+\
+\ ; Default font
+\
+ DefaultFont, FONT, "Liberation Sans": 13 : fwDemibold : 0
+
+endg
+
+
+
+
+
+
+endmodule
ADDED freshlib/gui/themes/win_gui.asm
Index: freshlib/gui/themes/win_gui.asm
==================================================================
--- /dev/null
+++ freshlib/gui/themes/win_gui.asm
@@ -0,0 +1,130 @@
+; _______________________________________________________________________________________
+;| |
+;| ..::FreshLib::.. Free, open source. Licensed under "BSD 2-clause" license." |
+;|_______________________________________________________________________________________|
+;
+; Description: This file contains procedures and data, that form the appearance of the
+; FreshLib GUI application. Colors, control borders, backgrownd drawing etc.
+;
+; Target OS: Any
+;
+; Dependencies:
+;
+; Notes: The user should be able to change these settings and if he uses external
+; procedures, then the code from this library should not be compiled.
+;_________________________________________________________________________________________
+module "GUI theme data and code library"
+
+
+; Theme colors and other parameters as margins, offsets, fonts, etc.
+iglobal
+
+
+ NamedArray GUI, \
+\
+\ ; Widgets border colors and width
+ clBorderNeutral, HEX, $ffa0a0a0, \
+ clBorderLight, HEX, $ffffffff, \
+ clBorderDark, HEX, $ff404040, \
+ clBorderNeutralGray, HEX, $ff909090, \
+ clBorderLightGray, HEX, $ffe0e0e0, \
+ clBorderDarkGray, HEX, $ff808080, \
+ clBorderFocused, HEX, $ffff8000, \
+\
+ boxBorderWidth, NUM, 1, \
+\
+\ ; TButton colors and styles. The multivalue fields are for Neutral, Hovered and Pressed states.
+\
+ clBtnBk, HEX, <$ffd4d0c8, $ffe0e0e0, $ffa0a0a0, $80d4d0c8>, \
+ clBtnTxt, HEX, <$ff000000, $ff000000, $ff000000, $ff606060>, \
+ btnBorder, NUM, , \
+ btnPressedOfsX, NUM, 1, \
+ btnPressedOfsY, NUM, 1, \
+ btnMarginX, NUM, 8, \
+ btnMarginY, NUM, 8, \
+\
+\ ; TEdit colors and styles.
+\
+ clEditBk, HEX, $ffffffff, \
+ clEditBkFocused, HEX, $ffffffff, \
+ clEditTxt, HEX, $ff000000, \
+ clEditSel, HEX, $600a246c, \
+ clEditSelTxt, HEX, $ffffffff, \
+ editBorder, NUM, bxSunken, \
+ editBorderFocused, NUM, bxSunken, \
+\
+\ ; Dialog boxes and TForm color and styles
+\
+ clDialogBk, HEX, $ffd4d0c8, \
+ clDialogTxt, HEX, $ff000000, \
+ clSplitter, HEX, $ff606060, \
+\
+\ ; TProgress colors and styles
+\
+ clProgressBk, HEX, $ffd4d0c8, \
+ clProgressBar, HEX, $ff0a246c, \
+ progressBorder, NUM, bxSunken, \
+\
+\ ; TScrollbar colors and styles
+\
+ clScrollBk, HEX, <$3f808080, $a0d4d0c8>, \
+ clScrollSlider, HEX, <$7fd4d0c8, $ffd4d0c8>, \
+ borderScroll, NUM, bxRaised, \
+ scrollWidth, NUM, 16, \
+ minSliderHeight, NUM, 16, \
+\
+\ ; TLabel colors and styles
+\
+ clLabelBk, HEX, $00ffffff, \
+ clLabelTxt, HEX, $ff000000, \
+\
+\ ; TTreeView colors and styles.
+\
+ clTreeViewBack, HEX, $ffffffff, \
+ clTreeViewText, HEX, $ff000000, \
+ clTreeSelected, HEX, $ff0a246c, \
+ clTreeSelectedTxt, HEX, $ffffffff, \
+ clTreeFocused, HEX, $ff0a246c, \
+ clTreeFocusedTxt, HEX, $ffffff00, \
+\
+ tvBorder, NUM, bxSunken, \
+\
+ tvIcons, PNG, <"%lib%/gui/images/treeview/plus.png", "%lib%/gui/images/treeview/minus.png">, \
+\
+\ ; TMenu colors and styles
+\
+ clMenuBack, HEX, $ffd4d0c8, \
+ clMenuText, HEX, $ff000000, \
+ clMenuTextGray, HEX, $80000000, \
+ borderMenu, NUM, bxRaised, \
+ menuIconMargin, NUM, 4, \
+ menuMinTextDist, NUM, 32, \
+ menuSubIcon, PNG, "%lib%/gui/images/menu/submenu.png", \
+ menuSubIconSel, PNG, "%lib%/gui/images/menu/submenusel.png", \
+ menuSubIconGray, PNG, "%lib%/gui/images/menu/submenugray.png", \
+\
+\ ; Menu graphics
+\
+ iconMenuChecked, PNG, "%lib%/gui/images/menu/check.png", \
+ iconMenuCheckedGray,PNG, "%lib%/gui/images/menu/check_gray.png", \
+\
+\ ; Checkbox colors
+\
+ clCheckboxBack, HEX, <$ffffffff, $ffffffff, $ffffffff, $ffc0c0c0>, \
+ clCheckboxTxt, HEX, $ff000000, \
+ clCheckboxTxtGray, HEX, $ff808080, \
+ cbIconSize, NUM, 13, \
+ cbMargin, NUM, 2, \
+ borderCheckbox, NUM, bxSunken, \
+ iconChecked, PNG, "%lib%/gui/images/checkbox/check.png", \
+ iconCheckedGray, PNG, "%lib%/gui/images/checkbox/check_gray.png", \
+\
+\ ; Default font
+\
+ DefaultFont, FONT, "Liberation Sans":13:fwNormal:0
+
+endg
+
+
+
+endmodule
Index: freshlib/imports/Linux/libFC.inc
==================================================================
--- freshlib/imports/Linux/libFC.inc
+++ freshlib/imports/Linux/libFC.inc
@@ -13,10 +13,12 @@
;_________________________________________________________________________________________
import_proto 'libfontconfig.so.1', \
+ FcInit, , 'FcInit', \
+ FcFini, , 'FcFini', \
FcInitLoadConfigAndFonts, , 'FcInitLoadConfigAndFonts', \
FcPatternCreate, , 'FcPatternCreate', \
FcObjectSetBuild, <.first, ...>, 'FcObjectSetBuild', \
FcFontList, <.config, .pPattern, .ObjSet>, 'FcFontList', \
FcPatternGetString, <.pPattern, .obj, .n, .pBuffer>, 'FcPatternGetString', \
@@ -24,6 +26,7 @@
FcFontSetDestroy, <.pFontSet>, 'FcFontSetDestroy', \
FcNameParse, <.name>, 'FcNameParse', \
FcConfigSubstitute, <.config, .pattern, .matchkind>, 'FcConfigSubstitute', \
FcDefaultSubstitute, <.pattern>, 'FcDefaultSubstitute', \
FcFontMatch, <.config, .pattern, .pResult>, 'FcFontMatch', \
- FcPatternDestroy, <.pattern>, 'FcPatternDestroy'
+ FcPatternDestroy, <.pattern>, 'FcPatternDestroy', \
+ FcPatternPrint, <.pattern>, 'FcPatternPrint'
Index: freshlib/imports/Linux/libFT.inc
==================================================================
--- freshlib/imports/Linux/libFT.inc
+++ freshlib/imports/Linux/libFT.inc
@@ -32,10 +32,12 @@
FTC_Manager_LookupSize, <.manager, .scaler, .pSize>, 'FTC_Manager_LookupSize', \
FTC_Manager_RemoveFaceID, <.manager, .face_id>, 'FTC_Manager_RemoveFaceID', \
FTC_ImageCache_New, <.manager, .pImageCache>, 'FTC_ImageCache_New', \
FTC_ImageCache_Lookup, <.cache, .type, .glyph_index, \
.pGlyph, .pNode>, 'FTC_ImageCache_Lookup', \
+ FTC_ImageCache_LookupScaler, <.cache, .scaler, .load_flags, \
+ .gindex, .pGlyph, .pNode>, 'FTC_ImageCache_LookupScaler', \
FTC_CMapCache_New, <.manager, .pCMapCache>, 'FTC_CMapCache_New', \
FTC_CMapCache_Lookup, <.cache, .face_id, .cmap_index, .char_code>, 'FTC_CMapCache_Lookup'
Index: freshlib/imports/Linux/libX11.inc
==================================================================
--- freshlib/imports/Linux/libX11.inc
+++ freshlib/imports/Linux/libX11.inc
@@ -46,11 +46,11 @@
XChangeActivePointerGrab ,, 'XChangeActivePointerGrab', \
XChangeGC ,, 'XChangeGC', \
XChangeKeyboardControl ,, 'XChangeKeyboardControl', \
XChangeKeyboardMapping ,, 'XChangeKeyboardMapping', \
XChangePointerControl ,, 'XChangePointerControl', \
- XChangeProperty ,, 'XChangeProperty', \
+ XChangeProperty ,<.display, .wnd, .property, .type, .format, .mode, .pData, .n_elements>, 'XChangeProperty', \
XChangeSaveSet ,, 'XChangeSaveSet', \
XChangeWindowAttributes ,<.display, .hwnd, .valmask, .pSetWinAttr>, 'XChangeWindowAttributes', \
XCheckIfEvent ,, 'XCheckIfEvent', \
XCheckMaskEvent ,, 'XCheckMaskEvent', \
XCheckTypedEvent ,<.display, .event_type, .pEvent>, 'XCheckTypedEvent', \
@@ -57,11 +57,11 @@
XCheckTypedWindowEvent ,, 'XCheckTypedWindowEvent', \
XCheckWindowEvent ,, 'XCheckWindowEvent', \
XCirculateSubwindows ,, 'XCirculateSubwindows', \
XCirculateSubwindowsDown ,, 'XCirculateSubwindowsDown', \
XCirculateSubwindowsUp ,, 'XCirculateSubwindowsUp', \
- XClearArea ,, 'XClearArea', \
+ XClearArea ,<.display, .window, .x, .y, .width, .height, .exposures>, 'XClearArea', \
XClearWindow ,, 'XClearWindow', \
XClipBox ,, 'XClipBox', \
XCloseDisplay ,, 'XCloseDisplay', \
XCloseIM ,, 'XCloseIM', \
XCloseOM ,, 'XCloseOM', \
@@ -77,11 +77,11 @@
XCopyPlane ,, 'XCopyPlane', \
XCreateBitmapFromData ,, 'XCreateBitmapFromData', \
XCreateColormap ,, 'XCreateColormap', \
XCreateFontCursor ,, 'XCreateFontCursor', \
XCreateFontSet ,, 'XCreateFontSet', \
- XCreateGC ,, 'XCreateGC', \
+ XCreateGC ,<.display, .drawable, .mask, .pValues>, 'XCreateGC', \
XCreateGlyphCursor ,, 'XCreateGlyphCursor', \
XCreateIC ,, 'XCreateIC', \
XCreateImage ,, 'XCreateImage', \
XCreateOC ,, 'XCreateOC', \
XCreatePixmap ,, 'XCreatePixmap', \
ADDED freshlib/imports/Win32/gdiplus.inc
Index: freshlib/imports/Win32/gdiplus.inc
==================================================================
--- /dev/null
+++ freshlib/imports/Win32/gdiplus.inc
@@ -0,0 +1,632 @@
+; gdiplus.dll API calls (ASCII)
+import_proto gdiplus, \
+ GdipAddPathArc, , 'GdipAddPathArc', \
+ GdipAddPathArcI, , 'GdipAddPathArcI', \
+ GdipAddPathBezier, , 'GdipAddPathBezier', \
+ GdipAddPathBezierI, , 'GdipAddPathBezierI', \
+ GdipAddPathBeziers, , 'GdipAddPathBeziers', \
+ GdipAddPathBeziersI, , 'GdipAddPathBeziersI', \
+ GdipAddPathClosedCurve, , 'GdipAddPathClosedCurve', \
+ GdipAddPathClosedCurve2, , 'GdipAddPathClosedCurve2', \
+ GdipAddPathClosedCurve2I, , 'GdipAddPathClosedCurve2I', \
+ GdipAddPathClosedCurveI, , 'GdipAddPathClosedCurveI', \
+ GdipAddPathCurve, , 'GdipAddPathCurve', \
+ GdipAddPathCurve2, , 'GdipAddPathCurve2', \
+ GdipAddPathCurve2I, , 'GdipAddPathCurve2I', \
+ GdipAddPathCurve3, , 'GdipAddPathCurve3', \
+ GdipAddPathCurve3I, , 'GdipAddPathCurve3I', \
+ GdipAddPathCurveI, , 'GdipAddPathCurveI', \
+ GdipAddPathEllipse, , 'GdipAddPathEllipse', \
+ GdipAddPathEllipseI, , 'GdipAddPathEllipseI', \
+ GdipAddPathLine, , 'GdipAddPathLine', \
+ GdipAddPathLine2, , 'GdipAddPathLine2', \
+ GdipAddPathLine2I, , 'GdipAddPathLine2I', \
+ GdipAddPathLineI, , 'GdipAddPathLineI', \
+ GdipAddPathPath, , 'GdipAddPathPath', \
+ GdipAddPathPie, , 'GdipAddPathPie', \
+ GdipAddPathPieI, , 'GdipAddPathPieI', \
+ GdipAddPathPolygon, , 'GdipAddPathPolygon', \
+ GdipAddPathPolygonI, , 'GdipAddPathPolygonI', \
+ GdipAddPathRectangle, , 'GdipAddPathRectangle', \
+ GdipAddPathRectangleI, , 'GdipAddPathRectangleI', \
+ GdipAddPathRectangles, , 'GdipAddPathRectangles', \
+ GdipAddPathRectanglesI, , 'GdipAddPathRectanglesI', \
+ GdipAddPathString, , 'GdipAddPathString', \
+ GdipAddPathStringI, , 'GdipAddPathStringI', \
+ GdipAlloc, , 'GdipAlloc', \
+ GdipBeginContainer, , 'GdipBeginContainer', \
+ GdipBeginContainer2, , 'GdipBeginContainer2', \
+ GdipBeginContainerI, , 'GdipBeginContainerI', \
+ GdipBitmapApplyEffect, , 'GdipBitmapApplyEffect', \
+ GdipBitmapConvertFormat, , 'GdipBitmapConvertFormat', \
+ GdipBitmapCreateApplyEffect, , 'GdipBitmapCreateApplyEffect', \
+ GdipBitmapGetHistogram, , 'GdipBitmapGetHistogram', \
+ GdipBitmapGetHistogramSize, , 'GdipBitmapGetHistogramSize', \
+ GdipBitmapGetPixel, , 'GdipBitmapGetPixel', \
+ GdipBitmapLockBits, , 'GdipBitmapLockBits', \
+ GdipBitmapSetPixel, , 'GdipBitmapSetPixel', \
+ GdipBitmapSetResolution, , 'GdipBitmapSetResolution', \
+ GdipBitmapUnlockBits, , 'GdipBitmapUnlockBits', \
+ GdipClearPathMarkers, , 'GdipClearPathMarkers', \
+ GdipCloneBitmapArea, , 'GdipCloneBitmapArea', \
+ GdipCloneBitmapAreaI, , 'GdipCloneBitmapAreaI', \
+ GdipCloneBrush, , 'GdipCloneBrush', \
+ GdipCloneCustomLineCap, , 'GdipCloneCustomLineCap', \
+ GdipCloneFont, , 'GdipCloneFont', \
+ GdipCloneFontFamily, , 'GdipCloneFontFamily', \
+ GdipCloneImage, , 'GdipCloneImage', \
+ GdipCloneImageAttributes, , 'GdipCloneImageAttributes', \
+ GdipCloneMatrix, , 'GdipCloneMatrix', \
+ GdipClonePath, , 'GdipClonePath', \
+ GdipClonePen, , 'GdipClonePen', \
+ GdipCloneRegion, , 'GdipCloneRegion', \
+ GdipCloneStringFormat, , 'GdipCloneStringFormat', \
+ GdipClosePathFigure, , 'GdipClosePathFigure', \
+ GdipClosePathFigures, , 'GdipClosePathFigures', \
+ GdipCombineRegionPath, , 'GdipCombineRegionPath', \
+ GdipCombineRegionRect, , 'GdipCombineRegionRect', \
+ GdipCombineRegionRectI, , 'GdipCombineRegionRectI', \
+ GdipCombineRegionRegion, , 'GdipCombineRegionRegion', \
+ GdipComment, , 'GdipComment', \
+ GdipConvertToEmfPlus, , 'GdipConvertToEmfPlus', \
+ GdipConvertToEmfPlusToFile, , 'GdipConvertToEmfPlusToFile', \
+ GdipConvertToEmfPlusToStream, , 'GdipConvertToEmfPlusToStream', \
+ GdipCreateAdjustableArrowCap, , 'GdipCreateAdjustableArrowCap', \
+ GdipCreateBitmapFromDirectDrawSurface, , 'GdipCreateBitmapFromDirectDrawSurface', \
+ GdipCreateBitmapFromFile, , 'GdipCreateBitmapFromFile', \
+ GdipCreateBitmapFromFileICM, , 'GdipCreateBitmapFromFileICM', \
+ GdipCreateBitmapFromGdiDib, , 'GdipCreateBitmapFromGdiDib', \
+ GdipCreateBitmapFromGraphics, , 'GdipCreateBitmapFromGraphics', \
+ GdipCreateBitmapFromHBITMAP, , 'GdipCreateBitmapFromHBITMAP', \
+ GdipCreateBitmapFromHICON, , 'GdipCreateBitmapFromHICON', \
+ GdipCreateBitmapFromResource, , 'GdipCreateBitmapFromResource', \
+ GdipCreateBitmapFromScan0, , 'GdipCreateBitmapFromScan0', \
+ GdipCreateBitmapFromStream, , 'GdipCreateBitmapFromStream', \
+ GdipCreateBitmapFromStreamICM, , 'GdipCreateBitmapFromStreamICM', \
+ GdipCreateCachedBitmap, , 'GdipCreateCachedBitmap', \
+ GdipCreateCustomLineCap, , 'GdipCreateCustomLineCap', \
+ GdipCreateEffect, , 'GdipCreateEffect', \
+ GdipCreateFont, , 'GdipCreateFont', \
+ GdipCreateFontFamilyFromName, , 'GdipCreateFontFamilyFromName', \
+ GdipCreateFontFromDC, , 'GdipCreateFontFromDC', \
+ GdipCreateFontFromLogfontA, , 'GdipCreateFontFromLogfontA', \
+ GdipCreateFontFromLogfontW, , 'GdipCreateFontFromLogfontW', \
+ GdipCreateFromHDC, , 'GdipCreateFromHDC', \
+ GdipCreateFromHDC2, , 'GdipCreateFromHDC2', \
+ GdipCreateFromHWND, , 'GdipCreateFromHWND', \
+ GdipCreateFromHWNDICM, , 'GdipCreateFromHWNDICM', \
+ GdipCreateHBITMAPFromBitmap, , 'GdipCreateHBITMAPFromBitmap', \
+ GdipCreateHICONFromBitmap, , 'GdipCreateHICONFromBitmap', \
+ GdipCreateHalftonePalette, , 'GdipCreateHalftonePalette', \
+ GdipCreateHatchBrush, , 'GdipCreateHatchBrush', \
+ GdipCreateImageAttributes, , 'GdipCreateImageAttributes', \
+ GdipCreateLineBrush, , 'GdipCreateLineBrush', \
+ GdipCreateLineBrushFromRect, , 'GdipCreateLineBrushFromRect', \
+ GdipCreateLineBrushFromRectI, , 'GdipCreateLineBrushFromRectI', \
+ GdipCreateLineBrushFromRectWithAngle, , 'GdipCreateLineBrushFromRectWithAngle', \
+ GdipCreateLineBrushFromRectWithAngleI, , 'GdipCreateLineBrushFromRectWithAngleI', \
+ GdipCreateLineBrushI, , 'GdipCreateLineBrushI', \
+ GdipCreateMatrix, , 'GdipCreateMatrix', \
+ GdipCreateMatrix2, , 'GdipCreateMatrix2', \
+ GdipCreateMatrix3, , 'GdipCreateMatrix3', \
+ GdipCreateMatrix3I, , 'GdipCreateMatrix3I', \
+ GdipCreateMetafileFromEmf, , 'GdipCreateMetafileFromEmf', \
+ GdipCreateMetafileFromFile, , 'GdipCreateMetafileFromFile', \
+ GdipCreateMetafileFromStream, , 'GdipCreateMetafileFromStream', \
+ GdipCreateMetafileFromWmf, , 'GdipCreateMetafileFromWmf', \
+ GdipCreateMetafileFromWmfFile, , 'GdipCreateMetafileFromWmfFile', \
+ GdipCreatePath, , 'GdipCreatePath', \
+ GdipCreatePath2, , 'GdipCreatePath2', \
+ GdipCreatePath2I, , 'GdipCreatePath2I', \
+ GdipCreatePathGradient, , 'GdipCreatePathGradient', \
+ GdipCreatePathGradientFromPath, , 'GdipCreatePathGradientFromPath', \
+ GdipCreatePathGradientI, , 'GdipCreatePathGradientI', \
+ GdipCreatePathIter, , 'GdipCreatePathIter', \
+ GdipCreatePen1, , 'GdipCreatePen1', \
+ GdipCreatePen2, , 'GdipCreatePen2', \
+ GdipCreateRegion, , 'GdipCreateRegion', \
+ GdipCreateRegionHrgn, , 'GdipCreateRegionHrgn', \
+ GdipCreateRegionPath, , 'GdipCreateRegionPath', \
+ GdipCreateRegionRect, , 'GdipCreateRegionRect', \
+ GdipCreateRegionRectI, , 'GdipCreateRegionRectI', \
+ GdipCreateRegionRgnData, , 'GdipCreateRegionRgnData', \
+ GdipCreateSolidFill, , 'GdipCreateSolidFill', \
+ GdipCreateStreamOnFile, , 'GdipCreateStreamOnFile', \
+ GdipCreateStringFormat, , 'GdipCreateStringFormat', \
+ GdipCreateTexture, , 'GdipCreateTexture', \
+ GdipCreateTexture2, , 'GdipCreateTexture2', \
+ GdipCreateTexture2I, , 'GdipCreateTexture2I', \
+ GdipCreateTextureIA, , 'GdipCreateTextureIA', \
+ GdipCreateTextureIAI, , 'GdipCreateTextureIAI', \
+ GdipDeleteBrush, , 'GdipDeleteBrush', \
+ GdipDeleteCachedBitmap, , 'GdipDeleteCachedBitmap', \
+ GdipDeleteCustomLineCap, , 'GdipDeleteCustomLineCap', \
+ GdipDeleteEffect, , 'GdipDeleteEffect', \
+ GdipDeleteFont, , 'GdipDeleteFont', \
+ GdipDeleteFontFamily, , 'GdipDeleteFontFamily', \
+ GdipDeleteGraphics, , 'GdipDeleteGraphics', \
+ GdipDeleteMatrix, , 'GdipDeleteMatrix', \
+ GdipDeletePath, , 'GdipDeletePath', \
+ GdipDeletePathIter, , 'GdipDeletePathIter', \
+ GdipDeletePen, , 'GdipDeletePen', \
+ GdipDeletePrivateFontCollection, , 'GdipDeletePrivateFontCollection', \
+ GdipDeleteRegion, , 'GdipDeleteRegion', \
+ GdipDeleteStringFormat, , 'GdipDeleteStringFormat', \
+ GdipDisposeImage, , 'GdipDisposeImage', \
+ GdipDisposeImageAttributes, , 'GdipDisposeImageAttributes', \
+ GdipDrawArc, , 'GdipDrawArc', \
+ GdipDrawArcI, , 'GdipDrawArcI', \
+ GdipDrawBezier, , 'GdipDrawBezier', \
+ GdipDrawBezierI, , 'GdipDrawBezierI', \
+ GdipDrawBeziers, , 'GdipDrawBeziers', \
+ GdipDrawBeziersI, , 'GdipDrawBeziersI', \
+ GdipDrawCachedBitmap, , 'GdipDrawCachedBitmap', \
+ GdipDrawClosedCurve, , 'GdipDrawClosedCurve', \
+ GdipDrawClosedCurve2, , 'GdipDrawClosedCurve2', \
+ GdipDrawClosedCurve2I, , 'GdipDrawClosedCurve2I', \
+ GdipDrawClosedCurveI, , 'GdipDrawClosedCurveI', \
+ GdipDrawCurve, , 'GdipDrawCurve', \
+ GdipDrawCurve2, , 'GdipDrawCurve2', \
+ GdipDrawCurve2I, , 'GdipDrawCurve2I', \
+ GdipDrawCurve3, , 'GdipDrawCurve3', \
+ GdipDrawCurve3I, , 'GdipDrawCurve3I', \
+ GdipDrawCurveI, , 'GdipDrawCurveI', \
+ GdipDrawDriverString, , 'GdipDrawDriverString', \
+ GdipDrawEllipse, , 'GdipDrawEllipse', \
+ GdipDrawEllipseI, , 'GdipDrawEllipseI', \
+ GdipDrawImage, , 'GdipDrawImage', \
+ GdipDrawImageFX, , 'GdipDrawImageFX', \
+ GdipDrawImageI, , 'GdipDrawImageI', \
+ GdipDrawImagePointRect, , 'GdipDrawImagePointRect', \
+ GdipDrawImagePointRectI, , 'GdipDrawImagePointRectI', \
+ GdipDrawImagePoints, , 'GdipDrawImagePoints', \
+ GdipDrawImagePointsI, , 'GdipDrawImagePointsI', \
+ GdipDrawImagePointsRect, , 'GdipDrawImagePointsRect', \
+ GdipDrawImagePointsRectI, , 'GdipDrawImagePointsRectI', \
+ GdipDrawImageRect, , 'GdipDrawImageRect', \
+ GdipDrawImageRectI, , 'GdipDrawImageRectI', \
+ GdipDrawImageRectRect, , 'GdipDrawImageRectRect', \
+ GdipDrawImageRectRectI, , 'GdipDrawImageRectRectI', \
+ GdipDrawLine, , 'GdipDrawLine', \
+ GdipDrawLineI, , 'GdipDrawLineI', \
+ GdipDrawLines, , 'GdipDrawLines', \
+ GdipDrawLinesI, , 'GdipDrawLinesI', \
+ GdipDrawPath, , 'GdipDrawPath', \
+ GdipDrawPie, , 'GdipDrawPie', \
+ GdipDrawPieI, , 'GdipDrawPieI', \
+ GdipDrawPolygon, , 'GdipDrawPolygon', \
+ GdipDrawPolygonI, , 'GdipDrawPolygonI', \
+ GdipDrawRectangle, , 'GdipDrawRectangle', \
+ GdipDrawRectangleI, , 'GdipDrawRectangleI', \
+ GdipDrawRectangles, , 'GdipDrawRectangles', \
+ GdipDrawRectanglesI, , 'GdipDrawRectanglesI', \
+ GdipDrawString, , 'GdipDrawString', \
+ GdipEmfToWmfBits, , 'GdipEmfToWmfBits', \
+ GdipEndContainer, , 'GdipEndContainer', \
+ GdipEnumerateMetafileDestPoint, , 'GdipEnumerateMetafileDestPoint', \
+ GdipEnumerateMetafileDestPointI, , 'GdipEnumerateMetafileDestPointI', \
+ GdipEnumerateMetafileDestPoints, , 'GdipEnumerateMetafileDestPoints', \
+ GdipEnumerateMetafileDestPointsI, , 'GdipEnumerateMetafileDestPointsI', \
+ GdipEnumerateMetafileDestRect, , 'GdipEnumerateMetafileDestRect', \
+ GdipEnumerateMetafileDestRectI, , 'GdipEnumerateMetafileDestRectI', \
+ GdipEnumerateMetafileSrcRectDestPoint, , 'GdipEnumerateMetafileSrcRectDestPoint', \
+ GdipEnumerateMetafileSrcRectDestPointI, , 'GdipEnumerateMetafileSrcRectDestPointI', \
+ GdipEnumerateMetafileSrcRectDestPoints, , 'GdipEnumerateMetafileSrcRectDestPoints', \
+ GdipEnumerateMetafileSrcRectDestPointsI, , 'GdipEnumerateMetafileSrcRectDestPointsI', \
+ GdipEnumerateMetafileSrcRectDestRect,