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 @@ + + + +image/svg+xml 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 @@ + + + +image/svg+xml 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 @@ + + + +image/svg+xml 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 @@ + + + +image/svg+xml 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 @@ + + + +image/svg+xml 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 @@ + + + +image/svg+xml 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 @@ + + + +image/svg+xml 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 @@ + + + +image/svg+xml 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 @@ + + + +image/svg+xml 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 @@ + + + +image/svg+xml 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 @@ + + + +image/svg+xml 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 @@ + + + +image/svg+xml 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 @@ + + + +image/svg+xml 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 @@ + + + +image/svg+xml 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 @@ + + + +image/svg+xml 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 @@ + + + +image/svg+xml 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 @@ + + + +image/svg+xml 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, , 'GdipEnumerateMetafileSrcRectDestRect', \ + GdipEnumerateMetafileSrcRectDestRectI, , 'GdipEnumerateMetafileSrcRectDestRectI', \ + GdipFillClosedCurve, , 'GdipFillClosedCurve', \ + GdipFillClosedCurve2, , 'GdipFillClosedCurve2', \ + GdipFillClosedCurve2I, , 'GdipFillClosedCurve2I', \ + GdipFillClosedCurveI, , 'GdipFillClosedCurveI', \ + GdipFillEllipse, , 'GdipFillEllipse', \ + GdipFillEllipseI, , 'GdipFillEllipseI', \ + GdipFillPath, , 'GdipFillPath', \ + GdipFillPie, , 'GdipFillPie', \ + GdipFillPieI, , 'GdipFillPieI', \ + GdipFillPolygon, , 'GdipFillPolygon', \ + GdipFillPolygon2, , 'GdipFillPolygon2', \ + GdipFillPolygon2I, , 'GdipFillPolygon2I', \ + GdipFillPolygonI, , 'GdipFillPolygonI', \ + GdipFillRectangle, , 'GdipFillRectangle', \ + GdipFillRectangleI, , 'GdipFillRectangleI', \ + GdipFillRectangles, , 'GdipFillRectangles', \ + GdipFillRectanglesI, , 'GdipFillRectanglesI', \ + GdipFillRegion, , 'GdipFillRegion', \ + GdipFindFirstImageItem, , 'GdipFindFirstImageItem', \ + GdipFindNextImageItem, , 'GdipFindNextImageItem', \ + GdipFlattenPath, , 'GdipFlattenPath', \ + GdipFlush, , 'GdipFlush', \ + GdipFree, , 'GdipFree', \ + GdipGetAdjustableArrowCapFillState, , 'GdipGetAdjustableArrowCapFillState', \ + GdipGetAdjustableArrowCapHeight, , 'GdipGetAdjustableArrowCapHeight', \ + GdipGetAdjustableArrowCapMiddleInset, , 'GdipGetAdjustableArrowCapMiddleInset', \ + GdipGetAdjustableArrowCapWidth, , 'GdipGetAdjustableArrowCapWidth', \ + GdipGetAllPropertyItems, , 'GdipGetAllPropertyItems', \ + GdipGetBrushType, , 'GdipGetBrushType', \ + GdipGetCellAscent, , 'GdipGetCellAscent', \ + GdipGetCellDescent, , 'GdipGetCellDescent', \ + GdipGetClip, , 'GdipGetClip', \ + GdipGetClipBounds, , 'GdipGetClipBounds', \ + GdipGetClipBoundsI, , 'GdipGetClipBoundsI', \ + GdipGetCompositingMode, , 'GdipGetCompositingMode', \ + GdipGetCompositingQuality, , 'GdipGetCompositingQuality', \ + GdipGetCustomLineCapBaseCap, , 'GdipGetCustomLineCapBaseCap', \ + GdipGetCustomLineCapBaseInset, , 'GdipGetCustomLineCapBaseInset', \ + GdipGetCustomLineCapStrokeCaps, , 'GdipGetCustomLineCapStrokeCaps', \ + GdipGetCustomLineCapStrokeJoin, , 'GdipGetCustomLineCapStrokeJoin', \ + GdipGetCustomLineCapType, , 'GdipGetCustomLineCapType', \ + GdipGetCustomLineCapWidthScale, , 'GdipGetCustomLineCapWidthScale', \ + GdipGetDC, , 'GdipGetDC', \ + GdipGetDpiX, , 'GdipGetDpiX', \ + GdipGetDpiY, , 'GdipGetDpiY', \ + GdipGetEffectParameterSize, , 'GdipGetEffectParameterSize', \ + GdipGetEffectParameters, , 'GdipGetEffectParameters', \ + GdipGetEmHeight, , 'GdipGetEmHeight', \ + GdipGetEncoderParameterList, , 'GdipGetEncoderParameterList', \ + GdipGetEncoderParameterListSize, , 'GdipGetEncoderParameterListSize', \ + GdipGetFamily, , 'GdipGetFamily', \ + GdipGetFamilyName, , 'GdipGetFamilyName', \ + GdipGetFontCollectionFamilyCount, , 'GdipGetFontCollectionFamilyCount', \ + GdipGetFontCollectionFamilyList, , 'GdipGetFontCollectionFamilyList', \ + GdipGetFontHeight, , 'GdipGetFontHeight', \ + GdipGetFontHeightGivenDPI, , 'GdipGetFontHeightGivenDPI', \ + GdipGetFontSize, , 'GdipGetFontSize', \ + GdipGetFontStyle, , 'GdipGetFontStyle', \ + GdipGetFontUnit, , 'GdipGetFontUnit', \ + GdipGetGenericFontFamilyMonospace, , 'GdipGetGenericFontFamilyMonospace', \ + GdipGetGenericFontFamilySansSerif, , 'GdipGetGenericFontFamilySansSerif', \ + GdipGetGenericFontFamilySerif, , 'GdipGetGenericFontFamilySerif', \ + GdipGetHatchBackgroundColor, , 'GdipGetHatchBackgroundColor', \ + GdipGetHatchForegroundColor, , 'GdipGetHatchForegroundColor', \ + GdipGetHatchStyle, , 'GdipGetHatchStyle', \ + GdipGetHemfFromMetafile, , 'GdipGetHemfFromMetafile', \ + GdipGetImageAttributesAdjustedPalette, , 'GdipGetImageAttributesAdjustedPalette', \ + GdipGetImageBounds, , 'GdipGetImageBounds', \ + GdipGetImageDecoders, , 'GdipGetImageDecoders', \ + GdipGetImageDecodersSize, , 'GdipGetImageDecodersSize', \ + GdipGetImageDimension, , 'GdipGetImageDimension', \ + GdipGetImageEncoders, , 'GdipGetImageEncoders', \ + GdipGetImageEncodersSize, , 'GdipGetImageEncodersSize', \ + GdipGetImageFlags, , 'GdipGetImageFlags', \ + GdipGetImageGraphicsContext, , 'GdipGetImageGraphicsContext', \ + GdipGetImageHeight, , 'GdipGetImageHeight', \ + GdipGetImageHorizontalResolution, , 'GdipGetImageHorizontalResolution', \ + GdipGetImageItemData, , 'GdipGetImageItemData', \ + GdipGetImagePalette, , 'GdipGetImagePalette', \ + GdipGetImagePaletteSize, , 'GdipGetImagePaletteSize', \ + GdipGetImagePixelFormat, , 'GdipGetImagePixelFormat', \ + GdipGetImageRawFormat, , 'GdipGetImageRawFormat', \ + GdipGetImageThumbnail, , 'GdipGetImageThumbnail', \ + GdipGetImageType, , 'GdipGetImageType', \ + GdipGetImageVerticalResolution, , 'GdipGetImageVerticalResolution', \ + GdipGetImageWidth, , 'GdipGetImageWidth', \ + GdipGetInterpolationMode, , 'GdipGetInterpolationMode', \ + GdipGetLineBlend, , 'GdipGetLineBlend', \ + GdipGetLineBlendCount, , 'GdipGetLineBlendCount', \ + GdipGetLineColors, , 'GdipGetLineColors', \ + GdipGetLineGammaCorrection, , 'GdipGetLineGammaCorrection', \ + GdipGetLinePresetBlend, , 'GdipGetLinePresetBlend', \ + GdipGetLinePresetBlendCount, , 'GdipGetLinePresetBlendCount', \ + GdipGetLineRect, , 'GdipGetLineRect', \ + GdipGetLineRectI, , 'GdipGetLineRectI', \ + GdipGetLineSpacing, , 'GdipGetLineSpacing', \ + GdipGetLineTransform, , 'GdipGetLineTransform', \ + GdipGetLineWrapMode, , 'GdipGetLineWrapMode', \ + GdipGetLogFontA, , 'GdipGetLogFontA', \ + GdipGetLogFontW, , 'GdipGetLogFontW', \ + GdipGetMatrixElements, , 'GdipGetMatrixElements', \ + GdipGetMetafileDownLevelRasterizationLimit, , 'GdipGetMetafileDownLevelRasterizationLimit', \ + GdipGetMetafileHeaderFromEmf, , 'GdipGetMetafileHeaderFromEmf', \ + GdipGetMetafileHeaderFromFile, , 'GdipGetMetafileHeaderFromFile', \ + GdipGetMetafileHeaderFromMetafile, , 'GdipGetMetafileHeaderFromMetafile', \ + GdipGetMetafileHeaderFromStream, , 'GdipGetMetafileHeaderFromStream', \ + GdipGetMetafileHeaderFromWmf, , 'GdipGetMetafileHeaderFromWmf', \ + GdipGetNearestColor, , 'GdipGetNearestColor', \ + GdipGetPageScale, , 'GdipGetPageScale', \ + GdipGetPageUnit, , 'GdipGetPageUnit', \ + GdipGetPathData, , 'GdipGetPathData', \ + GdipGetPathFillMode, , 'GdipGetPathFillMode', \ + GdipGetPathGradientBlend, , 'GdipGetPathGradientBlend', \ + GdipGetPathGradientBlendCount, , 'GdipGetPathGradientBlendCount', \ + GdipGetPathGradientCenterColor, , 'GdipGetPathGradientCenterColor', \ + GdipGetPathGradientCenterPoint, , 'GdipGetPathGradientCenterPoint', \ + GdipGetPathGradientCenterPointI, , 'GdipGetPathGradientCenterPointI', \ + GdipGetPathGradientFocusScales, , 'GdipGetPathGradientFocusScales', \ + GdipGetPathGradientGammaCorrection, , 'GdipGetPathGradientGammaCorrection', \ + GdipGetPathGradientPath, , 'GdipGetPathGradientPath', \ + GdipGetPathGradientPointCount, , 'GdipGetPathGradientPointCount', \ + GdipGetPathGradientPresetBlend, , 'GdipGetPathGradientPresetBlend', \ + GdipGetPathGradientPresetBlendCount, , 'GdipGetPathGradientPresetBlendCount', \ + GdipGetPathGradientRect, , 'GdipGetPathGradientRect', \ + GdipGetPathGradientRectI, , 'GdipGetPathGradientRectI', \ + GdipGetPathGradientSurroundColorCount, , 'GdipGetPathGradientSurroundColorCount', \ + GdipGetPathGradientSurroundColorsWithCount, , 'GdipGetPathGradientSurroundColorsWithCount', \ + GdipGetPathGradientTransform, , 'GdipGetPathGradientTransform', \ + GdipGetPathGradientWrapMode, , 'GdipGetPathGradientWrapMode', \ + GdipGetPathLastPoint, , 'GdipGetPathLastPoint', \ + GdipGetPathPoints, , 'GdipGetPathPoints', \ + GdipGetPathPointsI, , 'GdipGetPathPointsI', \ + GdipGetPathTypes, , 'GdipGetPathTypes', \ + GdipGetPathWorldBounds, , 'GdipGetPathWorldBounds', \ + GdipGetPathWorldBoundsI, , 'GdipGetPathWorldBoundsI', \ + GdipGetPenBrushFill, , 'GdipGetPenBrushFill', \ + GdipGetPenColor, , 'GdipGetPenColor', \ + GdipGetPenCompoundArray, , 'GdipGetPenCompoundArray', \ + GdipGetPenCompoundCount, , 'GdipGetPenCompoundCount', \ + GdipGetPenCustomEndCap, , 'GdipGetPenCustomEndCap', \ + GdipGetPenCustomStartCap, , 'GdipGetPenCustomStartCap', \ + GdipGetPenDashArray, , 'GdipGetPenDashArray', \ + GdipGetPenDashCap197819, , 'GdipGetPenDashCap197819', \ + GdipGetPenDashCount, , 'GdipGetPenDashCount', \ + GdipGetPenDashOffset, , 'GdipGetPenDashOffset', \ + GdipGetPenDashStyle, , 'GdipGetPenDashStyle', \ + GdipGetPenEndCap, , 'GdipGetPenEndCap', \ + GdipGetPenFillType, , 'GdipGetPenFillType', \ + GdipGetPenLineJoin, , 'GdipGetPenLineJoin', \ + GdipGetPenMiterLimit, , 'GdipGetPenMiterLimit', \ + GdipGetPenMode, , 'GdipGetPenMode', \ + GdipGetPenStartCap, , 'GdipGetPenStartCap', \ + GdipGetPenTransform, , 'GdipGetPenTransform', \ + GdipGetPenUnit, , 'GdipGetPenUnit', \ + GdipGetPenWidth, , 'GdipGetPenWidth', \ + GdipGetPixelOffsetMode, , 'GdipGetPixelOffsetMode', \ + GdipGetPointCount, , 'GdipGetPointCount', \ + GdipGetPropertyCount, , 'GdipGetPropertyCount', \ + GdipGetPropertyIdList, , 'GdipGetPropertyIdList', \ + GdipGetPropertyItem, , 'GdipGetPropertyItem', \ + GdipGetPropertyItemSize, , 'GdipGetPropertyItemSize', \ + GdipGetPropertySize, , 'GdipGetPropertySize', \ + GdipGetRegionBounds, , 'GdipGetRegionBounds', \ + GdipGetRegionBoundsI, , 'GdipGetRegionBoundsI', \ + GdipGetRegionData, , 'GdipGetRegionData', \ + GdipGetRegionDataSize, , 'GdipGetRegionDataSize', \ + GdipGetRegionHRgn, , 'GdipGetRegionHRgn', \ + GdipGetRegionScans, , 'GdipGetRegionScans', \ + GdipGetRegionScansCount, , 'GdipGetRegionScansCount', \ + GdipGetRegionScansI, , 'GdipGetRegionScansI', \ + GdipGetRenderingOrigin, , 'GdipGetRenderingOrigin', \ + GdipGetSmoothingMode, , 'GdipGetSmoothingMode', \ + GdipGetSolidFillColor, , 'GdipGetSolidFillColor', \ + GdipGetStringFormatAlign, , 'GdipGetStringFormatAlign', \ + GdipGetStringFormatDigitSubstitution, , 'GdipGetStringFormatDigitSubstitution', \ + GdipGetStringFormatFlags, , 'GdipGetStringFormatFlags', \ + GdipGetStringFormatHotkeyPrefix, , 'GdipGetStringFormatHotkeyPrefix', \ + GdipGetStringFormatLineAlign, , 'GdipGetStringFormatLineAlign', \ + GdipGetStringFormatMeasurableCharacterRangeCount, , 'GdipGetStringFormatMeasurableCharacterRangeCount', \ + GdipGetStringFormatTabStopCount, , 'GdipGetStringFormatTabStopCount', \ + GdipGetStringFormatTabStops, , 'GdipGetStringFormatTabStops', \ + GdipGetStringFormatTrimming, , 'GdipGetStringFormatTrimming', \ + GdipGetTextContrast, , 'GdipGetTextContrast', \ + GdipGetTextRenderingHint, , 'GdipGetTextRenderingHint', \ + GdipGetTextureImage, , 'GdipGetTextureImage', \ + GdipGetTextureTransform, , 'GdipGetTextureTransform', \ + GdipGetTextureWrapMode, , 'GdipGetTextureWrapMode', \ + GdipGetVisibleClipBounds, , 'GdipGetVisibleClipBounds', \ + GdipGetVisibleClipBoundsI, , 'GdipGetVisibleClipBoundsI', \ + GdipGetWorldTransform, , 'GdipGetWorldTransform', \ + GdipGraphicsClear, , 'GdipGraphicsClear', \ + GdipGraphicsSetAbort, , 'GdipGraphicsSetAbort', \ + GdipImageForceValidation, , 'GdipImageForceValidation', \ + GdipImageGetFrameCount, , 'GdipImageGetFrameCount', \ + GdipImageGetFrameDimensionsCount, , 'GdipImageGetFrameDimensionsCount', \ + GdipImageGetFrameDimensionsList, , 'GdipImageGetFrameDimensionsList', \ + GdipImageRotateFlip, , 'GdipImageRotateFlip', \ + GdipImageSelectActiveFrame, , 'GdipImageSelectActiveFrame', \ + GdipImageSetAbort, , 'GdipImageSetAbort', \ + GdipInitializePalette, , 'GdipInitializePalette', \ + GdipInvertMatrix, , 'GdipInvertMatrix', \ + GdipIsClipEmpty, , 'GdipIsClipEmpty', \ + GdipIsEmptyRegion, , 'GdipIsEmptyRegion', \ + GdipIsEqualRegion, , 'GdipIsEqualRegion', \ + GdipIsInfiniteRegion, , 'GdipIsInfiniteRegion', \ + GdipIsMatrixEqual, , 'GdipIsMatrixEqual', \ + GdipIsMatrixIdentity, , 'GdipIsMatrixIdentity', \ + GdipIsMatrixInvertible, , 'GdipIsMatrixInvertible', \ + GdipIsOutlineVisiblePathPoint, , 'GdipIsOutlineVisiblePathPoint', \ + GdipIsOutlineVisiblePathPointI, , 'GdipIsOutlineVisiblePathPointI', \ + GdipIsStyleAvailable, , 'GdipIsStyleAvailable', \ + GdipIsVisibleClipEmpty, , 'GdipIsVisibleClipEmpty', \ + GdipIsVisiblePathPoint, , 'GdipIsVisiblePathPoint', \ + GdipIsVisiblePathPointI, , 'GdipIsVisiblePathPointI', \ + GdipIsVisiblePoint, , 'GdipIsVisiblePoint', \ + GdipIsVisiblePointI, , 'GdipIsVisiblePointI', \ + GdipIsVisibleRect, , 'GdipIsVisibleRect', \ + GdipIsVisibleRectI, , 'GdipIsVisibleRectI', \ + GdipIsVisibleRegionPoint, , 'GdipIsVisibleRegionPoint', \ + GdipIsVisibleRegionPointI, , 'GdipIsVisibleRegionPointI', \ + GdipIsVisibleRegionRect, , 'GdipIsVisibleRegionRect', \ + GdipIsVisibleRegionRectI, , 'GdipIsVisibleRegionRectI', \ + GdipLoadImageFromFile, , 'GdipLoadImageFromFile', \ + GdipLoadImageFromFileICM, , 'GdipLoadImageFromFileICM', \ + GdipLoadImageFromStream, , 'GdipLoadImageFromStream', \ + GdipLoadImageFromStreamICM, , 'GdipLoadImageFromStreamICM', \ + GdipMeasureCharacterRanges, , 'GdipMeasureCharacterRanges', \ + GdipMeasureDriverString, , 'GdipMeasureDriverString', \ + GdipMeasureString, , 'GdipMeasureString', \ + GdipMultiplyLineTransform, , 'GdipMultiplyLineTransform', \ + GdipMultiplyMatrix, , 'GdipMultiplyMatrix', \ + GdipMultiplyPathGradientTransform, , 'GdipMultiplyPathGradientTransform', \ + GdipMultiplyPenTransform, , 'GdipMultiplyPenTransform', \ + GdipMultiplyTextureTransform, , 'GdipMultiplyTextureTransform', \ + GdipMultiplyWorldTransform, , 'GdipMultiplyWorldTransform', \ + GdipNewInstalledFontCollection, , 'GdipNewInstalledFontCollection', \ + GdipNewPrivateFontCollection, , 'GdipNewPrivateFontCollection', \ + GdipPathIterCopyData, , 'GdipPathIterCopyData', \ + GdipPathIterEnumerate, , 'GdipPathIterEnumerate', \ + GdipPathIterGetCount, , 'GdipPathIterGetCount', \ + GdipPathIterGetSubpathCount, , 'GdipPathIterGetSubpathCount', \ + GdipPathIterHasCurve, , 'GdipPathIterHasCurve', \ + GdipPathIterIsValid, , 'GdipPathIterIsValid', \ + GdipPathIterNextMarker, , 'GdipPathIterNextMarker', \ + GdipPathIterNextMarkerPath, , 'GdipPathIterNextMarkerPath', \ + GdipPathIterNextPathType, , 'GdipPathIterNextPathType', \ + GdipPathIterNextSubpath, , 'GdipPathIterNextSubpath', \ + GdipPathIterNextSubpathPath, , 'GdipPathIterNextSubpathPath', \ + GdipPathIterRewind, , 'GdipPathIterRewind', \ + GdipPlayMetafileRecord, , 'GdipPlayMetafileRecord', \ + GdipPlayTSClientRecord, , 'GdipPlayTSClientRecord', \ + GdipPrivateAddFontFile, , 'GdipPrivateAddFontFile', \ + GdipPrivateAddMemoryFont, , 'GdipPrivateAddMemoryFont', \ + GdipRecordMetafile, , 'GdipRecordMetafile', \ + GdipRecordMetafileFileName, , 'GdipRecordMetafileFileName', \ + GdipRecordMetafileFileNameI, , 'GdipRecordMetafileFileNameI', \ + GdipRecordMetafileI, , 'GdipRecordMetafileI', \ + GdipRecordMetafileStream, , 'GdipRecordMetafileStream', \ + GdipRecordMetafileStreamI, , 'GdipRecordMetafileStreamI', \ + GdipReleaseDC, , 'GdipReleaseDC', \ + GdipRemovePropertyItem, , 'GdipRemovePropertyItem', \ + GdipResetClip, , 'GdipResetClip', \ + GdipResetImageAttributes, , 'GdipResetImageAttributes', \ + GdipResetLineTransform, , 'GdipResetLineTransform', \ + GdipResetPageTransform, , 'GdipResetPageTransform', \ + GdipResetPath, , 'GdipResetPath', \ + GdipResetPathGradientTransform, , 'GdipResetPathGradientTransform', \ + GdipResetPenTransform, , 'GdipResetPenTransform', \ + GdipResetTextureTransform, , 'GdipResetTextureTransform', \ + GdipResetWorldTransform, , 'GdipResetWorldTransform', \ + GdipRestoreGraphics, , 'GdipRestoreGraphics', \ + GdipReversePath, , 'GdipReversePath', \ + GdipRotateLineTransform, , 'GdipRotateLineTransform', \ + GdipRotateMatrix, , 'GdipRotateMatrix', \ + GdipRotatePathGradientTransform, , 'GdipRotatePathGradientTransform', \ + GdipRotatePenTransform, , 'GdipRotatePenTransform', \ + GdipRotateTextureTransform, , 'GdipRotateTextureTransform', \ + GdipRotateWorldTransform, , 'GdipRotateWorldTransform', \ + GdipSaveAdd, , 'GdipSaveAdd', \ + GdipSaveAddImage, , 'GdipSaveAddImage', \ + GdipSaveGraphics, , 'GdipSaveGraphics', \ + GdipSaveImageToFile, , 'GdipSaveImageToFile', \ + GdipSaveImageToStream, , 'GdipSaveImageToStream', \ + GdipScaleLineTransform, , 'GdipScaleLineTransform', \ + GdipScaleMatrix, , 'GdipScaleMatrix', \ + GdipScalePathGradientTransform, , 'GdipScalePathGradientTransform', \ + GdipScalePenTransform, , 'GdipScalePenTransform', \ + GdipScaleTextureTransform, , 'GdipScaleTextureTransform', \ + GdipScaleWorldTransform, , 'GdipScaleWorldTransform', \ + GdipSetAdjustableArrowCapFillState, , 'GdipSetAdjustableArrowCapFillState', \ + GdipSetAdjustableArrowCapHeight, , 'GdipSetAdjustableArrowCapHeight', \ + GdipSetAdjustableArrowCapMiddleInset, , 'GdipSetAdjustableArrowCapMiddleInset', \ + GdipSetAdjustableArrowCapWidth, , 'GdipSetAdjustableArrowCapWidth', \ + GdipSetClipGraphics, , 'GdipSetClipGraphics', \ + GdipSetClipHrgn, , 'GdipSetClipHrgn', \ + GdipSetClipPath, , 'GdipSetClipPath', \ + GdipSetClipRect, , 'GdipSetClipRect', \ + GdipSetClipRectI, , 'GdipSetClipRectI', \ + GdipSetClipRegion, , 'GdipSetClipRegion', \ + GdipSetCompositingMode, , 'GdipSetCompositingMode', \ + GdipSetCompositingQuality, , 'GdipSetCompositingQuality', \ + GdipSetCustomLineCapBaseCap, , 'GdipSetCustomLineCapBaseCap', \ + GdipSetCustomLineCapBaseInset, , 'GdipSetCustomLineCapBaseInset', \ + GdipSetCustomLineCapStrokeCaps, , 'GdipSetCustomLineCapStrokeCaps', \ + GdipSetCustomLineCapStrokeJoin, , 'GdipSetCustomLineCapStrokeJoin', \ + GdipSetCustomLineCapWidthScale, , 'GdipSetCustomLineCapWidthScale', \ + GdipSetEffectParameters, , 'GdipSetEffectParameters', \ + GdipSetEmpty, , 'GdipSetEmpty', \ + GdipSetImageAttributesCachedBackground, , 'GdipSetImageAttributesCachedBackground', \ + GdipSetImageAttributesColorKeys, , 'GdipSetImageAttributesColorKeys', \ + GdipSetImageAttributesColorMatrix, , 'GdipSetImageAttributesColorMatrix', \ + GdipSetImageAttributesGamma, , 'GdipSetImageAttributesGamma', \ + GdipSetImageAttributesNoOp, , 'GdipSetImageAttributesNoOp', \ + GdipSetImageAttributesOutputChannel, , 'GdipSetImageAttributesOutputChannel', \ + GdipSetImageAttributesOutputChannelColorProfile, , 'GdipSetImageAttributesOutputChannelColorProfile', \ + GdipSetImageAttributesRemapTable, , 'GdipSetImageAttributesRemapTable', \ + GdipSetImageAttributesThreshold, , 'GdipSetImageAttributesThreshold', \ + GdipSetImageAttributesToIdentity, , 'GdipSetImageAttributesToIdentity', \ + GdipSetImageAttributesWrapMode, , 'GdipSetImageAttributesWrapMode', \ + GdipSetImagePalette, , 'GdipSetImagePalette', \ + GdipSetInfinite, , 'GdipSetInfinite', \ + GdipSetInterpolationMode, , 'GdipSetInterpolationMode', \ + GdipSetLineBlend, , 'GdipSetLineBlend', \ + GdipSetLineColors, , 'GdipSetLineColors', \ + GdipSetLineGammaCorrection, , 'GdipSetLineGammaCorrection', \ + GdipSetLineLinearBlend, , 'GdipSetLineLinearBlend', \ + GdipSetLinePresetBlend, , 'GdipSetLinePresetBlend', \ + GdipSetLineSigmaBlend, , 'GdipSetLineSigmaBlend', \ + GdipSetLineTransform, , 'GdipSetLineTransform', \ + GdipSetLineWrapMode, , 'GdipSetLineWrapMode', \ + GdipSetMatrixElements, , 'GdipSetMatrixElements', \ + GdipSetMetafileDownLevelRasterizationLimit, , 'GdipSetMetafileDownLevelRasterizationLimit', \ + GdipSetPageScale, , 'GdipSetPageScale', \ + GdipSetPageUnit, , 'GdipSetPageUnit', \ + GdipSetPathFillMode, , 'GdipSetPathFillMode', \ + GdipSetPathGradientBlend, , 'GdipSetPathGradientBlend', \ + GdipSetPathGradientCenterColor, , 'GdipSetPathGradientCenterColor', \ + GdipSetPathGradientCenterPoint, , 'GdipSetPathGradientCenterPoint', \ + GdipSetPathGradientCenterPointI, , 'GdipSetPathGradientCenterPointI', \ + GdipSetPathGradientFocusScales, , 'GdipSetPathGradientFocusScales', \ + GdipSetPathGradientGammaCorrection, , 'GdipSetPathGradientGammaCorrection', \ + GdipSetPathGradientLinearBlend, , 'GdipSetPathGradientLinearBlend', \ + GdipSetPathGradientPath, , 'GdipSetPathGradientPath', \ + GdipSetPathGradientPresetBlend, , 'GdipSetPathGradientPresetBlend', \ + GdipSetPathGradientSigmaBlend, , 'GdipSetPathGradientSigmaBlend', \ + GdipSetPathGradientSurroundColorsWithCount, , 'GdipSetPathGradientSurroundColorsWithCount', \ + GdipSetPathGradientTransform, , 'GdipSetPathGradientTransform', \ + GdipSetPathGradientWrapMode, , 'GdipSetPathGradientWrapMode', \ + GdipSetPathMarker, , 'GdipSetPathMarker', \ + GdipSetPenBrushFill, , 'GdipSetPenBrushFill', \ + GdipSetPenColor, , 'GdipSetPenColor', \ + GdipSetPenCompoundArray, , 'GdipSetPenCompoundArray', \ + GdipSetPenCustomEndCap, , 'GdipSetPenCustomEndCap', \ + GdipSetPenCustomStartCap, , 'GdipSetPenCustomStartCap', \ + GdipSetPenDashArray, , 'GdipSetPenDashArray', \ + GdipSetPenDashCap197819, , 'GdipSetPenDashCap197819', \ + GdipSetPenDashOffset, , 'GdipSetPenDashOffset', \ + GdipSetPenDashStyle, , 'GdipSetPenDashStyle', \ + GdipSetPenEndCap, , 'GdipSetPenEndCap', \ + GdipSetPenLineCap197819, , 'GdipSetPenLineCap197819', \ + GdipSetPenLineJoin, , 'GdipSetPenLineJoin', \ + GdipSetPenMiterLimit, , 'GdipSetPenMiterLimit', \ + GdipSetPenMode, , 'GdipSetPenMode', \ + GdipSetPenStartCap, , 'GdipSetPenStartCap', \ + GdipSetPenTransform, , 'GdipSetPenTransform', \ + GdipSetPenUnit, , 'GdipSetPenUnit', \ + GdipSetPenWidth, , 'GdipSetPenWidth', \ + GdipSetPixelOffsetMode, , 'GdipSetPixelOffsetMode', \ + GdipSetPropertyItem, , 'GdipSetPropertyItem', \ + GdipSetRenderingOrigin, , 'GdipSetRenderingOrigin', \ + GdipSetSmoothingMode, , 'GdipSetSmoothingMode', \ + GdipSetSolidFillColor, , 'GdipSetSolidFillColor', \ + GdipSetStringFormatAlign, , 'GdipSetStringFormatAlign', \ + GdipSetStringFormatDigitSubstitution, , 'GdipSetStringFormatDigitSubstitution', \ + GdipSetStringFormatFlags, , 'GdipSetStringFormatFlags', \ + GdipSetStringFormatHotkeyPrefix, , 'GdipSetStringFormatHotkeyPrefix', \ + GdipSetStringFormatLineAlign, , 'GdipSetStringFormatLineAlign', \ + GdipSetStringFormatMeasurableCharacterRanges, , 'GdipSetStringFormatMeasurableCharacterRanges', \ + GdipSetStringFormatTabStops, , 'GdipSetStringFormatTabStops', \ + GdipSetStringFormatTrimming, , 'GdipSetStringFormatTrimming', \ + GdipSetTextContrast, , 'GdipSetTextContrast', \ + GdipSetTextRenderingHint, , 'GdipSetTextRenderingHint', \ + GdipSetTextureTransform, , 'GdipSetTextureTransform', \ + GdipSetTextureWrapMode, , 'GdipSetTextureWrapMode', \ + GdipSetWorldTransform, , 'GdipSetWorldTransform', \ + GdipShearMatrix, , 'GdipShearMatrix', \ + GdipStartPathFigure, , 'GdipStartPathFigure', \ + GdipStringFormatGetGenericDefault, , 'GdipStringFormatGetGenericDefault', \ + GdipStringFormatGetGenericTypographic, , 'GdipStringFormatGetGenericTypographic', \ + GdipTestControl, , 'GdipTestControl', \ + GdipTransformMatrixPoints, , 'GdipTransformMatrixPoints', \ + GdipTransformMatrixPointsI, , 'GdipTransformMatrixPointsI', \ + GdipTransformPath, , 'GdipTransformPath', \ + GdipTransformPoints, , 'GdipTransformPoints', \ + GdipTransformPointsI, , 'GdipTransformPointsI', \ + GdipTransformRegion, , 'GdipTransformRegion', \ + GdipTranslateClip, , 'GdipTranslateClip', \ + GdipTranslateClipI, , 'GdipTranslateClipI', \ + GdipTranslateLineTransform, , 'GdipTranslateLineTransform', \ + GdipTranslateMatrix, , 'GdipTranslateMatrix', \ + GdipTranslatePathGradientTransform, , 'GdipTranslatePathGradientTransform', \ + GdipTranslatePenTransform, , 'GdipTranslatePenTransform', \ + GdipTranslateRegion, , 'GdipTranslateRegion', \ + GdipTranslateRegionI, , 'GdipTranslateRegionI', \ + GdipTranslateTextureTransform, , 'GdipTranslateTextureTransform', \ + GdipTranslateWorldTransform, , 'GdipTranslateWorldTransform', \ + GdipVectorTransformMatrixPoints, , 'GdipVectorTransformMatrixPoints', \ + GdipVectorTransformMatrixPointsI, , 'GdipVectorTransformMatrixPointsI', \ + GdipWarpPath, , 'GdipWarpPath', \ + GdipWidenPath, , 'GdipWidenPath', \ + GdipWindingModeOutline, , 'GdipWindingModeOutline', \ + GdiplusNotificationHook, , 'GdiplusNotificationHook', \ + GdiplusNotificationUnhook, , 'GdiplusNotificationUnhook', \ + GdiplusShutdown, , 'GdiplusShutdown', \ + GdiplusStartup, , 'GdiplusStartup' Index: freshlib/macros/Linux/_import.inc ================================================================== --- freshlib/macros/Linux/_import.inc +++ freshlib/macros/Linux/_import.inc @@ -36,11 +36,11 @@ ..start: forward if ~arg eq ... arg dd ? else - label .more dword + label .more_arguments dword end if common .__info.argsize = $ - ..start end virtual .__info.argtype = 2 @@ -69,10 +69,11 @@ \forward \local fstr rept 1 i:func+1 \\{ func equ i func\\#i equ fstr:cnt:iname:ename:arg + iname\\#.@here: \\} \} macro __ImportAll \{ \common Index: freshlib/macros/_display.inc ================================================================== --- freshlib/macros/_display.inc +++ freshlib/macros/_display.inc @@ -30,25 +30,17 @@ } macro _disp arg1, arg2 { - local ..var - if arg2 eq display arg1 else local ..tmp, ..val ..tmp = arg1 -; ..val = arg1 -; virtual at 0 -; dd ..val -; load ..tmp dword from 0 -; end virtual - virtual at 0 repeat 32 if ..tmp > 0 db ..tmp mod arg2 ..tmp = ..tmp / arg2 Index: freshlib/macros/_globals.inc ================================================================== --- freshlib/macros/_globals.inc +++ freshlib/macros/_globals.inc @@ -208,41 +208,41 @@ __InitStringEngine macro IncludeAllGlobals { - local begin - - align 4 - begin = $-$$ - disp 3, 'Initialized data address: $', , 13 - IncludeIGlobals - DispSize 'Initialized data', ($ - begin) - - align 4 - begin = $-$$ - disp 3, 'Strings address: $', , 13 - _IncludeAllStrings - DispSize 'String data', ($ - begin) - - align 4 - begin = $-$$ - disp 3, 'I18n strings data:', , 13 - __IncludeI18nStrings - DispSize 'I18n strings data', ($ - begin) - - align 4 - begin = $-$$ - disp 3, 'Uninitialized data address: $', , 13 - IncludeUGlobals - DispSize 'Uninitialized data', ($ - begin) - - align 4 - begin = $-$$ - disp 3, 'I18n strings placeholders: $', , 13 - IncludeI18nLabels - DispSize 'I18n strings placeholders', ($ - begin) + local ..start + + align 4 + ..start = $ + disp 3, 'Initialized data address: $', <..start, 16>, 13 + IncludeIGlobals + DispSize 'Initialized data', ($ - ..start) + + align 4 + ..start = $ + disp 3, 'Strings address: $', <..start, 16>, 13 + _IncludeAllStrings + DispSize 'String data', ($ - ..start) + + align 4 + ..start = $ + disp 3, 'I18n strings data:', <..start, 16>, 13 + __IncludeI18nStrings + DispSize 'I18n strings data', ($ - ..start) + + align 4 + ..start = $ + disp 3, 'Uninitialized data address: $', <..start, 16>, 13 + IncludeUGlobals + DispSize 'Uninitialized data', ($ - ..start) + + align 4 + ..start = $ + disp 3, 'I18n strings placeholders: $', <..start, 16>, 13 + IncludeI18nLabels + DispSize 'I18n strings placeholders', ($ - ..start) } macro var expr { ADDED freshlib/macros/_realobjects.inc Index: freshlib/macros/_realobjects.inc ================================================================== --- /dev/null +++ freshlib/macros/_realobjects.inc @@ -0,0 +1,448 @@ +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 & used vtables.\\#name ; 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 + rept name\#@count i:1 \\{ + match class | meth, name\\#@method\\#i \\\{ + dd methods.\\\#class\\\#meth + \\\} + \\} + 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, [arg] { +common + 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 + +reverse + if ~arg eq + pushx arg + end if +common + + 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 + 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 getm target, ptrobj, method { + 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 + + if ~target eq eax + push eax + 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 + + push dword [eax+8+4*(ind and $ffff)] + pop target + + if ~target eq eax + pop eax + end if +} + + +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/macros/allmacros.inc ================================================================== --- freshlib/macros/allmacros.inc +++ freshlib/macros/allmacros.inc @@ -19,7 +19,8 @@ include '_display.inc' include '_itext.inc' include '_globals.inc' include '_datamacros.inc' include '_dispatch.inc' +include '_realobjects.inc' include '%TargetOS%/allmacros.inc' Index: freshlib/simpledebug/Linux/debug.asm ================================================================== --- freshlib/simpledebug/Linux/debug.asm +++ freshlib/simpledebug/Linux/debug.asm @@ -30,16 +30,10 @@ popad return endp -macro Output string { -if defined options.DebugMode & options.DebugMode = 1 - stdcall Output, string -end if -} - proc GetTimestamp begin pushad mov eax, 78 Index: freshlib/simpledebug/Win32/debug.asm ================================================================== --- freshlib/simpledebug/Win32/debug.asm +++ freshlib/simpledebug/Win32/debug.asm @@ -37,10 +37,25 @@ invoke SetConsoleTitleW, cConsoleTitle return endp end if + +if (defined options.DebugMode & options.DebugMode) +finalize FinishDebugConsole +.string rb 10 +begin + invoke WriteFile, [STDERR], ___CloseMsg, ___CloseMsg.length, 0, 0 + lea eax, [.string] + invoke ReadFile, [STDIN], eax, 1, 0, 0 + return +endp + +___CloseMsg text "Press ENTER to close." + +end if + maxConsoleWrite = 1024 proc Output, .ptrStr .dummy dd ? @@ -71,16 +86,10 @@ popad return endp -macro Output string { -if defined options.DebugMode & options.DebugMode = 1 - stdcall Output, string -end if -} - proc GetTimestamp begin pushad invoke GetTickCount Index: freshlib/simpledebug/debug.asm ================================================================== --- freshlib/simpledebug/debug.asm +++ freshlib/simpledebug/debug.asm @@ -12,10 +12,13 @@ ; Notes: use options.DebugMode={1|0} to enable/disable debug output of this library. ;_________________________________________________________________________________________ module "Simple debug library" SimpleDebugLoaded = 1 + +include "%TargetOS%/debug.asm" + match =DBG_CHAR_NEWLINE, DBG_CHAR_NEWLINE { DBG_CHAR_NEWLINE equ $0d, $0a } @@ -50,10 +53,26 @@ ..msg db msg, DBG_CHAR_NEWLINE, 0 label ..skip } + + +macro Output string { +if defined options.DebugMode & options.DebugMode = 1 + stdcall Output, string +end if +} + + +macro OutputLn string { +if defined options.DebugMode & options.DebugMode = 1 + stdcall Output, string + stdcall Output, <" ", DBG_CHAR_NEWLINE> +end if +} + proc OutputMemory, .ptr, .size begin pushad @@ -147,19 +166,10 @@ stdcall OutputNumber, number, radix, digits end if } -regEDI = 0 -regESI = 1 -regEBP = 2 -regESP = 3 -regEBX = 4 -regEDX = 5 -regECX = 6 -regEAX = 7 - proc OutputRegister, .reg, .radix begin pushad @@ -256,17 +266,21 @@ proc __simpStrLength;, .pString begin mov ecx, [esp+4] + jecxz .ret + .scan: cmp byte [ecx], 0 lea ecx, [ecx+1] jne .scan stc sbb ecx, [esp+4] + +.ret: retn 4 endp ;***************************************************** @@ -361,10 +375,8 @@ return endp -include "%TargetOS%/debug.asm" - endmodule Index: freshlib/system/Linux/files.asm ================================================================== --- freshlib/system/Linux/files.asm +++ freshlib/system/Linux/files.asm @@ -27,27 +27,27 @@ faOpenAlways = O_CREAT ; if the file does not exists it will be created. faCreateAlways = O_CREAT or O_TRUNC ; Creates new file always. If the file exists, truncates it. faCreateOnly = O_CREAT or O_EXCL ; Creates new file only if not exists, else error. - -initialize InitStdHandles -begin - if used STDIN - mov dword [__std_handle_in], 0 - end if - - if used STDOUT - mov dword [__std_handle_out], 1 - end if - - if used STDERR - mov dword [__std_handle_err], 2 - end if - return -endp - +if used STDIN | used STDOUT | used STDERR + initialize InitStdHandles + begin + if used STDIN + mov dword [__std_handle_in], 0 + end if + + if used STDOUT + mov dword [__std_handle_out], 1 + end if + + if used STDERR + mov dword [__std_handle_err], 2 + end if + return + endp +end if body FileOpenAccess begin Index: freshlib/system/Linux/timers.asm ================================================================== --- freshlib/system/Linux/timers.asm +++ freshlib/system/Linux/timers.asm @@ -24,11 +24,11 @@ endg if used TimerCreate - if ~(defined options.DebugMode & options.DebugMode=1) + if ~(defined options.DebugMode.NoTimers & options.DebugMode.NoTimers) initialize InitLinuxTimers .action lnx_sigaction .timer lnx_sigevent .time lnx_itimerspec @@ -56,17 +56,17 @@ mov [ecx+lnx_sigevent.value], 0 ; not used but must be set - the function fails without it... mov edx, __InternalTimerID int $80 -; DebugMsg 'Interval timer created.' + DebugMsg 'Interval timer created.' ; then start a thread that will process timer expiration events. stdcall ThreadCreate, __TimerHandler, 0 -; DebugMsg 'Timer thread created' + OutputValue 'Timer thread created. ID=$', eax, 16, 8 mov [__InternalTimerThread], eax ; start the timer mov ebx, [__InternalTimerID] @@ -77,52 +77,57 @@ mov [edx+lnx_itimerspec.it_value.tv_sec], 0 mov [edx+lnx_itimerspec.it_value.tv_nsec], __sys_time_slice*1000000 xor esi, esi int $80 -; DebugMsg 'Timer started' + DebugMsg 'Timer started' return endp finalize FreeLinuxTimers begin + ; stop the timer mov eax, sys_timer_delete mov ebx, [__InternalTimerID] int $80 -; DebugMsg 'Timer stopped.' + DebugMsg 'Timer stopped.' + + + mov [__FlagTimerTerminate], 1 + +; signal the thread (because it is probably in waiting state. +match =native, LinuxThreads { + mov eax, sys_tkill + mov ebx, [__InternalTimerThread] + mov ecx, SIGRTMAX + int $80 +} + +match =posix, LinuxThreads { + cinvoke pthread_kill, [__InternalTimerThread], SIGRTMAX +} cmp [__InternalTimerThread], 0 je .finish -; then stop the handling thread - mov [__FlagTimerTerminate], 1 - -match =native, LinuxCode { - mov eax, sys_kill - mov ebx, [__InternalTimerThread] - mov ecx, SIGRTMAX -} - -match =posix, LinuxCode { - cinvoke pthread_kill, [__InternalTimerThread], SIGRTMAX -} - ; waiting to timer thread to finish. This is bad implementation, -;here should be timer wait with signal terminate on timeout. +; here should be timer wait with signal terminate on timeout. + @@: + stdcall Sleep, 10 cmp [__InternalTimerThread], 0 jne @b -; DebugMsg 'Timer thread terminated.' .finish: + DebugMsg 'Timer thread terminated.' return endp end if end if @@ -135,13 +140,10 @@ proc __TimerProc, .signal begin push ebx edi - cmp [fGlobalTerminate], 0 - jne .exit - lea eax, [__ptrFirstTimer] xor edi, edi .loop: mov eax, [eax+TTimer.next] @@ -170,10 +172,12 @@ .end_timers: test edi, edi jz .exit + +; signal the timers thread is some timer is changed. match =native, LinuxThreads { mov eax, sys_tkill mov ebx, [__InternalTimerThread] mov ecx, SIGRTMAX @@ -260,11 +264,11 @@ .end_list: cmp [.remain], 0 jne .from_begin ; wait for signal - mov eax, sys_pause + mov eax, sys_pause int $80 jmp .from_begin .quit: mov [__InternalTimerThread], 0 Index: freshlib/system/Win32/timers.asm ================================================================== --- freshlib/system/Win32/timers.asm +++ freshlib/system/Win32/timers.asm @@ -24,11 +24,11 @@ end if endg -if used TimerCreate +if used TimerCreate & ~ ( defined options.DebugMode.NoTimers & options.DebugMode.NoTimers ) initialize InitWin32Timers begin invoke SetTimer, 0, 0, __sys_time_slice, __TimerProc mov [__InternalTimerID], eax Index: freshlib/test_code/I18nTest.asm ================================================================== --- freshlib/test_code/I18nTest.asm +++ freshlib/test_code/I18nTest.asm @@ -103,8 +103,6 @@ Istring5 itext , \ , \ , \ -@AllImportEmbeded ; or @AllImportSection -@AllDataEmbeded ; or @AllDataSection Index: freshlib/test_code/I18nTest.fpr ================================================================== --- freshlib/test_code/I18nTest.fpr +++ freshlib/test_code/I18nTest.fpr cannot compute difference between binary files Index: freshlib/test_code/test_real_obj.fpr ================================================================== --- freshlib/test_code/test_real_obj.fpr +++ freshlib/test_code/test_real_obj.fpr cannot compute difference between binary files Index: freshlib/test_code0/TestGround.asm ================================================================== --- freshlib/test_code0/TestGround.asm +++ freshlib/test_code0/TestGround.asm @@ -21,26 +21,26 @@ __TestData: frmMainForm: if used frmMainForm ObjTemplate tfParent or tfEnd, TForm, frmMain, \ - x, 300, \ - y, 250, \ - width, 360, \ - height, 240, \ - Visible, TRUE, \ - Caption, 'FreshLib minimal application test.' + x = 300, \ + y = 250, \ + width = 360, \ + height = 240, \ + Visible = TRUE, \ + Caption = 'FreshLib minimal application test.' ObjTemplate tfChild or tfEnd, TButton, btnOpenModal, \ - x, 50, \ - y, 50, \ - width, 120, \ - height, 75, \ - Visible, TRUE, \ - TextAlign, dtfAlignCenter or dtfAlignMiddle or dtfWordWrap , \ - Caption, 'Click to check your assembly skills.', \ - OnClick, OpenModalForm + x = 50, \ + y = 50, \ + width = 120, \ + height = 75, \ + Visible = TRUE, \ + TextAlign = dtfAlignCenter or dtfAlignMiddle or dtfWordWrap , \ + Caption = 'Click to check your assembly skills.', \ + OnClick = OpenModalForm end if __TestDataSize = $ - __TestData endg Index: freshlib/test_code0/TestLib.asm ================================================================== --- freshlib/test_code0/TestLib.asm +++ freshlib/test_code0/TestLib.asm @@ -40,15 +40,15 @@ include '%lib%/freshlib.asm' ; use one and only one of the following files. ; ;include 'TestGroundSplitGrid.asm' -;include 'TestGroundNull.asm' -;include 'TestGround.asm' +;include 'TestGroundNull.asm' ; in order to check whether for compilation of dead code. +include 'TestGround.asm' ;include 'TestGroundComplex.asm' ;include 'TestGroundKeyboard.asm' -include 'TestGroundFreshEdit.asm' +;include 'TestGroundFreshEdit.asm' ;include 'TestGroundConfig.asm' ;include 'TestGroundDirFunctions.asm' ;include 'TestGrids.asm' ;include 'TestTreeView.asm' ;include 'TestResizeEvents.asm' @@ -61,16 +61,16 @@ ; there is a bug somewhere in the ELF generator (FASM or possibly ELF macros) ; that makes some sizes of the ELF executable not loadable. (the Linux loader crashes with SEGFAULT) end if uglobal - buffer rb 256 +; buffer rb 256 endg iglobal ; The example from RFC-1951 - TestArray dw 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 2, 0, 4, 0, 4, 0 +; TestArray dw 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 2, 0, 4, 0, 4, 0 endg ; Main Program start: ADDED freshlib/test_code0/TestMenu.asm Index: freshlib/test_code0/TestMenu.asm ================================================================== --- /dev/null +++ freshlib/test_code0/TestMenu.asm @@ -0,0 +1,401 @@ +; _______________________________________________________________________________________ +;| | +;| ..:: Fresh IDE ::.. template project. | +;|_______________________________________________________________________________________| +; +; Description: FreshLib portable console application. +; +; Target OS: Any, supported by FreshLib +; +; Dependencies: FreshLib +; +; Notes: +;_________________________________________________________________________________________ + +include "%lib%/freshlib.inc" + +@BinaryType GUI, compact + +options.DebugMode = 1 + options.DebugMode.NoTimers = 0 + options.DebugMode.XSync = 0 + options.DebugMode.XErrors =0 + +options.ShowSizes = 1 +options.SkipZeroSizes = 0 + +ThemeGUI equ win_gui + +include "%lib%/freshlib.asm" + + +iglobal +TemplateMainForm: + ObjTemplate tfParent or tfEnd, TForm, frmMain, \ + x = 200, \ + y = 200, \ + width = 320, \ + height = 240, \ + OnCreate = FormOnCreate, \ + OnClose = MainFormOnClose, \ + OnDestroy = FormOnDestroy, \ + Caption = 'Popup menu test' + + ObjTemplate tfChild, TEdit, editTest, \ + x = 10, y = 200, width = 300, height = 24, \ + Text = "This is test TEdit control", \ + Visible = TRUE + + ObjTemplate tfParent, TActionList, ActionList1, \ + ImgIcons = imgMenuList + + ObjTemplate tfChild, TAction, actCheck, \ + Caption = "Check it", HintText = "Action that can be checked and unchecked.", \ + OnExecute = ActionOnCheck, \ + IconIndex = 9 + + ObjTemplate tfChild, TAction, actNew, \ + Caption = "New", HintText = "Create new file.", \ + OnExecute = ActionOnExecute, \ + IconIndex = 0 + + ObjTemplate tfChild, TAction, actOpen, \ + Caption = "Open", HintText = "Open file for editing.", \ + OnExecute = ActionOnExecute, \ + IconIndex = 1 + + ObjTemplate tfChild, TAction, actClean, \ + Caption = "Cleanup list", HintText = "Removes not existing files from the list.", \ + OnExecute = ActionOnExecute, \ + IconIndex = -1 + + ObjTemplate tfChild, TAction, actSave, \ + Caption = "Save", HintText = "Save edited file to the disk.", \ + OnExecute = ActionOnExecute, \ + IconIndex = 2 + + ObjTemplate tfChild, TAction, actSaveAs, \ + Caption = "Save As", HintText = "Save edited file with different name.", \ + OnExecute = ActionOnExecute, \ + IconIndex = 22 + + ObjTemplate tfChild, TAction, actSaveAll, \ + Caption = "Save All", HintText = "Save all edited files to the disk.", \ + OnExecute = ActionOnExecute, \ + IconIndex = 23 + + ObjTemplate tfChild, TAction, actClose, \ + Caption = "Close", HintText = "Close current edited file.", \ + OnExecute = ActionOnExecute, \ + IconIndex = 21 + + ObjTemplate tfChild, TAction, actCloseAll, \ + Caption = "Close All", HintText = "Close all edited files and the project.", \ + OnExecute = ActionOnExecute, \ + IconIndex = 24 + + ObjTemplate tfChild or tfEnd, TAction, actExit, \ + Caption = "Exit", HintText = "Exit Fresh IDE.", \ + OnExecute = ActionOnExecute, \ + IconIndex = -1 + + + ObjTemplate tfChild, TButton, btnSkinWin, \ + x = 60, y = 10, width = 84, height = 24, \ + Caption = "Win skin", \ + TextAlign = dtfAlignCenter or dtfAlignMiddle, \ + Visible = TRUE, \ + OnClick = SetWinSkin + + ObjTemplate tfChild, TButton, btnSkinFlat, \ + x = 146, y = 10, width = 84, height = 24, \ + Caption = "Flat skin", \ + TextAlign = dtfAlignCenter or dtfAlignMiddle, \ + Visible = TRUE, \ + OnClick = SetFlatSkin + + ObjTemplate tfChild, TButton, btnOpenMenu, \ + x = 10, \ + y = 10, \ + width = 32, \ + height = 32, \ + Icon = [iconMenu], \ + IconPosition = iposCenter, \ + Visible = TRUE, \ + OnClick = OpenMenuClick, \ + OnKeyPressed = ButtonKeyPressed + + ObjTemplate tfChild, TButton, btnChangeAction1, \ + x = 146, y = 52, width = 84, height = 24, \ + Caption = "Set act. 1", \ + TextAlign = dtfAlignCenter or dtfAlignMiddle, \ + Visible = TRUE, \ + OnClick = SetAction1 + + ObjTemplate tfChild, TButton, btnChangeAction1, \ + x = 146, y = 78, width = 84, height = 24, \ + Caption = "Set act. 2", \ + TextAlign = dtfAlignCenter or dtfAlignMiddle, \ + Visible = TRUE, \ + OnClick = SetAction2 + + ObjTemplate tfChild, TButton, btnWithAction2, \ + x = 10, y = 78, width = 100, height = 24, \ + IconPosition = iposLeft, TextAlign = dtfAlignLeft or dtfAlignMiddle, \ + Action = [actExit], \ + Visible = TRUE + + ObjTemplate tfChild, TButton, btnWithAction1, \ + x = 10, y = 52, width = 100, height = 24, \ + IconPosition = iposLeft, TextAlign = dtfAlignLeft or dtfAlignMiddle, \ + Action = [actCheck], \ + Visible = TRUE + + ObjTemplate tfChild, TCheckbox, cbEnableDisable3, \ + x = 10, y = 130, width = 130, height = 24, \ + Caption = "Enable action", \ + OnClick = EnableActionClick, \ + Visible = TRUE + + ObjTemplate tfChild, TCheckbox, cbEnableDisable2, \ + x = 146, y = 130, width = 100, height = 24, \ + Action = [actCheck], \ + Visible = TRUE + + ObjTemplate tfChild or tfEnd, TCheckbox, cbEnableDisable, \ + x = 146, y = 104, width = 100, height = 24, \ + Action = [actCheck], \ + Visible = TRUE + + +TemplateMainMenu: + ObjTemplate tfEnd, TMenu, mainMenu, \ + Visible = FALSE + +TemplateSubMenu: + ObjTemplate tfEnd, TMenu, subMenu, \ + Enabled = TRUE, \ + Caption = "Reopen", \ + Visible = FALSE + + + + getfile imgMenu, "_test_images/menu.png" + + dd imgMenuList.size + getfile imgMenuList, "_test_images/img_list.png" + + getfile cfgFlat, "theme_flat.cfg" + dd 0 + + getfile cfgWin, "theme_win.cfg" + dd 0 + +endg + + +uglobal + iconMenu dd ? +endg + + +;rb 423 + + +start: + InitializeAll + + + create [pApplication], TApplication + + call GUI.Init + + stdcall CreateFromTemplate, TemplateMainForm, 0 + set [pApplication], TApplication:MainWindow, frmMain + + set [frmMain], TWindow:Visible, TRUE ; must be set visible after creation, because it loads + ; needed images in OnCreate event handler. + + + stdcall CreateFromTemplate, TemplateMainMenu, 0 + stdcall CreateFromTemplate, TemplateSubMenu, 0 + + exec [mainMenu], TMenu:AddItem, mitAction, [actCheck] + exec [mainMenu], TMenu:AddItem, mitAction, [actNew] + exec [mainMenu], TMenu:AddItem, mitSubmenu, [subMenu] + exec [mainMenu], TMenu:AddItem, mitAction, [actOpen] + exec [mainMenu], TMenu:AddItem, mitSeparator, + exec [mainMenu], TMenu:AddItem, mitAction, [actSave] + exec [mainMenu], TMenu:AddItem, mitAction, [actSaveAs] + exec [mainMenu], TMenu:AddItem, mitAction, [actSaveAll] + exec [mainMenu], TMenu:AddItem, mitSeparator, 0 + exec [mainMenu], TMenu:AddItem, mitAction, [actClose] + exec [mainMenu], TMenu:AddItem, mitAction, [actCloseAll] + exec [mainMenu], TMenu:AddItem, mitSeparator, 0 + exec [mainMenu], TMenu:AddItem, mitAction, [actExit] + + + exec [actCheck], TAction:SetAccelerator, Ctrl+Shift, "N" + exec [actNew], TAction:SetAccelerator, Ctrl, "N" + exec [actOpen], TAction:SetAccelerator, Ctrl, "O" + exec [actSave], TAction:SetAccelerator, Ctrl, "S" + exec [actSaveAll], TAction:SetAccelerator, Ctrl+Shift, "S" + exec [actClose], TAction:SetAccelerator, Ctrl+fkScancode, keyF4 + exec [actExit], TAction:SetAccelerator, Alt, "X" + + set [actCheck], TAction:Checked, 1 + set [actCheck], TAction:Enabled, 0 + +; set [cbEnableDisable2], TCheckbox:Enabled, 0 + + + exec [subMenu], TMenu:AddItem, mitAction, [actClean] + exec [subMenu], TMenu:AddItem, mitSeparator, 0 + exec [subMenu], TMenu:AddItem, mitString, "/home/johnfound/Fresh/source/Fresh.fpr" + exec [subMenu], TMenu:AddItem, mitString, "/home/johnfound/Fresh/source/Fresh.asm" + exec [subMenu], TMenu:AddItem, mitString, "/home/johnfound/Fresh/freshlib/freshlib.inc" + + stdcall Run + + FinalizeAll + stdcall TerminateAll, 0 + + + +; Sample event handlers. They work with other objects on the form. + +proc FormOnCreate as TObject.OnCreate +begin + DebugMsg "Form OnCreate event handler." + + stdcall CreateImagePNG, imgMenu, imgMenu.size + mov [iconMenu], eax + + return +endp + + + +proc FormOnDestroy as TObject.OnDestroy +begin + DebugMsg "MainForm destroy event handler." + return +endp + + + +proc MainFormOnClose as TForm.OnClose +begin + DebugMsg "Main form OnClose event handler" + clc + return +endp + + + + +proc OpenMenuClick as TButton.OnClick +begin + exec [mainMenu], TMenu:Show, [btnOpenMenu], 0, 32 + return +endp + + +proc ButtonKeyPressed as TWindow.OnKeyPressed +begin + stdcall CreateKeyName, [.utf8], [.scancode], [.kbdState] + push eax + + stdcall StrPtr, eax + OutputLn eax + + OutputValue " UTF-8: $", [.utf8], 16, 8 + OutputValue "Scan code: $", [.scancode], 16, 8 + OutputValue " State: $", [.kbdState], 16, 8 + DebugMsg " " + + stdcall StrDel + return +endp + + +proc SetWinSkin as TButton.OnClick +begin + stdcall StringToNamedArray, GUI.meta, cfgWin + exec [frmMain], TWindow:RefreshAll + return +endp + + +proc SetFlatSkin as TButton.OnClick +begin + stdcall StringToNamedArray, GUI.meta, cfgFlat + exec [frmMain], TWindow:RefreshAll + return +endp + + + +proc ActionOnExecute as TAction.OnExecute +begin + mov esi, [.Action] + + stdcall StrDupMem, 'Action "' + mov ebx, eax + + get eax, [.Action], TAction:Caption + + stdcall StrCat, ebx, eax + + stdcall StrCat, ebx, '" executed from control $' + + stdcall NumToStr, [.Ctrl], ntsHex or ntsFixedWidth + 8 + stdcall StrCat, ebx, eax + stdcall StrDel, eax + + stdcall ShowMessage, [frmMain], smiInformation, "Action execution", ebx, smbOK + + stdcall StrDel, ebx + return +endp + + + + +proc ActionOnCheck as TAction.OnExecute +begin + get eax, [.Action], TAction:Checked + xor eax, 1 + set [.Action], TAction:Checked, eax + return +endp + + + +proc SetAction1 as TButton.OnClick +begin + set [btnWithAction1], TButton:Action, [actOpen] + set [btnWithAction2], TButton:Action, [actSaveAll] + return +endp + + +proc SetAction2 as TButton.OnClick +begin + set [btnWithAction1], TButton:Action, [actCheck] + set [btnWithAction2], TButton:Action, [actClose] + return +endp + + + +proc EnableActionClick as TButton.OnClick +begin + get eax, [.self], TCheckbox:Checked + + set [actCheck], TAction:Enabled, eax + + return +endp + + ADDED freshlib/test_code0/TestMenu.fpr Index: freshlib/test_code0/TestMenu.fpr ================================================================== --- /dev/null +++ freshlib/test_code0/TestMenu.fpr cannot compute difference between binary files ADDED freshlib/test_code0/TestNewGUI.asm Index: freshlib/test_code0/TestNewGUI.asm ================================================================== --- /dev/null +++ freshlib/test_code0/TestNewGUI.asm @@ -0,0 +1,556 @@ +; _______________________________________________________________________________________ +;| | +;| ..:: Fresh IDE ::.. template project. | +;|_______________________________________________________________________________________| +; +; Description: FreshLib portable console application. +; +; Target OS: Any, supported by FreshLib +; +; Dependencies: FreshLib +; +; Notes: +;_________________________________________________________________________________________ + +include "%lib%/freshlib.inc" + +@BinaryType GUI, compact + +options.DebugMode = 0 + options.DebugMode.NoTimers = 0 + options.DebugMode.XSync = 0 + options.DebugMode.XErrors =0 + +options.ShowSizes = 1 +options.SkipZeroSizes = 0 + +ThemeGUI equ flat_gui + +include "%lib%/freshlib.asm" + + +iglobal +TemplateMainForm: + ObjTemplate tfParent or tfEnd, TForm, frmMain, \ + x = 100, \ + y = 50, \ + width = 600, \ + height = 520, \ + OnCreate = FormOnCreate, \ + OnClose = MainFormOnClose, \ + OnDestroy = FormOnDestroy, \ + Caption = 'The new GUI toolkit test form.' + + ObjTemplate tfChild, TLabel, NONE, \ + x = 10, y = 10, width = 200, height = 24, \ + Caption = "Progress bar test:", \ + Visible = TRUE + + + ObjTemplate tfChild, TProgress, Progress1, \ + x = 38, y = 32, width = 200, height = 24, \ + Max = 100, Pos = 70, \ + Visible = TRUE + + ObjTemplate tfChild, TButton, btnArrowLeft, \ + x = 10, \ + y = 32, \ + width = 24, \ + height = 24, \ + Icon = [iconArrowLeft], \ + IconPosition = iposCenter, \ + Visible = TRUE, \ + OnClick = ArrowLeftClick + + ObjTemplate tfChild, TButton, btnArrowRight, \ + x = 242, \ + y = 32, \ + width = 24, \ + height = 24, \ + Icon = [iconArrowRight], \ + IconPosition = iposCenter, \ + Visible = TRUE, \ + OnClick = ArrowRightClick + + + ObjTemplate tfChild, TLabel, NONE, \ + x = 10, y = 75, width = 200, height = 24, \ + Caption = "Buttons test:", \ + Visible = TRUE + + ObjTemplate tfChild, TButton, btnDisabled, \ + x = 448, \ + y = 100, \ + width = 128, \ + height = 48, \ + TextAlign = dtfAlignJustify or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\ + Caption = "Disabled", \ + Icon = [iconTest1], \ + IconPosition = iposLeft, \ + Enabled = FALSE, \ + Visible = TRUE + + ObjTemplate tfChild, TButton, btnChild1, \ + x = 10, \ + y = 100, \ + width = 407, \ + height = 242, \ + TextAlign = dtfAlignJustify or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\ + Caption = utf8_long, \ + Icon = [iconTest1], \ + IconPosition = iposLeft, \ + Visible = TRUE, \ + OnClick = Button1Click + + ObjTemplate tfChild, TButton, btnChild2, \ + x = 448, \ + y = 160, \ + width = 128, \ + height = 48, \ + TextAlign = dtfAlignJustify or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\ + Caption = utf8_string, \ + Icon = [iconTest2], \ + IconPosition = iposRight, \ + Enabled = TRUE, \ + Visible = TRUE, \ + OnClick = Button2Click + + ObjTemplate tfChild, TButton, btnChild3, \ + x = 448, \ + y = 220, \ + width = 128, \ + height = 122, \ + TextAlign = dtfAlignCenter or dtfAlignBottom or dtfCRLF or dtfWordWrap,\ + Caption = "Workers of the world, unite!", \ + Icon = [iconTest3], \ + IconPosition = iposCenter, \ + Enabled = TRUE, \ + Visible = TRUE + + ObjTemplate tfChild, TButton, btnAlignLeft, \ + x = 10, \ + y = 350, \ + width = 64, \ + height = 32, \ + TextAlign = dtfAlignCenter or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\ + Caption = 'Left', \ + Visible = TRUE, \ + OnClick = LeftClick + + ObjTemplate tfChild, TButton, btnAlignRight, \ + x = 84, \ + y = 350, \ + width = 64, \ + height = 32, \ + TextAlign = dtfAlignCenter or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\ + Caption = 'Right', \ + Visible = TRUE, \ + OnClick = RightClick + + ObjTemplate tfChild, TButton, btnAlignCenter, \ + x = 158, \ + y = 350, \ + width = 64, \ + height = 32, \ + TextAlign = dtfAlignCenter or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\ + Caption = 'Center', \ + Visible = TRUE, \ + OnClick = CenterClick + + ObjTemplate tfChild, TButton, btnAlignJust, \ + x = 232, \ + y = 350, \ + width = 64, \ + height = 32, \ + TextAlign = dtfAlignCenter or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\ + Caption = 'Justify', \ + Visible = TRUE, \ + OnClick = JustifyClick + + ObjTemplate tfChild, TButton, btnAlignTop, \ + x = 306, \ + y = 350, \ + width = 64, \ + height = 32, \ + TextAlign = dtfAlignCenter or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\ + Caption = 'Top', \ + Visible = TRUE, \ + OnClick = TopClick + + ObjTemplate tfChild, TButton, btnAlignMiddle, \ + x = 380, \ + y = 350, \ + width = 64, \ + height = 32, \ + TextAlign = dtfAlignCenter or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\ + Caption = 'Middle', \ + Visible = TRUE, \ + OnClick = MiddleClick + + ObjTemplate tfChild, TButton, btnAlignBottom, \ + x = 454, \ + y = 350, \ + width = 64, \ + height = 32, \ + TextAlign = dtfAlignCenter or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\ + Caption = 'Bottom', \ + Visible = TRUE, \ + OnClick = BottomClick + + ObjTemplate tfChild, TLabel, NONE, \ + x = 10, y = 390, width = 200, height = 24, \ + Caption = "Line editor test:", \ + Visible = TRUE + + ObjTemplate tfChild, TEdit, editTest, \ + Text = "This is simple line editor.", \ + x = 10, y=415, width=306, height=24, \ + MarginLeft= 2, \ + MarginRight= 2, \ + Visible = TRUE + + ObjTemplate tfChild, TLabel, NONE, \ + x = 10, y = 445, width = 200, height = 24, \ + Caption = "Message boxes test:", \ + Visible = TRUE + + ObjTemplate tfChild, TButton, btnMsgError, \ + x = 10, \ + y = 470, \ + width = 72, \ + height = 32, \ + TextAlign = dtfAlignCenter or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\ + Caption = 'Error', \ + Visible = TRUE, \ + OnClick = ErrorClick + + ObjTemplate tfChild, TButton, btnMsgWarning, \ + x = 88, \ + y = 470, \ + width = 72, \ + height = 32, \ + TextAlign = dtfAlignCenter or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\ + Caption = 'Warning', \ + Visible = TRUE, \ + OnClick = WarningClick + + ObjTemplate tfChild, TButton, btnMsgQuestion, \ + x = 166, \ + y = 470, \ + width = 72, \ + height = 32, \ + TextAlign = dtfAlignCenter or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\ + Caption = 'Question', \ + Visible = TRUE, \ + OnClick = QuestionClick + + ObjTemplate tfChild or tfEnd, TButton, btnMsgInfo, \ + x = 244, \ + y = 470, \ + width = 72, \ + height = 32, \ + TextAlign = dtfAlignCenter or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\ + Caption = 'Info', \ + Visible = TRUE, \ + OnClick = InfoClick + + + + getfile imgTestIcon1, '_test_images/speech.png' + getfile imgTestIcon2, '_test_images/globe.png' + getfile imgTestIcon3, '_test_images/star.png' + + getfile imgArrowLeft, '_test_images/left.png' + getfile imgArrowRight, '_test_images/right.png' + + getfile imgFolder, "_test_images/folder.png" + getfile imgFile, "_test_images/document.png" + + +include "UTF8_examples.asm" + + +endg + + +uglobal + iconTest1 dd ? + iconTest2 dd ? + iconTest3 dd ? + iconArrowLeft dd ? + iconArrowRight dd ? + + iconFolder dd ? + iconFile dd ? +endg + + + +;rb 423 + + +start: + InitializeAll + + create [pApplication], TApplication + + call GUI.Init + + stdcall CreateFromTemplate, TemplateMainForm, 0 + + set [pApplication], TApplication:MainWindow, frmMain + + set [frmMain], TWindow:Visible, TRUE ; must be set visible after creation, because it loads + ; needed images in OnCreate event handler. + + stdcall Run + + FinalizeAll + stdcall TerminateAll, 0 + + + +; Sample event handlers. They work with other objects on the form. + +proc FormOnCreate as TObject.OnCreate +begin + DebugMsg "Form OnCreate event handler." + + stdcall CreateImagePNG, imgTestIcon1, imgTestIcon1.size + mov [iconTest1], eax + + stdcall CreateImagePNG, imgTestIcon2, imgTestIcon2.size + mov [iconTest2], eax + + stdcall CreateImagePNG, imgTestIcon3, imgTestIcon3.size + mov [iconTest3], eax + + stdcall CreateImagePNG, imgArrowLeft, imgArrowLeft.size + mov [iconArrowLeft], eax + + stdcall CreateImagePNG, imgArrowRight, imgArrowRight.size + mov [iconArrowRight], eax + + stdcall CreateImagePNG, imgFolder, imgFolder.size + mov [iconFolder], eax + + stdcall CreateImagePNG, imgFile, imgFile.size + mov [iconFile], eax + + return +endp + + +proc FormOnDestroy as TObject.OnDestroy +begin + DebugMsg "MainForm destroy event handler." + return +endp + + + + +proc LeftClick as TButton.OnClick +begin + get eax, [btnChild1], TButton:TextAlign + and eax, not dtfHAlignMask + or eax, dtfAlignLeft + + set [btnChild1], TButton:TextAlign, eax + return +endp + + +proc RightClick as TButton.OnClick +begin + get eax, [btnChild1], TButton:TextAlign + and eax, not dtfHAlignMask + or eax, dtfAlignRight + + set [btnChild1], TButton:TextAlign, eax + return +endp + + +proc CenterClick as TButton.OnClick +begin + get eax, [btnChild1], TButton:TextAlign + and eax, not dtfHAlignMask + or eax, dtfAlignCenter + + set [btnChild1], TButton:TextAlign, eax + return +endp + +proc JustifyClick as TButton.OnClick +begin + get eax, [btnChild1], TButton:TextAlign + and eax, not dtfHAlignMask + or eax, dtfAlignJustify + + set [btnChild1], TButton:TextAlign, eax + return +endp + + +proc TopClick as TButton.OnClick +begin + get eax, [btnChild1], TButton:TextAlign + and eax, not dtfVAlignMask + or eax, dtfAlignTop + + set [btnChild1], TButton:TextAlign, eax + return +endp + +proc MiddleClick as TButton.OnClick +begin + get eax, [btnChild1], TButton:TextAlign + and eax, not dtfVAlignMask + or eax, dtfAlignMiddle + + set [btnChild1], TButton:TextAlign, eax + return +endp + +proc BottomClick as TButton.OnClick +begin + get eax, [btnChild1], TButton:TextAlign + and eax, not dtfVAlignMask + or eax, dtfAlignBottom + + set [btnChild1], TButton:TextAlign, eax + return +endp + + +proc Button1Click as TButton.OnClick +begin + DebugMsg 'Button1 clicked' + return +endp + + + +proc Button2Click as TButton.OnClick +begin + DebugMsg 'Button2 clicked' + return +endp + + + +proc MainFormOnClose as TForm.OnClose +begin + DebugMsg "Main form OnClose event handler" + clc + return +endp + + + +;proc PaintMainFormBG as TWindow.OnPaint +;begin +; +;; tile test background +; mov esi, [.self] +; mov edi, [.canvas] +; mov ebx, [imgTest] +; xor edx, edx +; +; test ebx, ebx +; jz .finish +; +;.yloop: +; +; xor ecx, ecx +; +;.xloop: +; stdcall BlendImage, edi, ecx, edx, ebx, 0, 0, [ebx+TImage.width], [ebx+TImage.height] +; +; add ecx, [ebx+TImage.width] +; cmp ecx, [edi+TImage.width] +; jb .xloop +; +; add edx, [ebx+TImage.height] +; cmp edx, [edi+TImage.height] +; jb .yloop +; +;.finish: +; return +;endp + + + +proc ButtonPaint as TWindow.OnPaint +begin + stdcall DrawSolidRect, [.canvas], 40, 40, 140, 140, 0 + return +endp + + +proc ArrowLeftClick as TButton.OnClick +begin + get eax, [Progress1], TProgress:Pos + + dec eax + jns @f + + mov eax, 100 + +@@: + set [Progress1], TProgress:Pos, eax + return +endp + + +proc ArrowRightClick as TButton.OnClick +begin + get eax, [Progress1], TProgress:Pos + + inc eax + cmp eax, 100 + jbe @f + + xor eax, eax + +@@: + set [Progress1], TProgress:Pos, eax + return +endp + + + + +proc ErrorClick as TButton.OnClick +begin + stdcall ShowMessage, [frmMain], smiError, "Dialog box test.", "This is test of common dialog boxes.", smbOK + return +endp + + + +proc WarningClick as TButton.OnClick +begin + stdcall ShowMessage, [frmMain], smiWarning, "Dialog box test.", "This is test of common dialog boxes.", smbOK + return +endp + + + +proc QuestionClick as TButton.OnClick +begin + stdcall ShowMessage, [frmMain], smiQuestion, "Dialog box test.", "This is test of common dialog boxes.", smbYes or smbNo or smbMaybe + return +endp + + + +proc InfoClick as TButton.OnClick +begin + stdcall ShowMessage, [frmMain], smiInformation, "Dialog box test.", "This is test of common dialog boxes.", smbOK or smbCancel + return +endp + + + ADDED freshlib/test_code0/TestNewGUI.fpr Index: freshlib/test_code0/TestNewGUI.fpr ================================================================== --- /dev/null +++ freshlib/test_code0/TestNewGUI.fpr cannot compute difference between binary files Index: freshlib/test_code0/TestPNG.asm ================================================================== --- freshlib/test_code0/TestPNG.asm +++ freshlib/test_code0/TestPNG.asm @@ -14,11 +14,11 @@ include "%lib%/freshlib.inc" @BinaryType GUI, compact -options.DebugMode = 0 +options.DebugMode = 1 options.ShowSizes = 1 options.SkipZeroSizes = 1 options.DebugMode.XSync = 0 options.DebugMode.XErrors =0 @@ -67,11 +67,15 @@ endg start: InitializeAll + create [pApplication], TApplication + + stdcall TestBackground + stdcall CreateFromTemplate, TemplateMainForm, 0 set [pApplication], TApplication:MainWindow, frmMain stdcall Run @@ -142,18 +146,10 @@ .img dd ? begin pushad DebugMsg 'Button1 clicked' - - mov eax, [frmMain] - stdcall AllocateContext, [eax+TWindow.handle] - jc .end - - mov ebx, eax - stdcall SetDrawMode, eax, cmCopy - stdcall CreateImagePNG, pngBackground, sizeof.pngBackground mov [.img], eax mov edi, PngFiles @@ -181,12 +177,22 @@ mov ecx, xStart add edx, yStep jmp .loop .finish_demo: - stdcall DrawImage, ebx, [.img], 0, 0 - stdcall ReleaseContext, ebx + + get ebx, [frmMain], TWindow:Canvas + mov esi, [.img] + + stdcall BlendImage, ebx, 0, 0, esi, 0, 0, [esi+TImage.width], [esi+TImage.height] + +; exec [frmMain], TWindow:Refresh + + mov eax, [frmMain] + stdcall _RefreshWindow, [eax+TWindow.handle] + + DebugMsg "Draw on window" .end: popad return endp @@ -207,14 +213,14 @@ stdcall FontCreate4, 'DejaVu', 20, 1000, 0 mov [.font], eax mov eax, [frmMain] - stdcall AllocateContext, [eax+TWindow.handle] + stdcall __AllocateContext, [eax+TWindow.handle] mov [.context], eax - stdcall SetDrawMode, eax, cmCopy + stdcall __SetDrawMode, eax, cmCopy stdcall CreateImagePNG, pngBackground, sizeof.pngBackground mov [.bkgnd], eax stdcall CreateImagePNG, pngBackground, sizeof.pngBackground @@ -393,11 +399,11 @@ stdcall DestroyImage, [.bkgnd] stdcall DestroyImage, [.work] stdcall DestroyImage, [.art] - stdcall ReleaseContext, [.context] + stdcall __ReleaseContext, [.context] stdcall FontDestroy2, [.font] popad return ADDED freshlib/test_code0/TestSplitGrid.asm Index: freshlib/test_code0/TestSplitGrid.asm ================================================================== --- /dev/null +++ freshlib/test_code0/TestSplitGrid.asm @@ -0,0 +1,376 @@ +; _______________________________________________________________________________________ +;| | +;| ..:: Fresh IDE ::.. template project. | +;|_______________________________________________________________________________________| +; +; Description: FreshLib portable console application. +; +; Target OS: Any, supported by FreshLib +; +; Dependencies: FreshLib +; +; Notes: +;_________________________________________________________________________________________ + +include "%lib%/freshlib.inc" + +@BinaryType GUI, compact + +options.DebugMode = 1 + options.DebugMode.NoTimers = 0 + options.DebugMode.XSync = 0 + options.DebugMode.XErrors =0 + +options.ShowSizes = 1 +options.SkipZeroSizes = 1 + +ThemeGUI equ flat_gui + +include "%lib%/freshlib.asm" + + +iglobal + +TemplateMainForm: + ObjTemplate tfParent or tfEnd, TForm, frmMain, \ + x = 100, \ + y = 50, \ + width = 640, \ + height = 480, \ + OnCreate = FormOnCreate, \ + OnClose = MainFormOnClose, \ + OnDestroy = FormOnDestroy, \ + SplitGrid = SplitTest, \ + Caption = 'Split grids test form' + + + ObjTemplate tfChild, TEdit, editDir, \ + Text = "/home", \ + x = 10, y=10, width=370, height=24, \ + MarginLeft= 2, \ + MarginRight= 2, \ + OnCreate = EditOnCreate, \ + SplitCell = SplitTest.cellEdit, \ + Visible = TRUE + + ObjTemplate tfChild, TButton, btnArrowRight, \ + x = 384, \ + y = 10, \ + width = 24, \ + height = 24, \ + Icon = [iconArrowRight], \ + IconPosition = iposCenter, \ + SplitCell = SplitTest.cellButton, \ + Visible = TRUE, \ + OnClick = ReadFolderClick + + ObjTemplate tfChild, TLabel, lblEmpty, \ + SplitCell = SplitTest.cellEmpty, \ + Caption = utf8_long, \ + TextAlign = dtfAlignJustify or dtfAlignTop or dtfCRLF or dtfWordWrap, \ + Visible = TRUE + + ObjTemplate tfChild or tfEnd, TTreeView, tvFolders, \ + x = 10, y = 40, width = 200, height = 200, \ + SplitCell = SplitTest.cellTree, \ +\; OnFocusItem = TreeFocusItem, \ + Visible = TRUE + + +include "UTF8_examples.asm" + + + +SplitStart SplitTest + + Split stVert, 6, 24, 16, 48 + Split stHoriz or stOriginBR or stJustGap, 6, 64, 48, 200 + Cell cellEdit + Cell cellButton + + Split stHoriz or stRelative, 6, 16384, 3000, 29000 + Cell cellTree + Cell cellEmpty + +SplitEnd + + +if ThemeGUI eq win_gui + getfile imgArrowRight, '_test_images/right2.png' + getfile imgFolder, "_test_images/folder2.png" + getfile imgFile, "_test_images/document2.png" +end if + + +if ThemeGUI eq flat_gui + getfile imgArrowRight, '_test_images/right.png' + + getfile imgFolder, "_test_images/folder.png" + getfile imgFile, "_test_images/document.png" +end if + + +endg + + +uglobal + iconArrowRight dd ? + + iconFolder dd ? + iconFile dd ? +endg + + +;rb 423 + + +start: + InitializeAll + + create [pApplication], TApplication + + stdcall GUI.Init + + stdcall CreateFromTemplate, TemplateMainForm, 0 + + set [pApplication], TApplication:MainWindow, frmMain + + set [frmMain], TWindow:Visible, TRUE ; must be set visible after creation, because it loads + ; needed images in OnCreate event handler. + + stdcall Run + + FinalizeAll + stdcall TerminateAll, 0 + + + +; Sample event handlers. They work with other objects on the form. + +proc FormOnCreate as TObject.OnCreate +begin + DebugMsg "Form OnCreate event handler." + + stdcall CreateImagePNG, imgArrowRight, imgArrowRight.size + mov [iconArrowRight], eax + + stdcall CreateImagePNG, imgFolder, imgFolder.size + mov [iconFolder], eax + + stdcall CreateImagePNG, imgFile, imgFile.size + mov [iconFile], eax + + return +endp + + +proc EditOnCreate as TObject.OnCreate +begin + + if TargetOS eq Win32 + + set [editDir], TEdit:Text, txt "c:\" + + else + + set [editDir], TEdit:Text, txt "/home" + + end if + + return +endp + + +proc FormOnDestroy as TObject.OnDestroy +begin + DebugMsg "MainForm destroy event handler." + return +endp + + +proc MainFormOnClose as TForm.OnClose +begin + DebugMsg "Main form OnClose event handler" + clc + return +endp + + + + + +proc TreeFocusItem as TTreeView.OnFocusItem +begin + mov ebx, [.pItem] + + stdcall FileWriteString, [STDOUT], [ebx+TTreeViewItem.UserData] + stdcall FileWriteString, [STDOUT], + +; stdcall StrExtractExt, [ebx+TTreeViewItem.UserData] +; jc .finish +; +; stdcall StrCompNoCase, eax, txt ".txt" +; stdcall StrDel, eax +; jnc .finish + + + stdcall LoadBinaryFile, [ebx+TTreeViewItem.UserData] + jc .finish + + push eax + + set [lblEmpty], TLabel:Caption, eax + + stdcall FreeMem ; from the stack + +.finish: + return +endp + + + + + +proc ReadFolderClick as TButton.OnClick +begin + pushad + + get edi, [frmMain], TWindow:Cursor + + stdcall GetStockCursor, mcWait + push eax + + mov eax, [frmMain] + stdcall SetMouseCursor, [eax+TWindow.handle] + + stdcall ProcessSystemEvents + + mov esi, [tvFolders] + get ebx, [editDir], TEdit:Text + mov edx, [esi+TTreeView._items] + + stdcall DeleteArrayItems, edx, 0, [edx+TArray.count] + + stdcall ___DoReadDir, ebx, edx, -1 + mov [esi+TTreeView._items], edx + jc .error + +.finish: + stdcall StrDel, ebx + + OutputValue "Files tree items:", [edx+TArray.count], 10, 8 + + exec [tvFolders], TTreeView:__RebuildIndex + exec [tvFolders], TWindow:Refresh + + set [frmMain], TWindow:Cursor, edi + + popad + return + +.error: + stdcall GetErrorString, eax + push eax + + stdcall ShowMessage, [frmMain], smiError, "File error", eax, smbOK + + stdcall FreeErrorString ; from the stack + jmp .finish + +endp + + + + +proc ___DoReadDir, .hDir, .pArray, .Level +begin + pushad + + mov edx, [.pArray] + mov ebx, [.Level] + inc ebx + + stdcall DirectoryRead, [.hDir] + jc .finish + + mov esi, eax + xor ecx, ecx + + stdcall SortDirArray, esi, fdsByType + +.loop: + cmp ecx, [esi+TArray.count] + jae .end_loop + + stdcall StrPtr, [esi+TArray.array + 8*ecx + TDirItem.hFilename] + + cmp byte [eax], "." + je .next + +; Output eax +; DebugMsg "" + + stdcall StrDup, [.hDir] + stdcall StrCharCat, eax, "/" + stdcall StrCat, eax, [esi+TArray.array+8*ecx+TDirItem.hFilename] + push eax + + stdcall AddArrayItems, edx, 1 + + push [esi+TArray.array + 8*ecx + TDirItem.hFilename] ; name + pop [eax+TTreeViewItem.caption] + pop [eax+TTreeViewItem.UserData] ; the full filename + mov [eax+TTreeViewItem.level], ebx + mov [eax+TTreeViewItem.state], tvisExpanded + + push edx + + mov edx, [iconFolder] + cmp [esi+TArray.array + 8*ecx + TDirItem.Type], ftDirectory + je @f + + mov edx, [iconFile] + cmp [esi+TArray.array + 8*ecx + TDirItem.Type], ftFile + je @f + + xor edx, edx + +@@: + mov [eax+TTreeViewItem.imgNormal], edx + + pop edx + + cmp [esi+TArray.array + 8*ecx + TDirItem.Type], ftDirectory + jne .next + + stdcall StrDup, [.hDir] + push eax + + stdcall StrCharCat, eax, "/" + stdcall StrCat, eax, [esi+TArray.array + 8*ecx + TDirItem.hFilename] + + stdcall ___DoReadDir, eax, edx, ebx + + stdcall StrDel ; from the stack + +.next: + inc ecx + jmp .loop + +.end_loop: + stdcall FreeMem, esi + + clc + xor eax, eax + +.finish: + mov [esp+regEAX*4], eax + mov [esp+regEDX*4], edx + popad + return +endp + + + + + ADDED freshlib/test_code0/TestSplitGrid.fpr Index: freshlib/test_code0/TestSplitGrid.fpr ================================================================== --- /dev/null +++ freshlib/test_code0/TestSplitGrid.fpr cannot compute difference between binary files ADDED freshlib/test_code0/TestTV.fpr Index: freshlib/test_code0/TestTV.fpr ================================================================== --- /dev/null +++ freshlib/test_code0/TestTV.fpr cannot compute difference between binary files ADDED freshlib/test_code0/TestTVmain.asm Index: freshlib/test_code0/TestTVmain.asm ================================================================== --- /dev/null +++ freshlib/test_code0/TestTVmain.asm @@ -0,0 +1,311 @@ +; _______________________________________________________________________________________ +;| | +;| ..:: Fresh IDE ::.. template project. | +;|_______________________________________________________________________________________| +; +; Description: FreshLib portable console application. +; +; Target OS: Any, supported by FreshLib +; +; Dependencies: FreshLib +; +; Notes: +;_________________________________________________________________________________________ + +include "%lib%/freshlib.inc" + +@BinaryType GUI, compact + +options.DebugMode = 0 + options.DebugMode.NoTimers = 0 + options.DebugMode.XSync = 0 + options.DebugMode.XErrors =0 + +options.ShowSizes = 1 +options.SkipZeroSizes = 1 + +ThemeGUI equ flat_gui + +include "%lib%/freshlib.asm" + + +iglobal + +TemplateMainForm: + ObjTemplate tfParent or tfEnd, TForm, frmMain, \ + x = 100, \ + y = 50, \ + width = 418, \ + height = 510, \ + OnCreate = FormOnCreate, \ + OnClose = MainFormOnClose, \ + OnDestroy = FormOnDestroy, \ + Caption = 'The new GUI toolkit test form.' + + + ObjTemplate tfChild, TEdit, editDir, \ + Text = "/home", \ + x = 10, y=10, width=370, height=24, \ + MarginLeft= 2, \ + MarginRight= 2, \ + OnCreate = EditOnCreate, \ + Visible = TRUE + + ObjTemplate tfChild, TButton, btnArrowRight, \ + x = 384, \ + y = 10, \ + width = 24, \ + height = 24, \ + Icon = [iconArrowRight], \ + IconPosition = iposCenter, \ + Visible = TRUE, \ + OnClick = ReadFolderClick + + ObjTemplate tfChild or tfEnd, TTreeView, tvFolders, \ + x = 10, y = 40, width = 400, height = 460, \ + Visible = TRUE + + +if ThemeGUI eq win_gui + getfile imgArrowRight, '_test_images/right2.png' + getfile imgFolder, "_test_images/folder2.png" + getfile imgFile, "_test_images/document2.png" +end if + + +if ThemeGUI eq flat_gui + getfile imgArrowRight, '_test_images/right.png' + + getfile imgFolder, "_test_images/folder.png" + getfile imgFile, "_test_images/document.png" +end if + + +endg + + +uglobal + iconArrowRight dd ? + + iconFolder dd ? + iconFile dd ? +endg + + +;rb 423 + + +start: + InitializeAll + + create [pApplication], TApplication + + stdcall GUI.Init + + stdcall CreateFromTemplate, TemplateMainForm, 0 + + set [pApplication], TApplication:MainWindow, frmMain + + set [frmMain], TWindow:Visible, TRUE ; must be set visible after creation, because it loads + ; needed images in OnCreate event handler. + + stdcall Run + + FinalizeAll + stdcall TerminateAll, 0 + + + +; Sample event handlers. They work with other objects on the form. + +proc FormOnCreate as TObject.OnCreate +begin + DebugMsg "Form OnCreate event handler." + + stdcall CreateImagePNG, imgArrowRight, imgArrowRight.size + mov [iconArrowRight], eax + + stdcall CreateImagePNG, imgFolder, imgFolder.size + mov [iconFolder], eax + + stdcall CreateImagePNG, imgFile, imgFile.size + mov [iconFile], eax + + return +endp + + +proc EditOnCreate as TObject.OnCreate +begin + + if TargetOS eq Win32 + + set [editDir], TEdit:Text, txt "c:\" + + else + + set [editDir], TEdit:Text, txt "/home" + + end if + + return +endp + + +proc FormOnDestroy as TObject.OnDestroy +begin + DebugMsg "MainForm destroy event handler." + return +endp + + +proc MainFormOnClose as TForm.OnClose +begin + DebugMsg "Main form OnClose event handler" + clc + return +endp + + + + + + + +proc ReadFolderClick as TButton.OnClick +begin + pushad + + get edi, [frmMain], TWindow:Cursor + + stdcall GetStockCursor, mcWait + push eax + + mov eax, [frmMain] + stdcall SetMouseCursor, [eax+TWindow.handle] + + stdcall ProcessSystemEvents + + mov esi, [tvFolders] + get ebx, [editDir], TEdit:Text + mov edx, [esi+TTreeView._items] + + stdcall DeleteArrayItems, edx, 0, [edx+TArray.count] + + stdcall ___DoReadDir, ebx, edx, -1 + mov [esi+TTreeView._items], edx + jc .error + +.finish: + stdcall StrDel, ebx + + OutputValue "Files tree items:", [edx+TArray.count], 10, 8 + + exec [tvFolders], TTreeView:__RebuildIndex + exec [tvFolders], TWindow:Refresh + + set [frmMain], TWindow:Cursor, edi + + popad + return + +.error: + stdcall GetErrorString, eax + push eax + + stdcall ShowMessage, [frmMain], smiError, "File error", eax, smbOK + + stdcall FreeErrorString ; from the stack + jmp .finish + +endp + + + + +proc ___DoReadDir, .hDir, .pArray, .Level +begin + pushad + + mov edx, [.pArray] + mov ebx, [.Level] + inc ebx + + stdcall DirectoryRead, [.hDir] + jc .finish + + mov esi, eax + xor ecx, ecx + + + stdcall SortDirArray, esi, fdsByType + +.loop: + cmp ecx, [esi+TArray.count] + jae .end_loop + + stdcall StrPtr, [esi+TArray.array + 8*ecx + TDirItem.hFilename] + + cmp byte [eax], "." + je .next + +; Output eax +; DebugMsg "" + + stdcall AddArrayItems, edx, 1 + + push [esi+TArray.array + 8*ecx + TDirItem.hFilename] ; name + pop [eax+TTreeViewItem.caption] + mov [eax+TTreeViewItem.level], ebx + mov [eax+TTreeViewItem.state], tvisExpanded + + push edx + + mov edx, [iconFolder] + cmp [esi+TArray.array + 8*ecx + TDirItem.Type], ftDirectory + je @f + + mov edx, [iconFile] + cmp [esi+TArray.array + 8*ecx + TDirItem.Type], ftFile + je @f + + xor edx, edx + +@@: + mov [eax+TTreeViewItem.imgNormal], edx + + pop edx + + cmp [esi+TArray.array + 8*ecx + TDirItem.Type], ftDirectory + jne .next + + stdcall StrDup, [.hDir] + push eax + + stdcall StrCharCat, eax, "/" + stdcall StrCat, eax, [esi+TArray.array + 8*ecx + TDirItem.hFilename] + + stdcall ___DoReadDir, eax, edx, ebx + + stdcall StrDel ; from the stack + +.next: + inc ecx + jmp .loop + +.end_loop: + stdcall FreeMem, esi + + clc + xor eax, eax + +.finish: + mov [esp+regEAX*4], eax + mov [esp+regEDX*4], edx + popad + return +endp + + + + Index: freshlib/test_code0/TestText.asm ================================================================== --- freshlib/test_code0/TestText.asm +++ freshlib/test_code0/TestText.asm @@ -60,10 +60,11 @@ rb 423 + start: InitializeAll create [pApplication], TApplication @@ -102,74 +103,86 @@ proc Button2Click as TButton.OnClick .font dd ? .width dd ? .height dd ? .y dd ? +.start dd ? begin pushad DebugMsg 'Button2 clicked' - stdcall FontCreate4, 'Fixedsys Excelsior 3.01', 16, 600, ffItalic + stdcall FontCreate4, 'Ubuntu', 16, 900, ffUnderline mov [.font], eax stdcall CreateImage, 1024, 600 mov esi, eax mov edi, [frmMain] stdcall AllocateContext, [edi+TWindow.handle] mov edi, eax - stdcall DrawSolidRect, esi, 0, 0, 1024, 600, $d0d0d8 + stdcall DrawSolidRect, esi, 0, 0, 1024, 600, $ffd0d0d8 stdcall DrawSolidRect, esi, 320, 0, 320, 480, $ff0000ff + + stdcall GetFontMetrics, [.font] + mov [.height], eax + stdcall GetTimestamp - mov ebx, eax + mov [.start], eax mov edx, 7 mov ecx, -100 -;TestStr text 'X' -; stdcall DrawString2, esi, TestStr, 440, 280, [.font], $ff000000 - - mov ecx, 100 - mov [.y], 0 + mov ecx, 1000 + mov [.y], 5 .loop: ; 85 characters text - stdcall DrawString2, esi, 'Button BRAVO This is simple text, displayed by FreeType library using FreeType cache.', 0, [.y], [.font], $ffff0000 - -; stdcall GetTextBounds2, 'Button BRAVO This is simple text, displayed by FreeType library using FreeType cache.', [.font] +; stdcall DrawString2, esi, 'uon ravo s s smpe ex, spaye y reeype rary usng reeype cace.', -1, 150, [.y], [.font], $ff000000 + stdcall DrawString2, esi, 'Button BRAVO This is simple text, displayed by FreeType library using FreeType cache.', -1, 150, [.y], [.font], $ff000000 mov [.width], eax - mov [.height], edx + + mov edx, ebx + add ebx, [.y] + neg edx +; stdcall DrawSolidRect, esi, 150, ebx, eax, 1, $ffff0000 +; stdcall DrawSolidRect, esi, 150, [.y], eax, 1, $ffff0000 + +; stdcall GetTextBounds2, 'Button BRAVO This is simple text, displayed by FreeType library using FreeType cache.', -1, [.font] - add [.y], edx + mov eax, [.height] + add [.y], eax dec ecx jnz .loop stdcall GetTimestamp - sub eax, ebx + sub eax, [.start] stdcall NumToStr, eax, ntsUnsigned or ntsDec push eax - stdcall DrawString2, esi, eax, 40, 500, [.font], $ff000000 + stdcall StrPtr, eax + stdcall DrawString2, esi, eax, -1, 40, 500, [.font], $ff000000 stdcall StrDel ; from the stack - stdcall NumToStr, [.width], ntsDec or ntsUnsigned + stdcall NumToStr, [.width], ntsDec or ntsSigned push eax - stdcall DrawString2, esi, eax, 40, 520, [.font], $ff000000 + stdcall StrPtr, eax + stdcall DrawString2, esi, eax, -1, 40, 520, [.font], $ff000000 stdcall StrDel ; from the stack stdcall NumToStr, [.height], ntsDec or ntsUnsigned push eax - stdcall DrawString2, esi, eax, 40, 540, [.font], $ff000000 + stdcall StrPtr, eax + stdcall DrawString2, esi, eax, -1, 40, 540, [.font], $ff000000 stdcall StrDel ; from the stack Index: freshlib/test_code0/TestText.fpr ================================================================== --- freshlib/test_code0/TestText.fpr +++ freshlib/test_code0/TestText.fpr cannot compute difference between binary files ADDED freshlib/test_code0/TestThemes.asm Index: freshlib/test_code0/TestThemes.asm ================================================================== --- /dev/null +++ freshlib/test_code0/TestThemes.asm @@ -0,0 +1,476 @@ +; _______________________________________________________________________________________ +;| | +;| ..:: Fresh IDE ::.. template project. | +;|_______________________________________________________________________________________| +; +; Description: FreshLib portable console application. +; +; Target OS: Any, supported by FreshLib +; +; Dependencies: FreshLib +; +; Notes: +;_________________________________________________________________________________________ + +include "%lib%/freshlib.inc" + +@BinaryType GUI, compact + +options.DebugMode = 0 + options.DebugMode.NoTimers = 1 + options.DebugMode.XSync = 0 + options.DebugMode.XErrors =0 + +options.ShowSizes = 1 +options.SkipZeroSizes = 0 + +options.WholeTheme = 1 + +ThemeGUI equ win_gui + +include "%lib%/freshlib.asm" + + +iglobal +TemplateMainForm: + ObjTemplate tfParent or tfEnd, TForm, frmMain, \ + x = 100, \ + y = 50, \ + width = 320, \ + height = 520, \ + OnCreate = FormOnCreate, \ + OnClose = MainFormOnClose, \ + OnDestroy = FormOnDestroy, \ + Caption = 'The new GUI toolkit test form.' + + ObjTemplate tfChild, TLabel, NONE, \ + x = 10, y = 10, width=400, height = 19, \ + Caption = "Load theme from file:", \ + Visible = TRUE + + + ObjTemplate tfChild, TButton, btnTheme1, \ + x = 10, \ + y = 32, \ + width = 90, \ + height = 24, \ + TextAlign = dtfAlignCenter or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\ + Caption = "Theme Win", \ + Visible = TRUE, \ + OnClick = LoadTheme1Click + + ObjTemplate tfChild, TButton, btnTheme2, \ + x = 102, \ + y = 32, \ + width = 90, \ + height = 24, \ + TextAlign = dtfAlignCenter or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\ + Caption = "Theme Flat", \ + Visible = TRUE, \ + OnClick = LoadTheme2Click + + + ObjTemplate tfChild, TLabel, NONE, \ + x = 10, y = 393, width=400, height = 19, \ + Caption = "Load/Save custom theme:", \ + Visible = TRUE + + + ObjTemplate tfChild, TEdit, editTest, \ + Text = "Theme.cfg", \ + x = 10, y=415, width=168, height=24, \ + MarginLeft= 2, \ + MarginRight= 2, \ + Visible = TRUE + + ObjTemplate tfChild, TButton, btnThemeSave, \ + x = 180, y = 415, width = 64, height = 24, \ + TextAlign = dtfAlignCenter or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\ + Caption = 'Save', \ + Visible = TRUE, \ + OnClick = SaveThemeClick + + + ObjTemplate tfChild, TButton, btnThemeLoad, \ + x = 246, y = 415, width = 64, height = 24, \ + TextAlign = dtfAlignCenter or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\ + Caption = 'Load', \ + Visible = TRUE, \ + OnClick = LoadThemeClick + + ObjTemplate tfChild, TProgress, NONE, \ + x = 10, y = 490, width = 300, height = 19, \ + Max = 100, Pos = 30, \ + Visible = TRUE + + + ObjTemplate tfChild or tfEnd, TTreeView, tvPreview, \ + x = 10, y = 64, width = 300, height = 300, \ + OnCreate = TreeOnCreate, \ + Visible = TRUE + + + + + + getfile imgFolder1, "_test_images/folder2.png" + getfile imgFile1, "_test_images/document2.png" + + getfile imgFolder2, "_test_images/folder.png" + getfile imgFile2, "_test_images/document.png" + +endg + + + + +uglobal + iconFolder dd ? + iconFile dd ? +endg + + +;rb 423 + + +start: + InitializeAll + + + create [pApplication], TApplication + + call GUI.Init + + stdcall CreateFromTemplate, TemplateMainForm, 0 + + set [pApplication], TApplication:MainWindow, frmMain + + set [frmMain], TWindow:Visible, TRUE ; must be set visible after creation, because it loads + ; needed images in OnCreate event handler. + + stdcall Run + + FinalizeAll + stdcall TerminateAll, 0 + + + +; Sample event handlers. They work with other objects on the form. + +proc FormOnCreate as TObject.OnCreate +begin + DebugMsg "Form OnCreate event handler." + + if ThemeGUI eq win_gui + + stdcall CreateIconSet1 + + else + + stdcall CreateIconSet2 + + end if + + return +endp + + +proc FreeIconSet +begin + xor ecx, ecx + + cmp [iconFolder], ecx + je @f + stdcall DestroyImage, [iconFolder] + mov [iconFolder], ecx +@@: + cmp [iconFile], ecx + je @f + stdcall DestroyImage, [iconFile] + mov [iconFile], ecx +@@: + + return +endp + + +proc CreateIconSet1 +begin + stdcall FreeIconSet + + stdcall CreateImagePNG, imgFolder1, imgFolder1.size + mov [iconFolder], eax + + stdcall CreateImagePNG, imgFile1, imgFile1.size + mov [iconFile], eax + + return +endp + + + +proc CreateIconSet2 +begin + stdcall FreeIconSet + + stdcall CreateImagePNG, imgFolder2, imgFolder2.size + mov [iconFolder], eax + + stdcall CreateImagePNG, imgFile2, imgFile2.size + mov [iconFile], eax + + return +endp + + +proc TreeOnCreate as TObject.OnCreate +begin + stdcall LoadExampleTreeContent, [.self] + + return +endp + + + + +proc FormOnDestroy as TObject.OnDestroy +begin + DebugMsg "MainForm destroy event handler." + return +endp + + + +proc MainFormOnClose as TForm.OnClose +begin + DebugMsg "Main form OnClose event handler" + clc + return +endp + + + + +proc LoadTheme1Click as TButton.OnClick +begin + pushad + + stdcall LoadBinaryFile, "./theme_win.cfg" + jc .finish + + push eax + + stdcall StringToNamedArray, GUI.meta, eax + + stdcall FreeMem ; from the stack. + + stdcall CreateIconSet1 + stdcall LoadExampleTreeContent, [tvPreview] + + exec [frmMain], TWindow:RefreshAll + +.finish: + popad + return +endp + + +proc LoadTheme2Click as TButton.OnClick +begin + pushad + + stdcall LoadBinaryFile, "./theme_flat.cfg" + jc .finish + + push eax + + stdcall StringToNamedArray, GUI.meta, eax + + stdcall FreeMem ; from the stack. + + stdcall CreateIconSet2 + stdcall LoadExampleTreeContent, [tvPreview] + + exec [frmMain], TWindow:RefreshAll + +.finish: + popad + return +endp + + +proc SaveThemeClick as TButton.OnClick +begin + pushad + + get ebx, [editTest], TEdit:Text + + stdcall NamedArrayToString, GUI.meta + mov edi, eax + + stdcall StrPtr, eax + mov esi, eax + + stdcall StrPtr, ebx + + stdcall SaveBinaryFile, eax, esi, [esi+string.len] + + stdcall StrDel, ebx + stdcall StrDel, edi + + popad + return +endp + + + + +proc LoadThemeClick as TButton.OnClick +begin + pushad + + get ebx, [editTest], TEdit:Text + + stdcall LoadBinaryFile, ebx + jc .finish + + push eax + + stdcall StringToNamedArray, GUI.meta, eax + + stdcall FreeMem ; from the stack. + + exec [frmMain], TWindow:RefreshAll + +.finish: + stdcall StrDel, ebx + popad + return +endp + + + + +proc LoadExampleTreeContent, .pTreeView +begin + pushad + + mov esi, [.pTreeView] + mov edx, [esi+TTreeView._items] + + stdcall DeleteArrayItems, edx, 0, [edx+TArray.count] + + stdcall ___DoReadDir, txt ".", edx, -1 + mov [esi+TTreeView._items], edx + jc .error + +.finish: + + OutputValue "Files tree items:", [edx+TArray.count], 10, 8 + + exec [.pTreeView], TTreeView:__RebuildIndex + exec [.pTreeView], TWindow:Refresh + + set [frmMain], TWindow:Cursor, edi + + popad + return + +.error: + stdcall GetErrorString, eax + push eax + + stdcall ShowMessage, [frmMain], smiError, "File error", eax, smbOK + + stdcall FreeErrorString ; from the stack + jmp .finish + +endp + + + + +proc ___DoReadDir, .hDir, .pArray, .Level +begin + pushad + + mov edx, [.pArray] + mov ebx, [.Level] + inc ebx + + stdcall DirectoryRead, [.hDir] + jc .finish + + mov esi, eax + xor ecx, ecx + + + stdcall SortDirArray, esi, fdsByType + +.loop: + cmp ecx, [esi+TArray.count] + jae .end_loop + + stdcall StrPtr, [esi+TArray.array + 8*ecx + TDirItem.hFilename] + + cmp byte [eax], "." + je .next + +; Output eax +; DebugMsg "" + + stdcall AddArrayItems, edx, 1 + + push [esi+TArray.array + 8*ecx + TDirItem.hFilename] ; name + pop [eax+TTreeViewItem.caption] + mov [eax+TTreeViewItem.level], ebx + mov [eax+TTreeViewItem.state], tvisExpanded + + push edx + + mov edx, [iconFolder] + cmp [esi+TArray.array + 8*ecx + TDirItem.Type], ftDirectory + je @f + + mov edx, [iconFile] + cmp [esi+TArray.array + 8*ecx + TDirItem.Type], ftFile + je @f + + xor edx, edx + +@@: + mov [eax+TTreeViewItem.imgNormal], edx + + pop edx + + cmp [esi+TArray.array + 8*ecx + TDirItem.Type], ftDirectory + jne .next + + stdcall StrDup, [.hDir] + push eax + + stdcall StrCharCat, eax, "/" + stdcall StrCat, eax, [esi+TArray.array + 8*ecx + TDirItem.hFilename] + + stdcall ___DoReadDir, eax, edx, ebx + + stdcall StrDel ; from the stack + +.next: + inc ecx + jmp .loop + +.end_loop: + stdcall FreeMem, esi + + clc + xor eax, eax + +.finish: + mov [esp+regEAX*4], eax + mov [esp+regEDX*4], edx + popad + return +endp + + ADDED freshlib/test_code0/TestThemes.fpr Index: freshlib/test_code0/TestThemes.fpr ================================================================== --- /dev/null +++ freshlib/test_code0/TestThemes.fpr cannot compute difference between binary files ADDED freshlib/test_code0/ThemesConfigBuild.asm Index: freshlib/test_code0/ThemesConfigBuild.asm ================================================================== --- /dev/null +++ freshlib/test_code0/ThemesConfigBuild.asm @@ -0,0 +1,406 @@ +; _______________________________________________________________________________________ +;| | +;| ..:: Fresh IDE ::.. template project. | +;|_______________________________________________________________________________________| +; +; Description: FreshLib portable console application. +; +; Target OS: Any, supported by FreshLib +; +; Dependencies: FreshLib +; +; Notes: +;_________________________________________________________________________________________ + +include "%lib%/freshlib.inc" + +@BinaryType GUI, compact + +options.DebugMode = 0 + options.DebugMode.NoTimers = 1 + options.DebugMode.XSync = 0 + options.DebugMode.XErrors =0 + +options.ShowSizes = 1 +options.SkipZeroSizes = 0 + +options.WholeTheme = 1 + +ThemeGUI equ + +include "%lib%/freshlib.asm" + + +GUI fix ThemeFlat + +include "%lib%/gui/themes/flat_gui.asm" + +GUI fix ThemeWin + +include "%lib%/gui/themes/win_gui.asm" + + +;rb 423 + + +start: + InitializeAll + + create [pApplication], TApplication, 0 + + call ThemeFlat.Init + call ThemeWin.Init + + +; Save flat theme + + stdcall NamedArrayToString, ThemeFlat.meta + push eax + + stdcall StrPtr, eax + mov esi, eax + + stdcall SaveBinaryFile, "theme_flat.cfg", esi, [esi+string.len] + + stdcall StrDel ; from the stack + + +; Save win theme + + stdcall NamedArrayToString, ThemeWin.meta + push eax + + stdcall StrPtr, eax + mov esi, eax + + stdcall SaveBinaryFile, "theme_win.cfg", esi, [esi+string.len] + + stdcall StrDel ; from the stack + + + destroy [pApplication] + + FinalizeAll + stdcall TerminateAll, 0 + + + +; Sample event handlers. They work with other objects on the form. + +proc FormOnCreate as TObject.OnCreate +begin + DebugMsg "Form OnCreate event handler." + + if ThemeGUI eq win_gui + + stdcall CreateIconSet1 + + else + + stdcall CreateIconSet2 + + end if + + return +endp + + +proc FreeIconSet +begin + xor ecx, ecx + + cmp [iconFolder], ecx + je @f + stdcall DestroyImage, [iconFolder] + mov [iconFolder], ecx +@@: + cmp [iconFile], ecx + je @f + stdcall DestroyImage, [iconFile] + mov [iconFile], ecx +@@: + + return +endp + + +proc CreateIconSet1 +begin + stdcall FreeIconSet + + stdcall CreateImagePNG, imgFolder1, imgFolder1.size + mov [iconFolder], eax + + stdcall CreateImagePNG, imgFile1, imgFile1.size + mov [iconFile], eax + + return +endp + + + +proc CreateIconSet2 +begin + stdcall FreeIconSet + + stdcall CreateImagePNG, imgFolder2, imgFolder2.size + mov [iconFolder], eax + + stdcall CreateImagePNG, imgFile2, imgFile2.size + mov [iconFile], eax + + return +endp + + +proc TreeOnCreate as TObject.OnCreate +begin + stdcall LoadExampleTreeContent, [.self] + + return +endp + + + + +proc FormOnDestroy as TObject.OnDestroy +begin + DebugMsg "MainForm destroy event handler." + return +endp + + + +proc MainFormOnClose as TForm.OnClose +begin + DebugMsg "Main form OnClose event handler" + clc + return +endp + + + + +proc LoadTheme1Click as TButton.OnClick +begin + pushad + + stdcall LoadBinaryFile, "./theme_win.cfg" + jc .finish + + push eax + + stdcall StringToNamedArray, GUI.meta, eax + + stdcall FreeMem ; from the stack. + + stdcall CreateIconSet1 + stdcall LoadExampleTreeContent, [tvPreview] + + exec [frmMain], TWindow:RefreshAll + +.finish: + popad + return +endp + + +proc LoadTheme2Click as TButton.OnClick +begin + pushad + + stdcall LoadBinaryFile, "./theme_flat.cfg" + jc .finish + + push eax + + stdcall StringToNamedArray, GUI.meta, eax + + stdcall FreeMem ; from the stack. + + stdcall CreateIconSet2 + stdcall LoadExampleTreeContent, [tvPreview] + + exec [frmMain], TWindow:RefreshAll + +.finish: + popad + return +endp + + +proc SaveThemeClick as TButton.OnClick +begin + pushad + + get ebx, [editTest], TEdit:Text + + stdcall NamedArrayToString, GUI.meta + mov edi, eax + + stdcall StrPtr, eax + mov esi, eax + + stdcall StrPtr, ebx + + stdcall SaveBinaryFile, eax, esi, [esi+string.len] + + stdcall StrDel, ebx + stdcall StrDel, edi + + popad + return +endp + + + + +proc LoadThemeClick as TButton.OnClick +begin + pushad + + get ebx, [editTest], TEdit:Text + + stdcall LoadBinaryFile, ebx + jc .finish + + push eax + + stdcall StringToNamedArray, GUI.meta, eax + + stdcall FreeMem ; from the stack. + + exec [frmMain], TWindow:RefreshAll + +.finish: + stdcall StrDel, ebx + popad + return +endp + + + + +proc LoadExampleTreeContent, .pTreeView +begin + pushad + + mov esi, [.pTreeView] + mov edx, [esi+TTreeView._items] + + stdcall DeleteArrayItems, edx, 0, [edx+TArray.count] + + stdcall ___DoReadDir, txt ".", edx, -1 + mov [esi+TTreeView._items], edx + jc .error + +.finish: + + OutputValue "Files tree items:", [edx+TArray.count], 10, 8 + + exec [.pTreeView], TTreeView:__RebuildIndex + exec [.pTreeView], TWindow:Refresh + + set [frmMain], TWindow:Cursor, edi + + popad + return + +.error: + stdcall GetErrorString, eax + push eax + + stdcall ShowMessage, [frmMain], smiError, "File error", eax, smbOK + + stdcall FreeErrorString ; from the stack + jmp .finish + +endp + + + + +proc ___DoReadDir, .hDir, .pArray, .Level +begin + pushad + + mov edx, [.pArray] + mov ebx, [.Level] + inc ebx + + stdcall DirectoryRead, [.hDir] + jc .finish + + mov esi, eax + xor ecx, ecx + + + stdcall SortDirArray, esi, fdsByType + +.loop: + cmp ecx, [esi+TArray.count] + jae .end_loop + + stdcall StrPtr, [esi+TArray.array + 8*ecx + TDirItem.hFilename] + + cmp byte [eax], "." + je .next + +; Output eax +; DebugMsg "" + + stdcall AddArrayItems, edx, 1 + + push [esi+TArray.array + 8*ecx + TDirItem.hFilename] ; name + pop [eax+TTreeViewItem.caption] + mov [eax+TTreeViewItem.level], ebx + mov [eax+TTreeViewItem.state], tvisExpanded + + push edx + + mov edx, [iconFolder] + cmp [esi+TArray.array + 8*ecx + TDirItem.Type], ftDirectory + je @f + + mov edx, [iconFile] + cmp [esi+TArray.array + 8*ecx + TDirItem.Type], ftFile + je @f + + xor edx, edx + +@@: + mov [eax+TTreeViewItem.imgNormal], edx + + pop edx + + cmp [esi+TArray.array + 8*ecx + TDirItem.Type], ftDirectory + jne .next + + stdcall StrDup, [.hDir] + push eax + + stdcall StrCharCat, eax, "/" + stdcall StrCat, eax, [esi+TArray.array + 8*ecx + TDirItem.hFilename] + + stdcall ___DoReadDir, eax, edx, ebx + + stdcall StrDel ; from the stack + +.next: + inc ecx + jmp .loop + +.end_loop: + stdcall FreeMem, esi + + clc + xor eax, eax + +.finish: + mov [esp+regEAX*4], eax + mov [esp+regEDX*4], edx + popad + return +endp + + ADDED freshlib/test_code0/ThemesConfigBuild.fpr Index: freshlib/test_code0/ThemesConfigBuild.fpr ================================================================== --- /dev/null +++ freshlib/test_code0/ThemesConfigBuild.fpr cannot compute difference between binary files Index: freshlib/test_code0/UTF8_examples.asm ================================================================== --- freshlib/test_code0/UTF8_examples.asm +++ freshlib/test_code0/UTF8_examples.asm @@ -1,5 +1,5 @@ utf8_string db $49, $C3, $B1, $74, $C3, $AB, $72, $6E, $C3, $A2, $74, $69, $C3, $B4, $6E, $C3, $A0, $6C, $69, $7A, $C3, $A6, $74, $69, $C3, $B8, $6E, $00 ; the word "Internationalization" written with different languages chars ; greek, cyrillic and latin in one text. - utf8_long file 'UnicodeSample.txt':3 + utf8_long file 'UnicodeSample.txt' dd 0 Index: freshlib/test_code0/UnicodeSample.txt ================================================================== --- freshlib/test_code0/UnicodeSample.txt +++ freshlib/test_code0/UnicodeSample.txt @@ -1,6 +1,8 @@ -Russian: Я могу есть стекло, оно мне не вредит. +Russian: Я могу есть стекло, оно мне не вредит. Yoruba: Mo lè je̩ dígí, kò ní pa mí lára. -Chinese: 我能吞下玻璃而不伤身体。 +Chinese: 我能吞下玻璃而不伤身体。 Greek: Μπορώ να φάω σπασμένα γυαλιά χωρίς να πάθω τίποτα. -Québécois: J'peux manger d'la vitre, ça m'fa pas mal. -Ukrainian: Я можу їсти скло, і воно мені не зашкодить. +Québécois: J'peux manger d'la vitre, ça m'fa pas mal. +Ukrainian: Я можу їсти скло, і воно мені не зашкодить. + +Това е един много дълъг параграф, в който се говори за това, че мога да консумирам неорганични силикатни аморфни материали без вреда за здравето или материалното ми положение. ADDED freshlib/test_code0/_test_images/document.png Index: freshlib/test_code0/_test_images/document.png ================================================================== --- /dev/null +++ freshlib/test_code0/_test_images/document.png cannot compute difference between binary files ADDED freshlib/test_code0/_test_images/document2.png Index: freshlib/test_code0/_test_images/document2.png ================================================================== --- /dev/null +++ freshlib/test_code0/_test_images/document2.png cannot compute difference between binary files ADDED freshlib/test_code0/_test_images/folder.png Index: freshlib/test_code0/_test_images/folder.png ================================================================== --- /dev/null +++ freshlib/test_code0/_test_images/folder.png cannot compute difference between binary files ADDED freshlib/test_code0/_test_images/folder2.png Index: freshlib/test_code0/_test_images/folder2.png ================================================================== --- /dev/null +++ freshlib/test_code0/_test_images/folder2.png cannot compute difference between binary files ADDED freshlib/test_code0/_test_images/globe.png Index: freshlib/test_code0/_test_images/globe.png ================================================================== --- /dev/null +++ freshlib/test_code0/_test_images/globe.png cannot compute difference between binary files DELETED freshlib/test_code0/_test_images/icon.gif Index: freshlib/test_code0/_test_images/icon.gif ================================================================== --- freshlib/test_code0/_test_images/icon.gif +++ /dev/null cannot compute difference between binary files ADDED freshlib/test_code0/_test_images/img_list.png Index: freshlib/test_code0/_test_images/img_list.png ================================================================== --- /dev/null +++ freshlib/test_code0/_test_images/img_list.png cannot compute difference between binary files ADDED freshlib/test_code0/_test_images/left.png Index: freshlib/test_code0/_test_images/left.png ================================================================== --- /dev/null +++ freshlib/test_code0/_test_images/left.png cannot compute difference between binary files ADDED freshlib/test_code0/_test_images/menu.png Index: freshlib/test_code0/_test_images/menu.png ================================================================== --- /dev/null +++ freshlib/test_code0/_test_images/menu.png cannot compute difference between binary files ADDED freshlib/test_code0/_test_images/right.png Index: freshlib/test_code0/_test_images/right.png ================================================================== --- /dev/null +++ freshlib/test_code0/_test_images/right.png cannot compute difference between binary files ADDED freshlib/test_code0/_test_images/right2.png Index: freshlib/test_code0/_test_images/right2.png ================================================================== --- /dev/null +++ freshlib/test_code0/_test_images/right2.png cannot compute difference between binary files ADDED freshlib/test_code0/_test_images/speech.png Index: freshlib/test_code0/_test_images/speech.png ================================================================== --- /dev/null +++ freshlib/test_code0/_test_images/speech.png cannot compute difference between binary files ADDED freshlib/test_code0/_test_images/star.png Index: freshlib/test_code0/_test_images/star.png ================================================================== --- /dev/null +++ freshlib/test_code0/_test_images/star.png cannot compute difference between binary files ADDED freshlib/test_code0/_test_images/svg/document.svg Index: freshlib/test_code0/_test_images/svg/document.svg ================================================================== --- /dev/null +++ freshlib/test_code0/_test_images/svg/document.svg @@ -0,0 +1,73 @@ + + + +image/svg+xml ADDED freshlib/test_code0/_test_images/svg/folder.svg Index: freshlib/test_code0/_test_images/svg/folder.svg ================================================================== --- /dev/null +++ freshlib/test_code0/_test_images/svg/folder.svg @@ -0,0 +1,70 @@ + + + +image/svg+xml ADDED freshlib/test_code0/_test_images/svg/left.svg Index: freshlib/test_code0/_test_images/svg/left.svg ================================================================== --- /dev/null +++ freshlib/test_code0/_test_images/svg/left.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ADDED freshlib/test_code0/_test_images/svg/menu.svg Index: freshlib/test_code0/_test_images/svg/menu.svg ================================================================== --- /dev/null +++ freshlib/test_code0/_test_images/svg/menu.svg @@ -0,0 +1,68 @@ + + + +image/svg+xml ADDED freshlib/test_code0/_test_images/svg/right.svg Index: freshlib/test_code0/_test_images/svg/right.svg ================================================================== --- /dev/null +++ freshlib/test_code0/_test_images/svg/right.svg @@ -0,0 +1,82 @@ + + + +image/svg+xml ADDED freshlib/test_code0/_test_images/svg/star.svg Index: freshlib/test_code0/_test_images/svg/star.svg ================================================================== --- /dev/null +++ freshlib/test_code0/_test_images/svg/star.svg @@ -0,0 +1,67 @@ + + + +image/svg+xml DELETED freshlib/test_code0/_test_images/test.gif Index: freshlib/test_code0/_test_images/test.gif ================================================================== --- freshlib/test_code0/_test_images/test.gif +++ /dev/null cannot compute difference between binary files ADDED freshlib/test_code0/theme_flat.cfg Index: freshlib/test_code0/theme_flat.cfg ================================================================== --- /dev/null +++ freshlib/test_code0/theme_flat.cfg @@ -0,0 +1,63 @@ +clBorderNeutral = $FF1ABC9C +clBorderLight = $FF1ABC9C +clBorderDark = $FF1ABC9C +clBorderNeutralGray = $FF606060 +clBorderLightGray = $FF606060 +clBorderDarkGray = $FF606060 +clBorderFocused = $FFE74C3C +boxBorderWidth = 2 +clBtnBk = $FF1ABC9C, $FF48C9B0, $FF16A085, $807B7B7B +clBtnTxt = $FFFFFFFF, $FFFFFFFF, $FFBDC3C7, $80FFFFFF +btnBorder = 0, 0, 0, 0 +btnPressedOfsX = 0 +btnPressedOfsY = 0 +btnMarginX = 8 +btnMarginY = 8 +clEditBk = $FFECF0F1 +clEditBkFocused = $FFECF0F1 +clEditTxt = $FF000000 +clEditSel = $602980B9 +clEditSelTxt = $FFFFFFFF +editBorder = 3 +editBorderFocused = 3 +clDialogBk = $FFECF0F1 +clDialogTxt = $FF000000 +clSplitter = $FF34495E +clProgressBk = $FFECF0F1 +clProgressBar = $FF1ABC9C +progressBorder = 3 +clScrollBk = $3FBDC3C7, $A0BDC3C7 +clScrollSlider = $7F7F8C8D, $FF1ABC9C +borderScroll = 0 +scrollWidth = 12 +minSliderHeight = 12 +clLabelBk = $0 +clLabelTxt = $FF000000 +clTreeViewBack = $FFECF0F1 +clTreeViewText = $FF000000 +clTreeSelected = $FF2980B9 +clTreeSelectedTxt = $FFFFFFFF +clTreeFocused = $FFD35400 +clTreeFocusedTxt = $FFFFFFFF +tvBorder = 3 +tvIcons = 297:iVBORw0KGgoAAAANSUhEUgAAAAsAAAALCAMAAACecocUAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAEJQTFRFAAAAgICAkra2n5+fmaOjkqiolqamlaWllqWllKWnlaWllaSmlqWllaWllqWllaWmlaWmlaWmlaWmlaWmlaWmlaWml3PoaAAAABV0Uk5TAAIHCBkjLkFmbm9zd4Ciu8vM4uj9nlc1ogAAADhJREFUCJlj4OJhZoABXlEhDkY4W1RUkB3BFhXlZ0OwRUX4WOBsUVFhViziCPUC7Jjmc3IzwawFAEAMBLa48vXWAAAAAElFTkSuQmCC, 333:iVBORw0KGgoAAAANSUhEUgAAAAsAAAALCAYAAACprHcmAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAADKSURBVBiVhY+7TgJhFIS/+d3QmWDhE/gQhlfgAbb46U00aENMoKCgs5ZIRey49FpbmFhZm9iQ0FFaC2yGQjFcVna6Oec7l1FvMLgATijWV2LrGHFXREo0wmkp6QomBex0WS4/hDRN5xbtQ6Rx66Za/RaAbfWGozegkoO+X8V4Lsnh5x/ZuJm3NUhNSQYI62K9VnsVet5hny5jfPkb3Oxk8i2wXFuL1taVTXMd46fR42+qfj3Gj39hgKNs0QZmibNOXoY93Y/HZ3n1FeLFO3+97VjQAAAAAElFTkSuQmCC +clMenuBack = $FFECF0F1 +clMenuText = $FF000000 +clMenuTextGray = $90000000 +borderMenu = 3 +menuIconMargin = 4 +menuMinTextDist = 32 +menuSubIcon = 206:iVBORw0KGgoAAAANSUhEUgAAAAYAAAALCAYAAABcUvyWAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABLSURBVBiVjc+xDYBADATBeSQCIgqgYzJaoARSInqgH5MQvQ6JzezVyT7YMAgUdoxJFA5MSRQuzEkUbiztHXrOz8SvG/Gr2GNF65cP8X4dCPkfyx8AAAAASUVORK5CYII- +menuSubIconSel = 207:iVBORw0KGgoAAAANSUhEUgAAAAYAAAALCAYAAABcUvyWAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABMSURBVBiVjc+xDYAwEEPRCxIFFQOwcTpWyAi0VOzAPi8FXTgk3H5Z3w7smGKMJw1zBuDAkgG4sGYAbmwFXuKI87Pxy5GuSn9UlNHeAYWml41HdWNxAAAAAElFTkSuQmCC +menuSubIconGray = 280:iVBORw0KGgoAAAANSUhEUgAAAAYAAAALCAYAAABcUvyWAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAACVSURBVBiVY5i6dOnEhoYGJgY0wMTAwJgnpqq6YObMmaxoEgwM/xkYY//w8K7tW7WKE0UCCnzZf//ZMXPVKn4GBgYGxqlLl/1HM/4q0x8WdwxLGRgYtP+x/JmPTeIq0x+WRHSJQyysLNaZ8WFPkSU2/2Rl8UgPC/sIdxUjw//FLF8+BxeFhX2HK5u2ZFnX////GdEtAgDKqy21io/rDwAAAABJRU5ErkJggg-- +iconMenuChecked = 172:iVBORw0KGgoAAAANSUhEUgAAAAcAAAAQCAYAAADagWXwAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAApSURBVBiVY2CgP2B87mPTgEuShYGBoR6XJBM+YwdCkoWBgaERnwJ6AwCTrAMDeKqy3AAAAABJRU5ErkJggg-- +iconMenuCheckedGray = 172:iVBORw0KGgoAAAANSUhEUgAAAAcAAAAQCAYAAADagWXwAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAApSURBVBiVY2CgP2DMy8trwCXJwsDAUI9LkgmfsQMhycLAwNCITwG9AQBg/wLetiFJMAAAAABJRU5ErkJggg-- +clCheckboxBack = $FFE0E0E0, $FFFFFFFF, $FFC0C0C0, $80C0C0C0 +clCheckboxTxt = $FF000000 +clCheckboxTxtGray = $FF606060 +cbIconSize = 13 +cbMargin = 2 +borderCheckbox = 3 +iconChecked = 166:iVBORw0KGgoAAAANSUhEUgAAAA0AAAANCAYAAABy6+R8AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAAjSURBVCiRY2AYfoARXeC5j81/dDHJLUdQ1DGRY9Mg1zQcAQAaUwQKOrN/dgAAAABJRU5ErkJggg-- +iconCheckedGray = 166:iVBORw0KGgoAAAANSUhEUgAAAA0AAAANCAYAAABy6+R8AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAAjSURBVCiRY2AYfoARXSA/P/8/utjEiRNR1DGRY9Mg1zQcAQAXqwQKOqarXQAAAABJRU5ErkJggg-- +DefaultFont = 'Liberation Sans' : 13 : 4 : $0 ADDED freshlib/test_code0/theme_win.cfg Index: freshlib/test_code0/theme_win.cfg ================================================================== --- /dev/null +++ freshlib/test_code0/theme_win.cfg @@ -0,0 +1,63 @@ +clBorderNeutral = $FFA0A0A0 +clBorderLight = $FFFFFFFF +clBorderDark = $FF404040 +clBorderNeutralGray = $FF909090 +clBorderLightGray = $FFE0E0E0 +clBorderDarkGray = $FF808080 +clBorderFocused = $FFFF8000 +boxBorderWidth = 1 +clBtnBk = $FFD4D0C8, $FFE0E0E0, $FFA0A0A0, $80D4D0C8 +clBtnTxt = $FF000000, $FF000000, $FF000000, $FF606060 +btnBorder = 1, 1, 2 +btnPressedOfsX = 1 +btnPressedOfsY = 1 +btnMarginX = 8 +btnMarginY = 8 +clEditBk = $FFFFFFFF +clEditBkFocused = $FFFFFFFF +clEditTxt = $FF000000 +clEditSel = $600A246C +clEditSelTxt = $FFFFFFFF +editBorder = 2 +editBorderFocused = 2 +clDialogBk = $FFD4D0C8 +clDialogTxt = $FF000000 +clSplitter = $FF606060 +clProgressBk = $FFD4D0C8 +clProgressBar = $FF0A246C +progressBorder = 2 +clScrollBk = $3F808080, $A0D4D0C8 +clScrollSlider = $7FD4D0C8, $FFD4D0C8 +borderScroll = 1 +scrollWidth = 16 +minSliderHeight = 16 +clLabelBk = $FFFFFF +clLabelTxt = $FF000000 +clTreeViewBack = $FFFFFFFF +clTreeViewText = $FF000000 +clTreeSelected = $FF0A246C +clTreeSelectedTxt = $FFFFFFFF +clTreeFocused = $FF0A246C +clTreeFocusedTxt = $FFFFFF00 +tvBorder = 2 +tvIcons = 117:iVBORw0KGgoAAAANSUhEUgAAAAsAAAALAQMAAACTYuVlAAAABlBMVEUAAAAAAAClZ7nPAAAAAXRSTlMAQObYZgAAAB1JREFUCNdjYGBgqD/A4ODA4AJG8TAGUAQozsAAAGXeBi6dny4xAAAAAElFTkSuQmCC, 114:iVBORw0KGgoAAAANSUhEUgAAAAsAAAALAQMAAACTYuVlAAAABlBMVEUAAAAAAAClZ7nPAAAAAXRSTlMAQObYZgAAABpJREFUCNdjYGBgqD/A4OAARfEOCDZQnIEBAGTOBh7FK7i2AAAAAElFTkSuQmCC +clMenuBack = $FFD4D0C8 +clMenuText = $FF000000 +clMenuTextGray = $80000000 +borderMenu = 1 +menuIconMargin = 4 +menuMinTextDist = 32 +menuSubIcon = 206:iVBORw0KGgoAAAANSUhEUgAAAAYAAAALCAYAAABcUvyWAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABLSURBVBiVjc+xDYBADATBeSQCIgqgYzJaoARSInqgH5MQvQ6JzezVyT7YMAgUdoxJFA5MSRQuzEkUbiztHXrOz8SvG/Gr2GNF65cP8X4dCPkfyx8AAAAASUVORK5CYII- +menuSubIconSel = 207:iVBORw0KGgoAAAANSUhEUgAAAAYAAAALCAYAAABcUvyWAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABMSURBVBiVjc+xDYAwEEPRCxIFFQOwcTpWyAi0VOzAPi8FXTgk3H5Z3w7smGKMJw1zBuDAkgG4sGYAbmwFXuKI87Pxy5GuSn9UlNHeAYWml41HdWNxAAAAAElFTkSuQmCC +menuSubIconGray = 280:iVBORw0KGgoAAAANSUhEUgAAAAYAAAALCAYAAABcUvyWAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAACVSURBVBiVY5i6dOnEhoYGJgY0wMTAwJgnpqq6YObMmaxoEgwM/xkYY//w8K7tW7WKE0UCCnzZf//ZMXPVKn4GBgYGxqlLl/1HM/4q0x8WdwxLGRgYtP+x/JmPTeIq0x+WRHSJQyysLNaZ8WFPkSU2/2Rl8UgPC/sIdxUjw//FLF8+BxeFhX2HK5u2ZFnX////GdEtAgDKqy21io/rDwAAAABJRU5ErkJggg-- +iconMenuChecked = 246:iVBORw0KGgoAAAANSUhEUgAAAAgAAAAQCAYAAAArij59AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABzSURBVCiRzc6xDUEBFIXhjxhAp6UUjSEkbwSjmIDEBFaxgNIYKEWhlKO5LxJ5r+aU9z85/+X3GfSjLDDug1NyJ5cuOCInErJBDmRHSpd9wSMZIuc6bElDXuRGJu3kjFyr9KzC6tu7JI/PUvfnc7Iu71/lDbA1NqOlVrCQAAAAAElFTkSuQmCC +iconMenuCheckedGray = 299:iVBORw0KGgoAAAANSUhEUgAAAAgAAAAQCAYAAAArij59AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAACoSURBVCiRxY4hjgJBFAXrd2YMiiOsJTgEAvF7xqJJUGQvsQoPIcFhOAEWT7KTTPoCHAEJa1es7LcKNYOmbL3kFbwfeyXquh4Dw95BVVUfkq7AX+iRhaQTMJR0CO5+jDFun3eSNsBM0iWltC/MbApMYowKIaSc8xfwKMvyE8hB0gK4A+uc8xnAzFZN0/wAhJTSzczmwC8wAHZt2353yt195O5LoBP+bv4BnNI5/xB5g9MAAAAASUVORK5CYII- +clCheckboxBack = $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFC0C0C0 +clCheckboxTxt = $FF000000 +clCheckboxTxtGray = $FF808080 +cbIconSize = 13 +cbMargin = 2 +borderCheckbox = 2 +iconChecked = 282:iVBORw0KGgoAAAANSUhEUgAAAA0AAAANCAYAAABy6+R8AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAACXSURBVCiRzc89DgFhEIDhVy/Z0gEUolFIuIBCotNKFC6goHQdV9BxD41Cp1gVBRF5NRPZbMh+jcR08/NMZuDPwgm4A1upoAveQMF5CqiD+wAHMCs2M3AFdkpoHeAO9ssbF9E8g+2ozaImuPx0RhPMY+AIDsFr5Buw9u3+HngpbBc8gY2qx0fgI8ATHFSANxyDW3CaCH4YL0VGUkYKfrkaAAAAAElFTkSuQmCC +iconCheckedGray = 404:iVBORw0KGgoAAAANSUhEUgAAAA0AAAANCAYAAABy6+R8AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAERSURBVCiRvdAhS0NhFIfx57zvhYUJBs0uGMTqB9h2LwMR7KJLbmAQP4FN8EOYBItNEAQx7N67G9UmliHKxbYomOS955iUaZgW/bcD51ce+K/Jb57iON5S1b5zbjfP81H0E0iSZEVVj0WkBqwCIzcNtNvtGVU9BWpm9uS9PwGIADqdzmwIYc97f5Gm6d2EOwKWzOzNe785GAxeABxAVVV94DCEkDebzWWAVqu1DXQBRGQ/y7KbLyGSJFlU1WtgzsyenXM7ZnYG1M3ssiiKdcA+kAPIsuzRzNaAVxFZMLMroA6MoyjqTYJPBFAUxa2IbAABwMxURLppmo6/B/KTR1mWD41G415E5oGD4XB4Pq3u3+8d34hqDI8BY9gAAAAASUVORK5CYII- +DefaultFont = 'Liberation Sans' : 13 : 2 : $0