Custom Drawn Interface: what changed
Revision 2 to 3. Removed lines have a minus sign; added lines have a plus sign.
| Old | New | Line | |
|---|---|---|---|
| 1 | - | ||
| 1 | + | [](</File:Warning-icon.png>) | |
| 2 | 2 | ||
| 3 | + | **Warning:** THIS INFORMATION IS EXTREMELY DATED AND NEEDS UPDATING as of 2015 | |
| 4 | + | ||
| 5 | + | ## Contents | |
| 6 | + | ||
| 7 | + | * 1 Other Interfaces | |
| 8 | + | * 1.1 Platform specific Tips | |
| 9 | + | * 1.2 Interface Development Articles | |
| 10 | + | * 2 Introduction | |
| 11 | + | * 3 FAQ | |
| 12 | + | * 3.1 Diagram of the Custom Drawn Interface | |
| 13 | + | * 4 The LCL-CustomDrawn Backends | |
| 14 | + | * 4.1 LCL-CustomDrawn-Android | |
| 15 | + | * 4.2 LCL-CustomDrawn-X11 | |
| 16 | + | * 4.3 LCL-CustomDrawn-Cocoa | |
| 17 | + | * 4.4 LCL-CustomDrawn-Windows | |
| 18 | + | * 4.5 LCL-CustomDrawn-iPhone | |
| 19 | + | * 5 Canvas | |
| 20 | + | * 5.1 Getting the TLazCanvas object inside TCanvas | |
| 21 | + | * 5.2 Drawing optimization roadmap | |
| 22 | + | * 5.2.1 Optimizations already done | |
| 23 | + | * 5.2.2 Optimizations to be done | |
| 24 | + | * 6 Font rendering | |
| 25 | + | * 7 Message and Common Dialogs | |
| 26 | + | * 8 Windowed visual controls | |
| 27 | + | * 9 Conditional defines accepted by LCL-CustomDrawn | |
| 28 | + | * 10 Screenshots | |
| 29 | + | * 11 See Also | |
| 30 | + | ||
| 31 | + | ## Other Interfaces | |
| 32 | + | ||
| 33 | + | * [[Lazarus known issues \(things that will never be fixed\|Lazarus known issues (things that will never be fixed)]]> "Lazarus known issues \(things that will never be fixed\)") \- A list of interface compatibility issues | |
| 34 | + | * [[Win32/64 Interface]] \- The Windows API (formerly Win32 API) interface for Windows 95/98/Me/2000/XP/Vista/10, but not CE | |
| 35 | + | * [[Windows CE Interface]] \- For Pocket PC and Smartphones | |
| 36 | + | * [[Carbon Interface]] \- The Carbon 32 bit interface for macOS (deprecated; removed from macOS 10.15) | |
| 37 | + | * [[Cocoa Interface]] \- The Cocoa 64 bit interface for macOS | |
| 38 | + | * [[Qt Interface]] \- The Qt4 interface for Unixes, macOS, Windows, and Linux-based PDAs | |
| 39 | + | * [[Qt5 Interface]] \- The Qt5 interface for Unixes, macOS, Windows, and Linux-based PDAs | |
| 40 | + | * [[GTK1 Interface]] \- The gtk1 interface for Unixes, macOS (X11), Windows | |
| 41 | + | * [[GTK2 Interface]] \- The gtk2 interface for Unixes, macOS (X11), Windows | |
| 42 | + | * [[GTK3 Interface]] \- The gtk3 interface for Unixes, macOS (X11), Windows | |
| 43 | + | * [[fpGUI Interface]] \- Based on the fpGUI library, which is a cross-platform toolkit completely written in Object Pascal | |
| 44 | + | * Custom Drawn Interface \- A cross-platform LCL backend written completely in Object Pascal inside Lazarus. The Lazarus interface to Android. | |
| 45 | + | ||
| 46 | + | ### Platform specific Tips | |
| 47 | + | ||
| 48 | + | * [[Android Programming]] \- For Android smartphones and tablets | |
| 49 | + | * [[iPhone/iPod development]] \- About using Objective Pascal to develop iOS applications | |
| 50 | + | * [[FreeBSD Programming Tips]] \- FreeBSD programming tips | |
| 51 | + | * [[Linux Programming Tips]] \- How to execute particular programming tasks in Linux | |
| 52 | + | * [[macOS Programming Tips]] \- Lazarus tips, useful tools, Unix commands, and more... | |
| 53 | + | * [[WinCE Programming Tips]] \- Using the telephone API, sending SMSes, and more... | |
| 54 | + | * [[Windows Programming Tips]] \- Desktop Windows programming tips | |
| 55 | + | ||
| 56 | + | ### Interface Development Articles | |
| 57 | + | ||
| 58 | + | * [[Carbon interface internals]] \- If you want to help improving the Carbon interface | |
| 59 | + | * [[Windows CE Development Notes]] \- For Pocket PC and Smartphones | |
| 60 | + | * [[Adding a new interface]] \- How to add a new widget set interface | |
| 61 | + | * [[LCL Defines]] \- Choosing the right options to recompile LCL | |
| 62 | + | * [[LCL Internals]] \- Some info about the inner workings of the LCL | |
| 63 | + | * [[Cocoa Internals]] \- Some info about the inner workings of the Cocoa widgetset | |
| 64 | + | ||
| 3 | 65 | ## Introduction | |
| 4 | 66 | ||
| 5 | - | ||
| 67 | + | LCL-CustomDrawn-Android has the following features: | |
| 6 | 68 | ||
| 7 | - | ||
| 8 | - | ||
| 9 | - | ||
| 10 | - | ||
| 11 | - | ||
| 69 | + | * Backends for X11, Android and Windows and a partially working one for Cocoa, more can be added in the future | |
| 70 | + | * Painting is done completely inside Lazarus without any interference from the native libraries except for text drawing. This assures a complete perfection of the executed drawings in all platforms and a uniform level of supported features | |
| 71 | + | * Only 1 native window is utilized for each form, in the Android backend at the moment this is 1 native window for the entire application | |
| 72 | + | * Utilizes the Lazarus Custom Drawn Controls for implementing the LCL standard controls | |
| 73 | + | * Utilizes as it's painting engine the lcl parts: TLazIntfImage, TRawImage, lazcanvas and lazregions | |
| 12 | 74 | ||
| 13 | 75 | ## FAQ | |
| 14 | 76 | ||
| 15 | 77 | ### Diagram of the Custom Drawn Interface | |
| 16 | 78 | ||
| 17 | - | ||
| 79 | + | [](</File:customdrawn_diagram.png>) | |
| 18 | 80 | ||
| 19 | - | ||
| 81 | + | Legend: | |
| 20 | 82 | ||
| 21 | - | ||
| 22 | - | ||
| 23 | - | ||
| 83 | + | * Blue - New elements implemented as part of the LCL-CustomDrawn project | |
| 84 | + | * Yellow - Pre-existing LCL elements | |
| 85 | + | * Gray - System APIs | |
| 24 | 86 | ||
| 25 | 87 | ## The LCL-CustomDrawn Backends | |
| 26 | 88 | ||
| 27 | - | ||
| 89 | + | LCL-CustomDrawn needs backends to implement the most basic parts of the widgetset. Each backend should implement the following minimal parts: | |
| 28 | 90 | ||
| 29 | - | ||
| 30 | - | ||
| 31 | - | ||
| 32 | - | ||
| 91 | + | * TWidgetSet.Run, ProcessMessages, etc | |
| 92 | + | * TForm | |
| 93 | + | * TWinControl with all events | |
| 94 | + | * TTrayIcon | |
| 33 | 95 | ||
| 34 | 96 | ### LCL-CustomDrawn-Android | |
| 35 | 97 | ||
| 36 | 98 | This backend is working. See this page [[Custom Drawn Interface/Android]] | |
| 37 | 99 | ||
| 38 | 100 | And also [[Android Programming]] | |
| 39 | 101 | ||
| 40 | 102 | ### LCL-CustomDrawn-X11 | |
| 41 | 103 | ||
| 42 | 104 | This backend is working. See [[Custom Drawn Interface/X11]] | |
| 43 | 105 | ||
| 44 | 106 | ### LCL-CustomDrawn-Cocoa | |
| 45 | 107 | ||
| 46 | - | ||
| 108 | + | This backend is working. | |
| 47 | 109 | ||
| 48 | 110 | ### LCL-CustomDrawn-Windows | |
| 49 | 111 | ||
| 50 | - | ||
| 112 | + | This backend is working. | |
| 51 | 113 | ||
| 52 | 114 | ### LCL-CustomDrawn-iPhone | |
| 53 | 115 | ||
| 54 | - | ||
| 116 | + | This is planned, but not yet started. | |
| 55 | 117 | ||
| 56 | 118 | ## Canvas | |
| 57 | 119 | ||
| 58 | - | ||
| 120 | + | TCanvas will be fully non-native in this widgetset and based on [[Developing with Graphics|LazCanvas]]. All drawings to visual controls and on the OnPaint event of controls of the form are naturally double-buffered because the entire drawing of the form is first performed on an off-screen buffer and then copied in 1 operation to the form native canvas. In reality there is only 1 TLazCanvas for the entire form, but sub-controls will think they are on a separate canvas because the property BaseWindowOrg sets an internal start position of the canvas and also because all drawings will be clipped to reflect the size and shape of the sub-control. | |
| 59 | 121 | ||
| 60 | 122 | ### Getting the TLazCanvas object inside TCanvas | |
| 61 | 123 | ||
| 62 | - | ||
| 63 | - | ||
| 64 | - | ||
| 124 | + | This works only in the LCL-CustomDrawn interface: | |
| 125 | + | ``` | |
| 65 | 126 | uses lazcanvas, lclintf; | |
| 66 | - | ||
| 67 | - | ||
| 68 | - | ||
| 69 | - | ||
| 70 | - | ||
| 71 | - | ||
| 72 | - | ||
| 73 | - | ||
| 74 | - | ||
| 127 | + | ||
| 128 | + | var | |
| 129 | + | MyLazCanvas: TLazCanvas: | |
| 130 | + | begin | |
| 131 | + | if nctLazCanvas in LCLIntf.GetAvailableNativeCanvasTypes(MyCanvas.Handle) then | |
| 132 | + | begin | |
| 133 | + | MyLazCanvas := TLazCanvas(LCLIntf.GetNativeCanvas(MyCanvas.Handle, nctLazCanvas)); | |
| 134 | + | // do something here with TLazCanvas | |
| 135 | + | end; | |
| 75 | 136 | ``` | |
| 76 | 137 | ||
| 77 | 138 | ### Drawing optimization roadmap | |
| 78 | 139 | ||
| 79 | 140 | #### Optimizations already done | |
| 80 | 141 | ||
| 81 | - | ||
| 82 | - | ||
| 83 | - | ||
| 84 | - | ||
| 85 | - | ||
| 86 | - | ||
| 87 | - | ||
| 88 | - | ||
| 89 | - | ||
| 90 | - | ||
| 142 | + | * Give 1 bitmap to each control and buffer the control images and only redraw them if invalidated. This greatly helps in large forms when invalidating only 1 control. | |
| 143 | + | * Don't draw controls which are completely covered by other ones. Commits: | |
| 144 | + | * [http://svn.freepascal.org/cgi-bin/viewvc.cgi?view=rev&root=lazarus&revision=36437](<http://svn.freepascal.org/cgi-bin/viewvc.cgi?view=rev&root=lazarus&revision=36437>) | |
| 145 | + | * [http://svn.freepascal.org/cgi-bin/viewvc.cgi?view=rev&root=lazarus&revision=36455](<http://svn.freepascal.org/cgi-bin/viewvc.cgi?view=rev&root=lazarus&revision=36455>) | |
| 146 | + | * Change the control bitmaps to use the native format (with ifdefs for ARGB32 for alpha blending support). This was implemented together with the next optimization: | |
| 147 | + | * Optimize the case of drawing a bitmap to a canvas, when the pixel formats match and the clip rect is inexistent or rectangular. The magnifier full painting went from 630ms to 477ms for me. | |
| 148 | + | * [http://svn.freepascal.org/cgi-bin/viewvc.cgi?view=rev&root=lazarus&revision=36576](<http://svn.freepascal.org/cgi-bin/viewvc.cgi?view=rev&root=lazarus&revision=36576>) | |
| 149 | + | * [http://svn.freepascal.org/cgi-bin/viewvc.cgi?view=rev&root=lazarus&revision=36578](<http://svn.freepascal.org/cgi-bin/viewvc.cgi?view=rev&root=lazarus&revision=36578>) | |
| 150 | + | * Optimize rectangle area filling if the clip rect is inexistent or rectangular. Decreased the drawing of a fullscreen form in X11 with 4 buttons from 95ms to 33ms for me | |
| 151 | + | * [http://svn.freepascal.org/cgi-bin/viewvc.cgi?view=rev&root=lazarus&revision=36580](<http://svn.freepascal.org/cgi-bin/viewvc.cgi?view=rev&root=lazarus&revision=36580>) | |
| 91 | 152 | ||
| 92 | 153 | #### Optimizations to be done | |
| 93 | 154 | ||
| 94 | - | ||
| 95 | - | ||
| 96 | - | ||
| 155 | + | * Buffer the native bitmap of the form instead of generating it on each operation | |
| 156 | + | * Reuse the buffered native bitmap contents if they don't change | |
| 157 | + | * Support invalidating only a rectangle instead of the entire control | |
| 97 | 158 | ||
| 98 | 159 | ## Font rendering | |
| 99 | 160 | ||
| 100 | - | ||
| 161 | + | When the define CD_UseNativeText is activated, LCL-CustomDrawn will use the native text rendering of the platform as provided by the backend. If it isn't activated, then it will use [[LazFreeType]] to render the text. The define is automatically activated for some backends if convenient when using them. | |
| 101 | 162 | ||
| 102 | 163 | ## Message and Common Dialogs | |
| 103 | 164 | ||
| 104 | - | ||
| 165 | + | Message and Common Dialogs might be native if this is considered very convenient for the backend. If not, they will be non-native. At the moment the Android backend has native message boxes. | |
| 105 | 166 | ||
| 106 | 167 | ## Windowed visual controls | |
| 107 | 168 | ||
| 108 | 169 | All Windowed visual controls (TButton, TPageControl, etc) will be based in the [[Lazarus Custom Drawn Controls]] | |
| 109 | 170 | ||
| 110 | 171 | ## Conditional defines accepted by LCL-CustomDrawn | |
| 111 | 172 | ||
| 112 | - | ||
| 173 | + | One easy way to set a conditional define for the LCL-CustomDrawn is to define it in the file lcl/interfaces/customdrawn/customdrawndefines.inc | |
| 113 | 174 | ||
| 114 | - | ||
| 175 | + | Here are defines which affect the functionality offered by this interface: | |
| 115 | 176 | ||
| 116 | - | ||
| 177 | + | * CD_UseNativeText - Activates using native text instead of PasFreeType. This define will be automatically set if convenient for a particular backend, don't set it manually unless you know what you are doing. | |
| 117 | 178 | ||
| 118 | - | ||
| 179 | + | And here debug information defines: | |
| 119 | 180 | ||
| 120 | - | ||
| 121 | - | ||
| 122 | - | ||
| 123 | - | ||
| 124 | - | ||
| 125 | - | ||
| 126 | - | ||
| 127 | - | ||
| 128 | - | ||
| 129 | - | ||
| 181 | + | * VerboseCDPaintProfiler - Adds profiling information to indicate how fast the paint event is processed | |
| 182 | + | * VerboseCDWinAPI - Extended verbose information for LCLIntf calls, except those which are covered by one of these defines instead: | |
| 183 | + | * VerboseCDText - Verbose info for text winapi calls | |
| 184 | + | * VerboseCDDrawing - Verbose info for Canvas and drawing operations | |
| 185 | + | * VerboseCDBitmap - Verbose info for Bitmap and rawimage creation and handling | |
| 186 | + | * VerboseCDForms - Extended verbose information for TWSCustomForm methods and about the non-native form from customdrawnproc (when utilized) | |
| 187 | + | * VerboseCDEvents - Extended verbose information for native events (for example mouse click, key input, etc). This excludes the paint event | |
| 188 | + | * VerboseCDPaintEvent - Debug info for the paint event | |
| 189 | + | * VerboseCDApplication - Verbose info for App routines from the Widgetset object | |
| 190 | + | * VerboseCDMessages - Verbose info for messages from the operating system (Paint, keyboard, mouse) | |
| 130 | 191 | ||
| 131 | 192 | ## Screenshots | |
| 132 | 193 | ||
| 133 | - | ||
| 194 | + | [](</File:Lazclock_customdrawn.png>) | |
| 134 | 195 | ||
| 135 | - | ||
| 196 | + | [](</File:lcl_android_30_mar.png>) [](</File:vpr-android.png>) | |
| 136 | 197 | ||
| 137 | 198 | ## See Also | |
| 138 | 199 | ||
| 139 | - | ||
| 200 | + | * [[Lazarus Custom Drawn Controls]] | |
| 140 | 201 | ||
| 141 | 202 | --- | |
| 142 | - | ||
| 143 | - | ||
| 203 | + | *From the Free Pascal wiki, page "Custom Drawn Interface", as the Internet Archive kept it on 2023-02-01. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).* |
