https://wiki.freepascal.org/api.php?action=feedcontributions&user=Sekelsenmat&feedformat=atomFree Pascal wiki - User contributions [en]2024-03-29T10:15:00ZUser contributionsMediaWiki 1.35.6https://wiki.freepascal.org/index.php?title=Lazarus_1.10.0_release_notes&diff=110397Lazarus 1.10.0 release notes2017-06-16T04:36:47Z<p>Sekelsenmat: /* Components */</p>
<hr />
<div>'''Lazarus 1.10.0 is not yet released. This page is under construction!'''<br />
<br />
Statistics:<br />
# commits: xxx<br />
# log: svn log -r xxxx:xxxx<br />
# resolved bug tracker issues: xxx<br />
<br />
= LCL Interfaces Changes =<br />
<br />
= LCL Changes =<br />
<br />
=== MouseEntered deprecated/missing ===<br />
<br />
* Old behaviour: No warning on using MouseEntered<br />
* New behaviour: Warning: Symbol "MouseEntered" is deprecated: "use MouseInClient instead"<br />
* Reason: Delphi compatibility<br />
* Remedy: use property MouseInClient instead<br />
<br />
= IDE Changes =<br />
<br />
= IDE Interfaces Changes =<br />
<br />
= Components =<br />
<br />
=== TOpenGLControl ===<br />
* New property Options of type set, currently with ocoMacRetinaMode as the only member. If set, ocoMacRetinaMode determines that the OpenGL controls will use retina support (high resolution mode).<br />
<br />
= Changes affecting compatibility =<br />
<br />
==LazUtils==<br />
<br />
==LCL incompatibilities==<br />
<br />
=== TCustomComboBox.ReadOnly was deprecated ===<br />
* Old behavior: When True, only items from the list are accepted, by direct selection from the list or AutoComplete.<br />
* New behavior: it does nothing and will be removed.<br />
* Reason: Delphi-compatibility, confusing naming, WS compatibility (different behavior on Win32/Qt/Gtk)<br />
* Remedy: Use extended styles for the same feature.<br />
<br />
==Components incompatibilities==<br />
<br />
==IDE incompatibilities==<br />
<br />
= Previous release notes =<br />
<br />
*[[Lazarus 1.8.0 release notes]]<br />
*[[Lazarus 1.6.0 release notes]]<br />
*[[Lazarus 1.4.0 release notes]]<br />
*[[Lazarus 1.2.0 release notes]]<br />
*[[Lazarus 1.0 release notes]]<br />
<br />
{{Navbar Lazarus Release Notes}}<br />
<br />
[[Category:Release Notes]]<br />
[[Category:Lazarus]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=Cocoa_Internals&diff=109994Cocoa Internals2017-05-26T07:10:11Z<p>Sekelsenmat: /* Themed Drawing / Custom Controls */</p>
<hr />
<div>The page is about Cocoa Widgetset internal implementation. The page should be useful for Cocoa widgetset developers (maintainers and/or constributors) as well as any developers who need to use Cocoa specific API.<br />
<br />
{{Other Interfaces}}<br />
<br />
=LCL specific ObjC classes=<br />
In order to control and handle an NSView's behavior LCL uses decedent classes from standard Cocoa controls. I.e. for NSWindow TCocoaWindow is introduced.<br />
The decedent are used for the purpose of "overriding" default class implementation, where it is needed. In some cases using delegate classes is not enough.<br />
<br />
= Handles =<br />
* Window handle (HWND) is always NSView. <br />
** TCustomWSForm it is content NSView.<br />
** Any control that has scroll bars (i.e. TCustomWSList) the it its the embedding NSScrollView (TCocoaScrollView)<br />
<br />
{| class="wikitable"<br />
! LCL Control !! Cocoa class !! Notes<br />
|----<br />
|TMemo||NSTextView inside a NSScrollView||-<br />
|}<br />
<br />
=Code Style=<br />
The following requirement applies for Cocoa widgetset. Other widgetset my be following some other rules (historically), but in general LCL follows the same requirements.<br />
<br />
* '''Operators''' Keep the operator separated by spaces between operands<br />
A := B; <br />
A := B * C;<br />
* '''Blocks''' The main rule is to make 2 character spacing from the code block start. Begin / Else should start on a new line. <br />
<br />
procedure B;<br />
begin<br />
if A then // 2 character spacing from begin<br />
begin<br />
Start Here // 2 character spacing from begin<br />
Next Line<br />
end<br />
else<br />
begin<br />
Another Line<br />
end;<br />
end;<br />
<br />
* '''Standard Function Name''' please keep naming in ProperCase. Reserved words should be lower case. Name of (global/local) variables and fields should match declaration. (local variables should start with lower case)<br />
<br />
if not Assigned(A) then<br />
begin<br />
Result := nil;<br />
end;<br />
=Themed Drawing / Custom Controls=<br />
HITheme API is deprecated by Apple together with Carbon. It's still available in OSX, but for i386 only. Presumably will be completely removed on 64-bit only OSX.<br />
<br />
However, some LCL controls cannot be mapped to existing Cocoa provided controls and thus might require some "custom drawing". The drawing should look system native though. In order to achieve that NSCell family could be used. NSCell allows to draw (hit-test and as well as handle user input) for OSX native elements. If Apple to change appears of controls (cells), the LCL application would "pick-up" the look automatically.<br />
<br />
In order to be drawn NSCells requires a present of NSView, thus it's hard to use them forthe implementation of LCL TTheme APIs<br />
<br />
Example of NSCell usage is CocoaStatusBar drawing<br />
==Fonts==<br />
NSFont class provides a number of class methods to get proper system font without selecting the font by name. The same of getting system-native font size. <br />
<br />
=Writing a Cocoa app without the LCL=<br />
<br />
This is useful for testing hard to debug bugs in the LCL. Here is an example program written in Pascal-Cocoa which creates a window with 2 buttons and a simple set of menus:<br />
<br />
<syntaxhighlight><br />
program cocoa_without_lcl;<br />
<br />
{$mode objfpc}{$H+}<br />
{$modeswitch objectivec1}<br />
<br />
uses<br />
CocoaAll, classes, sysutils;<br />
<br />
type<br />
{ TMyDelegate }<br />
TMyDelegate = objcclass(NSObject)<br />
public<br />
procedure HandleButtonClick_A(sender: id); message 'HandleButtonClick_A:';<br />
procedure HandleButtonClick_B(sender: id); message 'HandleButtonClick_B:';<br />
procedure HandleMenuClick_A(sender: id); message 'HandleMenuClick_A:';<br />
procedure HandleMenuClick_B(sender: id); message 'HandleMenuClick_B:';<br />
end;<br />
<br />
var<br />
appName: NSString;<br />
window: NSWindow;<br />
pool: NSAutoreleasePool;<br />
lText: NSTextField;<br />
lButton: NSButton;<br />
lDelegate: TMyDelegate;<br />
//<br />
MainMenu_A: NSMenu;<br />
TopItem_A: NSMenuItem;<br />
TopMenu_A: NSMenu;<br />
MenuItem_A: NSMenuItem;<br />
//<br />
MainMenu_B: NSMenu;<br />
TopItem_B: NSMenuItem;<br />
TopMenu_B: NSMenu;<br />
MenuItem_B: NSMenuItem;<br />
<br />
procedure TMyDelegate.HandleButtonClick_A(sender: id);<br />
begin<br />
NSApp.setMainMenu(MainMenu_A);<br />
end;<br />
<br />
procedure TMyDelegate.HandleButtonClick_B(sender: id);<br />
begin<br />
NSApp.setMainMenu(MainMenu_B);<br />
end;<br />
<br />
procedure TMyDelegate.HandleMenuClick_A(sender: id);<br />
var<br />
Str: string;<br />
begin<br />
Str := 'A '+inttostr(random(888));<br />
window.setTitle(NSSTR(@Str[1]));<br />
end;<br />
<br />
procedure TMyDelegate.HandleMenuClick_B(sender: id);<br />
var<br />
Str: string;<br />
begin<br />
Str := 'B '+inttostr(random(888));<br />
window.setTitle(NSSTR(@Str[1]));<br />
end;<br />
<br />
procedure CreateMenus;<br />
var<br />
nsTitle: NSString;<br />
nsKey : NSString;<br />
<br />
function CreateMenuItem(AName, AShortcut: string; ASelector: SEL): NSMenuItem;<br />
begin<br />
nsKey := NSSTR(PChar(AShortcut));<br />
nsTitle := NSSTR(PChar(AName));<br />
Result := NSMenuItem.alloc.initWithTitle_action_keyEquivalent(nsTitle, ASelector, nsKey);<br />
Result.setKeyEquivalentModifierMask(NSCommandKeyMask);<br />
nsTitle.release;<br />
nsKey.release;<br />
Result.setKeyEquivalentModifierMask(NSCommandKeyMask);<br />
Result.setTarget(lDelegate);<br />
end;<br />
<br />
begin<br />
MainMenu_A := NSMenu.alloc.initWithTitle(NSSTR('Menu A'));<br />
TopItem_A := CreateMenuItem('TopItem A', '', nil);<br />
MainMenu_A.insertItem_atIndex(TopItem_A, 0);<br />
TopMenu_A := NSMenu.alloc.initWithTitle(NSSTR('TopMenu A'));<br />
TopItem_A.setSubmenu(TopMenu_A);<br />
MenuItem_A := CreateMenuItem('MenuItem A', 'A', objcselector('HandleMenuClick_A:'));<br />
MenuItem_A.setTarget(lDelegate);<br />
TopMenu_A.insertItem_atIndex(MenuItem_A, 0);<br />
<br />
MainMenu_B := NSMenu.alloc.initWithTitle(NSSTR('Menu B'));<br />
TopItem_B := CreateMenuItem('TopItem B', '', nil);<br />
MainMenu_B.insertItem_atIndex(TopItem_B, 0);<br />
TopMenu_B := NSMenu.alloc.initWithTitle(NSSTR('TopMenu B'));<br />
TopItem_B.setSubmenu(TopMenu_B);<br />
MenuItem_B := CreateMenuItem('MenuItem B', 'B', objcselector('HandleMenuClick_B:'));<br />
MenuItem_B.setTarget(lDelegate);<br />
TopMenu_B.insertItem_atIndex(MenuItem_B, 0);<br />
end;<br />
<br />
<br />
begin<br />
// Autorelease pool, app and window creation<br />
pool := NSAutoreleasePool.new;<br />
NSApp := NSApplication.sharedApplication;<br />
NSApp.setActivationPolicy(NSApplicationActivationPolicyRegular);<br />
appName := NSProcessInfo.processInfo.processName;<br />
window := NSWindow.alloc.initWithContentRect_styleMask_backing_defer(NSMakeRect(0, 0, 200, 200),<br />
NSTitledWindowMask or NSClosableWindowMask or NSMiniaturizableWindowMask,<br />
NSBackingStoreBuffered, False).autorelease;<br />
lDelegate := TMyDelegate.alloc.init;<br />
<br />
// text label<br />
lText := NSTextField.alloc.initWithFrame(NSMakeRect(50, 50, 120, 50)).autorelease;<br />
lText.setBezeled(False);<br />
lText.setDrawsBackground(False);<br />
lText.setEditable(False);<br />
lText.setSelectable(False);<br />
lText.setStringValue(NSSTR('NSTextField'));<br />
window.contentView.addSubview(lText);<br />
<br />
// button<br />
lButton := NSButton.alloc.initWithFrame(NSMakeRect(50, 100, 120, 50)).autorelease;<br />
window.contentView.addSubview(lButton);<br />
lButton.setTitle(NSSTR('Button A!'));<br />
lButton.setButtonType(NSMomentaryLightButton);<br />
lButton.setBezelStyle(NSRoundedBezelStyle);<br />
// button event handler setting<br />
lButton.setTarget(lDelegate);<br />
lButton.setAction(ObjCSelector(lDelegate.HandleButtonClick_A));<br />
<br />
// button B<br />
lButton := NSButton.alloc.initWithFrame(NSMakeRect(50, 150, 120, 50)).autorelease;<br />
window.contentView.addSubview(lButton);<br />
lButton.setTitle(NSSTR('Button B!'));<br />
lButton.setButtonType(NSMomentaryLightButton);<br />
lButton.setBezelStyle(NSRoundedBezelStyle);<br />
// button event handler setting<br />
lButton.setTarget(lDelegate);<br />
lButton.setAction(ObjCSelector(lDelegate.HandleButtonClick_B));<br />
<br />
// Menus<br />
CreateMenus();<br />
NSApp.setMainMenu(MainMenu_A);<br />
<br />
// Window showing and app running<br />
window.center;<br />
window.setTitle(appName);<br />
window.makeKeyAndOrderFront(nil);<br />
NSApp.activateIgnoringOtherApps(true);<br />
NSApp.run;<br />
end.<br />
</syntaxhighlight><br />
<br />
[[Category:Mac OS]]<br />
[[Category:Mac OS X]]<br />
[[Category:Cocoa]]<br />
[[Category:Lazarus internals]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=Pascal_for_Java_users&diff=109906Pascal for Java users2017-05-21T08:16:55Z<p>Sekelsenmat: /* Translating Java keywords/concepts */</p>
<hr />
<div>{{Pascal for Java users}}<br />
<br />
== Translating common program snippets ==<br />
The following site shows how common problems are solved in various programming languages, including Javan and FreePascal/Object Pascal: [http://rosettacode.org/wiki/Category:Pascal Rosetta Code]<br />
<br />
== Translating Java keywords/concepts ==<br />
{| class="wikitable"<br />
! Java !! [[Pascal]] !! Additional comments<br />
|-<br />
| &nbsp; { &nbsp;<br />
| &nbsp; [[Begin]] &nbsp;<br />
| &nbsp;<br />
|-<br />
| &nbsp; } &nbsp;<br />
| &nbsp; [[End]]<br />
| &nbsp;<br />
|-<br />
| &nbsp; = &nbsp;<br />
| &nbsp; :=<br />
| &nbsp; [[Becomes]] &nbsp;<br />
|-<br />
| &nbsp; == &nbsp;<br />
| &nbsp; =<br />
| &nbsp; [[Equal]]<br />
|-<br />
| &nbsp; / &nbsp;<br />
| &nbsp; / <br />
| &nbsp; [[Slash|Division]] (or sometimes [[Div|div]]) &nbsp;<br />
|-<br />
| &nbsp; % &nbsp;<br />
| &nbsp; [[Mod]]<br />
| &nbsp; '''Mod'''ulo operation<br />
|-<br />
| &nbsp; ! &nbsp;<br />
| &nbsp; [[Not]]<br />
| &nbsp;<br />
|-<br />
| &nbsp; != &nbsp;<br />
| &nbsp; <><br />
| &nbsp; [[Not equal]] &nbsp;<br />
|-<br />
| &nbsp; && &nbsp;<br />
| &nbsp; [[And]]<br />
| &nbsp;<br />
|-<br />
| &nbsp; <nowiki> || </nowiki> &nbsp;<br />
| &nbsp; [[Or]]<br />
| &nbsp;<br />
|-<br />
| &nbsp; ^ &nbsp;<br />
| &nbsp; [[Xor]]<br />
| &nbsp;<br />
|-<br />
| &nbsp; >> &nbsp;<br />
| &nbsp; [[Shr]]<br />
| &nbsp; bit '''sh'''ift '''r'''ight &nbsp;<br />
|-<br />
| &nbsp; << &nbsp;<br />
| &nbsp; [[Shl]]<br />
| &nbsp; bit '''sh'''ift '''l'''eft &nbsp;<br />
|-<br />
| &nbsp; ++ &nbsp;<br />
| &nbsp; [[Inc]]<br />
| &nbsp;<br />
|-<br />
| &nbsp; -- &nbsp;<br />
| &nbsp; [[Dec]]<br />
| &nbsp;<br />
|-<br />
| &nbsp; /* &nbsp;<br />
| &nbsp; {<br />
| &nbsp; [[Comments|Comment]] start <br />
|-<br />
| &nbsp; /* &nbsp;<br />
| &nbsp; (*<br />
| &nbsp; [[Comments|Comment]] start <br />
|-<br />
| &nbsp; */ &nbsp;<br />
| &nbsp; }<br />
| &nbsp; Comment end <br />
|-<br />
| &nbsp; */ &nbsp;<br />
| &nbsp; *)<br />
| &nbsp; Comment end <br />
|-<br />
| &nbsp; // &nbsp;<br />
| &nbsp; //<br />
| &nbsp; End of line comment (only one line comment) &nbsp;<br />
|-<br />
| &nbsp; public static void main(String[] args) { }<br />
| &nbsp; [[Program]] ProgramName; [[Begin]] [[End]].<br />
| &nbsp; Note the period after End<br />
|-<br />
| &nbsp; someType arrayVar[];<br />
| &nbsp; arrayVar: [[Array]] [[Of]] someType;<br />
| &nbsp;<br />
|-<br />
| &nbsp; someType arrayVar[#];<br />
| &nbsp; arrayVar: [[Array]][MINRANGE..MAXRANGE] [[Of]] someType;<br />
| &nbsp;<br />
|-<br />
| &nbsp; null<br />
| &nbsp; [[Nil]]<br />
| &nbsp;<br />
|-<br />
| &nbsp; abstract<br />
| &nbsp; [[Abstract]]<br />
| &nbsp;<br />
|-<br />
| &nbsp; break<br />
| &nbsp; [[Break]]<br />
| &nbsp;<br />
|-<br />
| &nbsp; class TheClass { }<br />
| &nbsp; TheClass = [[Class]] [[End]];<br />
| &nbsp; Delphi OOP<br />
|-<br />
| &nbsp; class TheClass { }<br />
| &nbsp; TheClass = [[Object]] [[End]];<br />
| &nbsp; Turbo Pascal OOP<br />
|-<br />
| &nbsp; class TheClass<T> { }<br />
| &nbsp; [[Generic]] TheClass = [[Class]]<T> [[End]];<br />
| &nbsp; Generics are classes only as of 2.2.2, likely to support more in the future<br />
|-<br />
| &nbsp; TheClass()<br />
| &nbsp; [[Constructor]] CtorName<br />
| &nbsp; Constructor name is by convention either Init or Create<br />
|-<br />
| &nbsp; continue<br />
| &nbsp; [[Continue]]<br />
| &nbsp; <br />
|-<br />
| &nbsp; do while &nbsp;<br />
| &nbsp; [[Repeat]] [[Until]] [[Not]]&nbsp;<br />
| &nbsp;<br />
|-<br />
| &nbsp; do while ! &nbsp;<br />
| &nbsp; [[Repeat]] [[Until]] &nbsp;<br />
| &nbsp;<br />
|-<br />
| &nbsp; enum TheEnum&nbsp;<br />
| &nbsp; TheEnum = ( MINVALUE .. MAXVALUE ); &nbsp;<br />
| &nbsp;<br />
|-<br />
| &nbsp; enum TheEnum = {MINVALUE, MAXVALUE}&nbsp;<br />
| &nbsp; TheEnum = ( MINVALUE, MAXVALUE ); &nbsp;<br />
| &nbsp;<br />
|-<br />
| &nbsp; TheEnum enumVar; &nbsp;<br />
| &nbsp; enumVar := [[Set]] [[Of]] TheEnum; &nbsp;<br />
| &nbsp;<br />
|-<br />
| &nbsp; extends<br />
| &nbsp; SubClass = [[Class]](BaseClass)<br />
| &nbsp; class SubClass extends BaseClass --> SubClass(BaseClass)<br />
|-<br />
| &nbsp; final<br />
| &nbsp; [[Const]]<br />
| &nbsp; for constants, not uninheritables<br />
|- <br />
| &nbsp; for ++ &nbsp;<br />
| &nbsp; [[For]] [[To]] [[Do]]<br />
| &nbsp;<br />
|-<br />
| &nbsp; for -- &nbsp;<br />
| &nbsp; [[For]] [[Downto]] [[Do]] &nbsp;<br />
| &nbsp;<br />
|-<br />
| &nbsp; if() &nbsp;<br />
| &nbsp; [[If]] [[Then]]<br />
| &nbsp;<br />
|-<br />
| &nbsp; if() else &nbsp;<br />
| &nbsp; [[If]] [[Then]] [[Else]]<br />
| &nbsp;<br />
|-<br />
| &nbsp; implements<br />
| &nbsp; SomeClass = [[Class]](SomeInterface)<br />
| &nbsp; <br />
|-<br />
| &nbsp; import<br />
| &nbsp; [[Uses]]<br />
| &nbsp;<br />
|-<br />
| &nbsp; instanceof<br />
| &nbsp; [[Is]]<br />
| &nbsp;<br />
|-<br />
| &nbsp; interface<br />
| &nbsp; TheInterface = [[Interface]]<br />
| &nbsp;<br />
|-<br />
| &nbsp; native<br />
| &nbsp; [[StdCall]]<br />
| &nbsp; For Windows<br />
|-<br />
| &nbsp; native<br />
| &nbsp; [[CDecl]]<br />
| &nbsp; For Unix<br />
|-<br />
| &nbsp; new primitive_type[#];<br />
| &nbsp; [[SetLength]](ArrayVar, #);<br />
| &nbsp; &nbsp;<br />
|-<br />
| &nbsp; new Class();<br />
| &nbsp; InstanceVar := TheClass.Create;<br />
| &nbsp; &nbsp;<br />
|-<br />
| &nbsp; package pkgName;<br />
| &nbsp; [[Unit]] unitName; [[Interface]] [[Implementation]] [[End]].<br />
| &nbsp; Note the period after End<br />
|-<br />
| &nbsp; private<br />
| &nbsp; [[Private]]<br />
| &nbsp;<br />
|-<br />
| &nbsp; protected<br />
| &nbsp; [[Protected]]<br />
| &nbsp;<br />
|-<br />
| &nbsp; public<br />
| &nbsp; [[Public]]<br />
| &nbsp;<br />
|-<br />
| &nbsp; return<br />
| &nbsp; FunctionName :=<br />
| &nbsp;<br />
|-<br />
| &nbsp; return<br />
| &nbsp; [[Result]] :=<br />
| &nbsp; ObjFPC or Delphi modes<br />
|-<br />
| &nbsp; static<br />
| &nbsp; [[Static]]<br />
| &nbsp;<br />
|-<br />
| &nbsp; static<br />
| &nbsp; [[Class]] [[Function]]<br />
| &nbsp;<br />
|-<br />
| &nbsp; static<br />
| &nbsp; [[Class]] [[Procedure]]<br />
| &nbsp;<br />
|-<br />
| &nbsp; super<br />
| &nbsp; [[Inherited]]<br />
| &nbsp; Parent constructor call<br />
|-<br />
| &nbsp; switch case break &nbsp;<br />
| &nbsp; [[Case]] [[Of]] [[End]] <br />
| &nbsp;<br />
|-<br />
| &nbsp; switch case break default &nbsp;<br />
| &nbsp; [[Case]] [[Of]] [[Else]] [[End]] &nbsp;<br />
| &nbsp;<br />
|-<br />
| &nbsp; synchronized<br />
| &nbsp; [[TCriticalSection]]<br />
| &nbsp;<br />
|-<br />
| &nbsp; this<br />
| &nbsp; [[Self]]<br />
| &nbsp;<br />
|-<br />
| &nbsp; throw<br />
| &nbsp; [[Raise]]<br />
| &nbsp;<br />
|-<br />
| &nbsp; throws<br />
| &nbsp;<br />
| &nbsp;<br />
|-<br />
| &nbsp; transient<br />
| &nbsp;<br />
| &nbsp;<br />
|-<br />
| &nbsp; try { } catch<br />
| &nbsp; [[Try]] [[except]]<br />
| &nbsp;<br />
|-<br />
| &nbsp; try { } catch finally<br />
| &nbsp; [[Try]] [[Finally]]<br />
| &nbsp;<br />
|-<br />
| &nbsp; void<br />
| &nbsp; [[Procedure]]<br />
| &nbsp;<br />
|-<br />
| &nbsp; volatile<br />
| &nbsp;<br />
| &nbsp;<br />
|-<br />
| &nbsp; while &nbsp;<br />
| &nbsp; [[While]] [[Do]]<br />
| &nbsp;<br />
|}<br />
<br />
== Translating Java data types ==<br />
{| class="wikitable"<br />
! Java type !! [[Pascal]] [[Data_type|type]] !! Size (bits) !! Range !!<br />
|-<br />
| &nbsp; byte &nbsp;<br />
| &nbsp; [[Shortint]]<br />
| &nbsp; 8-bit<br />
| &nbsp; -128 .. 127<br />
| &nbsp;<br />
|-<br />
| &nbsp; short &nbsp;<br />
| &nbsp; [[Smallint]]<br />
| &nbsp; 16-bit<br />
| &nbsp; -32768 .. 32767 &nbsp;<br />
|-<br />
| &nbsp; int &nbsp;<br />
| &nbsp; [[Longint]]<br />
| &nbsp; 32-bit<br />
| &nbsp; -2147483648..2147483647 &nbsp;<br />
| &nbsp; <br />
|-<br />
| &nbsp; int &nbsp;<br />
| &nbsp; [[Integer]]<br />
| &nbsp; 32-bit<br />
| &nbsp; -2147483648..2147483647 &nbsp;<br />
| &nbsp; <br />
|-<br />
| &nbsp; long &nbsp;<br />
| &nbsp; [[Int64]]<br />
| &nbsp; 64-bit<br />
| &nbsp; -9 223 372 036 854 775 808 .. 9 223 372 036 854 775 807 &nbsp;<br />
| &nbsp; <br />
|-<br />
| &nbsp; float &nbsp;<br />
| &nbsp; [[Single]]<br />
| &nbsp; 32-bit<br />
| &nbsp; 1.5E-45 .. 3.4E+38 &nbsp;<br />
|<br />
|-<br />
| &nbsp; double &nbsp;<br />
| &nbsp; [[Double]]<br />
| &nbsp; 64-bit<br />
| &nbsp; 5.0E-324 .. 1.7E+308 &nbsp;<br />
|<br />
|-<br />
| &nbsp; boolean &nbsp;<br />
| &nbsp; [[Boolean]]<br />
| &nbsp; <br />
| &nbsp; [[False]] [[True]]<br />
| &nbsp;<br />
|-<br />
| &nbsp; char &nbsp;<br />
| &nbsp; [[WideChar]]<br />
| &nbsp; 16-bit<br />
| &nbsp; <br />
| &nbsp;<br />
|-<br />
| &nbsp; String &nbsp;<br />
| &nbsp; [[String]]<br />
| &nbsp; <br />
| &nbsp;<br />
|-<br />
|-<br />
|}<br />
<br />
== See also ==<br />
* [[Using Pascal Libraries with Java]]<br />
<br />
[[Category:FPC]]<br />
[[Category:Pascal]]<br />
[[Category:Java]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=Cocoa_Interface&diff=109889Cocoa Interface2017-05-20T06:08:08Z<p>Sekelsenmat: </p>
<hr />
<div>{{Platform only|macOS|macOS|macOS}}<br />
{{Platform only|iOS|iOS|iOS}}<br />
{{Other Interfaces}}<br />
==Cocoa bindings==<br />
This interface uses the native support in Free Pascal for direct communication with Objective-C was added through the [[FPC PasCocoa|Objective Pascal]] dialect.<br />
<br />
==Cocoa FAQ==<br />
<br />
===TButton looks too small!===<br />
If you design a button in another widgetset with Autosize=Off it might happen that the button looks too small in Cocoa, and a number of people complained about this, such as in these BTS reports: [https://bugs.freepascal.org/view.php?id=31185]. <br />
<br />
If you don't care about the button size, just set AutoSize=True. If you want to have a custom width for the button, but wants to allow the LCL to choose the right Height so that the button will look good in Cocoa, then the solution in this case is to set the following properties in the Object Inspector:<br />
<br />
* AutoSize=True<br />
* Constrains.MinWidth = Constrains.MaxWidth = your desired width.<br />
<br />
==Roadmap==<br />
<br />
Located here: [[Roadmap#Status_of_features_on_each_widgetset]]<br />
<br />
[[Category:Mac OS X]]<br />
[[Category:Cocoa]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=File:Fpvectorial_coords.png&diff=101562File:Fpvectorial coords.png2016-06-21T09:54:29Z<p>Sekelsenmat: Sekelsenmat uploaded a new version of &quot;File:Fpvectorial coords.png&quot;</p>
<hr />
<div></div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=fpvectorial&diff=101261fpvectorial2016-05-30T06:45:47Z<p>Sekelsenmat: /* Coordinates in FPVectorial */</p>
<hr />
<div>== Introduction ==<br />
<br />
FPVectorial offers support to read, modify and write vectorial images.<br />
<br />
Its counterpart library is [[fcl-image]], which works with raster images. FPVectorial comes with a unit which allows to draw a vectorial image to a TFPCustomCanvas, but no routines are provided to convert raster images to vectorial images.<br />
<br />
== Download ==<br />
<br />
fpvectorial comes in the Lazarus SVN, in the directory components/fpvectorial:<br />
<br />
svn co http://svn.freepascal.org/svn/lazarus/trunk/components/fpvectorial fpvectorial<br />
<br />
Downloading the fpvviewer project:<br />
<br />
svn co https://lazarus-ccr.svn.sourceforge.net/svnroot/lazarus-ccr/applications/fpvviewer fpvviewer<br />
<br />
== Current file list ==<br />
<br />
FPVectorial is located in Free Pascal 2.3.1+ in the directory fpc/packages/fpvectorial/src<br />
<br />
The central unit is ''[[doc:fcl/fpvectorial|fpvectorial]]''.<br />
<br />
'''Readers for various image formats'''<br />
<br />
* '''pdfvectorialreader''' - Read support for PDF files, supports compression, only reads the first page<br />
* '''avisocncgcodereader''' - Read support for the G-Code from the Aviso CNC machine<br />
* '''cdrvectorialreader''' - Initial work of a reader support for Corel Draw CDR files<br />
* '''dxfvectorialreader''' - Read support for DXF, the Drawing eXchange Format utilized by the AutoCAD<br />
* '''svgvectorialreader''' - Read support for SVG<br />
* '''epsvectorialreader''' - Read support for Encapsulated PostScript<br />
<br />
'''Writers for various image formats'''<br />
<br />
* '''avisocncgcodewriter''' - Write support for the G-Code from the Aviso CNC machine<br />
* '''svgvectorialwriter''' - Write support for SVG. The most advanced writer at the moment. Supports lines, curves and text. Supports pen color and width.<br />
<br />
'''Other units'''<br />
<br />
* '''fpvtocanvas''' - Converts a vectorial document to a TFPCustomCanvas descendent (like TCanvas). Essentially converts the vectorial image to a raster image<br />
* '''fpvutils''' - Utility functions which don't belong to fpvectorial.pas or that would bring unwanted dependencies to it. Color conversion functions.<br />
* '''pdfvrlexico''', '''pdfvrsemantico''', '''pdfvrsintatico''', '''avisozlib''' - Other units from the PDF reader, don't use directly<br />
<br />
==Formats==<br />
<br />
===PDF===<br />
<br />
The PDF format is developed by Adobe (tm) and it is fully documented. Inside, PDF is simply text, so it is rather easy to parse, but parts of this text are usually can be compressed.<br />
<br />
Link to the PDF Reference: http://www.adobe.com/devnet/pdf/pdf_reference.html<br />
<br />
===CorelDraw===<br />
<br />
Corel does not release public documentation for its CorelDraw file format. Any information about this format depends on reverse engineering and guessing. The format is binary and consists of a tree of chunks.<br />
<br />
See also [[fpvectorial#fpcorelexplorer]]<br />
<br />
===SVG===<br />
<br />
Scalable Vectorial Graphics (SVG) is a standard from W3C for vectorial graphics. It is the native format of Inkscape and stores its data as a single, uncompressed XML file with the extension ".svg".<br />
<br />
Link to the specification: http://www.w3.org/TR/SVG/<br />
<br />
A very serious shortcoming in SVG is that it does not allow real world units to be specified in the drawing routines, only pixel values accepted, which makes it impossible to have a document with real world units. This can be worked around by simply hardcoding to a fixed DPI resolution, which is 90 DPI for Inkscape. Read more here:<br />
<br />
* http://stackoverflow.com/questions/1346922/svg-and-dpi-absolute-units-and-user-units-inkscape-vs-firefox-vs-imagemagick<br />
* http://www.inkscapeforum.com/viewtopic.php?f=16&t=5904<br />
* http://www.inkscapeforum.com/viewtopic.php?f=16&t=3700&p=17179&hilit=units+path#p17179<br />
<br />
Following Inkscape and the Opera Browser, FPVectorial also hardcodes to 90 DPI.<br />
<br />
As of February 2014 support for SVG is partial.<br />
<br />
===DXF===<br />
<br />
The Drawing eXchange Format from Autodesk AutoCAD. This format is documented, but the quality of the documentation is rather low, lacking adequate explanations.<br />
<br />
The format itself is rather simple, composed by text. Each unit is composed of two lines, the first one being a number describing the type of data and then another line with the value itself, which might be text or a number.<br />
<br />
The most common problem in other DXF reading libraries is that they don't support the actual DXF writen by newer versions of AutoCAD. This is not the case with fpvectorial, which was tested with AutoCAD 2000 and also the previous simpler formats.<br />
<br />
Link to the documentation:<br />
<br />
* http://www.autodesk.com/techpubs/autocad/acad2000/dxf/<br />
<br />
The software fpvviewer can be utilized to show the internal structure of a DXF file. This software can be found in the lazarus-ccr svn in applications/fpvviewer. More info here: [[fpvectorial#fpvviewer]]<br />
<br />
===PostScript===<br />
<br />
PostScript is a graphics drawing programming language and fpvectorial has an interpreter which can execute PostScript and convert its commands into its internal format. This is done by reader modules, for example epsvectorialreader. The interpreter is separated into a Tokenizer and an Executer. The tokens are classified into 3 types: Procedures, ExpressionTokens and Comments. Procedures are inside a {..} block in PostScript and in FPVectorial they are not tokenezed in the first pass, but instead on the first usage. The entire document is tokenized in one run, before executing the tokens, except for the procedures. The PostScript interpreter contains a Stack and a lookup Dictionary, as specified in PostScript.<br />
<br />
PostScript can be embedded into various formats, and the interpreter currently supports the EPS format.<br />
<br />
'''References''':<br />
<br />
* http://en.wikipedia.org/wiki/Encapsulated_PostScript<br />
* http://partners.adobe.com/public/developer/en/ps/PLRM.pdf<br />
<br />
===LAS===<br />
<br />
LAS is geospatial data encoded in the ASPRS LASer (LAS) file format, which exists in versions 1.0, 1.1, 1.2, 1.3 and 1.4. Version 2.0 does not yet exist as of December 2011.<br />
<br />
'''References''':<br />
<br />
* http://en.wikipedia.org/wiki/LibLAS<br />
* http://www.asprs.org/a/society/committees/lidar/lidar_format.html<br />
* http://trac.liblas.org/wiki/Software<br />
* http://www.cs.unc.edu/~isenburg/lastools/<br />
* http://www.fugroviewer.com/<br />
* Example las file: www.appliedimagery.com/downloads/sampledata/Serpent%20Mound%20Model%20LAS%20Data.las<br />
* Specification docs up to 1.3: http://www.asprs.org/a/society/committees/standards/lidar_exchange_format.html<br />
* Specification for 1.4: http://www.asprs.org/Press-Releases/LAS-1-4-Draft-Specification-Released-by-ASPRS.html<br />
<br />
==Types of data in FPVectorial==<br />
<br />
FPVectorial holds lists of three types of objects: paths, text and entities.<br />
<br />
Essentially paths are sequences of points, through which run lines and bezier curves. A path can be a line, a bezier, a polyline, a polybezier or any combination of these elements. The main characteristic of paths is that they can be utilized to guide a milling machine, also known as CNC machine, into physically executing the drawing. Before being able to execute a drawing which contains either text or entities in a CNC machine, these items need to be converted to paths.<br />
<br />
Text, just like the name says are strings drawn with fonts.<br />
<br />
Entities are things like circles, arcs, ellipses, rotated ellipses, etc.<br />
<br />
==Usage examples==<br />
<br />
===Format conversion===<br />
<br />
This example loads a PDF, converts it to G-Code and writes the G-Code to a TStrings descendent<br />
<br />
<syntaxhighlight><br />
uses<br />
fpvectorial, pdfvectorialreader, avisocncgcodewriter;<br />
<br />
var<br />
Vec: TvVectorialDocument;<br />
begin<br />
if dialogoAbrir.Execute() then<br />
begin<br />
Vec := TvVectorialDocument.Create;<br />
try<br />
Vec.ReadFromFile(dialogoAbrir.FileName, vfPDF);<br />
Vec.WriteToStrings(synCodigo.Lines, vfGCodeAvisoCNCPrototipoV5);<br />
finally<br />
Vec.Free;<br />
end;<br />
end;<br />
end;<br />
</syntaxhighlight><br />
<br />
===Adding paths, bezier lines and text===<br />
<br />
This example shows how to add various elements.<br />
<br />
<syntaxhighlight><br />
{<br />
Author: Felipe Monteiro de Carvalho<br />
<br />
License: Public Domain<br />
}<br />
program fpvwritetest;<br />
<br />
{$mode objfpc}{$H+}<br />
<br />
uses<br />
fpvectorial, svgvectorialwriter;<br />
<br />
const<br />
cFormat = vfSVG;<br />
cExtension = '.svg';<br />
var<br />
VecDoc: TvVectorialDocument;<br />
Vec: TvVectorialPage;<br />
begin<br />
VecDoc := TvVectorialDocument.Create;<br />
try<br />
Vec := VecDoc.AddPage();<br />
// All documents are 10cm x 10cm<br />
Vec.Width := 100;<br />
Vec.Height := 100;<br />
<br />
// ...<br />
<br />
// multi_test_1 Combines various elements<br />
Vec.Clear;<br />
Vec.StartPath(0, 20);<br />
Vec.AddLineToPath(30, 30);<br />
Vec.EndPath();<br />
Vec.StartPath(0, 0);<br />
Vec.AddLineToPath(100, 0);<br />
Vec.AddLineToPath(100, 100);<br />
Vec.AddLineToPath(0, 100);<br />
Vec.AddLineToPath(0, 0);<br />
Vec.EndPath();<br />
Vec.StartPath(0, 0);<br />
Vec.AddLineToPath(10, 10);<br />
Vec.AddBezierToPath(10, 20, 20, 20, 20, 10);<br />
Vec.AddLineToPath(30, 0);<br />
Vec.EndPath();<br />
Vec.AddText(10, 10, 0, '10,10 Some text in english.');<br />
Vec.AddText(20, 20, 0, '20, 20 Mówić, cześć, Włosku, Parabéns.');<br />
Vec.AddText(30, 30, 0, '30, 30 森林,是一个高密');<br />
VecDoc.WriteToFile('multi_test_1' + cExtension, cFormat);<br />
finally<br />
VecDoc.Free;<br />
end;<br />
end.<br />
</syntaxhighlight><br />
<br />
And here is the output of this example when rendered by the Opera Browser:<br />
<br />
[[Image:Fpvectorial_svg_output.PNG]]<br />
<br />
===Adding Aligned Coordinates===<br />
<br />
One can either add horizontal coordinates:<br />
<br />
<syntaxhighlight>Vec.AddAlignedDimension(Make2DPoint(100, 50), Make2DPoint(200, 100), Make2DPoint(100, 150), Make2DPoint(200, 150));</syntaxhighlight><br />
<br />
[[Image:Aligned_dimension_horizontal.png]]<br />
<br />
Or add vertical coordinates:<br />
<br />
<syntaxhighlight>Vec.AddAlignedDimension(Make2DPoint(50, 250), Make2DPoint(100, 200), Make2DPoint(150, 250), Make2DPoint(150, 200));</syntaxhighlight><br />
<br />
[[Image:Aligned_dimension_vertical.png]]<br />
<br />
===Rendering the image into a TCanvas===<br />
<br />
To render a vectorial image into a TCanvas or TFPCustomCanvas use the unit fpvtocanvas and its routines:<br />
<br />
<syntaxhighlight><br />
unit fpvtocanvas;<br />
//..<br />
{@@<br />
This function draws a FPVectorial vectorial image to a TFPCustomCanvas<br />
descendent, such as TCanvas from the LCL.<br />
<br />
Be careful that by default this routine does not execute coordinate transformations,<br />
and that FPVectorial works with a start point in the bottom-left corner, with<br />
the X growing to the right and the Y growing to the top. This will result in<br />
an image in TFPCustomCanvas mirrored in the Y axis in relation with the document<br />
as seen in a PDF viewer, for example. This can be easily changed with the<br />
provided parameters. To have the standard view of an image viewer one could<br />
use this function like this:<br />
<br />
DrawFPVectorialToCanvas(ASource, ADest, 0, ASource.Height, 1.0, -1.0);<br />
}<br />
procedure DrawFPVectorialToCanvas(ASource: TvVectorialPage;<br />
ADest: TFPCustomCanvas;<br />
ADestX: Integer = 0; ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0);<br />
</syntaxhighlight><br />
<br />
And below an example taken from lazarus-ccr/application/fpvviewer<br />
<br />
<syntaxhighlight><br />
uses fpvtocanvas;<br />
<br />
procedure TfrmFPVViewer.btnVisualizeClick(Sender: TObject);<br />
const<br />
FPVVIEWER_MAX_IMAGE_SIZE = 1000;<br />
FPVVIEWER_MIN_IMAGE_SIZE = 100;<br />
FPVVIEWER_SPACE_FOR_NEGATIVE_COORDS = 100;<br />
var<br />
Vec: TvVectorialDocument;<br />
CanvasSize: TPoint;<br />
begin<br />
// First check the in input<br />
//if not CheckInput() then Exit;<br />
<br />
notebook.PageIndex := 0;<br />
<br />
Drawer.Clear;<br />
<br />
Vec := TvVectorialDocument.Create;<br />
try<br />
Vec.ReadFromFile(editFileName.FileName);<br />
<br />
// We need to be robust, because sometimes the document size won't be given<br />
// also give up drawing everything if we need more then 4MB of RAM for the image<br />
// and also give some space in the image to allow for negative coordinates<br />
if Vec.Width * spinScale.Value > FPVVIEWER_MAX_IMAGE_SIZE then CanvasSize.X := FPVVIEWER_MAX_IMAGE_SIZE<br />
else if Vec.Width < FPVVIEWER_MIN_IMAGE_SIZE then CanvasSize.X := Drawer.Width<br />
else CanvasSize.X := Round(Vec.Width * spinScale.Value);<br />
if CanvasSize.X < Drawer.Width then CanvasSize.X := Drawer.Width;<br />
<br />
if Vec.Height * spinScale.Value > FPVVIEWER_MAX_IMAGE_SIZE then CanvasSize.Y := FPVVIEWER_MAX_IMAGE_SIZE<br />
else if Vec.Height < FPVVIEWER_MIN_IMAGE_SIZE then CanvasSize.Y := Drawer.Height<br />
else CanvasSize.Y := Round(Vec.Height * spinScale.Value);<br />
if CanvasSize.Y < Drawer.Height then CanvasSize.Y := Drawer.Height;<br />
<br />
Drawer.Drawing.Width := CanvasSize.X;<br />
Drawer.Drawing.Height := CanvasSize.Y;<br />
Drawer.Drawing.Canvas.Brush.Color := clWhite;<br />
Drawer.Drawing.Canvas.Brush.Style := bsSolid;<br />
Drawer.Drawing.Canvas.FillRect(0, 0, Drawer.Drawing.Width, Drawer.Drawing.Height);<br />
DrawFPVectorialToCanvas(<br />
Vec.GetPage(0),<br />
Drawer.Drawing.Canvas,<br />
FPVVIEWER_SPACE_FOR_NEGATIVE_COORDS,<br />
Drawer.Drawing.Height - FPVVIEWER_SPACE_FOR_NEGATIVE_COORDS,<br />
spinScale.Value,<br />
-1 * spinScale.Value);<br />
Drawer.Invalidate;<br />
finally<br />
Vec.Free;<br />
end;<br />
end;<br />
</syntaxhighlight><br />
<br />
===Coordinates in FPVectorial===<br />
<br />
It is important to note that FPVectorial works with two different systems of coordinates: Top-Left Coordinates and Bottom-Left Coordinates. TCanvas uses the coordinates from the Windows API, with the origin in the top-left corner and with the X axis growing to the right and the Y axis growing to the bottom. FPVectorial, besides supporting this system, also supports another one for drawing formats where this system is native such as CAD software, Inkscape, the Mac OS X APIs (Carbon and Cocoa), etc. In FPVectorial the origin is in bottom-left for all vectorial graphics formats except SVG. The X axis grows to the right and the Y axis to the top. The origin is in the top-left for SVG and all text document formats such as DOCX.<br />
<br />
[[Image:Fpvectorial_coords.png]]<br />
<br />
When the coordinates do not match TCanvas, one should be careful when converting coordinates between TCanvas and FPVectorial. To convert coordinates between TCanvas and FPVectorial, one needs the height of the Canvas. The following routine from the unit '''fpvutils''' can be used to execute this conversion:<br />
<br />
<syntaxhighlight><br />
{@@ Converts the coordinate system from a TCanvas to FPVectorial<br />
The basic difference is that the Y axis is positioned differently and<br />
points upwards in FPVectorial and downwards in TCanvas.<br />
The X axis doesn't change. The fix is trivial and requires only the Height of<br />
the Canvas as extra info.<br />
}<br />
function CanvasCoordsToFPVectorial(AY: Integer; AHeight: Integer):<br />
Integer; inline;<br />
begin<br />
Result := AHeight - AY;<br />
end;<br />
</syntaxhighlight><br />
<br />
And there is also a difference regarding the text positioning. In TCanvas.TextOut the text is positioned based on the top-left coordinates of the text area. In fpvectorial it is based on the bottom-left. Again, there is a convenient routine in the unit '''fpvutils''' to convert between the coordinate systems:<br />
<br />
<syntaxhighlight><br />
{@@<br />
LCL Text is positioned based on the top-left corner of the text.<br />
Besides that, one also needs to take the general coordinate change into account too.<br />
<br />
@param ACanvasHeight Should receive TCanvas.Height<br />
@param ATextHeight Should receive TFont.Size<br />
}<br />
function CanvasTextPosToFPVectorial(AY: Integer; ACanvasHeight, ATextHeight: Integer): Integer;<br />
begin<br />
Result := CanvasCoordsToFPVectorial(AY, ACanvasHeight) - ATextHeight;<br />
end;<br />
</syntaxhighlight><br />
<br />
===More examples===<br />
<br />
Please see in the FPC repository: http://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/packages/fpvectorial/examples/<br />
<br />
==fpvviewer==<br />
<br />
The Free Pascal Vectorial Viewer is a sample application which implements a simple CAD viewer using fpvectorial.<br />
<br />
Besides being able to visualize vectorial drawings, this software can also help in exploring the internal structure of DXF file:<br />
<br />
[[Image:Fpvviewer_EPS.png]][[Image:fpvviewer.png]]<br />
<br />
It's source code can be found in the Lazarus-CCR in the directory application/fpvviewer<br />
<br />
Link to download the Lazarus-CCR from subversion:<br />
<br />
svn co https://lazarus-ccr.svn.sourceforge.net/svnroot/lazarus-ccr lazarus-ccr<br />
<br />
===Contour line generation===<br />
<br />
fpvviewer can generate contour lines from .raw files. These files can be generated with fpv3dviewer<br />
<br />
[[Image:contourlines_las.PNG]]<br />
<br />
[[Image:contourlines_regular.PNG]]<br />
<br />
===FPVectorial Debug Tokens===<br />
<br />
FPVViewer can be utilized to see the internal debug tokens from fpvectorial, see:<br />
<br />
[[Image:fpvectorial_debug_tokens.png]]<br />
<br />
==fpcorelexplorer==<br />
<br />
An application was developed for helping studying the CDR file format. At the moment this application can identify the version of CorelDraw files. It is located in fpctrunk/packages/fpvectorial/examples/fpcorelexplorer.lpi<br />
<br />
[[Image:fpcorelexplorer.png]]<br />
<br />
==fpv3dviewer==<br />
<br />
One of the examples of fpvectorial located in lazarus/components/fpvectorial/examples/fpv3dviewer.lpi is a 3D viewer.<br />
<br />
[[Image:FPV3DViewer.png]]<br />
<br />
==Articles about fpvectorial==<br />
<br />
* Revista Clube Delphi Edition #131: http://www.devmedia.com.br/assgold/listmag.asp?site=3<br />
<br />
Go to back [[Package_List|Packages List]]<br />
<br />
[[Category:Graphics]]<br />
[[Category:Packages]]<br />
[[Category:FPVectorial]]<br />
[[Category:Lazarus-CCR]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=Cocoa_Interface&diff=97786Cocoa Interface2015-11-12T14:26:51Z<p>Sekelsenmat: </p>
<hr />
<div>{{Platform only|Mac OS X|Mac OS X|Mac OS X}}<br />
{{Platform only|iOS|iOS|iOS}}<br />
{{Other Interfaces}}<br />
==Cocoa bindings==<br />
This interface uses the native support in Free Pascal for direct communication with Objective-C was added through the [[FPC PasCocoa|Objective Pascal]] dialect.<br />
<br />
==Roadmap==<br />
<br />
Located here: [[Roadmap#Status_of_features_on_each_widgetset]]<br />
<br />
[[Category:Mac OS X]]<br />
[[Category:Cocoa]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=Cocoa_Internals&diff=97785Cocoa Internals2015-11-12T13:56:30Z<p>Sekelsenmat: </p>
<hr />
<div>The page is about Cocoa Widgetset internal implementation. The page should be useful for Cocoa widgetset developers (maintainers and/or constributors) as well as any developers who need to use Cocoa specific API.<br />
<br />
{{Other Interfaces}}<br />
<br />
=LCL specific ObjC classes=<br />
In order to control and handle an NSView's behavior LCL uses decedent classes from standard Cocoa controls. I.e. for NSWindow TCocoaWindow is introduced.<br />
The decedent are used for the purpose of "overriding" default class implementation, where it is needed. In some cases using delegate classes is not enough.<br />
<br />
= Handles =<br />
* Window handle (HWND) is always NSView. <br />
** TCustomWSForm it is content NSView.<br />
** Any control that has scroll bars (i.e. TCustomWSList) the it its the embedding NSScrollView (TCocoaScrollView)<br />
<br />
{| class="wikitable"<br />
! LCL Control !! Cocoa class !! Notes<br />
|----<br />
|TMemo||NSTextView inside a NSScrollView||-<br />
|}<br />
<br />
=Code Style=<br />
The following requirement applies for Cocoa widgetset. Other widgetset my be following some other rules (historically), but in general LCL follows the same requirements.<br />
<br />
* '''Operators''' Keep the operator separated by spaces between operands<br />
A := B; <br />
A := B * C;<br />
* '''Blocks''' The main rule is to make 2 character spacing from the code block start. Begin / Else should start on a new line. <br />
<br />
procedure B;<br />
begin<br />
if A then // 2 character spacing from begin<br />
begin<br />
Start Here // 2 character spacing from begin<br />
Next Line<br />
end<br />
else<br />
begin<br />
Another Line<br />
end;<br />
end;<br />
<br />
* '''Standard Function Name''' please keep naming in ProperCase. Reserved words should be lower case. Name of (global/local) variables and fields should match declaration. (local variables should start with lower case)<br />
<br />
if not Assigned(A) then<br />
begin<br />
Result := nil;<br />
end;<br />
=Themed Drawing / Custom Controls=<br />
HITheme API is deprecated by Apple together with Carbon. It's still available in OSX, but for i386 only. Presumably will be completely removed on 64-bit only OSX.<br />
<br />
However, some LCL controls cannot be mapped to existing Cocoa provided controls and thus might require some "custom drawing". The drawing should look system native though. In order to achieve that NSCell family could be used. NSCell allows to draw (hit-test and as well as handle user input) for OSX native elements. If Apple to change appears of controls (cells), the LCL application would "pick-up" the look automatically.<br />
<br />
In order to be drawn NSCells requires a present of NSView, thus it's hard to use them forthe implementation of LCL TTheme APIs<br />
<br />
Example of NSCell usage is CocoaStatusBar drawing<br />
==Fonts==<br />
NSFont class provides a number of class methods to get proper system font without selecting the font by name. The same of getting system-native font size. <br />
<br />
[[Category:Mac OS]]<br />
[[Category:Mac OS X]]<br />
[[Category:Cocoa]]<br />
[[Category:Lazarus internals]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=Cocoa_Internals&diff=97784Cocoa Internals2015-11-12T13:56:14Z<p>Sekelsenmat: /* Handles */</p>
<hr />
<div>The page is about Cocoa Widgetset internal implementation. The page should be useful for Cocoa widgetset developers (maintainers and/or constributors) as well as any developers who need to use Cocoa specific API.<br />
<br />
=LCL specific ObjC classes=<br />
In order to control and handle an NSView's behavior LCL uses decedent classes from standard Cocoa controls. I.e. for NSWindow TCocoaWindow is introduced.<br />
The decedent are used for the purpose of "overriding" default class implementation, where it is needed. In some cases using delegate classes is not enough.<br />
<br />
= Handles =<br />
* Window handle (HWND) is always NSView. <br />
** TCustomWSForm it is content NSView.<br />
** Any control that has scroll bars (i.e. TCustomWSList) the it its the embedding NSScrollView (TCocoaScrollView)<br />
<br />
{| class="wikitable"<br />
! LCL Control !! Cocoa class !! Notes<br />
|----<br />
|TMemo||NSTextView inside a NSScrollView||-<br />
|}<br />
<br />
=Code Style=<br />
The following requirement applies for Cocoa widgetset. Other widgetset my be following some other rules (historically), but in general LCL follows the same requirements.<br />
<br />
* '''Operators''' Keep the operator separated by spaces between operands<br />
A := B; <br />
A := B * C;<br />
* '''Blocks''' The main rule is to make 2 character spacing from the code block start. Begin / Else should start on a new line. <br />
<br />
procedure B;<br />
begin<br />
if A then // 2 character spacing from begin<br />
begin<br />
Start Here // 2 character spacing from begin<br />
Next Line<br />
end<br />
else<br />
begin<br />
Another Line<br />
end;<br />
end;<br />
<br />
* '''Standard Function Name''' please keep naming in ProperCase. Reserved words should be lower case. Name of (global/local) variables and fields should match declaration. (local variables should start with lower case)<br />
<br />
if not Assigned(A) then<br />
begin<br />
Result := nil;<br />
end;<br />
=Themed Drawing / Custom Controls=<br />
HITheme API is deprecated by Apple together with Carbon. It's still available in OSX, but for i386 only. Presumably will be completely removed on 64-bit only OSX.<br />
<br />
However, some LCL controls cannot be mapped to existing Cocoa provided controls and thus might require some "custom drawing". The drawing should look system native though. In order to achieve that NSCell family could be used. NSCell allows to draw (hit-test and as well as handle user input) for OSX native elements. If Apple to change appears of controls (cells), the LCL application would "pick-up" the look automatically.<br />
<br />
In order to be drawn NSCells requires a present of NSView, thus it's hard to use them forthe implementation of LCL TTheme APIs<br />
<br />
Example of NSCell usage is CocoaStatusBar drawing<br />
==Fonts==<br />
NSFont class provides a number of class methods to get proper system font without selecting the font by name. The same of getting system-native font size. <br />
<br />
[[Category:Mac OS]]<br />
[[Category:Mac OS X]]<br />
[[Category:Cocoa]]<br />
[[Category:Lazarus internals]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=Template:Other_Interfaces&diff=97783Template:Other Interfaces2015-11-12T13:54:57Z<p>Sekelsenmat: /* Interfaces Development Articles */</p>
<hr />
<div>==Other Interfaces==<br />
{{Interfaces}}<br />
<br />
===Platform specific Tips===<br />
*[[Windows Programming Tips]] - Desktop Windows programming tips.<br />
*[[Linux Programming Tips]] - How to execute particular programming tasks in Linux<br />
*[[OS X Programming Tips]] - Lazarus installation, useful tools, Unix commands, and more...<br />
*[[WinCE Programming Tips]] - Using the telephone API, sending SMSes, and more...<br />
*[[Android Programming]] - For Android smartphones and tablets<br />
*[[iPhone/iPod development]] - About using Objective Pascal to develop iOS applications<br />
<br />
===Interfaces Development Articles===<br />
*[[Carbon interface internals]] - If you want to help improving the Carbon interface<br />
*[[Windows CE Development Notes]] - For Pocket PC and Smartphones<br />
*[[Adding a new interface]] - How to add a new widget set interface<br />
*[[LCL Defines]] - Choosing the right options to recompile LCL<br />
*[[LCL Internals]] - Some info about the inner workings of the LCL<br />
*[[Cocoa Internals]] - Some info about the inner workings of the Cocoa widgetset</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=Roadmap&diff=96015Roadmap2015-09-29T07:19:38Z<p>Sekelsenmat: /* Status of dialogs on each LCL Interface */</p>
<hr />
<div>{{Roadmap}}<br />
<br />
This document gives an idea of the current status of the various parts of Lazarus and also helps new contributors to find a suitable place where they can help. It also shows the people implementing the various parts and the targets.<br />
<br />
'''NOTE: This page refers to the LCL Interface portion (that talks to the backend toolkits) of the Lazarus Component Library. It does NOT reflect on the actual features of the individual GUI toolkits (eg: GTK2, GTK3, Qt, fpGUI etc).'''<br />
<br />
__TOC__<br />
<br />
{{Template:Development Status}}<br />
<br />
==General status of LCL interfaces==<br />
<br />
{{Template:Widgetset Roadmap}}<br />
<br />
==Current status of the various parts of Lazarus==<br />
<br />
<br />
{| class="wikitable sortable"<br />
! Unit !! Item !! State !! Target !! Skills !! Responsible !! Comments<br />
|---- class="working"<br />
|IDE||TCollection Editor||working||0.9.x||FCL, RTTI, IDE||-||A generic TCollection editor for the various TCollections in the LCL/FCL.<br />
|---- class="working"<br />
|IDE||TActionList||working||0.9.x||-||-||-<br />
|---- class="working"<br />
|IDE||Doc Editor||working||-||fpdoc||-||The doc editor will be an integrated fpDoc editor similar to fpde. It will be a process of its own, so that it can show help for dialogs as well. It should also be able to write help for packages.<br />
|---- class="working"<br />
|IDE||Export LFM as xml||working||-||-||-||Load and save LFM files to XML.<br />
|---- class="partial"<br />
|IDE||[[Icon Editor Roadmap]]||in progress||post 1.0||-||-||A simple icon editor with the ability to create lrs files. It will be a good example and can help newbies to create icons for their components.<br />
|---- class="working"<br />
|LCL||Borderspacing||working||0.9.x||-||-||for aligned controls<br />
|---- class="working"<br />
|LCL||Drag&Drop||working||||-||-||<br />
|---- class="working"<br />
|LCL||Port to Darwin Power PC, Mac OS X||working||0.9.x||-||-||depends on FPC 1.9.5<br />
|---- class="working"<br />
|LCL||Port to Mac OS X x86||working||-||-||-||depends on FPC 2.1.1<br />
|---- class="working"<br />
|LCL||TSplitter||working||0.9.x||easy||-||-<br />
|---- class="working"<br />
|LCL||TFindDialog||working||-||-||-||Implemented in 0.9.16<br />
|---- class="working"<br />
|LCL||TReplaceDialog||working||-||-||-||Implemented in 0.9.16<br />
|---- class="working"<br />
|LCL||TControl.Font||in progress||0.9.x||-||-||-<br />
|---- class="working"<br />
|LCL||TTabControl||in progress||0.9.x||-||-||-<br />
|---- class="partial"<br />
|LCL||Docking (= the combination of forms)||partially working, in progress||post 1.0||deep LCL and interfaces||Mattias||-<br />
|---- class="working"<br />
|LCL||Frames (= forms as children)||working||0.9.28||deep knowledge of LCL||Mattias, Paul||-<br />
|---- class="working"<br />
|IDE||Visual Form Inheritence||working||post 1.0||IDE||Mattias||Properties are not yet propagated to open descendants<br />
|---- class="partial"<br />
|LCL||MDI - Multiple Documents Interfaces Putting fo ...||in progress||1.2||deep LCL and interfaces||[[User:Zeljan|Zeljan]]||An MDI LCL emulator for widgetsets which does not support MDI, also native implementation of MDI for qt and win32/64. Currently only qt has full MDI support, others are in progress.<br />
|---- class="not"<br />
|LCL||Palette support||not implemented||-||-||-||Required to correctly show colors on a 256 colors display<br />
|---- class="partial"<br />
|LCL||TCoolBar||partially working, in progress||post 1.0||LCL and anchoring||[[User:JuhaManninen|Juha]]||-<br />
|---- class="partial"<br />
|LCL||TControlBar||skeleton implementation to prevent errors in Delphi conversion, in progress||post 1.0||LCL and anchoring||[[User:JuhaManninen|Juha]]||-<br />
|---- class="working"<br />
|LCL||TMaskEdit||working||-||-||[[User:Bart|Bart]]||-<br />
|---- class="not"<br />
|LCL||TDirectoryTreeView||not implemented||-||-||-||-<br />
|---- class="not"<br />
|LCL||Constrain maximization to specific area||not implemented||-||winapi, gtk||-||When maximizing a window, the left, top, width and height can all be constrained to a specific rectangular area on the screen/desktop. After this is done, constrain the source editor and maybe other windows<br />
|---- class="working"<br />
|Components||TIcon||working||0.9.26||-||Marc||-<br />
|---- class="working"<br />
|Components||CUPS Package||working||0.9.x||easy||-||<br />
|---- class="working"<br />
|}<br />
<br />
==Status of features on each LCL Interface==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|Accelerator Keys<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Caret<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Clipboard<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|Cursors<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="partial"|Partially Implemented||class="not"|Not Implemented<br />
|----<br />
|Drag & Drop<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|[[Drop files event]]<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Applicable<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|MDI Support<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Printing<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Regions<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="partial"|Partially Implemented||class="working"|Working<br />
|----<br />
|TCustomControl descendents<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|Unicode Support<br />
|class="working"|Working||class="not"|Impossible to Implement||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|[[BidiMode]]<br />
|class="working"|Working||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Application||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TTimer||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TApplication.QueueAsyncCall||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|TThread.Synchronize||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class="unknown"|Unknown<br />
|class="working"|Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|PostMessage||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class=""unknown"|Unknown<br />
|class="not"|Not Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|PostThreadMessage||class="working"|Working||class="unknown"|Unknown||class="unknown"|Unknown<br />
|class="unknown"|Unknown||class="unknown"|Unknown||class="unknown"|Unknown<br />
|class="unknown"|Unknown||class="unknown"|Unknown||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of Graphics on each LCL Interface==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBitmap/TPixmap/TIcon/etc||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TBrush||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TFont||class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TPen||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|ExtTextOut||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="unknown"|Unknown||class="working"|Working<br />
|}<br />
<br />
==Status of native controls on each LCL Interface==<br />
Native controls are TWinControl descendants which do not descend from TCustomControl.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBitBtn||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TCalendar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TCheckBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TCheckGroup||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TCheckListBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TComboBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TEdit||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TForm||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TGroupBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TIdleTimer||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TImageList||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working|| class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TListBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TListView||class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TMainMenu||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TMemo||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TMenuItem||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TPageControl and TTabSheet||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TPairSplitter||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TPanel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TPopupMenu||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TProgressBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TRadioButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|----<br />
|TRadioGroup||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="partial"|Partially Implemented||class="not"|Not Implemented<br />
|----<br />
|TScrollBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TScrollBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TSpinEdit||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|----<br />
|TSplitter||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TStaticText||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TStatusBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TToggleBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TTrackbar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TTrayIcon||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of dialogs on each LCL Interface==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|LCLIntf.MessageBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="working"|Working<br />
|class="working"|Working||class="unknown"|Unknown||class="partial"|Implemented for Android<br />
|----<br />
|Application.MessageBox, MessageDlg, LCLIntf.PromptUser||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="unknown"|Unknown||class="partial"|Implemented for Android<br />
|----<br />
|LCLIntf.AskUser||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|TColorDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TFontDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TOpenDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TPrinterSetupDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TSaveDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of TCustomControl based controls on each LCL Interface==<br />
Note that being a TCustomControl descendant does not guarantee that a control has no widgetset implementation. TArrow has it, although it has a good default implementation. TNotebook is fully implemented in the LCL.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TArrow ||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TNoteBook||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TUpDown||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TStringGrid||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TDrawGrid||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TToolBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TTreeView||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TValueListEditor||class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of TGraphicControl based controls on each LCL Interface==<br />
'''Note:''' These are for LCL wrapped components only, '''not''' for the specific GUI toolkit features itself.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBevel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TLabel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="partial"|Implemented for Android<br />
|----<br />
|TShape||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TSpeedButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TPaintBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TImage||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|}<br />
<br />
==Status of LazDeviceAPIs on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! customdrawn-android<br />
|----<br />
|Accelerometer||class="working"|Working<br />
|----<br />
|Messaging (SMS, MMS and E-Mail)||class="partial"|SMS Implemented<br />
|----<br />
|PositionInfo||class="working"|Working<br />
|}<br />
<br />
==See Also==<br />
<br />
*[[LCL Internals]]<br />
*[[TAChart Roadmap]]<br />
<br />
[[Category:Lazarus]]<br />
[[Category:Roadmaps]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=Roadmap&diff=96014Roadmap2015-09-29T07:19:09Z<p>Sekelsenmat: /* Status of features on each LCL Interface */</p>
<hr />
<div>{{Roadmap}}<br />
<br />
This document gives an idea of the current status of the various parts of Lazarus and also helps new contributors to find a suitable place where they can help. It also shows the people implementing the various parts and the targets.<br />
<br />
'''NOTE: This page refers to the LCL Interface portion (that talks to the backend toolkits) of the Lazarus Component Library. It does NOT reflect on the actual features of the individual GUI toolkits (eg: GTK2, GTK3, Qt, fpGUI etc).'''<br />
<br />
__TOC__<br />
<br />
{{Template:Development Status}}<br />
<br />
==General status of LCL interfaces==<br />
<br />
{{Template:Widgetset Roadmap}}<br />
<br />
==Current status of the various parts of Lazarus==<br />
<br />
<br />
{| class="wikitable sortable"<br />
! Unit !! Item !! State !! Target !! Skills !! Responsible !! Comments<br />
|---- class="working"<br />
|IDE||TCollection Editor||working||0.9.x||FCL, RTTI, IDE||-||A generic TCollection editor for the various TCollections in the LCL/FCL.<br />
|---- class="working"<br />
|IDE||TActionList||working||0.9.x||-||-||-<br />
|---- class="working"<br />
|IDE||Doc Editor||working||-||fpdoc||-||The doc editor will be an integrated fpDoc editor similar to fpde. It will be a process of its own, so that it can show help for dialogs as well. It should also be able to write help for packages.<br />
|---- class="working"<br />
|IDE||Export LFM as xml||working||-||-||-||Load and save LFM files to XML.<br />
|---- class="partial"<br />
|IDE||[[Icon Editor Roadmap]]||in progress||post 1.0||-||-||A simple icon editor with the ability to create lrs files. It will be a good example and can help newbies to create icons for their components.<br />
|---- class="working"<br />
|LCL||Borderspacing||working||0.9.x||-||-||for aligned controls<br />
|---- class="working"<br />
|LCL||Drag&Drop||working||||-||-||<br />
|---- class="working"<br />
|LCL||Port to Darwin Power PC, Mac OS X||working||0.9.x||-||-||depends on FPC 1.9.5<br />
|---- class="working"<br />
|LCL||Port to Mac OS X x86||working||-||-||-||depends on FPC 2.1.1<br />
|---- class="working"<br />
|LCL||TSplitter||working||0.9.x||easy||-||-<br />
|---- class="working"<br />
|LCL||TFindDialog||working||-||-||-||Implemented in 0.9.16<br />
|---- class="working"<br />
|LCL||TReplaceDialog||working||-||-||-||Implemented in 0.9.16<br />
|---- class="working"<br />
|LCL||TControl.Font||in progress||0.9.x||-||-||-<br />
|---- class="working"<br />
|LCL||TTabControl||in progress||0.9.x||-||-||-<br />
|---- class="partial"<br />
|LCL||Docking (= the combination of forms)||partially working, in progress||post 1.0||deep LCL and interfaces||Mattias||-<br />
|---- class="working"<br />
|LCL||Frames (= forms as children)||working||0.9.28||deep knowledge of LCL||Mattias, Paul||-<br />
|---- class="working"<br />
|IDE||Visual Form Inheritence||working||post 1.0||IDE||Mattias||Properties are not yet propagated to open descendants<br />
|---- class="partial"<br />
|LCL||MDI - Multiple Documents Interfaces Putting fo ...||in progress||1.2||deep LCL and interfaces||[[User:Zeljan|Zeljan]]||An MDI LCL emulator for widgetsets which does not support MDI, also native implementation of MDI for qt and win32/64. Currently only qt has full MDI support, others are in progress.<br />
|---- class="not"<br />
|LCL||Palette support||not implemented||-||-||-||Required to correctly show colors on a 256 colors display<br />
|---- class="partial"<br />
|LCL||TCoolBar||partially working, in progress||post 1.0||LCL and anchoring||[[User:JuhaManninen|Juha]]||-<br />
|---- class="partial"<br />
|LCL||TControlBar||skeleton implementation to prevent errors in Delphi conversion, in progress||post 1.0||LCL and anchoring||[[User:JuhaManninen|Juha]]||-<br />
|---- class="working"<br />
|LCL||TMaskEdit||working||-||-||[[User:Bart|Bart]]||-<br />
|---- class="not"<br />
|LCL||TDirectoryTreeView||not implemented||-||-||-||-<br />
|---- class="not"<br />
|LCL||Constrain maximization to specific area||not implemented||-||winapi, gtk||-||When maximizing a window, the left, top, width and height can all be constrained to a specific rectangular area on the screen/desktop. After this is done, constrain the source editor and maybe other windows<br />
|---- class="working"<br />
|Components||TIcon||working||0.9.26||-||Marc||-<br />
|---- class="working"<br />
|Components||CUPS Package||working||0.9.x||easy||-||<br />
|---- class="working"<br />
|}<br />
<br />
==Status of features on each LCL Interface==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|Accelerator Keys<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Caret<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Clipboard<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|Cursors<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="partial"|Partially Implemented||class="not"|Not Implemented<br />
|----<br />
|Drag & Drop<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|[[Drop files event]]<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Applicable<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|MDI Support<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Printing<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Regions<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="partial"|Partially Implemented||class="working"|Working<br />
|----<br />
|TCustomControl descendents<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|Unicode Support<br />
|class="working"|Working||class="not"|Impossible to Implement||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|[[BidiMode]]<br />
|class="working"|Working||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Application||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TTimer||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TApplication.QueueAsyncCall||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|TThread.Synchronize||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class="unknown"|Unknown<br />
|class="working"|Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|PostMessage||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class=""unknown"|Unknown<br />
|class="not"|Not Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|PostThreadMessage||class="working"|Working||class="unknown"|Unknown||class="unknown"|Unknown<br />
|class="unknown"|Unknown||class="unknown"|Unknown||class="unknown"|Unknown<br />
|class="unknown"|Unknown||class="unknown"|Unknown||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of Graphics on each LCL Interface==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBitmap/TPixmap/TIcon/etc||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TBrush||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TFont||class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TPen||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|ExtTextOut||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="unknown"|Unknown||class="working"|Working<br />
|}<br />
<br />
==Status of native controls on each LCL Interface==<br />
Native controls are TWinControl descendants which do not descend from TCustomControl.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBitBtn||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TCalendar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TCheckBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TCheckGroup||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TCheckListBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TComboBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TEdit||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TForm||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TGroupBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TIdleTimer||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TImageList||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working|| class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TListBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TListView||class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TMainMenu||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TMemo||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TMenuItem||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TPageControl and TTabSheet||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TPairSplitter||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TPanel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TPopupMenu||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TProgressBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TRadioButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|----<br />
|TRadioGroup||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="partial"|Partially Implemented||class="not"|Not Implemented<br />
|----<br />
|TScrollBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TScrollBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TSpinEdit||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|----<br />
|TSplitter||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TStaticText||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TStatusBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TToggleBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TTrackbar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TTrayIcon||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of dialogs on each LCL Interface==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|LCLIntf.MessageBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="working"|Working<br />
|class="working"|Working||class="unknown"|Unknown||class="partial"|Implemented for Android<br />
|----<br />
|Application.MessageBox, MessageDlg, LCLIntf.PromptUser||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="unknown"|Unknown||class="partial"|Implemented for Android<br />
|----<br />
|LCLIntf.AskUser||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|TColorDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TFontDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TOpenDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TPrinterSetupDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TSaveDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of TCustomControl based controls on each LCL Interface==<br />
Note that being a TCustomControl descendant does not guarantee that a control has no widgetset implementation. TArrow has it, although it has a good default implementation. TNotebook is fully implemented in the LCL.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TArrow ||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TNoteBook||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TUpDown||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TStringGrid||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TDrawGrid||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TToolBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TTreeView||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TValueListEditor||class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of TGraphicControl based controls on each LCL Interface==<br />
'''Note:''' These are for LCL wrapped components only, '''not''' for the specific GUI toolkit features itself.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBevel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TLabel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="partial"|Implemented for Android<br />
|----<br />
|TShape||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TSpeedButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TPaintBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TImage||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|}<br />
<br />
==Status of LazDeviceAPIs on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! customdrawn-android<br />
|----<br />
|Accelerometer||class="working"|Working<br />
|----<br />
|Messaging (SMS, MMS and E-Mail)||class="partial"|SMS Implemented<br />
|----<br />
|PositionInfo||class="working"|Working<br />
|}<br />
<br />
==See Also==<br />
<br />
*[[LCL Internals]]<br />
*[[TAChart Roadmap]]<br />
<br />
[[Category:Lazarus]]<br />
[[Category:Roadmaps]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=LCL_Internals&diff=94362LCL Internals2015-08-01T06:27:35Z<p>Sekelsenmat: /* TSpeedButton */</p>
<hr />
<div>{{LCL Internals}}<br />
<br />
{{Other_Interfaces}}<br />
<br />
== Minimum Toolkit versions ==<br />
<br />
{| class="wikitable sortable"<br />
! Lazarus version !! Min. FPC !! Min. Gtk 2 !! Min. Qt 4 !! Min. Windows !! Min. Windows CE !! Min. Mac OS X (Carbon) !! Min. Mac OS X (Cocoa) !! Min. Req. of LCL-CustomDrawn<br />
|-<br />
|0.9.24<br />
|2.2.0<br />
|2.6+<br />
|4.2+<br />
|Windows 98+<br />
|Recommended 4.0+<br />
|10.4<br />
|N/A<br />
|N/A<br />
|-<br />
|0.9.26<br />
|2.2.2<br />
|2.6+<br />
|4.3+<br />
|Windows 98+<br />
|Recommended 4.0+<br />
|10.4<br />
|N/A<br />
|N/A<br />
|-<br />
|0.9.28<br />
|2.2.4<br />
|2.8+<br />
|4.5+<br />
|Windows 98+<br />
|Recommended 4.0+<br />
|10.4<br />
|N/A<br />
|N/A<br />
|-<br />
|0.9.30<br />
|2.4.0<br />
|2.8+<br />
|4.5+<br />
|Windows 98+<br />
|Recommended 5.0+<br />
|10.4<br />
|N/A<br />
|N/A<br />
|-<br />
|0.9.31<br />
|2.4.4<br />
|2.8+<br />
|4.5+<br />
|Windows 98+<br />
|Recommended 5.0+<br />
|10.4<br />
|10.6<br />
|Android 2.2+, Windows 2000+, X11, Mac OS X 10.6+<br />
|-<br />
|1.2.6<br />
|2.6.4<br />
|2.8+<br />
|4.5+*<br />
|Windows 98+<br />
|Recommended 5.0+<br />
|10.4<br />
|10.6<br />
|Android 2.2+, Windows 2000+, X11, Mac OS X 10.6+<br />
|}<br />
<br />
* - Actually 4.5.0 ...4.8.4 with pre-built Qt4Pas.dll, 4.8.5+ requires a different Qt4Pas.dll<br />
<br />
See Also: [[Installing_Lazarus_on_MacOS_X#Compatibility]]<br />
<br />
== Internals of the LCL ==<br />
<br />
There is the LCL, and the "interface". The LCL is the part that is platform independent, and it resides in the lazarus/lcl/ directory. This directory contains mainly class definitions. Many of the different controls are actually implemented in the lazarus/lcl/include/ directory in the various .inc files. This is to find the implementation of a specific control, TCustomMemo for example, faster (which is in custommemo.inc). Every .inc starts with a line {%MainUnit ...} to define where it is included.<br />
<br />
Then there is the "interface" which lives in a subdirectory of the lazarus/lcl/interfaces/ directory. The gtk interface is in gtk/, win32 in win32/, etc. They all have a Interfaces unit, which is used by the lcl and creates the main interface object. Usually the main interface object is defined in XXint.pp (win32int.pp), and implemented in various inc files, XXobject.inc, for the interface specific methods, XXwinapi.inc for winapi implementation methods, XXlistsl.inc for implementation of the stringlist used by the TComboBox, TListBox, and other such controls, XXcallback.inc for handling of widget events and taking appropriate action to notify the LCL.<br />
<br />
Every control has a WidgetSetClass property which is of the 'mirror' class in the interfaces directory, for example: mirror of TCustomEdit is TWSCustomEdit, which methods are implemented by TWin32WSCustomEdit in win32wsstdctrls. This is the way the LCL communicates with the interface, and how it lets the interface do things.<br />
<br />
Communication of interface back to LCL is mostly done by sending messages, usually 'DeliverMessage' which calls TControl.Perform(<message_id>, wparam, lparam) with wparam and lparam being the extra info for the message.<br />
<br />
=== Pie and RadialPie ===<br />
The LCLIntf unit contains two functions to draw pie-shapes:<br />
function [[doc:lcl/lclintf/pie.html|Pie]](DC: HDC; x1, y1, x2, y2, sx, sy, ex, ey: Integer): Boolean;<br />
function [[doc:lcl/lclintf/radialpie.html|RadialPie]](DC: HDC; x1, y1, x2, y2, Angle1, Angle2: Integer): Boolean; <br />
<br />
The Pie function uses a two points (sx,sy) and (ex,ey) to indicate start and end of the arc. RadialPie uses Angles to indicate start and end of the arc.<br />
<br />
Pie calls TWidgetSet.Pie and RadialPie calls TWidgetSet.RadialPie. The default implementation of TWidgetSet.Pie is to convert the parameters to angles and to call TWidgetSet.RadialPie. TWidgetSet.RadialPie creates an array of points for the arc and calls TWidgetSet.Polygon.<br />
<br />
The win32 widgetset overrides TWidgetSet.Pie to call the Windows Pie function directly.<br />
<br />
{{Note| in older versions of Lazarus there existed RadialPie with angles which did the same as the current RadialPie and RadialPie, which does the same as our Pie. Those functions have been removed in Lazarus 0.9.21.}}<br />
<br />
===Interfaces===<br />
<br />
{{Interfaces}}<br />
<br />
===Adding a new unit to the LCL===<br />
First add the new unit name into allclunits.pp.<br />
<br />
To make sure the unit is registered in the components palette see the files RegisterLCL.pas and pkgfileslcl.inc, they are located in lazarus/packager.<br />
<br />
== How to create a new Widgetset ==<br />
This is a step-by-step tutorial of developing a new [[Widgetset|widgetset]]. It is based on my experience creating the basics of the new qt4 interface.<br />
<br />
To start with, why would someone want to add an Widgetset? The answer is to be able to port existing lazarus software to more platforms, without modifying their code.<br />
<br />
Now, let´s write the widgetset. First of all, you need to have pascal bindings for the widget and know how to use it. Normally this is not hard. A few hours doing basic tutorials available on the internet should be enougth to get started. If the bindings do not exist already, you need to create them. If the tutorials are on another language, translate them to pascal and make them work.<br />
<br />
Now, for Qt I utilized Den Jean qt4 bindings for pascal, and created a very basic Qt program using them:<br />
<br />
<syntaxhighlight>program qttest;<br />
<br />
uses qt4;<br />
<br />
var<br />
App: QApplicationH;<br />
MainWindow: QMainWindowH;<br />
begin<br />
App := QApplication_Create(@argc,argv);<br />
<br />
MainWindow := QMainWindow_Create;<br />
<br />
QWidget_show(MainWindow);<br />
<br />
QApplication_Exec;<br />
end.</syntaxhighlight><br />
<br />
The above project compiles and creates a qt4 program. Now we will use its code to write a new widgetset. After we are done, the lazarus program below will compile fine into a qt4 software:<br />
<br />
<syntaxhighlight>program qttest;<br />
<br />
{$mode objfpc}{$H+}<br />
<br />
uses<br />
Interfaces, Classes, Forms,<br />
{ Add your units here }<br />
qtform;<br />
<br />
begin<br />
Application.Initialize;<br />
Application.CreateForm(TForm1, Form1);<br />
Application.Run;<br />
end.</syntaxhighlight><br />
<br />
Where the form is maintained by Lazarus IDE and designed visually.<br />
<br />
The first thing to do on a new widgetset is add an empty skeleton for it. Very early development widgetsets, like qt and carbon, can serve as an skeleton.<br />
<br />
Looking at the files on the many widgets you can see the first file to be called by the lcl: Interfaces.pas This file just calls another called QtInt.pas or similar. QtInt.pas has the code for the TWidgetSet class, which we must implement. On an empty skeleton you can see that the class has various functions it must implement:<br />
<br />
<syntaxhighlight> TQtWidgetSet = Class(TWidgetSet)<br />
private<br />
App: QApplicationH;<br />
public<br />
{$I qtwinapih.inc}<br />
{$I qtlclintfh.inc}<br />
public<br />
// Application<br />
procedure AppInit(var ScreenInfo: TScreenInfo); override;<br />
procedure AppRun(const ALoop: TApplicationMainLoop); override;<br />
procedure AppWaitMessage; override;<br />
procedure AppProcessMessages; override;<br />
procedure AppTerminate; override;<br />
procedure AppMinimize; override;<br />
procedure AppBringToFront; override;<br />
public<br />
constructor Create;<br />
destructor Destroy; override;<br />
function DCGetPixel(CanvasHandle: HDC; X, Y: integer): TGraphicsColor; override;<br />
procedure DCSetPixel(CanvasHandle: HDC; X, Y: integer; AColor: TGraphicsColor); override;<br />
procedure DCRedraw(CanvasHandle: HDC); override;<br />
procedure SetDesigning(AComponent: TComponent); override;<br />
<br />
function InitHintFont(HintFont: TObject): Boolean; override;<br />
<br />
// create and destroy<br />
function CreateComponent(Sender : TObject): THandle; override; // deprecated<br />
function CreateTimer(Interval: integer; TimerFunc: TFNTimerProc): integer; override;<br />
function DestroyTimer(TimerHandle: integer): boolean; override;<br />
end;</syntaxhighlight><br />
<br />
=== How to implement a new windowed component ===<br />
<br />
Windowed components are all descendents from TWinControl. Those controls have a Handle and thus, should be created by the Widgetset. It's easy to add new windowed components to a widgetset.<br />
<br />
Let's say you want to add TQtWSCustomEdit to Qt Widgetset. To start with TCustomEdit is a descendent of TWinControl and is located on the StdCtrls unit.<br />
<br />
Now, go to QtWSStrCtrls unit and look for the declaration of TQtWSCustomEdit.<br />
<br />
<syntaxhighlight> TQtWSCustomEdit = class(TWSCustomEdit)<br />
private<br />
protected<br />
public<br />
end;</syntaxhighlight><br />
<br />
Add static methods that are declared on TWSCustomEdit and override them. The code should now look like this:<br />
<br />
<syntaxhighlight> TQtWSCustomEdit = class(TWSCustomEdit)<br />
private<br />
protected<br />
public<br />
class function CreateHandle(const AWinControl: TWinControl;<br />
const AParams: TCreateParams): HWND; override;<br />
class procedure DestroyHandle(const AWinControl: TWinControl); override;<br />
{ class function GetSelStart(const ACustomEdit: TCustomEdit): integer; override;<br />
class function GetSelLength(const ACustomEdit: TCustomEdit): integer; override;<br />
<br />
class procedure SetCharCase(const ACustomEdit: TCustomEdit; NewCase: TEditCharCase); override;<br />
class procedure SetEchoMode(const ACustomEdit: TCustomEdit; NewMode: TEchoMode); override;<br />
class procedure SetMaxLength(const ACustomEdit: TCustomEdit; NewLength: integer); override;<br />
class procedure SetPasswordChar(const ACustomEdit: TCustomEdit; NewChar: char); override;<br />
class procedure SetReadOnly(const ACustomEdit: TCustomEdit; NewReadOnly: boolean); override;<br />
class procedure SetSelStart(const ACustomEdit: TCustomEdit; NewStart: integer); override;<br />
class procedure SetSelLength(const ACustomEdit: TCustomEdit; NewLength: integer); override;<br />
<br />
class procedure GetPreferredSize(const AWinControl: TWinControl;<br />
var PreferredWidth, PreferredHeight: integer); override;}<br />
end;</syntaxhighlight><br />
<br />
The commented part of the code are procedures you need to implement for TCustomEdit to be fully functional, but just CreateHandle and DestroyHandle should be enough for it to be show on the form and be editable, so it fits our needs in this article.<br />
<br />
Hit CTRL+SHIFT+C to code complete and the implement CreateHandle and DestroyHandle. In the case of Qt4 the code will be like this:<br />
<br />
<syntaxhighlight>{ TQtWSCustomEdit }<br />
<br />
class function TQtWSCustomEdit.CreateHandle(const AWinControl: TWinControl;<br />
const AParams: TCreateParams): HWND;<br />
var<br />
Widget: QWidgetH;<br />
Str: WideString;<br />
begin<br />
// Creates the widget<br />
WriteLn('Calling QTextDocument_create');<br />
Str := WideString((AWinControl as TCustomMemo).Lines.Text);<br />
Widget := QTextEdit_create(@Str, QWidgetH(AWinControl.Parent.Handle));<br />
<br />
// Sets it's initial properties<br />
QWidget_setGeometry(Widget, AWinControl.Left, AWinControl.Top,<br />
AWinControl.Width, AWinControl.Height);<br />
<br />
QWidget_show(Widget);<br />
<br />
Result := THandle(Widget);<br />
end;<br />
<br />
class procedure TQtWSCustomEdit.DestroyHandle(const AWinControl: TWinControl);<br />
begin<br />
QTextEdit_destroy(QTextEditH(AWinControl.Handle));<br />
end;</syntaxhighlight><br />
<br />
Now uncomment the like "RegisterWSComponent(TCustomEdit, TQtWSCustomEdit);" on the bottom of the unit and that's it!<br />
<br />
You can now drop a TCustomEdit on the bottom of a form and expect it to work. :^) <br />
<br />
=== Implementing TBitmap ===<br />
<br />
To implement TBitmap it is necessary to understand TRawImage and TLazIntfImage as explained here: [[Developing with Graphics#Working with TLazIntfImage.2C TRawImage and TLazCanvas]]<br />
<br />
So, let's say you want to compile the following code:<br />
<br />
<syntaxhighlight><br />
procedure TMyForm.HandleOnPaint(Sender: TObject);<br />
var<br />
Bitmap: TBitmap;<br />
begin<br />
Bitmap := TBitmap.Create;<br />
try<br />
Bitmap.LoadFromFile('myfile.bmp');<br />
Canvas.Draw(0, 0, Bitmap);<br />
finally<br />
Bitmap.Free;<br />
end;<br />
end;</syntaxhighlight><br />
<br />
Below is the order on which functions from the widgetset interface are called when executing that code:<br />
<br />
1 - BeginPaint<br />
<br />
This will be called only if the OnPaint event sends zero as the DC for the paint event<br />
<br />
2 - GetDC(0);<br />
<br />
Just create a device context.<br />
<br />
3 - TCDWidgetSet.RawImage_QueryDescription <br />
<br />
The default implementation of this routine is good for most widgetsets<br />
<br />
4 - TCDWidgetSet.RawImage_CreateBitmaps<br />
<br />
Here you need to create a native image object and load it from RawData.Data where the information is stored based on your description of the pixel format on item 2.<br />
<br />
5 - CreateCompatibleDC(0)<br />
<br />
This creates a temporary DC just to store the image, but at this point there is no information about the image so at this point this DC is really dummy<br />
<br />
6 - SelectObject<br />
<br />
With the image as the object to be selected and the DC just created above as target DC.<br />
<br />
7 - StretchMaskBlt<br />
<br />
Finally the drawing function! DestDC is the DC allocated on BeginPaint.<br />
<br />
8 - EndPaint<br />
<br />
Again, not always utilized.<br />
<br />
=== TBitmap.LoadFromDevice for screenshot taking ===<br />
<br />
It is recomended that you first implement TBitmap before trying this step.<br />
<br />
On LCL you can use the following code takes a screenshot from the entire screen and paints it on the canvas:<br />
<br />
<syntaxhighlight>var<br />
ScreenDC: HDC;<br />
Bitmap: TBitmap;<br />
begin<br />
Bitmap := TBitmap.Create;<br />
try<br />
ScreenDC := GetDC(0);<br />
Bitmap.LoadFromDevice(ScreenDC);<br />
ReleaseDC(0, ScreenDC);<br />
Canvas.Draw(0, 0, Bitmap);<br />
finally<br />
Bitmap.Free;<br />
end;<br />
end;</syntaxhighlight><br />
<br />
If you already implemented TBitmap, there are only 2 new functions to be implemented for LoadFromDevice: GetDeviceSize and GetRawImageFromDevice<br />
<br />
Below is a big trace, covering all widgetset functions being called on a OnPaint event that takes a screenshot and paints it on the screen. This trace was taken with Qt widgetset, and may have some imperfections. The Handle numbers should be used to check which object is being utilized on the functions.<br />
<br />
<br />
[WinAPI BeginPaint] Result=-1220713544<br />
<br />
[WinAPI GetClientBounds]<br />
<br />
[WinAPI SetWindowOrgEx] DC: -1220713544 NewX: 0 NewY: 0<br />
<br />
<syntaxhighlight>Enters on Paint event<br />
<br />
Bitmap := TBitmap.Create;<br />
try<br />
ScreenDC := GetDC(0);</syntaxhighlight><br />
<br />
[WinAPI GetDC] hWnd: 0 Result: -1220712920<br />
<br />
<syntaxhighlight> Bitmap.LoadFromDevice(ScreenDC);</syntaxhighlight><br />
<br />
[WinAPI GetDeviceSize]<br />
<br />
[WinAPI GetRawImageFromDevice] SrcDC: -1220712920 SrcWidth: 0 SrcHeight: 0<br />
<br />
[WinAPI CreateBitmapFromRawImage] Width:1024 Height:768 DataSize: 3145728 CreateMask: False Bitmap:-1220746696<br />
<br />
[WinAPI GetObject] GDIObj: -1220746696 Result=84 ObjectType=Image<br />
<br />
<syntaxhighlight> ReleaseDC(0, ScreenDC);</syntaxhighlight><br />
<br />
[WinAPI ReleaseDC] hWnd: 0 DC: -1220712920<br />
<br />
<syntaxhighlight> Canvas.Draw(0, 0, Bitmap);</syntaxhighlight><br />
<br />
[WinAPI CreateCompatibleDC] DC: 0<br />
<br />
[WinAPI GetDC] hWnd: 0 Result: -1220712920<br />
<br />
[WinAPI SelectObject] DC=-1220712920 GDIObj=-1220746696 Result=0 ObjectType=Image<br />
<br />
[WinAPI StretchMaskBlt] DestDC:-1220713544 SrcDC:-1220712920 Image:137185120 X:0 Y:0 W:1024 H:768 XSrc:0 YSrc:0 WSrc:1024 HSrc:768<br />
<br />
<syntaxhighlight>finally<br />
Bitmap.Free;<br />
end;</syntaxhighlight><br />
<br />
[WinAPI SelectObject] DC=-1220712920 GDIObj=0 Invalid GDI Object<br />
<br />
[WinAPI DeleteObject] GDIObject: -1220746696 Result=False ObjectType=Image<br />
<br />
<pre><br />
Now exited the OnPaint event<br />
</pre><br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
[WinAPI SetWindowOrgEx] DC: -1220713544 NewX: -152 NewY: -246<br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
TWidgetSet.InitializeCriticalSection<br />
<br />
TWidgetSet.EnterCriticalSection<br />
<br />
[WinAPI SelectObject] DC=-1220713544 GDIObj=0 Invalid GDI Object<br />
<br />
[WinAPI MoveToEx] DC:-1220713544 X:0 Y:0<br />
<br />
[WinAPI SelectObject] DC=-1220713544 GDIObj=-1220746760 Result=-1220746856 ObjectType=Brush<br />
<br />
[WinAPI SelectObject] DC=-1220713544 GDIObj=-1220746856 Result=-1220746856 ObjectType=Brush<br />
<br />
TWidgetSet.LeaveCriticalSection<br />
<br />
[WinAPI SetWindowOrgEx] DC: -1220713544 NewX: 0 NewY: 0<br />
<br />
[WinAPI EndPaint] Handle: -1220611768 PS.HDC: -1220713544<br />
<br />
=== Implementing drawing in the OnPaint event of a form or another control ===<br />
<br />
For drawing in the OnPaint event of a form, the event itself comes from the underlaying widgetset library. The LCL interface should handle this event and create an appropriate DC object on the event handler and then call LCLSendPaintMsg. Besides that one should also implement the corresponding drawing methods, such as Rectangle or ExtTextOut. Pen, Brush and Font related routines might also be useful.<br />
<br />
Here is the OnPaint event handler from the Cocoa widgetset which shows how it calls LCLSentPaintMsg:<br />
<br />
<syntaxhighlight><br />
procedure TLCLCommonCallback.Draw(ControlContext: NSGraphicsContext;<br />
const bounds, dirty:NSRect);<br />
var<br />
struct : TPaintStruct;<br />
begin<br />
if not Assigned(Context) then Context:=TCocoaContext.Create;<br />
<br />
Context.ctx:=ControlContext;<br />
if Context.InitDraw(Round(bounds.size.width), Round(bounds.size.height)) then<br />
begin<br />
FillChar(struct, SizeOf(TPaintStruct), 0);<br />
struct.hdc := HDC(Context);<br />
{$IFDEF VerboseWinAPI}<br />
DebugLn(Format('[TLCLCommonCallback.Draw] OnPaint event started context: %x', [HDC(context)]));<br />
{$ENDIF}<br />
LCLSendPaintMsg(Target, HDC(Context), @struct);<br />
{$IFDEF VerboseWinAPI}<br />
DebugLn('[TLCLCommonCallback.Draw] OnPaint event ended');<br />
{$ENDIF}<br />
end;<br />
end;<br />
</syntaxhighlight><br />
<br />
And a list of WinAPI routines which were called when running this event:<br />
<br />
<pre><br />
[TCocoaWidgetSet.GetDC] hWnd: 0 Result: 12400C0<br />
[TLCLCommonCallback.Draw] OnPaint event started context: 1240340<br />
TCocoaWidgetSet.CreatePenIndirect<br />
TCocoaWidgetSet.SelectObject DC: 1240340 GDIObj: 10EC460<br />
TCocoaWidgetSet.SelectObject Result: 0<br />
TCocoaWidgetSet.SelectObject DC: 1240340 GDIObj: 10EBF00<br />
TCocoaWidgetSet.SelectObject Result: 0<br />
[TCocoaWidgetSet.Rectangle] DC: 1240340 X1: 100 Y1: 100 X2: 200 Y2: 200<br />
TCocoaWidgetSet.SelectObject DC: 1240340 GDIObj: 10EC4A0<br />
TCocoaWidgetSet.SelectObject Result: 0<br />
[TCocoaWidgetSet.GetTextExtentPoint] DC: 1240340 Str: Some text Count: 9<br />
[TCocoaWidgetSet.GetTextExtentPoint] Size: 65,17<br />
[TLCLCommonCallback.Draw] OnPaint event ended<br />
</pre><br />
<br />
=== Implementing TLabel ===<br />
<br />
Implementing TLabel is particularly hard, despite it being such a basic component, because it requires that almost all painting be implemented. TLabel is not a windowed control, instead it depends on paint messages to be drawn directly into the form canvas.<br />
<br />
Before trying to get TLabel working it is recomended to test if drawing functions such as Rectangle work inside a form's OnPaint event.<br />
<br />
Several WinAPI methods need to be implemented, particularly:<br />
<br />
'''Device Context Methods'''<br />
<br />
BeginPaint, GetDC, EndPaint, ReleaseDC, CreateCompatibleDC<br />
<br />
see [[Device Contexts and GDI objects in the LCL interfaces]]<br />
<br />
'''GDI Objects Methods'''<br />
<br />
SelectObject, DeleteObject, CreateFontIndirect, CreateFontIndirectEx<br />
<br />
'''Miscelaneous functions'''<br />
<br />
InvalidateRect, GetClientBounds, SetWindowOrgEx<br />
<br />
'''Text drawing Methods'''<br />
<br />
DrawText. Instead of implementing DrawText one can also use the default TWidgetSet.DrawText, like the Carbon and Cocoa widgetsets do. But in this case it is necessary that one implements at least GetTextMetrics, GetTextExtentPoint and ExtTextOut. Without GetTextMetrics a form with a label will crash because the autosize will not be able to calculate the appropriate size for the label.<br />
<br />
'''Region functions to determine if the control is behind another'''<br />
<br />
CombineRgn, CreateRectRgn, GetClipRGN, RectVisible<br />
<br />
<br />
Below is the order in which paint procedures are called on a form with only one TLabel, to better understand the painting sequence:<br />
<br />
1 - GetDC is called once on software startup with hWnd = 0<br />
<br />
2 - The form is shown<br />
<br />
3 - GetDC is called again (this wouldn't happen without the label). A<br />
few font related functions are called, as well as DrawText with<br />
CalcRect set to True to calculate the size of the label.<br />
<br />
4 - InvalidateRect is called on the form canvas<br />
<br />
5 - Control goes back to the operating system until a paint message comes from the widgetset<br />
<br />
6 - BeginPaint is called, and at this point code on OnPaint event of the form will be executed<br />
<br />
7 - DrawText is called again with CalcRect set to false<br />
<br />
8 - The Painting ends.<br />
<br />
=== Implementing visibility for forms and controls and window state===<br />
<br />
The code that controls visibility is split between visibility for forms, and for controls<br />
<br />
'''Visibility for forms and window state'''<br />
<br />
This part also controls the state of the window (minimized, maximized or normal). It is implemented as a copy of the Windows API function ShowWindow, so you must implemente the TMyWidgetset.ShowWindow on the file mywinapi.inc Don´t forget to also add a header to the file mywinapih.inc<br />
<br />
Below is code that implements this function on the Qt widgetset. It should be very easy to understand, copy and implement on your own widgetset. You can also take a look how Gtk implements this. On Windows, the Windows API is called directly, of course, so there is no code to look at.<br />
<br />
<syntaxhighlight>{------------------------------------------------------------------------------<br />
function ShowWindow(hWnd: HWND; nCmdShow: Integer): Boolean;<br />
<br />
nCmdShow:<br />
SW_SHOWNORMAL, SW_MINIMIZE, SW_SHOWMAXIMIZED<br />
------------------------------------------------------------------------------}<br />
function TQtWidgetSet.ShowWindow(hWnd: HWND; nCmdShow: Integer): Boolean;<br />
var<br />
Widget: QWidgetH;<br />
begin<br />
{$ifdef VerboseQtWinAPI}<br />
WriteLn('WinAPI ShowWindow');<br />
{$endif}<br />
<br />
Result := False;<br />
<br />
Widget := QWidgetH(hWnd);<br />
<br />
// if Widget = nil then RaiseException('TQtWidgetSet.ShowWindow hWnd is nil');<br />
<br />
case nCmdShow of<br />
<br />
SW_SHOW: QWidget_setVisible(Widget, True);<br />
<br />
SW_SHOWNORMAL: QWidget_showNormal(Widget);<br />
<br />
SW_MINIMIZE: QWidget_setWindowState(Widget, QtWindowMinimized);<br />
<br />
SW_SHOWMINIMIZED: QWidget_showMinimized(Widget);<br />
<br />
SW_SHOWMAXIMIZED: QWidget_showMaximized(Widget);<br />
<br />
SW_HIDE: QWidget_setVisible(Widget, False);<br />
<br />
end;<br />
<br />
Result := True;<br />
end;</syntaxhighlight><br />
<br />
'''Visibility for controls'''<br />
<br />
For controls inside a form you need to implement TMyWSWinControl.ShowHide class function that resides on the TMyWSWinControl class on the file mywscontrols.pp<br />
<br />
Remember that most controls are descendent from TWinControl, so implementing this function there will guarantee that the Visible property is implemented for all standard controls that have it. Below is a sample code for Qt widgetset.<br />
<br />
<syntaxhighlight>{------------------------------------------------------------------------------<br />
Method: TQtWSWinControl.ShowHide<br />
Params: AWinControl - the calling object<br />
<br />
Returns: Nothing<br />
<br />
Shows or hides a widget.<br />
------------------------------------------------------------------------------}<br />
class procedure TQtWSWinControl.ShowHide(const AWinControl: TWinControl);<br />
begin<br />
if AWinControl = nil then exit;<br />
<br />
if not AWinControl.HandleAllocated then exit;<br />
<br />
if AWinControl.HandleObjectShouldBeVisible then<br />
QWidget_setVisible(TQtWidget(AWinControl.Handle).Widget, True)<br />
else QWidget_setVisible(TQtWidget(AWinControl.Handle).Widget, False);<br />
end;</syntaxhighlight><br />
<br />
=== Implementing TStrings based Components===<br />
Some components use a TStrings to store the information they display, such as: TCustomMemo, TCustomListBox and TCustomComboBox.<br />
<br />
To implement those it is not enougth to only implement their functions on the TQtCustomMemo class for example. One of the functions to implement will be called GetStrings, which looks like this:<br />
<br />
<syntaxhighlight>class function TQtWSCustomListBox.GetStrings(const ACustomListBox: TCustomListBox): TStrings;<br />
var<br />
ListWidgetH: QListWidgetH;<br />
begin<br />
ListWidgetH := QListWidgetH((TQtWidget(ACustomListBox.Handle).Widget));<br />
Result := TQtListStrings.Create(ListWidgetH, ACustomListBox);<br />
end;</syntaxhighlight><br />
<br />
This function must return a TStrings descendent designed to detect when strings are added to or removed from the string list and to send this information to the widgetset to update the control. For example, the following declaration shows what TQtListStrings looks like:<br />
<br />
<syntaxhighlight> TQtListStrings = class(TStrings)<br />
private<br />
FListChanged: Boolean; // StringList and QtListWidget out of sync<br />
FStringList: TStringList; // Holds the items to show<br />
FQtListWidget: QListWidgetH; // Qt Widget<br />
FOwner: TWinControl; // Lazarus Control Owning ListStrings<br />
FUpdating: Boolean; // We're changing Qt Widget<br />
procedure InternalUpdate;<br />
procedure ExternalUpdate(var Astr: TStringList; Clear: Boolean = True);<br />
procedure IsChanged; // OnChange triggered by program action<br />
protected<br />
function GetTextStr: string; override;<br />
function GetCount: integer; override;<br />
function Get(Index : Integer) : string; override;<br />
//procedure SetSorted(Val : boolean); virtual;<br />
public<br />
constructor Create(ListWidgetH : QListWidgetH; TheOwner: TWinControl);<br />
destructor Destroy; override;<br />
procedure Assign(Source : TPersistent); override;<br />
procedure Clear; override;<br />
procedure Delete(Index : integer); override;<br />
procedure Insert(Index : integer; const S: string); override;<br />
procedure SetText(TheText: PChar); override;<br />
//procedure Sort; virtual;<br />
public<br />
//property Sorted: boolean read FSorted write SetSorted;<br />
property Owner: TWinControl read FOwner;<br />
function ListChangedHandler(Sender: QObjectH; Event: QEventH): Boolean; cdecl;<br />
end;</syntaxhighlight><br />
<br />
You can see its implementation in the qtobjects.pas unit of the qt interface<br />
<br />
===Implementing Menus===<br />
<br />
Menus are available on the LCL to create main menus or popup menus. A TMenu is the owner of a larger menu structure with many items. Items can have subitems, and don't need extra TMenus.<br />
<br />
Also remember that on LCL the handle is only created when needed and at that time all properties of the controls are already initialized. This helps a lot on widgetsets where depending on the properties of a menu item it can be of one class or another, like Qt.<br />
<br />
The following things need to be implemented in order for the menus to work:<br />
<br />
1) All methods on the QtWSMenus unit, which will implement menu creation and modification<br />
<br />
2) function TWinCEWidgetSet.SetMenu(AWindowHandle: HWND; AMenuHandle: HMENU): Boolean; from the wincewinapi.inc file, which will implement support for a main menu associated with a window.<br />
<br />
====Menu Creation Order====<br />
<br />
<br />
One important thing to understand when implementing menus, is in which order they are created. For example, we want to create the following menu structure:<br />
<br />
[[Image:Menu_creation_order.png]]<br />
<br />
And when our application is executed, there will be a 'Creating MenuItem' message with the caption of the menu each time TQtWSMenuItem.CreateHandle is called, and a 'Creating Menu' message with the name of the menu (TMenu descendents don't have a caption), each time TQtWSMenu.CreateHandle is called.<br />
<br />
Here is the resulting output of such software:<br />
<br />
<pre><br />
Creating Menu. Name: MainMenu1<br />
Creating MenuItem: Item1 Parent=Menu.Items : TMenuItem<br />
Creating MenuItem: SubItem11 Parent=Item1 : TMenuItem<br />
Creating MenuItem: SubItem12 Parent=Item1 : TMenuItem<br />
Creating MenuItem: SubItem13 Parent=Item1 : TMenuItem<br />
Creating MenuItem: SubItem14 Parent=Item1 : TMenuItem<br />
Creating MenuItem: SubSubItem141 Parent=SubItem14 : TMenuItem<br />
Creating MenuItem: SubSubItem142 Parent=SubItem14 : TMenuItem<br />
Creating MenuItem: SubSubItem143 Parent=SubItem14 : TMenuItem<br />
Creating MenuItem: SubSubItem144 Parent=SubItem14 : TMenuItem<br />
Creating MenuItem: Item2 Parent=Menu.Items : TMenuItem<br />
Creating MenuItem: SubItem21 Parent=Item2 : TMenuItem<br />
Creating MenuItem: SubItem22 Parent=Item2 : TMenuItem<br />
Creating MenuItem: SubItem23 Parent=Item2 : TMenuItem<br />
Creating MenuItem: Item3 Parent=Menu.Items : TMenuItem<br />
Creating MenuItem: Item4 Parent=Menu.Items : TMenuItem<br />
</pre><br />
<br />
For all MenuItems one can use GetParentMenu to get their parent owner: Menu (TMainMenu).<br />
<br />
===Control enabling/disabling===<br />
<br />
The current way to set control enabling/disabling is by implementing the winapi EnableWindow. This API should work generically on any control. It should enable/disable mouse and keyboard input for the specified window or control, but also mark it as uneditable by the user, by making it greyed for example.<br />
<br />
<syntaxhighlight>{------------------------------------------------------------------------------<br />
Method: EnableWindow<br />
Params: HWnd - handle to window<br />
BEnable - whether to enable the window<br />
Returns: If the window was previously disabled<br />
<br />
Enables or disables mouse and keyboard input to the specified window or<br />
control.<br />
------------------------------------------------------------------------------}<br />
function TWin32WidgetSet.EnableWindow(hWnd: HWND; bEnable: Boolean): Boolean;</syntaxhighlight><br />
<br />
===Shaped Windows===<br />
<br />
Windows can be shaped based on a TBitmap or on a TRegion. The region is the visible part.<br />
<br />
To implement shaped windows based on a TBitmap, implement TWSWinControl.setShape<br />
<br />
To implement shaped windows based on a TRegion implement LCLIntf.SetWindowRgn<br />
<br />
See also: [[LCL Tips#Creating a non-rectangular window or control]]<br />
<br />
===System colors===<br />
<br />
Some color constants are actually system colors, like clBtnFace, clForm, clWindow, etc, etc.<br />
<br />
To implement support for system colors the WinAPI routine GetSysColor should be implemented:<br />
<br />
function GetSysColor(nIndex: Integer): DWORD; override;<br />
<br />
And here is a snip of the color constants which should be supported. Check LCLType for the latest values:<br />
<br />
<syntaxhighlight><br />
//==============================================<br />
// API system Color constants pbd<br />
// note these are usually shown ORed with<br />
// $80000000 as these would have interfered with<br />
// other MS color enumerations<br />
// GetSysColor and SetSysColor expects the values<br />
// below<br />
//==============================================<br />
<br />
type<br />
COLORREF = LongInt;<br />
TColorRef = COLORREF;<br />
<br />
const<br />
CLR_INVALID = TColorRef($FFFFFFFF);<br />
<br />
COLOR_SCROLLBAR = 0;<br />
COLOR_BACKGROUND = 1;<br />
COLOR_ACTIVECAPTION = 2;<br />
COLOR_INACTIVECAPTION = 3;<br />
COLOR_MENU = 4;<br />
COLOR_WINDOW = 5;<br />
COLOR_WINDOWFRAME = 6;<br />
COLOR_MENUTEXT = 7;<br />
COLOR_WINDOWTEXT = 8;<br />
COLOR_CAPTIONTEXT = 9;<br />
COLOR_ACTIVEBORDER = 10;<br />
COLOR_INACTIVEBORDER = 11;<br />
COLOR_APPWORKSPACE = 12;<br />
COLOR_HIGHLIGHT = 13;<br />
COLOR_HIGHLIGHTTEXT = 14;<br />
COLOR_BTNFACE = 15;<br />
COLOR_BTNSHADOW = 16;<br />
COLOR_GRAYTEXT = 17;<br />
COLOR_BTNTEXT = 18;<br />
COLOR_INACTIVECAPTIONTEXT = 19;<br />
COLOR_BTNHIGHLIGHT = 20;<br />
COLOR_3DDKSHADOW = 21;<br />
COLOR_3DLIGHT = 22;<br />
COLOR_INFOTEXT = 23;<br />
COLOR_INFOBK = 24;<br />
// PBD: 25 is unassigned in all the docs I can find<br />
// if someone finds what this is supposed to be then fill it in<br />
// note defaults below, and cl[ColorConst] in graphics<br />
COLOR_HOTLIGHT = 26;<br />
COLOR_GRADIENTACTIVECAPTION = 27;<br />
COLOR_GRADIENTINACTIVECAPTION = 28;<br />
COLOR_MENUHILIGHT = 29;<br />
COLOR_MENUBAR = 30;<br />
<br />
COLOR_FORM = 31;<br />
<br />
COLOR_ENDCOLORS = COLOR_FORM;<br />
<br />
COLOR_DESKTOP = COLOR_BACKGROUND;<br />
COLOR_3DFACE = COLOR_BTNFACE;<br />
COLOR_3DSHADOW = COLOR_BTNSHADOW;<br />
COLOR_3DHIGHLIGHT = COLOR_BTNHIGHLIGHT;<br />
COLOR_3DHILIGHT = COLOR_BTNHIGHLIGHT;<br />
COLOR_BTNHILIGHT = COLOR_BTNHIGHLIGHT;<br />
<br />
MAX_SYS_COLORS = COLOR_ENDCOLORS;<br />
SYS_COLOR_BASE = TColorRef($80000000);</syntaxhighlight><br />
<br />
===ShowMessage===<br />
<br />
These standard dialogs are implemented purely in the LCL in the following places:<br />
<br />
* Class TPromptDialog file lcl/include/promptdialog.inc<br />
<br />
===SpinEdit===<br />
<br />
Both TFloatSpinEdit and TSpinEdit are implemented in the class TWSFloatSpinEdit.<br />
<br />
===Clipboard===<br />
<br />
Clipboard support is implemented in lclintf by implementing Windows API routines. The routines are:<br />
<br />
<syntaxhighlight>function ClipboardFormatToMimeType(FormatID: TClipboardFormat): string; {$IFDEF IF_BASE_MEMBER}virtual;{$ENDIF}<br />
function ClipboardGetData(ClipboardType: TClipboardType;<br />
FormatID: TClipboardFormat; Stream: TStream): boolean; {$IFDEF IF_BASE_MEMBER}virtual;{$ENDIF}<br />
// ! ClipboardGetFormats: List will be created. You must free it yourself with FreeMem(List) !<br />
function ClipboardGetFormats(ClipboardType: TClipboardType;<br />
var Count: integer; var List: PClipboardFormat): boolean; {$IFDEF IF_BASE_MEMBER}virtual;{$ENDIF}<br />
function ClipboardGetOwnerShip(ClipboardType: TClipboardType;<br />
OnRequestProc: TClipboardRequestEvent; FormatCount: integer;<br />
Formats: PClipboardFormat): boolean; {$IFDEF IF_BASE_MEMBER}virtual;{$ENDIF}<br />
function ClipboardRegisterFormat(const AMimeType: string): TClipboardFormat; {$IFDEF IF_BASE_MEMBER}virtual;{$ENDIF}</syntaxhighlight><br />
<br />
Sequence of calls during program startup:<br />
<br />
<syntaxhighlight>TCocoaWidgetSet.ClipboardRegisterFormat AMimeType=image/bmp Result=51027040<br />
TCocoaWidgetSet.ClipboardRegisterFormat AMimeType=image/delphi.bitmap Result=0<br />
TCocoaWidgetSet.ClipboardRegisterFormat AMimeType=image/xpm Result=0<br />
TCocoaWidgetSet.ClipboardRegisterFormat AMimeType=image/png Result=0<br />
TCocoaWidgetSet.ClipboardRegisterFormat AMimeType=image/jpeg Result=0</syntaxhighlight><br />
<br />
Sequence of calls during "Caption := Clipboard.AsText":<br />
<br />
<syntaxhighlight>TCocoaWidgetSet.ClipboardRegisterFormat AMimeType=text/plain Result=51026976<br />
TCocoaWidgetSet.ClipboardGetData ClipboardType=clipboard FormatID: 51026976</syntaxhighlight><br />
<br />
===TSpeedButton===<br />
<br />
This control is a TGraphicControl descendent, so it has no handle and paints itself. To retain native look, it uses the function ThemeServices.DrawElement(Details.Element=teButton) to paint itself, so implement this function to have this control working. Naturally, lot's of other DC, WindowOrg, Text Drawing and Painting routines will have to be working, as explained for TLabel.<br />
<br />
===TRadioButton and TCheckButton===<br />
<br />
'''Messages:'''<br />
<br />
Basically the Widgetset must do:<br />
<br />
*Send LM_CHANGE when a radio button is unchecked/checked (LCL will take care if OnClick will be called or not)<br />
*Dont send LM_CHANGE when TWSCustomCheckBox.SetState is called (SetChecked)<br />
<br />
See also this bug report: http://bugs.freepascal.org/view.php?id=13939<br />
<br />
===FullScreen support===<br />
<br />
FullScreen is implemented as a Windows state wsFullScreen, and as such is implemented in LCLIntf.ShowWindow where the constant SW_SHOWFULLSCREEN should be handled.<br />
<br />
== An example of how the LCL interfaces work ==<br />
<br />
Below is a simple example. Suppose you have developed a trayicon component. How would you implement it in the LCL to work correctly on the various different supported platforms?<br />
<br />
You would need to generate the following files:<br />
<br />
\trayicon.pas<br />
<br />
\wstrayicon.pas<br />
<br />
\gtk\gtkwstrayicon.pas<br />
<br />
\gtk\trayintf.pas<br />
<br />
\win32\win32wstrayicon.pas<br />
<br />
\win32\trayintf.pas<br />
<br />
<br />
Providing separate wsXXX.pas and \$(LCLWidgetType)\XXXintf.pas files avoids the need for ifdefs altogether. You will need to add as a unit path $(LCLWidgetType) to the XXXintf.pas file in order initialize the correct trayintf.pas file, which in turn initializes the correct WS Tray class.<br />
<br />
Inside trayicon.pas you include wstrayicon. Derive your main class from an LCL class, and only use wstrayicon in its implementation. All LCL classes that communicate with a widgetset, must be derived from [[doc:/lcl/lclclasses/tlclcomponent.html|TLCLComponent]] declared in the [[doc:/lcl/lclclasses|LCLClasses]] unit.<br />
<br />
<syntaxhighlight>unit TrayIcon;<br />
<br />
interface<br />
<br />
type<br />
TTrayIcon = class(TLCLComponent)<br />
public<br />
procedure DoTray;<br />
end;<br />
<br />
implementation<br />
<br />
uses wstrayicon;<br />
<br />
procedure TTrayIcon.DoTray;<br />
begin<br />
// Call wstrayicon<br />
end;<br />
<br />
end.</syntaxhighlight><br />
<br />
in trayintf you use gtkwstrayicon or win32trayicon depending on which<br />
trayintf file it is.<br />
<br />
in wstrayicon you create a class like so:<br />
<br />
<syntaxhighlight>unit WSTrayIcon;<br />
<br />
uses WSLCLClasses, Controls, TrayIcon; // and other things as well<br />
<br />
TWSTrayIconClass = class of TWSTrayIcon;<br />
TWSTrayIcon = class(TWSWinControl);<br />
public<br />
class procedure EmbedTrayIcon(const ATrayIcon: TCustomTrayIcon);<br />
virtual; // these must all be virtual and class procedures!!<br />
class procedure RemoveTrayIcon(const ATrayIcon: TCustomTrayIcon); virtual;<br />
....<br />
end;<br />
...<br />
<br />
implementation<br />
<br />
procedure TWSTrayIcon.EmbedTrayIcon(const ATrayIcon: TCustomTrayIcon);<br />
begin<br />
//do nothing<br />
end;<br />
<br />
procedure TWSTrayIcon.RemoveTrayIcon(const ATrayIcon: TCustomTrayIcon);<br />
begin<br />
//do nothing<br />
end;</syntaxhighlight><br />
<br />
now in gtkwstrayicon.pas do this:<br />
<br />
<syntaxhighlight>uses WSTrayIcon, WSLCLClasses, Controls, TrayIcon, gtk, gdk;<br />
<br />
<br />
TGtkWSTrayIcon = class(TWSTrayIcon);<br />
private<br />
class function FindSystemTray(const ATrayIcon: TCustomTrayIcon):<br />
TWindow; virtual;<br />
public<br />
class procedure EmbedTrayIcon(const ATrayIcon: TCustomTrayIcon); override;<br />
class procedure RemoveTrayIcon(const ATrayIcon: TCustomTrayIcon);<br />
override;<br />
class function CreateHandle(const AWinControl: TWinControl; const<br />
AParams: TCreateParams): HWND; override;<br />
....<br />
end;<br />
...<br />
<br />
implementation<br />
<br />
procedure TGtkWSTrayIcon.CreateHandle(const AWinControl: TWinControl;<br />
const AParams: TCreateParams): HWND;<br />
var<br />
WidgetInfo: PWidgetInfo;<br />
begin<br />
<br />
Result := gtk_plug_new;<br />
WidgetInfo := CreateWidgetInfo(AWinControl, Result); // it's something<br />
like this anyway<br />
TGtkWSWincontrolClass(WidgetSetClass).SetCallbacks(AWinControl);<br />
// and more stuff<br />
end;<br />
<br />
function TGtkWSTrayIcon.FindSystemTray(const ATrayIcon:<br />
TCustomTrayIcon): TWindow;<br />
begin<br />
// do something<br />
end;<br />
<br />
<br />
procedure TGtkWSTrayIcon.EmbedTrayIcon(const ATrayIcon: TCustomTrayIcon);<br />
var<br />
SystemTray: TWindow;<br />
begin<br />
SystemTray := FindSystemTray(ATrayIcon);<br />
//do something<br />
end;<br />
<br />
procedure TGtkWSTrayIcon.RemoveTrayIcon(const ATrayIcon: TCustomTrayIcon);<br />
begin<br />
//do something<br />
end;<br />
<br />
......<br />
<br />
initialization<br />
<br />
RegisterWSComponent(TCustomTrayIcon, TGtkWSTrayIcon); //this is very<br />
important!!!<br />
<br />
end.</syntaxhighlight><br />
<br />
then finally in trayicon.pas you go as normal<br />
<br />
<syntaxhighlight>uses WSTrayIcon; //etc. you DON'T include GtkWSTrayIcon here!<br />
<br />
TCustomTrayIcon = class(TWinControl)<br />
public<br />
procedure EmbedControl;<br />
....<br />
end;<br />
<br />
...<br />
procedure TTrayIcon.EmbedControl;<br />
begin<br />
TWSTrayIconClass(WidgetSetClass).EmbedControl(Self);<br />
<br />
end;</syntaxhighlight><br />
<br />
----<br />
This document is work in progress. You can help by writing sections of this document. If you cannot find the information you are looking for in this document, please add your question to the [[Talk:LCL Internals|discussion page]]. This will help us to write documentation at a level that is neither too simple nor too complicated, and fully cover the areas that people want to know about.<br />
<br />
[[Category:LCL]]<br />
[[Category:Lazarus internals]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=fcl-json&diff=92444fcl-json2015-07-08T11:17:24Z<p>Sekelsenmat: /* Examples */</p>
<hr />
<div>fcl-json - a [[JSON]] (Javascript Object Notation) implementation <br />
<br />
== Notes ==<br />
Contains the fpjson JSON manipulation unit.<br />
<br />
Note: In FPJSON, accessing e.g. SomeJSONObject.Integers['price'] may give a SIGSEGV/Access Violation if that integer variable does not exist. This is apparently intentional, see [http://bugs.freepascal.org/view.php?id=22273]<br />
<br />
You'd have to use the .Find method (available since FPC 2.6.2) to first check if the element/variable (price in this example) exists.<br />
<br />
== Streaming ==<br />
fcl-json contains the unit "fpjsonrtti" which is used to load objects (TObject instances) from or save them to JSON format.<br />
<br />
See [[Streaming JSON]] for a short example.<br />
<br />
== Examples ==<br />
Example usage can be found in the Lazarus jsonviewer tool (located in lazarus/tools/jsonviewer).<br />
<br />
In particular, this part of the tool shows how to use json:<br />
<br />
<syntaxhighlight><br />
procedure TMainForm.OpenFile(Const AFileName : String);<br />
<br />
Var<br />
S : TFileStream;<br />
P : TJSONParser;<br />
D : TJSONData;<br />
begin<br />
S:=TFileStream.Create(AFileName,fmOpenRead);<br />
try<br />
P:=TJSONParser.Create(S);<br />
try<br />
P.Strict:=FStrict;<br />
D:=P.Parse;<br />
finally<br />
P.Free;<br />
end;<br />
finally<br />
S.Free;<br />
end;<br />
FFileName:=AFileName;<br />
SetCaption;<br />
FreeAndNil(FRoot);<br />
FRoot:=D;<br />
ShowJSONDocument;<br />
end;<br />
<br />
procedure TMainForm.ShowJSONDocument;<br />
<br />
begin<br />
With TVJSON.Items do<br />
begin<br />
BeginUpdate;<br />
try<br />
TVJSON.Items.Clear;<br />
SHowJSONData(Nil,FRoot);<br />
With TVJSON do<br />
If (Items.Count>0) and Assigned(Items[0]) then<br />
begin<br />
Items[0].Expand(False);<br />
Selected:=Items[0];<br />
end;<br />
finally<br />
EndUpdate;<br />
end;<br />
end;<br />
end;<br />
<br />
procedure TMainForm.ShowJSONData(AParent : TTreeNode; Data : TJSONData);<br />
<br />
Var<br />
N,N2 : TTreeNode;<br />
I : Integer;<br />
D : TJSONData;<br />
C : String;<br />
S : TStringList;<br />
<br />
begin<br />
N:=Nil;<br />
if Assigned(Data) then<br />
begin<br />
Case Data.JSONType of<br />
jtArray,<br />
jtObject:<br />
begin<br />
If (Data.JSONType=jtArray) then<br />
C:=SArray<br />
else<br />
C:=SObject;<br />
N:=TVJSON.Items.AddChild(AParent,Format(C,[Data.Count]));<br />
S:=TstringList.Create;<br />
try<br />
For I:=0 to Data.Count-1 do<br />
If Data.JSONtype=jtArray then<br />
S.AddObject(IntToStr(I),Data.items[i])<br />
else<br />
S.AddObject(TJSONObject(Data).Names[i],Data.items[i]);<br />
If FSortObjectMembers and (Data.JSONType=jtObject) then<br />
S.Sort;<br />
For I:=0 to S.Count-1 do<br />
begin<br />
N2:=TVJSON.Items.AddChild(N,S[i]);<br />
D:=TJSONData(S.Objects[i]);<br />
N2.ImageIndex:=ImageTypeMap[D.JSONType];<br />
N2.SelectedIndex:=ImageTypeMap[D.JSONType];<br />
ShowJSONData(N2,D);<br />
end<br />
finally<br />
S.Free;<br />
end;<br />
end;<br />
jtNull:<br />
N:=TVJSON.Items.AddChild(AParent,SNull);<br />
else<br />
N:=TVJSON.Items.AddChild(AParent,Data.AsString);<br />
end;<br />
If Assigned(N) then<br />
begin<br />
N.ImageIndex:=ImageTypeMap[Data.JSONType];<br />
N.SelectedIndex:=ImageTypeMap[Data.JSONType];<br />
N.Data:=Data;<br />
end;<br />
end;<br />
end; <br />
</syntaxhighlight><br />
<br />
Also, the [[FPC Applications/Projects Gallery#FPCTwit|fpctwit]] library makes use of JSON to send/receive data.<br />
<br />
== See also ==<br />
An article covering use of XML and JSON in FreePascal: [http://www.freepascal.org/~michael/articles/webdata/webdata.pdf PDF]<br />
<br />
[[Package List]]<br />
<br />
[[Category:Packages]]<br />
[[Category:Free Component Library]]<br />
[[Category:JSON]]<br />
[[Category:FPC]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=fcl-json&diff=92443fcl-json2015-07-08T11:17:13Z<p>Sekelsenmat: /* Examples */</p>
<hr />
<div>fcl-json - a [[JSON]] (Javascript Object Notation) implementation <br />
<br />
== Notes ==<br />
Contains the fpjson JSON manipulation unit.<br />
<br />
Note: In FPJSON, accessing e.g. SomeJSONObject.Integers['price'] may give a SIGSEGV/Access Violation if that integer variable does not exist. This is apparently intentional, see [http://bugs.freepascal.org/view.php?id=22273]<br />
<br />
You'd have to use the .Find method (available since FPC 2.6.2) to first check if the element/variable (price in this example) exists.<br />
<br />
== Streaming ==<br />
fcl-json contains the unit "fpjsonrtti" which is used to load objects (TObject instances) from or save them to JSON format.<br />
<br />
See [[Streaming JSON]] for a short example.<br />
<br />
== Examples ==<br />
Example usage can be found in the Lazarus jsonviewer tool (located in lazarus/tools/jsonviewer.<br />
<br />
In particular, this part of the tool shows how to use json:<br />
<br />
<syntaxhighlight><br />
procedure TMainForm.OpenFile(Const AFileName : String);<br />
<br />
Var<br />
S : TFileStream;<br />
P : TJSONParser;<br />
D : TJSONData;<br />
begin<br />
S:=TFileStream.Create(AFileName,fmOpenRead);<br />
try<br />
P:=TJSONParser.Create(S);<br />
try<br />
P.Strict:=FStrict;<br />
D:=P.Parse;<br />
finally<br />
P.Free;<br />
end;<br />
finally<br />
S.Free;<br />
end;<br />
FFileName:=AFileName;<br />
SetCaption;<br />
FreeAndNil(FRoot);<br />
FRoot:=D;<br />
ShowJSONDocument;<br />
end;<br />
<br />
procedure TMainForm.ShowJSONDocument;<br />
<br />
begin<br />
With TVJSON.Items do<br />
begin<br />
BeginUpdate;<br />
try<br />
TVJSON.Items.Clear;<br />
SHowJSONData(Nil,FRoot);<br />
With TVJSON do<br />
If (Items.Count>0) and Assigned(Items[0]) then<br />
begin<br />
Items[0].Expand(False);<br />
Selected:=Items[0];<br />
end;<br />
finally<br />
EndUpdate;<br />
end;<br />
end;<br />
end;<br />
<br />
procedure TMainForm.ShowJSONData(AParent : TTreeNode; Data : TJSONData);<br />
<br />
Var<br />
N,N2 : TTreeNode;<br />
I : Integer;<br />
D : TJSONData;<br />
C : String;<br />
S : TStringList;<br />
<br />
begin<br />
N:=Nil;<br />
if Assigned(Data) then<br />
begin<br />
Case Data.JSONType of<br />
jtArray,<br />
jtObject:<br />
begin<br />
If (Data.JSONType=jtArray) then<br />
C:=SArray<br />
else<br />
C:=SObject;<br />
N:=TVJSON.Items.AddChild(AParent,Format(C,[Data.Count]));<br />
S:=TstringList.Create;<br />
try<br />
For I:=0 to Data.Count-1 do<br />
If Data.JSONtype=jtArray then<br />
S.AddObject(IntToStr(I),Data.items[i])<br />
else<br />
S.AddObject(TJSONObject(Data).Names[i],Data.items[i]);<br />
If FSortObjectMembers and (Data.JSONType=jtObject) then<br />
S.Sort;<br />
For I:=0 to S.Count-1 do<br />
begin<br />
N2:=TVJSON.Items.AddChild(N,S[i]);<br />
D:=TJSONData(S.Objects[i]);<br />
N2.ImageIndex:=ImageTypeMap[D.JSONType];<br />
N2.SelectedIndex:=ImageTypeMap[D.JSONType];<br />
ShowJSONData(N2,D);<br />
end<br />
finally<br />
S.Free;<br />
end;<br />
end;<br />
jtNull:<br />
N:=TVJSON.Items.AddChild(AParent,SNull);<br />
else<br />
N:=TVJSON.Items.AddChild(AParent,Data.AsString);<br />
end;<br />
If Assigned(N) then<br />
begin<br />
N.ImageIndex:=ImageTypeMap[Data.JSONType];<br />
N.SelectedIndex:=ImageTypeMap[Data.JSONType];<br />
N.Data:=Data;<br />
end;<br />
end;<br />
end; <br />
</syntaxhighlight><br />
<br />
Also, the [[FPC Applications/Projects Gallery#FPCTwit|fpctwit]] library makes use of JSON to send/receive data.<br />
<br />
== See also ==<br />
An article covering use of XML and JSON in FreePascal: [http://www.freepascal.org/~michael/articles/webdata/webdata.pdf PDF]<br />
<br />
[[Package List]]<br />
<br />
[[Category:Packages]]<br />
[[Category:Free Component Library]]<br />
[[Category:JSON]]<br />
[[Category:FPC]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=FPC_PasCocoa&diff=87769FPC PasCocoa2015-04-04T11:34:51Z<p>Sekelsenmat: /* ObjectiveP Examples */</p>
<hr />
<div>{{Platform only|Mac OS X|Mac OS X|Mac OS X}}<br />
{{Platform only|iOS|iOS|iOS}}<br />
== Introduction ==<br />
<br />
A large and growing fraction of the Mac OS X system frameworks are written in Objective-C and only offer an Objective-C interface. This makes it unwieldy to use them directly from other programming languages. The Objective-C run time library, which is used for everything from defining classes to sending messages (calling methods), has a public procedural C interface however, which makes it possible to integrate other languages directly with Objective-C code. Two general approaches exist.<br />
<br />
The first approach is to create a ''bridge''. In this case calls to the Objective-C run time helpers are wrapped in host language constructs and helpers. The host language itself is generally not modified. A number of examples of Cocoa bridges can be found at http://www.cocoadev.com/index.pl?CocoaBridges.<br />
<br />
A second approach is to extend the host language so that it can directly interface with Objective-C code using new language constructs. A list of such language extensions can be found at http://www.cocoadev.com/index.pl?CocoaLanguages. As far as Pascal is concerned, a first proposal for Objective-Pascal was made by [http://www.pascal-central.com/cwpascal.html#Extensions%20providing%20compatibili MetroWerks in 1997]. Based on this preliminary proposal (it was never finalised nor implemented by MetroWerks) and on evolutions of the Object Pascal language since that time, we have designed our own Objective-Pascal dialect.<br />
<br />
== PasCocoa wrappers ==<br />
<br />
Before the compiler supported Objective-Pascal (as described below), the primary way for Objective-C interfacing was through ObjFPC wrapper classes. This process is described on the [[PasCocoa]] page, and falls in the ''bridge'' approach mentioned above. This approach is no longer recommended nor maintained.<br />
<br />
== Objective-C FPC Compiler ==<br />
<br />
All Objective-C support is now available in svn trunk. For instructions on how to check it out, see http://www.freepascal.org/develop.var#svn<br />
<br />
For an overview of some conceptual differences between Objective-Pascal and Object Pascal on the one hand, and between Objective-Pascal and Objective-C on the other hand, see [[FPC_PasCocoa/Differences]].<br />
<br />
== Syntax (implemented) ==<br />
<br />
=== Enabling Objective-C/Objective-Pascal ===<br />
<br />
The compiler has mode switches to enable the use of Objective-C-related constructs. To enabled Objective-C 1.0 language features, either add ''{$modeswitch objectivec1}'' to a source file, or using the ''-Mobjectivec1'' command line switch. Similarly, for Objective-C 2.0 language features use ''{$modeswitch objectivec2}'' resp. ''-Mobjectivec2'' (this automatically also enables Objective-C 1.0 features). Note that in the latter case, the resulting program may only work on Mac OS X 10.5 and later. Due to these being mode switches rather than actual syntax modes, they can be used in combination with every general syntax mode (fpc, objfpc, tp, delphi, macpas).<br />
<br />
Note that mode switches are reset when the general syntax mode is changed using, e.g., ''{$mode objfpc}''. So if you have such a statement in a unit, compiling it with ''-Mobjectivec1'' will not change anything. You will have to add ''{$modeswitch objectivec1}'' in the source code after the ''{$mode objfpc}'' in that case.<br />
<br />
Whether or not the compiler has support for Objective-C-related constructs can be checked using ''{$ifdef FPC_HAS_FEATURE_OBJECTIVEC1}''. There will be no separate switches when new Objective-C-related features are implemented. Since all this works happens in FPC trunk, simply expect that people are using the latest version available.<br />
<br />
=== Selectors ===<br />
<br />
To declare a selector for a method, use the ''objcselector()'' statement. It returns a value of the type ''objc.SEL''. It accepts one parameter, which can either be a constant string representing an Objective-C method name, or a method of an Objective-C class.<br />
<br />
<source><br />
{$modeswitch objectivec1}<br />
var<br />
a: SEL;<br />
begin<br />
a:=objcselector('initiWithWidth:andHeight:');<br />
a:=objcselector('myMethod');<br />
end.<br />
</source><br />
<br />
<br />
=== Method declaration ===<br />
<br />
In general methods are declared in the same way as in Object Pascal, with the exception that each objcclass method must also have a messaging name specified:<br />
<br />
<source><br />
NSSomeObject = objcclass(NSObject)<br />
procedure method(params: Integer); message 'method:';<br />
class procedure classmethod(para: char); override; // "message 'classmethod:'" not required, compiler will get this from the parent class<br />
end;<br />
</source><br />
<br />
Every objcclass/objcprotocol/objccategory method must be associated with an Objective-C message name, a.k.a. ''selector''. This can happen in two different ways:<br />
* an inherited method, an implemented protocol method or a method reintroduced by a category will automatically use the message name of the inherited/implemented/reintroduced method. If an explicit message name is specified, it must match the message name specified for the corresponding method.<br />
* in other cases, the ''message'' keyword must be used, followed by a constant string that contains the selector name.<br />
<br />
Instance and class methods correspond respectively to methods preceded with "-" and "+" in Objective-C. Furthermore, every method is by definition ''virtual'' in Objective-C/Pascal.<br />
<br />
'''Note:''' it's common for Objective-C to start method names with a lower case character.<br />
<br />
=== Class declaration ===<br />
<br />
====Regular declaration/definition====<br />
<br />
To declare an Objective-C class, use the keyword ''objcclass''. Objective-C classes must be declared like regular Object Pascal types in a ''type'' block:<br />
<source><br />
type<br />
ObjCClassName = objcclass [external [name 'ExternalClassName']] [(ObjCSuperClassName|ProtocolName [, ProtocolName, ProtocolName])] <br />
[private, protected, public]<br />
[variables declarations]<br />
[method declarations]<br />
end; <br />
</source><br />
<br />
* ''objcclass'': defines an Objective-C class type declaration<br />
* ''external'': many Objective-C classes are implemented in external frameworks, such as Cocoa. The ''external'' modifiers enables you to declare such external classes for use in Pascal code. It is possible to specify a different external name for the class than the identifier used in Pascal code, because the duplicate identifier rules in Objective-C are laxer than those of Pascal (e.g., there are both a class and a protocol called ''NSObject'' in Cocoa, so one of the two has to be renamed in Pascal)<br />
* ObjCSuperClassName: defines parent (or super) class for the class. If name is not specified, the class defines a new root class. See http://wiki.freepascal.org/FPC_PasCocoa/Differences#No_unique_root_class for more information.<br />
<br />
For example:<br />
<source><br />
// NSView is an external class, declared in some external framework<br />
// External classes from Apple's framework<br />
// have all fields in private sections<br />
NSView = objcclass external (NSResponder)<br />
private<br />
_subview : id; // private field<br />
public<br />
function initWithFrame(rect : NSRect): id; message 'initWithFrame:';<br />
procedure addSubview(aview: NSView); message 'addSubview:';<br />
procedure setAutoresizingMask(mask: NSUInteger); message 'setAutoresizingMask:';<br />
procedure setAutoresizesSubviews(flag: LongBool); message 'setAutoresizesSubviews:';<br />
procedure drawRect(dirtyRect: NSRect); message 'drawRect:';<br />
end;<br />
<br />
// MyView is a locally implemented class<br />
// that should be declared in the local unit<br />
// * drawRect_ method is overriden (the 'message' of the inherited method will be reused)<br />
// * customMessage_ is a newly added method<br />
// * data is a newly added field<br />
MyView = objcclass(MSView)<br />
public<br />
data : Integer;<br />
procedure customMessage(dirtyRect: NSRect); message 'customMessage';<br />
procedure drawRect(dirtyRect: NSRect); override;<br />
end;<br />
<br />
... <br />
procedure MyView.customMessage(dirtyRect: NSRect); <br />
begin<br />
end;<br />
<br />
procedure MyView.drawRect(dirtyRect: NSRect); <br />
begin<br />
end;<br />
<br />
<br />
</source><br />
<br />
====Formal declaration====<br />
In Objective-C, a class can also be declared formally using the ''[http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocDefiningClasses.html%23//apple_ref/doc/uid/TP30001163-CH12-SW1 @class SomeClass]'' syntax. This is called a ''forward declaration'' in Objective-C, but because this term has a different meaning in Pascal, we have termed this a ''formal declaration'' in Objective-Pascal.<br />
<br />
A formal declaration of an ''objcclass'' instructs the compiler to assume that somewhere, there is a complete definition of this ''objcclass'' (including fields, methods, etc), but that it is not in this unit. The practical upshot is that it is possible to use such a formal ''objcclass'' type for parameter types, field types, function result types and variable types, but that it is not possible to inherit from them, to send any messages to such instances, nor to access any fields (since the compiler does not know the full definition).<br />
<br />
The compiler will automatically resolve any uses of formal ''objcclass''es to the real declaration when this real declaration is also in scope. Hence, as soon as the unit containing the real declaration is added to the uses clause, the aforementioned restrictions no longer apply and the compiler will treat the occurrences of the formal ''objcclass'' type the same as the actual type.<br />
<br />
To declare a ''formal objcclass'', use the following syntax:<br />
<br />
<source><br />
type<br />
// note:<br />
// * no inheritance is specified<br />
// * the external name (if any) must match the external name of any real definition<br />
// to which this formal definition resolves later on<br />
MyExternalClass = objcclass external;<br />
</source><br />
<br />
Example:<br />
<source><br />
unit ContainerClass;<br />
<br />
{$mode objfpc}<br />
{$modeswitch objectivec1}<br />
<br />
interface<br />
<br />
type<br />
// Formal declaration of MyItemClass, which is defined in another unit<br />
MyItemClass = objcclass external;<br />
<br />
MyContainerClass = objcclass<br />
private<br />
item: MyItemClass;<br />
public<br />
function getItem: MyItemClass; message 'getItem';<br />
end;<br />
<br />
implementation<br />
<br />
function MyContainerClass.getItem: MyItemClass;<br />
begin<br />
// we cannot send any message to item, but<br />
// we can use it in assignments<br />
result:=item;<br />
end;<br />
<br />
end.<br />
<br />
// ======================<br />
// ======================<br />
<br />
unit ItemClass;<br />
<br />
{$mode objfpc}<br />
{$modeswitch objectivec1}<br />
<br />
interface<br />
<br />
<br />
type<br />
// the actual definition of MyItemClass<br />
MyItemClass = objcclass(NSObject)<br />
private<br />
content : longint;<br />
public<br />
function initWithContent(c: longint): MyItemClass; message 'initWithContent:';<br />
function getContent: longint; message 'getContent';<br />
end;<br />
<br />
implementation<br />
<br />
function MyItemClass.initWithContent(c: longint): MyItemClass;<br />
begin<br />
content:=c;<br />
result:=self;<br />
end;<br />
<br />
function MyItemClass.getContent: longint;<br />
begin<br />
result:=content;<br />
end;<br />
<br />
end.<br />
<br />
// ======================<br />
// ======================<br />
<br />
Program test;<br />
<br />
{$mode objfpc}<br />
{$modeswitch objectivec1}<br />
<br />
// regardless of the order of the units in the uses-clause, as soon as<br />
// ItemClass is used then the full declaration of MyItemClass is in<br />
// scope and all uses of the formal declaration are replaced by the<br />
// actual declaration<br />
uses<br />
ItemClass, ContainerClass;<br />
<br />
var<br />
c: MyContainerClass;<br />
l: longint;<br />
begin<br />
c:=MyContainerClass.alloc.init;<br />
...<br />
// even though MyContainerClass.getItem returns a "formal" MyItemClass,<br />
// the fact that the real declaration is in scope means that it can be<br />
// used as a regular MyItemClass instance<br />
l:=c.getItem.getContent;<br />
end.<br />
</source><br />
<br />
====Objective-Pascal class references====<br />
<br />
Just like in Object Pascal, it is possible to declare a class reference type for an Objective-Pascal class. In Objective-C, these are called meta-classes and are represented by the ''pobjc_class'' type. If you wish to mix code using the ''pobjc_class'' type and the Pascal syntax for class references, you have to use typecasts, as shown below.<br />
<br />
<source><br />
{$mode objfpc}<br />
{$modeswitch objectivec1}<br />
<br />
program Test;<br />
<br />
type<br />
TMyClass = objcclass (NSObject)<br />
end;<br />
TMyClassMeta = class of TMyClass; // declare the meta-class type for dynamic allocation<br />
<br />
var<br />
theClass: pobjc_class;<br />
begin<br />
theClass := TMyClass.classClass; // get the meta-class reference for TMyClass; could <br />
TMyClassMeta(theClass).alloc.init; // cast theClass as TMyClassMeta and send messages as normal<br />
end.<br />
</source><br />
<br />
=== Protocol declaration ===<br />
<br />
An Objective-C Protocol is pretty much the same as an ''interface'' in Object Pascal: it lists a number of methods to be implemented by classes that conform to the protocol. The only difference is that protocol methods can be ''optional''. Moreover, unlike in Object Pascal, a protocol can inherit from multiple other protocols:<br />
<br />
<source><br />
type<br />
ObjCProtocolName = objcprotocol [external [name 'ExternalClassName']] [(ObjCParentProtocol1[, ObjCParentProtocol2, ...])] <br />
[required, optional]<br />
[method declarations]<br />
end;<br />
</source><br />
<br />
* ''objcprotocol'': defines an Objective-C protocol type declaration<br />
* ''external'': same as with objcclass<br />
* ''ObjCParentProtocols'': the protocols this protocol inherits from (so a class conforming to this protocol, will also have to implement all methods from those other protocols)<br />
* ''required, optional'': If nothing is specified, the default is ''required''. ''optional'' methods do not have to be implemented by classes conforming to this protocol.<br />
<br />
Example:<br />
<source><br />
type<br />
MyProtocol = objccprotocol<br />
// default is required<br />
procedure aRequiredMethod; message 'aRequiredMethod';<br />
optional<br />
procedure anOptionalMethodWithPara(para: longint); message 'anOptionalMethodWithPara:';<br />
procedure anotherOptionalMethod; message 'anotherOptionalMethod';<br />
required<br />
function aSecondRequiredMethod: longint; message 'aSecondRequiredMethod';<br />
end;<br />
<br />
MyClassImplementingProtocol = objcclass(NSObject,MyProtocol)<br />
// the "message 'xxx'" modifiers can be repeated, but this is not required<br />
procedure aRequiredMethod;<br />
procedure anOptionalMethodWithPara(para: longint);<br />
function aSecondRequiredMethod: longint;<br />
end;<br />
</source><br />
<br />
Similar to ''objcclass''es, ''objcprotocol''s can be external in case they are implemented in e.g. the Cocoa framework.<br />
<br />
=== Category declaration ===<br />
<br />
An Objective-C category is similar to a ''class helper'' in Object Pascal: it allows adding methods to an existing class, without inheriting from that class. In Objective-C, this functionality goes even further: multiple categories can be in scope at the same time for a particular class, and a category can also replace existing methods in another class rather than only add new ones. Since all methods are virtual in Objective-C, this also means that this method changes for all classes that inherit from the class in which the method was replaced (unless they override it). An Objective-C category can also implement protocols.<br />
<br />
Note that a category cannot extend another category. Furthermore, if two categories add/replace a method with the same selector in the same class, it is undefined which method will actually be called at run time. This would depend on the order in which the categories are registered with the Objective-C run time.<br />
<br />
<source><br />
type<br />
ObjCCategoryName = objccategory [external [name 'ExternalCategoryName']] (ExtendedObjCClass[,ObjCProtocol1, ObjCProtocol2, ...])<br />
[method declarations]<br />
end;<br />
</source><br />
<br />
* ''objccategory'': defines an Objective-C category type declaration<br />
* ''external'': same as with objcclass. As of Objective-C 2.0, the name of a category is optional. ''Not yet implemented'': to declare an external category without a name, use an empty string.<br />
* ''method declarations'': the methods that this category adds or replaces in the extended class. These can be both class and instance methods. Note that when replacing a method in the extended class, you must mark this new method as ''reintroduce''. The reason that we do not use ''override'' here, is that the method is really replaced in the original class. This means, e.g., that if you call ''inherited'' from the new method, that you will call this method in the parent class of the extended class, and not the replaced method. The replaced method is "lost".<br />
* ''ObjCParentProtocols'': the protocols this category implements. The category will have to implement all required methods from these protocols.<br />
<br />
Example:<br />
<source><br />
type<br />
MyProtocol = objcprotocol<br />
procedure protocolmethod; message 'protocolmethod';<br />
end;<br />
<br />
MyCategory = objccategory(NSObject,MyProtocol)<br />
// method replaced in NSObject. This means that every objcclass that does not<br />
// override the hash function will now use this method instead. <br />
function hash: cuint; reintroduce;<br />
<br />
// we have to implement this method, since we declare that we implement the<br />
// MyProtocol protocol. This method is added to NSObject afterwards.<br />
procedure protocolmethod;<br />
<br />
// a random class methods added to NSObject<br />
class procedure newmethod; message 'newmethod';<br />
end;<br />
<br />
</source><br />
<br />
Similar to ''objcclass''es, ''objccategory''s can be external in case they are implemented in e.g. the Cocoa framework.<br />
<br />
=== The ''id'' type ===<br />
<br />
The ''id'' type is special in Objective-C/Pascal. It is assignment-compatible with instances of every objcclass and objcprotocol type, in two directions. This means that you can assign variables of any objcclass/objcprotocol type to a variable of the type ''id'', but also that you can assign these ''id'' variables to variables of any particular objcclass/objcprotocol type. In neither case an explicit typecast is required.<br />
<br />
Furthermore, it is possible to call any Objective-C method declared in an objcclass or objccategory that's in scope using an ''id''-typed variable. If, at run time, the objcclass instance stored in the ''id''-typed variable does not respond to the sent message, the program will terminate with a run time error.<br />
<br />
When there are multiple methods with the same Pascal identifier, the compiler will use the standard overload resolution logic to pick the most appropriate method. In this process, it will behave as if all objcclass/objccategory methods in scope have been declared as global procedures/functions with the ''overload'' specifier. If the compiler cannot determine which overloaded method to call, it will print an error. If you compile with -vh, it will print a list of all methods that could be used to implement the call when it cannot determine the appropriate overloaded method. In this case, you will have to use an explicit type cast to clarify the class type from which you wish to call a method.<br />
<br />
=== Fast enumeration ===<br />
<br />
''Fast enumeration'' is a convention that enables enumerating the elements in a Cocoa container class in a generic yet fast way. The syntax used for this feature is the ''for-in'' construct, both in Objective-C and in Objective-Pascal. This feature behaves identically in both languages. It requires the Objective-C 2.0 mode switch to be activated.<br />
<br />
Example:<br />
<source><br />
{$mode delphi}<br />
{$modeswitch objectivec2}<br />
<br />
uses<br />
CocoaAll;<br />
<br />
var<br />
arr: NSMutableArray;<br />
element: NSString;<br />
pool: NSAutoreleasePool;<br />
i: longint;<br />
begin<br />
pool:=NSAutoreleasePool.alloc.init;<br />
arr:=NSMutableArray.arrayWithObjects(<br />
NSSTR('One'),<br />
NSSTR('Two'),<br />
NSSTR('Three'),<br />
NSSTR('Four'),<br />
NSSTR('Five'),<br />
NSSTR('Six'),<br />
NSSTR('Seven'),<br />
nil);<br />
<br />
i:=0;<br />
for element in arr do<br />
begin<br />
inc(i);<br />
if i=2 then<br />
continue;<br />
if i=5 then<br />
break;<br />
if i in [2,5..10] then<br />
halt(1);<br />
NSLog(NSSTR('element: %@'),element);<br />
end;<br />
pool.release;<br />
end.<br />
</source><br />
<br />
== Syntax (proposed) ==<br />
<br />
== todo: == <br />
<br />
a) how to declare a constant NSString/CFString in Pascal (the @"somestring" from Objective-C)<br />
<br />
-- the dollar sign could work... ex. $theString<br />
<br />
== Objective Pascal Examples ==<br />
<br />
=== Creating and running application with one menu item ===<br />
<br />
Please note, that for the creation of the menu, the application must be located in the application bundle. Lazarus may create the bundle for you.<br />
<br />
<source><br />
program project1;<br />
<br />
{$mode objfpc}{$H+}<br />
{$modeswitch objectivec1}<br />
<br />
uses<br />
CocoaAll;<br />
<br />
type<br />
{ MyCallback }<br />
MyCallback = objcclass(NSObject)<br />
public<br />
procedure haltMenuEvent(sender: id); message 'haltMenuEvent:';<br />
end;<br />
<br />
var<br />
pool : NSAutoreleasePool;<br />
filemenu : NSMenu;<br />
subitem : NSMenuItem;<br />
app : NSApplication;<br />
callback : MyCallback;<br />
<br />
function NSStr(const s: AnsiString): NSString;<br />
begin<br />
if s='' then Result:=NSString.alloc.init<br />
else Result:=NSString.alloc.initWithCString(@s[1]);<br />
end;<br />
<br />
{ MyCallback }<br />
<br />
procedure MyCallback.haltMenuEvent(sender:id);<br />
begin<br />
WriteLn('HALT!');<br />
app.stop(self);<br />
end;<br />
<br />
procedure initMenus;<br />
var<br />
root : NSMenu;<br />
rootitem : NSMenuItem;<br />
begin<br />
root:=NSMenu.alloc.init;<br />
rootitem:=root.addItemWithTitle_action_keyEquivalent(NSStr(''), nil, NSStr(''));<br />
filemenu:=NSMenu.alloc.initWithTitle(NSStr('File'));<br />
rootitem.setSubmenu(filemenu);<br />
rootitem.setEnabled(true);<br />
subitem:=filemenu.addItemWithTitle_action_keyEquivalent(NSStr('Halt'), nil, NSStr(''));<br />
subitem.setEnabled(true);<br />
app.setMainMenu(root);<br />
end;<br />
<br />
procedure InitCallback;<br />
begin<br />
callback:=MyCallback.alloc;<br />
subitem.setAction(ObjCSelector(callback.haltMenuEvent));<br />
subitem.setTarget(callback);<br />
end;<br />
<br />
begin<br />
pool:=NSAutoreleasePool.alloc.init;<br />
app:=NSApplication.sharedApplication;<br />
initMenus;<br />
initCallback;<br />
app.run;<br />
pool.release;<br />
end.<br />
</source><br />
<br />
===Application with a single window and no menus===<br />
<br />
<source><br />
program simplewindow;<br />
<br />
{$mode objfpc}{$H+}<br />
{$modeswitch objectivec2}<br />
<br />
uses<br />
CocoaAll;<br />
<br />
var<br />
appName: NSString;<br />
window: NSWindow;<br />
pool: NSAutoreleasePool;<br />
begin<br />
pool := NSAutoreleasePool.new;<br />
NSApp := NSApplication.sharedApplication;<br />
NSApp.setActivationPolicy(NSApplicationActivationPolicyRegular);<br />
appName := NSProcessInfo.processInfo.processName;<br />
window := NSWindow.alloc.initWithContentRect_styleMask_backing_defer(NSMakeRect(0, 0, 200, 200),<br />
NSTitledWindowMask, NSBackingStoreBuffered, False).autorelease;<br />
window.center;<br />
window.setTitle(appName);<br />
window.makeKeyAndOrderFront(nil);<br />
NSApp.activateIgnoringOtherApps(true);<br />
NSApp.run;<br />
end.<br />
</source><br />
<br />
===Application with a simple window and menus===<br />
<br />
<source><br />
program simplewindow;<br />
<br />
{$mode objfpc}{$H+}<br />
{$modeswitch objectivec2}<br />
<br />
uses<br />
CocoaAll;<br />
<br />
var<br />
menubar: NSMenu;<br />
appMenu: NSMenu;<br />
appName: NSString;<br />
quitMenuItem: NSMenuItem;<br />
appMenuItem: NSMenuItem;<br />
quitTitle: NSString;<br />
window: NSWindow;<br />
pool: NSAutoreleasePool;<br />
begin<br />
pool := NSAutoreleasePool.new;<br />
NSApp := NSApplication.sharedApplication;<br />
NSApp.setActivationPolicy(NSApplicationActivationPolicyRegular);<br />
menubar := NSMenu.alloc.autorelease;<br />
appMenuItem := NSMenuItem.alloc.autorelease;<br />
menubar.addItem(appMenuItem);<br />
NSApp.setMainMenu(Menubar);<br />
appMenu := NSMenu.new.autorelease;<br />
appName := NSProcessInfo.processInfo.processName;<br />
quitTitle := NSSTR('Quit').stringByAppendingString(appName);<br />
quitMenuItem := NSMenuItem.alloc.initWithTitle_action_keyEquivalent(quitTitle,<br />
sel_registerName(PChar('terminate:')),<br />
NSSTR('q'));<br />
appMenu.addItem(quitMenuItem);<br />
appMenuitem.setSubmenu(appMenu);<br />
window := NSWindow.alloc.initWithContentRect_styleMask_backing_defer(NSMakeRect(0, 0, 200, 200),<br />
NSTitledWindowMask, NSBackingStoreBuffered, False).autorelease;<br />
window.center;<br />
window.setTitle(appName);<br />
window.makeKeyAndOrderFront(nil);<br />
NSApp.activateIgnoringOtherApps(true);<br />
NSApp.run;<br />
end.<br />
</source><br />
<br />
===Simple window and a non-editable text field inside it===<br />
<br />
This shows how to create and position a sub-control in a window:<br />
<br />
<source><br />
program simplewindow;<br />
<br />
{$mode objfpc}{$H+}<br />
{$modeswitch objectivec2}<br />
<br />
uses<br />
CocoaAll;<br />
<br />
var<br />
appName: NSString;<br />
window: NSWindow;<br />
pool: NSAutoreleasePool;<br />
lText: NSTextField;<br />
begin<br />
// Autorelease pool, app and window creation<br />
pool := NSAutoreleasePool.new;<br />
NSApp := NSApplication.sharedApplication;<br />
NSApp.setActivationPolicy(NSApplicationActivationPolicyRegular);<br />
appName := NSProcessInfo.processInfo.processName;<br />
window := NSWindow.alloc.initWithContentRect_styleMask_backing_defer(NSMakeRect(0, 0, 200, 200),<br />
NSTitledWindowMask or NSClosableWindowMask or NSMiniaturizableWindowMask,<br />
NSBackingStoreBuffered, False).autorelease;<br />
<br />
// text label<br />
lText := NSTextField.alloc.initWithFrame(NSMakeRect(50, 50, 200, 50)).autorelease;<br />
lText.setBezeled(False);<br />
lText.setDrawsBackground(False);<br />
lText.setEditable(False);<br />
lText.setSelectable(False);<br />
lText.setStringValue(NSSTR('NSTextField'));<br />
window.contentView.addSubview(lText);<br />
<br />
// Window showing and app running<br />
window.center;<br />
window.setTitle(appName);<br />
window.makeKeyAndOrderFront(nil);<br />
NSApp.activateIgnoringOtherApps(true);<br />
NSApp.run;<br />
end.<br />
</source><br />
<br />
===Button which handle an event===<br />
<br />
This event shows how to make a button that responds to clicking on it.<br />
<br />
<source><br />
program simplewindow;<br />
<br />
{$mode objfpc}{$H+}<br />
{$modeswitch objectivec1}<br />
<br />
uses<br />
CocoaAll;<br />
<br />
type<br />
{ TMyDelegate }<br />
TMyDelegate = objcclass(NSObject)<br />
public<br />
procedure HandleButtonClick(sender: id); message 'HandleButtonClick:';<br />
end;<br />
<br />
var<br />
appName: NSString;<br />
window: NSWindow;<br />
pool: NSAutoreleasePool;<br />
lText: NSTextField;<br />
lButton: NSButton;<br />
lDelegate: TMyDelegate;<br />
<br />
procedure TMyDelegate.HandleButtonClick(sender: id);<br />
begin<br />
lText.setStringValue(NSSTR('New text!'));<br />
end;<br />
<br />
begin<br />
// Autorelease pool, app and window creation<br />
pool := NSAutoreleasePool.new;<br />
NSApp := NSApplication.sharedApplication;<br />
NSApp.setActivationPolicy(NSApplicationActivationPolicyRegular);<br />
appName := NSProcessInfo.processInfo.processName;<br />
window := NSWindow.alloc.initWithContentRect_styleMask_backing_defer(NSMakeRect(0, 0, 200, 200),<br />
NSTitledWindowMask or NSClosableWindowMask or NSMiniaturizableWindowMask,<br />
NSBackingStoreBuffered, False).autorelease;<br />
<br />
// text label<br />
lText := NSTextField.alloc.initWithFrame(NSMakeRect(50, 50, 120, 50)).autorelease;<br />
lText.setBezeled(False);<br />
lText.setDrawsBackground(False);<br />
lText.setEditable(False);<br />
lText.setSelectable(False);<br />
lText.setStringValue(NSSTR('NSTextField'));<br />
window.contentView.addSubview(lText);<br />
<br />
// button<br />
lButton := NSButton.alloc.initWithFrame(NSMakeRect(50, 100, 120, 50)).autorelease;<br />
window.contentView.addSubview(lButton);<br />
lButton.setTitle(NSSTR('Button title!'));<br />
lButton.setButtonType(NSMomentaryLightButton);<br />
lButton.setBezelStyle(NSRoundedBezelStyle);<br />
<br />
// button event handler setting<br />
lDelegate := TMyDelegate.alloc.init;<br />
lButton.setTarget(lDelegate);<br />
lButton.setAction(ObjCSelector(lDelegate.HandleButtonClick));<br />
<br />
// Window showing and app running<br />
window.center;<br />
window.setTitle(appName);<br />
window.makeKeyAndOrderFront(nil);<br />
NSApp.activateIgnoringOtherApps(true);<br />
NSApp.run;<br />
end.<br />
</source><br />
<br />
[[Category:Objective-C]]<br />
[[Category:Objective Pascal]]<br />
[[Category:Mac OS X]]<br />
[[Category:Headers and Bindings]]<br />
[[Category:iOS]]<br />
[[Category:Cocoa]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=FPC_PasCocoa&diff=87768FPC PasCocoa2015-04-04T11:34:30Z<p>Sekelsenmat: /* Simple window and a non-editable text field inside it */</p>
<hr />
<div>{{Platform only|Mac OS X|Mac OS X|Mac OS X}}<br />
{{Platform only|iOS|iOS|iOS}}<br />
== Introduction ==<br />
<br />
A large and growing fraction of the Mac OS X system frameworks are written in Objective-C and only offer an Objective-C interface. This makes it unwieldy to use them directly from other programming languages. The Objective-C run time library, which is used for everything from defining classes to sending messages (calling methods), has a public procedural C interface however, which makes it possible to integrate other languages directly with Objective-C code. Two general approaches exist.<br />
<br />
The first approach is to create a ''bridge''. In this case calls to the Objective-C run time helpers are wrapped in host language constructs and helpers. The host language itself is generally not modified. A number of examples of Cocoa bridges can be found at http://www.cocoadev.com/index.pl?CocoaBridges.<br />
<br />
A second approach is to extend the host language so that it can directly interface with Objective-C code using new language constructs. A list of such language extensions can be found at http://www.cocoadev.com/index.pl?CocoaLanguages. As far as Pascal is concerned, a first proposal for Objective-Pascal was made by [http://www.pascal-central.com/cwpascal.html#Extensions%20providing%20compatibili MetroWerks in 1997]. Based on this preliminary proposal (it was never finalised nor implemented by MetroWerks) and on evolutions of the Object Pascal language since that time, we have designed our own Objective-Pascal dialect.<br />
<br />
== PasCocoa wrappers ==<br />
<br />
Before the compiler supported Objective-Pascal (as described below), the primary way for Objective-C interfacing was through ObjFPC wrapper classes. This process is described on the [[PasCocoa]] page, and falls in the ''bridge'' approach mentioned above. This approach is no longer recommended nor maintained.<br />
<br />
== Objective-C FPC Compiler ==<br />
<br />
All Objective-C support is now available in svn trunk. For instructions on how to check it out, see http://www.freepascal.org/develop.var#svn<br />
<br />
For an overview of some conceptual differences between Objective-Pascal and Object Pascal on the one hand, and between Objective-Pascal and Objective-C on the other hand, see [[FPC_PasCocoa/Differences]].<br />
<br />
== Syntax (implemented) ==<br />
<br />
=== Enabling Objective-C/Objective-Pascal ===<br />
<br />
The compiler has mode switches to enable the use of Objective-C-related constructs. To enabled Objective-C 1.0 language features, either add ''{$modeswitch objectivec1}'' to a source file, or using the ''-Mobjectivec1'' command line switch. Similarly, for Objective-C 2.0 language features use ''{$modeswitch objectivec2}'' resp. ''-Mobjectivec2'' (this automatically also enables Objective-C 1.0 features). Note that in the latter case, the resulting program may only work on Mac OS X 10.5 and later. Due to these being mode switches rather than actual syntax modes, they can be used in combination with every general syntax mode (fpc, objfpc, tp, delphi, macpas).<br />
<br />
Note that mode switches are reset when the general syntax mode is changed using, e.g., ''{$mode objfpc}''. So if you have such a statement in a unit, compiling it with ''-Mobjectivec1'' will not change anything. You will have to add ''{$modeswitch objectivec1}'' in the source code after the ''{$mode objfpc}'' in that case.<br />
<br />
Whether or not the compiler has support for Objective-C-related constructs can be checked using ''{$ifdef FPC_HAS_FEATURE_OBJECTIVEC1}''. There will be no separate switches when new Objective-C-related features are implemented. Since all this works happens in FPC trunk, simply expect that people are using the latest version available.<br />
<br />
=== Selectors ===<br />
<br />
To declare a selector for a method, use the ''objcselector()'' statement. It returns a value of the type ''objc.SEL''. It accepts one parameter, which can either be a constant string representing an Objective-C method name, or a method of an Objective-C class.<br />
<br />
<source><br />
{$modeswitch objectivec1}<br />
var<br />
a: SEL;<br />
begin<br />
a:=objcselector('initiWithWidth:andHeight:');<br />
a:=objcselector('myMethod');<br />
end.<br />
</source><br />
<br />
<br />
=== Method declaration ===<br />
<br />
In general methods are declared in the same way as in Object Pascal, with the exception that each objcclass method must also have a messaging name specified:<br />
<br />
<source><br />
NSSomeObject = objcclass(NSObject)<br />
procedure method(params: Integer); message 'method:';<br />
class procedure classmethod(para: char); override; // "message 'classmethod:'" not required, compiler will get this from the parent class<br />
end;<br />
</source><br />
<br />
Every objcclass/objcprotocol/objccategory method must be associated with an Objective-C message name, a.k.a. ''selector''. This can happen in two different ways:<br />
* an inherited method, an implemented protocol method or a method reintroduced by a category will automatically use the message name of the inherited/implemented/reintroduced method. If an explicit message name is specified, it must match the message name specified for the corresponding method.<br />
* in other cases, the ''message'' keyword must be used, followed by a constant string that contains the selector name.<br />
<br />
Instance and class methods correspond respectively to methods preceded with "-" and "+" in Objective-C. Furthermore, every method is by definition ''virtual'' in Objective-C/Pascal.<br />
<br />
'''Note:''' it's common for Objective-C to start method names with a lower case character.<br />
<br />
=== Class declaration ===<br />
<br />
====Regular declaration/definition====<br />
<br />
To declare an Objective-C class, use the keyword ''objcclass''. Objective-C classes must be declared like regular Object Pascal types in a ''type'' block:<br />
<source><br />
type<br />
ObjCClassName = objcclass [external [name 'ExternalClassName']] [(ObjCSuperClassName|ProtocolName [, ProtocolName, ProtocolName])] <br />
[private, protected, public]<br />
[variables declarations]<br />
[method declarations]<br />
end; <br />
</source><br />
<br />
* ''objcclass'': defines an Objective-C class type declaration<br />
* ''external'': many Objective-C classes are implemented in external frameworks, such as Cocoa. The ''external'' modifiers enables you to declare such external classes for use in Pascal code. It is possible to specify a different external name for the class than the identifier used in Pascal code, because the duplicate identifier rules in Objective-C are laxer than those of Pascal (e.g., there are both a class and a protocol called ''NSObject'' in Cocoa, so one of the two has to be renamed in Pascal)<br />
* ObjCSuperClassName: defines parent (or super) class for the class. If name is not specified, the class defines a new root class. See http://wiki.freepascal.org/FPC_PasCocoa/Differences#No_unique_root_class for more information.<br />
<br />
For example:<br />
<source><br />
// NSView is an external class, declared in some external framework<br />
// External classes from Apple's framework<br />
// have all fields in private sections<br />
NSView = objcclass external (NSResponder)<br />
private<br />
_subview : id; // private field<br />
public<br />
function initWithFrame(rect : NSRect): id; message 'initWithFrame:';<br />
procedure addSubview(aview: NSView); message 'addSubview:';<br />
procedure setAutoresizingMask(mask: NSUInteger); message 'setAutoresizingMask:';<br />
procedure setAutoresizesSubviews(flag: LongBool); message 'setAutoresizesSubviews:';<br />
procedure drawRect(dirtyRect: NSRect); message 'drawRect:';<br />
end;<br />
<br />
// MyView is a locally implemented class<br />
// that should be declared in the local unit<br />
// * drawRect_ method is overriden (the 'message' of the inherited method will be reused)<br />
// * customMessage_ is a newly added method<br />
// * data is a newly added field<br />
MyView = objcclass(MSView)<br />
public<br />
data : Integer;<br />
procedure customMessage(dirtyRect: NSRect); message 'customMessage';<br />
procedure drawRect(dirtyRect: NSRect); override;<br />
end;<br />
<br />
... <br />
procedure MyView.customMessage(dirtyRect: NSRect); <br />
begin<br />
end;<br />
<br />
procedure MyView.drawRect(dirtyRect: NSRect); <br />
begin<br />
end;<br />
<br />
<br />
</source><br />
<br />
====Formal declaration====<br />
In Objective-C, a class can also be declared formally using the ''[http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocDefiningClasses.html%23//apple_ref/doc/uid/TP30001163-CH12-SW1 @class SomeClass]'' syntax. This is called a ''forward declaration'' in Objective-C, but because this term has a different meaning in Pascal, we have termed this a ''formal declaration'' in Objective-Pascal.<br />
<br />
A formal declaration of an ''objcclass'' instructs the compiler to assume that somewhere, there is a complete definition of this ''objcclass'' (including fields, methods, etc), but that it is not in this unit. The practical upshot is that it is possible to use such a formal ''objcclass'' type for parameter types, field types, function result types and variable types, but that it is not possible to inherit from them, to send any messages to such instances, nor to access any fields (since the compiler does not know the full definition).<br />
<br />
The compiler will automatically resolve any uses of formal ''objcclass''es to the real declaration when this real declaration is also in scope. Hence, as soon as the unit containing the real declaration is added to the uses clause, the aforementioned restrictions no longer apply and the compiler will treat the occurrences of the formal ''objcclass'' type the same as the actual type.<br />
<br />
To declare a ''formal objcclass'', use the following syntax:<br />
<br />
<source><br />
type<br />
// note:<br />
// * no inheritance is specified<br />
// * the external name (if any) must match the external name of any real definition<br />
// to which this formal definition resolves later on<br />
MyExternalClass = objcclass external;<br />
</source><br />
<br />
Example:<br />
<source><br />
unit ContainerClass;<br />
<br />
{$mode objfpc}<br />
{$modeswitch objectivec1}<br />
<br />
interface<br />
<br />
type<br />
// Formal declaration of MyItemClass, which is defined in another unit<br />
MyItemClass = objcclass external;<br />
<br />
MyContainerClass = objcclass<br />
private<br />
item: MyItemClass;<br />
public<br />
function getItem: MyItemClass; message 'getItem';<br />
end;<br />
<br />
implementation<br />
<br />
function MyContainerClass.getItem: MyItemClass;<br />
begin<br />
// we cannot send any message to item, but<br />
// we can use it in assignments<br />
result:=item;<br />
end;<br />
<br />
end.<br />
<br />
// ======================<br />
// ======================<br />
<br />
unit ItemClass;<br />
<br />
{$mode objfpc}<br />
{$modeswitch objectivec1}<br />
<br />
interface<br />
<br />
<br />
type<br />
// the actual definition of MyItemClass<br />
MyItemClass = objcclass(NSObject)<br />
private<br />
content : longint;<br />
public<br />
function initWithContent(c: longint): MyItemClass; message 'initWithContent:';<br />
function getContent: longint; message 'getContent';<br />
end;<br />
<br />
implementation<br />
<br />
function MyItemClass.initWithContent(c: longint): MyItemClass;<br />
begin<br />
content:=c;<br />
result:=self;<br />
end;<br />
<br />
function MyItemClass.getContent: longint;<br />
begin<br />
result:=content;<br />
end;<br />
<br />
end.<br />
<br />
// ======================<br />
// ======================<br />
<br />
Program test;<br />
<br />
{$mode objfpc}<br />
{$modeswitch objectivec1}<br />
<br />
// regardless of the order of the units in the uses-clause, as soon as<br />
// ItemClass is used then the full declaration of MyItemClass is in<br />
// scope and all uses of the formal declaration are replaced by the<br />
// actual declaration<br />
uses<br />
ItemClass, ContainerClass;<br />
<br />
var<br />
c: MyContainerClass;<br />
l: longint;<br />
begin<br />
c:=MyContainerClass.alloc.init;<br />
...<br />
// even though MyContainerClass.getItem returns a "formal" MyItemClass,<br />
// the fact that the real declaration is in scope means that it can be<br />
// used as a regular MyItemClass instance<br />
l:=c.getItem.getContent;<br />
end.<br />
</source><br />
<br />
====Objective-Pascal class references====<br />
<br />
Just like in Object Pascal, it is possible to declare a class reference type for an Objective-Pascal class. In Objective-C, these are called meta-classes and are represented by the ''pobjc_class'' type. If you wish to mix code using the ''pobjc_class'' type and the Pascal syntax for class references, you have to use typecasts, as shown below.<br />
<br />
<source><br />
{$mode objfpc}<br />
{$modeswitch objectivec1}<br />
<br />
program Test;<br />
<br />
type<br />
TMyClass = objcclass (NSObject)<br />
end;<br />
TMyClassMeta = class of TMyClass; // declare the meta-class type for dynamic allocation<br />
<br />
var<br />
theClass: pobjc_class;<br />
begin<br />
theClass := TMyClass.classClass; // get the meta-class reference for TMyClass; could <br />
TMyClassMeta(theClass).alloc.init; // cast theClass as TMyClassMeta and send messages as normal<br />
end.<br />
</source><br />
<br />
=== Protocol declaration ===<br />
<br />
An Objective-C Protocol is pretty much the same as an ''interface'' in Object Pascal: it lists a number of methods to be implemented by classes that conform to the protocol. The only difference is that protocol methods can be ''optional''. Moreover, unlike in Object Pascal, a protocol can inherit from multiple other protocols:<br />
<br />
<source><br />
type<br />
ObjCProtocolName = objcprotocol [external [name 'ExternalClassName']] [(ObjCParentProtocol1[, ObjCParentProtocol2, ...])] <br />
[required, optional]<br />
[method declarations]<br />
end;<br />
</source><br />
<br />
* ''objcprotocol'': defines an Objective-C protocol type declaration<br />
* ''external'': same as with objcclass<br />
* ''ObjCParentProtocols'': the protocols this protocol inherits from (so a class conforming to this protocol, will also have to implement all methods from those other protocols)<br />
* ''required, optional'': If nothing is specified, the default is ''required''. ''optional'' methods do not have to be implemented by classes conforming to this protocol.<br />
<br />
Example:<br />
<source><br />
type<br />
MyProtocol = objccprotocol<br />
// default is required<br />
procedure aRequiredMethod; message 'aRequiredMethod';<br />
optional<br />
procedure anOptionalMethodWithPara(para: longint); message 'anOptionalMethodWithPara:';<br />
procedure anotherOptionalMethod; message 'anotherOptionalMethod';<br />
required<br />
function aSecondRequiredMethod: longint; message 'aSecondRequiredMethod';<br />
end;<br />
<br />
MyClassImplementingProtocol = objcclass(NSObject,MyProtocol)<br />
// the "message 'xxx'" modifiers can be repeated, but this is not required<br />
procedure aRequiredMethod;<br />
procedure anOptionalMethodWithPara(para: longint);<br />
function aSecondRequiredMethod: longint;<br />
end;<br />
</source><br />
<br />
Similar to ''objcclass''es, ''objcprotocol''s can be external in case they are implemented in e.g. the Cocoa framework.<br />
<br />
=== Category declaration ===<br />
<br />
An Objective-C category is similar to a ''class helper'' in Object Pascal: it allows adding methods to an existing class, without inheriting from that class. In Objective-C, this functionality goes even further: multiple categories can be in scope at the same time for a particular class, and a category can also replace existing methods in another class rather than only add new ones. Since all methods are virtual in Objective-C, this also means that this method changes for all classes that inherit from the class in which the method was replaced (unless they override it). An Objective-C category can also implement protocols.<br />
<br />
Note that a category cannot extend another category. Furthermore, if two categories add/replace a method with the same selector in the same class, it is undefined which method will actually be called at run time. This would depend on the order in which the categories are registered with the Objective-C run time.<br />
<br />
<source><br />
type<br />
ObjCCategoryName = objccategory [external [name 'ExternalCategoryName']] (ExtendedObjCClass[,ObjCProtocol1, ObjCProtocol2, ...])<br />
[method declarations]<br />
end;<br />
</source><br />
<br />
* ''objccategory'': defines an Objective-C category type declaration<br />
* ''external'': same as with objcclass. As of Objective-C 2.0, the name of a category is optional. ''Not yet implemented'': to declare an external category without a name, use an empty string.<br />
* ''method declarations'': the methods that this category adds or replaces in the extended class. These can be both class and instance methods. Note that when replacing a method in the extended class, you must mark this new method as ''reintroduce''. The reason that we do not use ''override'' here, is that the method is really replaced in the original class. This means, e.g., that if you call ''inherited'' from the new method, that you will call this method in the parent class of the extended class, and not the replaced method. The replaced method is "lost".<br />
* ''ObjCParentProtocols'': the protocols this category implements. The category will have to implement all required methods from these protocols.<br />
<br />
Example:<br />
<source><br />
type<br />
MyProtocol = objcprotocol<br />
procedure protocolmethod; message 'protocolmethod';<br />
end;<br />
<br />
MyCategory = objccategory(NSObject,MyProtocol)<br />
// method replaced in NSObject. This means that every objcclass that does not<br />
// override the hash function will now use this method instead. <br />
function hash: cuint; reintroduce;<br />
<br />
// we have to implement this method, since we declare that we implement the<br />
// MyProtocol protocol. This method is added to NSObject afterwards.<br />
procedure protocolmethod;<br />
<br />
// a random class methods added to NSObject<br />
class procedure newmethod; message 'newmethod';<br />
end;<br />
<br />
</source><br />
<br />
Similar to ''objcclass''es, ''objccategory''s can be external in case they are implemented in e.g. the Cocoa framework.<br />
<br />
=== The ''id'' type ===<br />
<br />
The ''id'' type is special in Objective-C/Pascal. It is assignment-compatible with instances of every objcclass and objcprotocol type, in two directions. This means that you can assign variables of any objcclass/objcprotocol type to a variable of the type ''id'', but also that you can assign these ''id'' variables to variables of any particular objcclass/objcprotocol type. In neither case an explicit typecast is required.<br />
<br />
Furthermore, it is possible to call any Objective-C method declared in an objcclass or objccategory that's in scope using an ''id''-typed variable. If, at run time, the objcclass instance stored in the ''id''-typed variable does not respond to the sent message, the program will terminate with a run time error.<br />
<br />
When there are multiple methods with the same Pascal identifier, the compiler will use the standard overload resolution logic to pick the most appropriate method. In this process, it will behave as if all objcclass/objccategory methods in scope have been declared as global procedures/functions with the ''overload'' specifier. If the compiler cannot determine which overloaded method to call, it will print an error. If you compile with -vh, it will print a list of all methods that could be used to implement the call when it cannot determine the appropriate overloaded method. In this case, you will have to use an explicit type cast to clarify the class type from which you wish to call a method.<br />
<br />
=== Fast enumeration ===<br />
<br />
''Fast enumeration'' is a convention that enables enumerating the elements in a Cocoa container class in a generic yet fast way. The syntax used for this feature is the ''for-in'' construct, both in Objective-C and in Objective-Pascal. This feature behaves identically in both languages. It requires the Objective-C 2.0 mode switch to be activated.<br />
<br />
Example:<br />
<source><br />
{$mode delphi}<br />
{$modeswitch objectivec2}<br />
<br />
uses<br />
CocoaAll;<br />
<br />
var<br />
arr: NSMutableArray;<br />
element: NSString;<br />
pool: NSAutoreleasePool;<br />
i: longint;<br />
begin<br />
pool:=NSAutoreleasePool.alloc.init;<br />
arr:=NSMutableArray.arrayWithObjects(<br />
NSSTR('One'),<br />
NSSTR('Two'),<br />
NSSTR('Three'),<br />
NSSTR('Four'),<br />
NSSTR('Five'),<br />
NSSTR('Six'),<br />
NSSTR('Seven'),<br />
nil);<br />
<br />
i:=0;<br />
for element in arr do<br />
begin<br />
inc(i);<br />
if i=2 then<br />
continue;<br />
if i=5 then<br />
break;<br />
if i in [2,5..10] then<br />
halt(1);<br />
NSLog(NSSTR('element: %@'),element);<br />
end;<br />
pool.release;<br />
end.<br />
</source><br />
<br />
== Syntax (proposed) ==<br />
<br />
== todo: == <br />
<br />
a) how to declare a constant NSString/CFString in Pascal (the @"somestring" from Objective-C)<br />
<br />
-- the dollar sign could work... ex. $theString<br />
<br />
== ObjectiveP Examples ==<br />
<br />
=== Creating and running application with one menu item ===<br />
<br />
Please note, that for the creation of the menu, the application must be located in the application bundle. Lazarus may create the bundle for you.<br />
<br />
<source><br />
program project1;<br />
<br />
{$mode objfpc}{$H+}<br />
{$modeswitch objectivec1}<br />
<br />
uses<br />
CocoaAll;<br />
<br />
type<br />
{ MyCallback }<br />
MyCallback = objcclass(NSObject)<br />
public<br />
procedure haltMenuEvent(sender: id); message 'haltMenuEvent:';<br />
end;<br />
<br />
var<br />
pool : NSAutoreleasePool;<br />
filemenu : NSMenu;<br />
subitem : NSMenuItem;<br />
app : NSApplication;<br />
callback : MyCallback;<br />
<br />
function NSStr(const s: AnsiString): NSString;<br />
begin<br />
if s='' then Result:=NSString.alloc.init<br />
else Result:=NSString.alloc.initWithCString(@s[1]);<br />
end;<br />
<br />
{ MyCallback }<br />
<br />
procedure MyCallback.haltMenuEvent(sender:id);<br />
begin<br />
WriteLn('HALT!');<br />
app.stop(self);<br />
end;<br />
<br />
procedure initMenus;<br />
var<br />
root : NSMenu;<br />
rootitem : NSMenuItem;<br />
begin<br />
root:=NSMenu.alloc.init;<br />
rootitem:=root.addItemWithTitle_action_keyEquivalent(NSStr(''), nil, NSStr(''));<br />
filemenu:=NSMenu.alloc.initWithTitle(NSStr('File'));<br />
rootitem.setSubmenu(filemenu);<br />
rootitem.setEnabled(true);<br />
subitem:=filemenu.addItemWithTitle_action_keyEquivalent(NSStr('Halt'), nil, NSStr(''));<br />
subitem.setEnabled(true);<br />
app.setMainMenu(root);<br />
end;<br />
<br />
procedure InitCallback;<br />
begin<br />
callback:=MyCallback.alloc;<br />
subitem.setAction(ObjCSelector(callback.haltMenuEvent));<br />
subitem.setTarget(callback);<br />
end;<br />
<br />
begin<br />
pool:=NSAutoreleasePool.alloc.init;<br />
app:=NSApplication.sharedApplication;<br />
initMenus;<br />
initCallback;<br />
app.run;<br />
pool.release;<br />
end.<br />
</source><br />
<br />
===Application with a single window and no menus===<br />
<br />
<source><br />
program simplewindow;<br />
<br />
{$mode objfpc}{$H+}<br />
{$modeswitch objectivec2}<br />
<br />
uses<br />
CocoaAll;<br />
<br />
var<br />
appName: NSString;<br />
window: NSWindow;<br />
pool: NSAutoreleasePool;<br />
begin<br />
pool := NSAutoreleasePool.new;<br />
NSApp := NSApplication.sharedApplication;<br />
NSApp.setActivationPolicy(NSApplicationActivationPolicyRegular);<br />
appName := NSProcessInfo.processInfo.processName;<br />
window := NSWindow.alloc.initWithContentRect_styleMask_backing_defer(NSMakeRect(0, 0, 200, 200),<br />
NSTitledWindowMask, NSBackingStoreBuffered, False).autorelease;<br />
window.center;<br />
window.setTitle(appName);<br />
window.makeKeyAndOrderFront(nil);<br />
NSApp.activateIgnoringOtherApps(true);<br />
NSApp.run;<br />
end.<br />
</source><br />
<br />
===Application with a simple window and menus===<br />
<br />
<source><br />
program simplewindow;<br />
<br />
{$mode objfpc}{$H+}<br />
{$modeswitch objectivec2}<br />
<br />
uses<br />
CocoaAll;<br />
<br />
var<br />
menubar: NSMenu;<br />
appMenu: NSMenu;<br />
appName: NSString;<br />
quitMenuItem: NSMenuItem;<br />
appMenuItem: NSMenuItem;<br />
quitTitle: NSString;<br />
window: NSWindow;<br />
pool: NSAutoreleasePool;<br />
begin<br />
pool := NSAutoreleasePool.new;<br />
NSApp := NSApplication.sharedApplication;<br />
NSApp.setActivationPolicy(NSApplicationActivationPolicyRegular);<br />
menubar := NSMenu.alloc.autorelease;<br />
appMenuItem := NSMenuItem.alloc.autorelease;<br />
menubar.addItem(appMenuItem);<br />
NSApp.setMainMenu(Menubar);<br />
appMenu := NSMenu.new.autorelease;<br />
appName := NSProcessInfo.processInfo.processName;<br />
quitTitle := NSSTR('Quit').stringByAppendingString(appName);<br />
quitMenuItem := NSMenuItem.alloc.initWithTitle_action_keyEquivalent(quitTitle,<br />
sel_registerName(PChar('terminate:')),<br />
NSSTR('q'));<br />
appMenu.addItem(quitMenuItem);<br />
appMenuitem.setSubmenu(appMenu);<br />
window := NSWindow.alloc.initWithContentRect_styleMask_backing_defer(NSMakeRect(0, 0, 200, 200),<br />
NSTitledWindowMask, NSBackingStoreBuffered, False).autorelease;<br />
window.center;<br />
window.setTitle(appName);<br />
window.makeKeyAndOrderFront(nil);<br />
NSApp.activateIgnoringOtherApps(true);<br />
NSApp.run;<br />
end.<br />
</source><br />
<br />
===Simple window and a non-editable text field inside it===<br />
<br />
This shows how to create and position a sub-control in a window:<br />
<br />
<source><br />
program simplewindow;<br />
<br />
{$mode objfpc}{$H+}<br />
{$modeswitch objectivec2}<br />
<br />
uses<br />
CocoaAll;<br />
<br />
var<br />
appName: NSString;<br />
window: NSWindow;<br />
pool: NSAutoreleasePool;<br />
lText: NSTextField;<br />
begin<br />
// Autorelease pool, app and window creation<br />
pool := NSAutoreleasePool.new;<br />
NSApp := NSApplication.sharedApplication;<br />
NSApp.setActivationPolicy(NSApplicationActivationPolicyRegular);<br />
appName := NSProcessInfo.processInfo.processName;<br />
window := NSWindow.alloc.initWithContentRect_styleMask_backing_defer(NSMakeRect(0, 0, 200, 200),<br />
NSTitledWindowMask or NSClosableWindowMask or NSMiniaturizableWindowMask,<br />
NSBackingStoreBuffered, False).autorelease;<br />
<br />
// text label<br />
lText := NSTextField.alloc.initWithFrame(NSMakeRect(50, 50, 200, 50)).autorelease;<br />
lText.setBezeled(False);<br />
lText.setDrawsBackground(False);<br />
lText.setEditable(False);<br />
lText.setSelectable(False);<br />
lText.setStringValue(NSSTR('NSTextField'));<br />
window.contentView.addSubview(lText);<br />
<br />
// Window showing and app running<br />
window.center;<br />
window.setTitle(appName);<br />
window.makeKeyAndOrderFront(nil);<br />
NSApp.activateIgnoringOtherApps(true);<br />
NSApp.run;<br />
end.<br />
</source><br />
<br />
===Button which handle an event===<br />
<br />
This event shows how to make a button that responds to clicking on it.<br />
<br />
<source><br />
program simplewindow;<br />
<br />
{$mode objfpc}{$H+}<br />
{$modeswitch objectivec1}<br />
<br />
uses<br />
CocoaAll;<br />
<br />
type<br />
{ TMyDelegate }<br />
TMyDelegate = objcclass(NSObject)<br />
public<br />
procedure HandleButtonClick(sender: id); message 'HandleButtonClick:';<br />
end;<br />
<br />
var<br />
appName: NSString;<br />
window: NSWindow;<br />
pool: NSAutoreleasePool;<br />
lText: NSTextField;<br />
lButton: NSButton;<br />
lDelegate: TMyDelegate;<br />
<br />
procedure TMyDelegate.HandleButtonClick(sender: id);<br />
begin<br />
lText.setStringValue(NSSTR('New text!'));<br />
end;<br />
<br />
begin<br />
// Autorelease pool, app and window creation<br />
pool := NSAutoreleasePool.new;<br />
NSApp := NSApplication.sharedApplication;<br />
NSApp.setActivationPolicy(NSApplicationActivationPolicyRegular);<br />
appName := NSProcessInfo.processInfo.processName;<br />
window := NSWindow.alloc.initWithContentRect_styleMask_backing_defer(NSMakeRect(0, 0, 200, 200),<br />
NSTitledWindowMask or NSClosableWindowMask or NSMiniaturizableWindowMask,<br />
NSBackingStoreBuffered, False).autorelease;<br />
<br />
// text label<br />
lText := NSTextField.alloc.initWithFrame(NSMakeRect(50, 50, 120, 50)).autorelease;<br />
lText.setBezeled(False);<br />
lText.setDrawsBackground(False);<br />
lText.setEditable(False);<br />
lText.setSelectable(False);<br />
lText.setStringValue(NSSTR('NSTextField'));<br />
window.contentView.addSubview(lText);<br />
<br />
// button<br />
lButton := NSButton.alloc.initWithFrame(NSMakeRect(50, 100, 120, 50)).autorelease;<br />
window.contentView.addSubview(lButton);<br />
lButton.setTitle(NSSTR('Button title!'));<br />
lButton.setButtonType(NSMomentaryLightButton);<br />
lButton.setBezelStyle(NSRoundedBezelStyle);<br />
<br />
// button event handler setting<br />
lDelegate := TMyDelegate.alloc.init;<br />
lButton.setTarget(lDelegate);<br />
lButton.setAction(ObjCSelector(lDelegate.HandleButtonClick));<br />
<br />
// Window showing and app running<br />
window.center;<br />
window.setTitle(appName);<br />
window.makeKeyAndOrderFront(nil);<br />
NSApp.activateIgnoringOtherApps(true);<br />
NSApp.run;<br />
end.<br />
</source><br />
<br />
[[Category:Objective-C]]<br />
[[Category:Objective Pascal]]<br />
[[Category:Mac OS X]]<br />
[[Category:Headers and Bindings]]<br />
[[Category:iOS]]<br />
[[Category:Cocoa]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=FPC_PasCocoa&diff=87767FPC PasCocoa2015-04-04T11:23:30Z<p>Sekelsenmat: /* Application with a simple window and menus */</p>
<hr />
<div>{{Platform only|Mac OS X|Mac OS X|Mac OS X}}<br />
{{Platform only|iOS|iOS|iOS}}<br />
== Introduction ==<br />
<br />
A large and growing fraction of the Mac OS X system frameworks are written in Objective-C and only offer an Objective-C interface. This makes it unwieldy to use them directly from other programming languages. The Objective-C run time library, which is used for everything from defining classes to sending messages (calling methods), has a public procedural C interface however, which makes it possible to integrate other languages directly with Objective-C code. Two general approaches exist.<br />
<br />
The first approach is to create a ''bridge''. In this case calls to the Objective-C run time helpers are wrapped in host language constructs and helpers. The host language itself is generally not modified. A number of examples of Cocoa bridges can be found at http://www.cocoadev.com/index.pl?CocoaBridges.<br />
<br />
A second approach is to extend the host language so that it can directly interface with Objective-C code using new language constructs. A list of such language extensions can be found at http://www.cocoadev.com/index.pl?CocoaLanguages. As far as Pascal is concerned, a first proposal for Objective-Pascal was made by [http://www.pascal-central.com/cwpascal.html#Extensions%20providing%20compatibili MetroWerks in 1997]. Based on this preliminary proposal (it was never finalised nor implemented by MetroWerks) and on evolutions of the Object Pascal language since that time, we have designed our own Objective-Pascal dialect.<br />
<br />
== PasCocoa wrappers ==<br />
<br />
Before the compiler supported Objective-Pascal (as described below), the primary way for Objective-C interfacing was through ObjFPC wrapper classes. This process is described on the [[PasCocoa]] page, and falls in the ''bridge'' approach mentioned above. This approach is no longer recommended nor maintained.<br />
<br />
== Objective-C FPC Compiler ==<br />
<br />
All Objective-C support is now available in svn trunk. For instructions on how to check it out, see http://www.freepascal.org/develop.var#svn<br />
<br />
For an overview of some conceptual differences between Objective-Pascal and Object Pascal on the one hand, and between Objective-Pascal and Objective-C on the other hand, see [[FPC_PasCocoa/Differences]].<br />
<br />
== Syntax (implemented) ==<br />
<br />
=== Enabling Objective-C/Objective-Pascal ===<br />
<br />
The compiler has mode switches to enable the use of Objective-C-related constructs. To enabled Objective-C 1.0 language features, either add ''{$modeswitch objectivec1}'' to a source file, or using the ''-Mobjectivec1'' command line switch. Similarly, for Objective-C 2.0 language features use ''{$modeswitch objectivec2}'' resp. ''-Mobjectivec2'' (this automatically also enables Objective-C 1.0 features). Note that in the latter case, the resulting program may only work on Mac OS X 10.5 and later. Due to these being mode switches rather than actual syntax modes, they can be used in combination with every general syntax mode (fpc, objfpc, tp, delphi, macpas).<br />
<br />
Note that mode switches are reset when the general syntax mode is changed using, e.g., ''{$mode objfpc}''. So if you have such a statement in a unit, compiling it with ''-Mobjectivec1'' will not change anything. You will have to add ''{$modeswitch objectivec1}'' in the source code after the ''{$mode objfpc}'' in that case.<br />
<br />
Whether or not the compiler has support for Objective-C-related constructs can be checked using ''{$ifdef FPC_HAS_FEATURE_OBJECTIVEC1}''. There will be no separate switches when new Objective-C-related features are implemented. Since all this works happens in FPC trunk, simply expect that people are using the latest version available.<br />
<br />
=== Selectors ===<br />
<br />
To declare a selector for a method, use the ''objcselector()'' statement. It returns a value of the type ''objc.SEL''. It accepts one parameter, which can either be a constant string representing an Objective-C method name, or a method of an Objective-C class.<br />
<br />
<source><br />
{$modeswitch objectivec1}<br />
var<br />
a: SEL;<br />
begin<br />
a:=objcselector('initiWithWidth:andHeight:');<br />
a:=objcselector('myMethod');<br />
end.<br />
</source><br />
<br />
<br />
=== Method declaration ===<br />
<br />
In general methods are declared in the same way as in Object Pascal, with the exception that each objcclass method must also have a messaging name specified:<br />
<br />
<source><br />
NSSomeObject = objcclass(NSObject)<br />
procedure method(params: Integer); message 'method:';<br />
class procedure classmethod(para: char); override; // "message 'classmethod:'" not required, compiler will get this from the parent class<br />
end;<br />
</source><br />
<br />
Every objcclass/objcprotocol/objccategory method must be associated with an Objective-C message name, a.k.a. ''selector''. This can happen in two different ways:<br />
* an inherited method, an implemented protocol method or a method reintroduced by a category will automatically use the message name of the inherited/implemented/reintroduced method. If an explicit message name is specified, it must match the message name specified for the corresponding method.<br />
* in other cases, the ''message'' keyword must be used, followed by a constant string that contains the selector name.<br />
<br />
Instance and class methods correspond respectively to methods preceded with "-" and "+" in Objective-C. Furthermore, every method is by definition ''virtual'' in Objective-C/Pascal.<br />
<br />
'''Note:''' it's common for Objective-C to start method names with a lower case character.<br />
<br />
=== Class declaration ===<br />
<br />
====Regular declaration/definition====<br />
<br />
To declare an Objective-C class, use the keyword ''objcclass''. Objective-C classes must be declared like regular Object Pascal types in a ''type'' block:<br />
<source><br />
type<br />
ObjCClassName = objcclass [external [name 'ExternalClassName']] [(ObjCSuperClassName|ProtocolName [, ProtocolName, ProtocolName])] <br />
[private, protected, public]<br />
[variables declarations]<br />
[method declarations]<br />
end; <br />
</source><br />
<br />
* ''objcclass'': defines an Objective-C class type declaration<br />
* ''external'': many Objective-C classes are implemented in external frameworks, such as Cocoa. The ''external'' modifiers enables you to declare such external classes for use in Pascal code. It is possible to specify a different external name for the class than the identifier used in Pascal code, because the duplicate identifier rules in Objective-C are laxer than those of Pascal (e.g., there are both a class and a protocol called ''NSObject'' in Cocoa, so one of the two has to be renamed in Pascal)<br />
* ObjCSuperClassName: defines parent (or super) class for the class. If name is not specified, the class defines a new root class. See http://wiki.freepascal.org/FPC_PasCocoa/Differences#No_unique_root_class for more information.<br />
<br />
For example:<br />
<source><br />
// NSView is an external class, declared in some external framework<br />
// External classes from Apple's framework<br />
// have all fields in private sections<br />
NSView = objcclass external (NSResponder)<br />
private<br />
_subview : id; // private field<br />
public<br />
function initWithFrame(rect : NSRect): id; message 'initWithFrame:';<br />
procedure addSubview(aview: NSView); message 'addSubview:';<br />
procedure setAutoresizingMask(mask: NSUInteger); message 'setAutoresizingMask:';<br />
procedure setAutoresizesSubviews(flag: LongBool); message 'setAutoresizesSubviews:';<br />
procedure drawRect(dirtyRect: NSRect); message 'drawRect:';<br />
end;<br />
<br />
// MyView is a locally implemented class<br />
// that should be declared in the local unit<br />
// * drawRect_ method is overriden (the 'message' of the inherited method will be reused)<br />
// * customMessage_ is a newly added method<br />
// * data is a newly added field<br />
MyView = objcclass(MSView)<br />
public<br />
data : Integer;<br />
procedure customMessage(dirtyRect: NSRect); message 'customMessage';<br />
procedure drawRect(dirtyRect: NSRect); override;<br />
end;<br />
<br />
... <br />
procedure MyView.customMessage(dirtyRect: NSRect); <br />
begin<br />
end;<br />
<br />
procedure MyView.drawRect(dirtyRect: NSRect); <br />
begin<br />
end;<br />
<br />
<br />
</source><br />
<br />
====Formal declaration====<br />
In Objective-C, a class can also be declared formally using the ''[http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocDefiningClasses.html%23//apple_ref/doc/uid/TP30001163-CH12-SW1 @class SomeClass]'' syntax. This is called a ''forward declaration'' in Objective-C, but because this term has a different meaning in Pascal, we have termed this a ''formal declaration'' in Objective-Pascal.<br />
<br />
A formal declaration of an ''objcclass'' instructs the compiler to assume that somewhere, there is a complete definition of this ''objcclass'' (including fields, methods, etc), but that it is not in this unit. The practical upshot is that it is possible to use such a formal ''objcclass'' type for parameter types, field types, function result types and variable types, but that it is not possible to inherit from them, to send any messages to such instances, nor to access any fields (since the compiler does not know the full definition).<br />
<br />
The compiler will automatically resolve any uses of formal ''objcclass''es to the real declaration when this real declaration is also in scope. Hence, as soon as the unit containing the real declaration is added to the uses clause, the aforementioned restrictions no longer apply and the compiler will treat the occurrences of the formal ''objcclass'' type the same as the actual type.<br />
<br />
To declare a ''formal objcclass'', use the following syntax:<br />
<br />
<source><br />
type<br />
// note:<br />
// * no inheritance is specified<br />
// * the external name (if any) must match the external name of any real definition<br />
// to which this formal definition resolves later on<br />
MyExternalClass = objcclass external;<br />
</source><br />
<br />
Example:<br />
<source><br />
unit ContainerClass;<br />
<br />
{$mode objfpc}<br />
{$modeswitch objectivec1}<br />
<br />
interface<br />
<br />
type<br />
// Formal declaration of MyItemClass, which is defined in another unit<br />
MyItemClass = objcclass external;<br />
<br />
MyContainerClass = objcclass<br />
private<br />
item: MyItemClass;<br />
public<br />
function getItem: MyItemClass; message 'getItem';<br />
end;<br />
<br />
implementation<br />
<br />
function MyContainerClass.getItem: MyItemClass;<br />
begin<br />
// we cannot send any message to item, but<br />
// we can use it in assignments<br />
result:=item;<br />
end;<br />
<br />
end.<br />
<br />
// ======================<br />
// ======================<br />
<br />
unit ItemClass;<br />
<br />
{$mode objfpc}<br />
{$modeswitch objectivec1}<br />
<br />
interface<br />
<br />
<br />
type<br />
// the actual definition of MyItemClass<br />
MyItemClass = objcclass(NSObject)<br />
private<br />
content : longint;<br />
public<br />
function initWithContent(c: longint): MyItemClass; message 'initWithContent:';<br />
function getContent: longint; message 'getContent';<br />
end;<br />
<br />
implementation<br />
<br />
function MyItemClass.initWithContent(c: longint): MyItemClass;<br />
begin<br />
content:=c;<br />
result:=self;<br />
end;<br />
<br />
function MyItemClass.getContent: longint;<br />
begin<br />
result:=content;<br />
end;<br />
<br />
end.<br />
<br />
// ======================<br />
// ======================<br />
<br />
Program test;<br />
<br />
{$mode objfpc}<br />
{$modeswitch objectivec1}<br />
<br />
// regardless of the order of the units in the uses-clause, as soon as<br />
// ItemClass is used then the full declaration of MyItemClass is in<br />
// scope and all uses of the formal declaration are replaced by the<br />
// actual declaration<br />
uses<br />
ItemClass, ContainerClass;<br />
<br />
var<br />
c: MyContainerClass;<br />
l: longint;<br />
begin<br />
c:=MyContainerClass.alloc.init;<br />
...<br />
// even though MyContainerClass.getItem returns a "formal" MyItemClass,<br />
// the fact that the real declaration is in scope means that it can be<br />
// used as a regular MyItemClass instance<br />
l:=c.getItem.getContent;<br />
end.<br />
</source><br />
<br />
====Objective-Pascal class references====<br />
<br />
Just like in Object Pascal, it is possible to declare a class reference type for an Objective-Pascal class. In Objective-C, these are called meta-classes and are represented by the ''pobjc_class'' type. If you wish to mix code using the ''pobjc_class'' type and the Pascal syntax for class references, you have to use typecasts, as shown below.<br />
<br />
<source><br />
{$mode objfpc}<br />
{$modeswitch objectivec1}<br />
<br />
program Test;<br />
<br />
type<br />
TMyClass = objcclass (NSObject)<br />
end;<br />
TMyClassMeta = class of TMyClass; // declare the meta-class type for dynamic allocation<br />
<br />
var<br />
theClass: pobjc_class;<br />
begin<br />
theClass := TMyClass.classClass; // get the meta-class reference for TMyClass; could <br />
TMyClassMeta(theClass).alloc.init; // cast theClass as TMyClassMeta and send messages as normal<br />
end.<br />
</source><br />
<br />
=== Protocol declaration ===<br />
<br />
An Objective-C Protocol is pretty much the same as an ''interface'' in Object Pascal: it lists a number of methods to be implemented by classes that conform to the protocol. The only difference is that protocol methods can be ''optional''. Moreover, unlike in Object Pascal, a protocol can inherit from multiple other protocols:<br />
<br />
<source><br />
type<br />
ObjCProtocolName = objcprotocol [external [name 'ExternalClassName']] [(ObjCParentProtocol1[, ObjCParentProtocol2, ...])] <br />
[required, optional]<br />
[method declarations]<br />
end;<br />
</source><br />
<br />
* ''objcprotocol'': defines an Objective-C protocol type declaration<br />
* ''external'': same as with objcclass<br />
* ''ObjCParentProtocols'': the protocols this protocol inherits from (so a class conforming to this protocol, will also have to implement all methods from those other protocols)<br />
* ''required, optional'': If nothing is specified, the default is ''required''. ''optional'' methods do not have to be implemented by classes conforming to this protocol.<br />
<br />
Example:<br />
<source><br />
type<br />
MyProtocol = objccprotocol<br />
// default is required<br />
procedure aRequiredMethod; message 'aRequiredMethod';<br />
optional<br />
procedure anOptionalMethodWithPara(para: longint); message 'anOptionalMethodWithPara:';<br />
procedure anotherOptionalMethod; message 'anotherOptionalMethod';<br />
required<br />
function aSecondRequiredMethod: longint; message 'aSecondRequiredMethod';<br />
end;<br />
<br />
MyClassImplementingProtocol = objcclass(NSObject,MyProtocol)<br />
// the "message 'xxx'" modifiers can be repeated, but this is not required<br />
procedure aRequiredMethod;<br />
procedure anOptionalMethodWithPara(para: longint);<br />
function aSecondRequiredMethod: longint;<br />
end;<br />
</source><br />
<br />
Similar to ''objcclass''es, ''objcprotocol''s can be external in case they are implemented in e.g. the Cocoa framework.<br />
<br />
=== Category declaration ===<br />
<br />
An Objective-C category is similar to a ''class helper'' in Object Pascal: it allows adding methods to an existing class, without inheriting from that class. In Objective-C, this functionality goes even further: multiple categories can be in scope at the same time for a particular class, and a category can also replace existing methods in another class rather than only add new ones. Since all methods are virtual in Objective-C, this also means that this method changes for all classes that inherit from the class in which the method was replaced (unless they override it). An Objective-C category can also implement protocols.<br />
<br />
Note that a category cannot extend another category. Furthermore, if two categories add/replace a method with the same selector in the same class, it is undefined which method will actually be called at run time. This would depend on the order in which the categories are registered with the Objective-C run time.<br />
<br />
<source><br />
type<br />
ObjCCategoryName = objccategory [external [name 'ExternalCategoryName']] (ExtendedObjCClass[,ObjCProtocol1, ObjCProtocol2, ...])<br />
[method declarations]<br />
end;<br />
</source><br />
<br />
* ''objccategory'': defines an Objective-C category type declaration<br />
* ''external'': same as with objcclass. As of Objective-C 2.0, the name of a category is optional. ''Not yet implemented'': to declare an external category without a name, use an empty string.<br />
* ''method declarations'': the methods that this category adds or replaces in the extended class. These can be both class and instance methods. Note that when replacing a method in the extended class, you must mark this new method as ''reintroduce''. The reason that we do not use ''override'' here, is that the method is really replaced in the original class. This means, e.g., that if you call ''inherited'' from the new method, that you will call this method in the parent class of the extended class, and not the replaced method. The replaced method is "lost".<br />
* ''ObjCParentProtocols'': the protocols this category implements. The category will have to implement all required methods from these protocols.<br />
<br />
Example:<br />
<source><br />
type<br />
MyProtocol = objcprotocol<br />
procedure protocolmethod; message 'protocolmethod';<br />
end;<br />
<br />
MyCategory = objccategory(NSObject,MyProtocol)<br />
// method replaced in NSObject. This means that every objcclass that does not<br />
// override the hash function will now use this method instead. <br />
function hash: cuint; reintroduce;<br />
<br />
// we have to implement this method, since we declare that we implement the<br />
// MyProtocol protocol. This method is added to NSObject afterwards.<br />
procedure protocolmethod;<br />
<br />
// a random class methods added to NSObject<br />
class procedure newmethod; message 'newmethod';<br />
end;<br />
<br />
</source><br />
<br />
Similar to ''objcclass''es, ''objccategory''s can be external in case they are implemented in e.g. the Cocoa framework.<br />
<br />
=== The ''id'' type ===<br />
<br />
The ''id'' type is special in Objective-C/Pascal. It is assignment-compatible with instances of every objcclass and objcprotocol type, in two directions. This means that you can assign variables of any objcclass/objcprotocol type to a variable of the type ''id'', but also that you can assign these ''id'' variables to variables of any particular objcclass/objcprotocol type. In neither case an explicit typecast is required.<br />
<br />
Furthermore, it is possible to call any Objective-C method declared in an objcclass or objccategory that's in scope using an ''id''-typed variable. If, at run time, the objcclass instance stored in the ''id''-typed variable does not respond to the sent message, the program will terminate with a run time error.<br />
<br />
When there are multiple methods with the same Pascal identifier, the compiler will use the standard overload resolution logic to pick the most appropriate method. In this process, it will behave as if all objcclass/objccategory methods in scope have been declared as global procedures/functions with the ''overload'' specifier. If the compiler cannot determine which overloaded method to call, it will print an error. If you compile with -vh, it will print a list of all methods that could be used to implement the call when it cannot determine the appropriate overloaded method. In this case, you will have to use an explicit type cast to clarify the class type from which you wish to call a method.<br />
<br />
=== Fast enumeration ===<br />
<br />
''Fast enumeration'' is a convention that enables enumerating the elements in a Cocoa container class in a generic yet fast way. The syntax used for this feature is the ''for-in'' construct, both in Objective-C and in Objective-Pascal. This feature behaves identically in both languages. It requires the Objective-C 2.0 mode switch to be activated.<br />
<br />
Example:<br />
<source><br />
{$mode delphi}<br />
{$modeswitch objectivec2}<br />
<br />
uses<br />
CocoaAll;<br />
<br />
var<br />
arr: NSMutableArray;<br />
element: NSString;<br />
pool: NSAutoreleasePool;<br />
i: longint;<br />
begin<br />
pool:=NSAutoreleasePool.alloc.init;<br />
arr:=NSMutableArray.arrayWithObjects(<br />
NSSTR('One'),<br />
NSSTR('Two'),<br />
NSSTR('Three'),<br />
NSSTR('Four'),<br />
NSSTR('Five'),<br />
NSSTR('Six'),<br />
NSSTR('Seven'),<br />
nil);<br />
<br />
i:=0;<br />
for element in arr do<br />
begin<br />
inc(i);<br />
if i=2 then<br />
continue;<br />
if i=5 then<br />
break;<br />
if i in [2,5..10] then<br />
halt(1);<br />
NSLog(NSSTR('element: %@'),element);<br />
end;<br />
pool.release;<br />
end.<br />
</source><br />
<br />
== Syntax (proposed) ==<br />
<br />
== todo: == <br />
<br />
a) how to declare a constant NSString/CFString in Pascal (the @"somestring" from Objective-C)<br />
<br />
-- the dollar sign could work... ex. $theString<br />
<br />
== ObjectiveP Examples ==<br />
<br />
=== Creating and running application with one menu item ===<br />
<br />
Please note, that for the creation of the menu, the application must be located in the application bundle. Lazarus may create the bundle for you.<br />
<br />
<source><br />
program project1;<br />
<br />
{$mode objfpc}{$H+}<br />
{$modeswitch objectivec1}<br />
<br />
uses<br />
CocoaAll;<br />
<br />
type<br />
{ MyCallback }<br />
MyCallback = objcclass(NSObject)<br />
public<br />
procedure haltMenuEvent(sender: id); message 'haltMenuEvent:';<br />
end;<br />
<br />
var<br />
pool : NSAutoreleasePool;<br />
filemenu : NSMenu;<br />
subitem : NSMenuItem;<br />
app : NSApplication;<br />
callback : MyCallback;<br />
<br />
function NSStr(const s: AnsiString): NSString;<br />
begin<br />
if s='' then Result:=NSString.alloc.init<br />
else Result:=NSString.alloc.initWithCString(@s[1]);<br />
end;<br />
<br />
{ MyCallback }<br />
<br />
procedure MyCallback.haltMenuEvent(sender:id);<br />
begin<br />
WriteLn('HALT!');<br />
app.stop(self);<br />
end;<br />
<br />
procedure initMenus;<br />
var<br />
root : NSMenu;<br />
rootitem : NSMenuItem;<br />
begin<br />
root:=NSMenu.alloc.init;<br />
rootitem:=root.addItemWithTitle_action_keyEquivalent(NSStr(''), nil, NSStr(''));<br />
filemenu:=NSMenu.alloc.initWithTitle(NSStr('File'));<br />
rootitem.setSubmenu(filemenu);<br />
rootitem.setEnabled(true);<br />
subitem:=filemenu.addItemWithTitle_action_keyEquivalent(NSStr('Halt'), nil, NSStr(''));<br />
subitem.setEnabled(true);<br />
app.setMainMenu(root);<br />
end;<br />
<br />
procedure InitCallback;<br />
begin<br />
callback:=MyCallback.alloc;<br />
subitem.setAction(ObjCSelector(callback.haltMenuEvent));<br />
subitem.setTarget(callback);<br />
end;<br />
<br />
begin<br />
pool:=NSAutoreleasePool.alloc.init;<br />
app:=NSApplication.sharedApplication;<br />
initMenus;<br />
initCallback;<br />
app.run;<br />
pool.release;<br />
end.<br />
</source><br />
<br />
===Application with a single window and no menus===<br />
<br />
<source><br />
program simplewindow;<br />
<br />
{$mode objfpc}{$H+}<br />
{$modeswitch objectivec2}<br />
<br />
uses<br />
CocoaAll;<br />
<br />
var<br />
appName: NSString;<br />
window: NSWindow;<br />
pool: NSAutoreleasePool;<br />
begin<br />
pool := NSAutoreleasePool.new;<br />
NSApp := NSApplication.sharedApplication;<br />
NSApp.setActivationPolicy(NSApplicationActivationPolicyRegular);<br />
appName := NSProcessInfo.processInfo.processName;<br />
window := NSWindow.alloc.initWithContentRect_styleMask_backing_defer(NSMakeRect(0, 0, 200, 200),<br />
NSTitledWindowMask, NSBackingStoreBuffered, False).autorelease;<br />
window.center;<br />
window.setTitle(appName);<br />
window.makeKeyAndOrderFront(nil);<br />
NSApp.activateIgnoringOtherApps(true);<br />
NSApp.run;<br />
end.<br />
</source><br />
<br />
===Application with a simple window and menus===<br />
<br />
<source><br />
program simplewindow;<br />
<br />
{$mode objfpc}{$H+}<br />
{$modeswitch objectivec2}<br />
<br />
uses<br />
CocoaAll;<br />
<br />
var<br />
menubar: NSMenu;<br />
appMenu: NSMenu;<br />
appName: NSString;<br />
quitMenuItem: NSMenuItem;<br />
appMenuItem: NSMenuItem;<br />
quitTitle: NSString;<br />
window: NSWindow;<br />
pool: NSAutoreleasePool;<br />
begin<br />
pool := NSAutoreleasePool.new;<br />
NSApp := NSApplication.sharedApplication;<br />
NSApp.setActivationPolicy(NSApplicationActivationPolicyRegular);<br />
menubar := NSMenu.alloc.autorelease;<br />
appMenuItem := NSMenuItem.alloc.autorelease;<br />
menubar.addItem(appMenuItem);<br />
NSApp.setMainMenu(Menubar);<br />
appMenu := NSMenu.new.autorelease;<br />
appName := NSProcessInfo.processInfo.processName;<br />
quitTitle := NSSTR('Quit').stringByAppendingString(appName);<br />
quitMenuItem := NSMenuItem.alloc.initWithTitle_action_keyEquivalent(quitTitle,<br />
sel_registerName(PChar('terminate:')),<br />
NSSTR('q'));<br />
appMenu.addItem(quitMenuItem);<br />
appMenuitem.setSubmenu(appMenu);<br />
window := NSWindow.alloc.initWithContentRect_styleMask_backing_defer(NSMakeRect(0, 0, 200, 200),<br />
NSTitledWindowMask, NSBackingStoreBuffered, False).autorelease;<br />
window.center;<br />
window.setTitle(appName);<br />
window.makeKeyAndOrderFront(nil);<br />
NSApp.activateIgnoringOtherApps(true);<br />
NSApp.run;<br />
end.<br />
</source><br />
<br />
===Simple window and a non-editable text field inside it===<br />
<br />
This shows how to create and position a sub-control in a window:<br />
<br />
<source><br />
program simplewindow;<br />
<br />
{$mode objfpc}{$H+}<br />
{$modeswitch objectivec2}<br />
<br />
uses<br />
CocoaAll;<br />
<br />
var<br />
appName: NSString;<br />
window: NSWindow;<br />
pool: NSAutoreleasePool;<br />
lText: NSTextField;<br />
begin<br />
// Autorelease pool, app and window creation<br />
pool := NSAutoreleasePool.new;<br />
NSApp := NSApplication.sharedApplication;<br />
NSApp.setActivationPolicy(NSApplicationActivationPolicyRegular);<br />
appName := NSProcessInfo.processInfo.processName;<br />
window := NSWindow.alloc.initWithContentRect_styleMask_backing_defer(NSMakeRect(0, 0, 200, 200),<br />
NSTitledWindowMask or NSClosableWindowMask or NSMiniaturizableWindowMask,<br />
NSBackingStoreBuffered, False).autorelease;<br />
<br />
// text label<br />
lText := NSTextField.alloc.initWithFrame(NSMakeRect(50, 50, 200, 50)).autorelease;<br />
lText.setBezeled(False);<br />
lText.setDrawsBackground(False);<br />
lText.setEditable(False);<br />
lText.setSelectable(False);<br />
lText.setStringValue(NSSTR('NSTextField'));<br />
window.contentView.addSubview(lText);<br />
<br />
// Window showing and app running<br />
window.center;<br />
window.setTitle(appName);<br />
window.makeKeyAndOrderFront(nil);<br />
NSApp.activateIgnoringOtherApps(true);<br />
NSApp.run;<br />
end.<br />
</source><br />
<br />
[[Category:Objective-C]]<br />
[[Category:Objective Pascal]]<br />
[[Category:Mac OS X]]<br />
[[Category:Headers and Bindings]]<br />
[[Category:iOS]]<br />
[[Category:Cocoa]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=FPC_PasCocoa&diff=87766FPC PasCocoa2015-04-04T11:23:10Z<p>Sekelsenmat: /* Application with a simple window and menus */</p>
<hr />
<div>{{Platform only|Mac OS X|Mac OS X|Mac OS X}}<br />
{{Platform only|iOS|iOS|iOS}}<br />
== Introduction ==<br />
<br />
A large and growing fraction of the Mac OS X system frameworks are written in Objective-C and only offer an Objective-C interface. This makes it unwieldy to use them directly from other programming languages. The Objective-C run time library, which is used for everything from defining classes to sending messages (calling methods), has a public procedural C interface however, which makes it possible to integrate other languages directly with Objective-C code. Two general approaches exist.<br />
<br />
The first approach is to create a ''bridge''. In this case calls to the Objective-C run time helpers are wrapped in host language constructs and helpers. The host language itself is generally not modified. A number of examples of Cocoa bridges can be found at http://www.cocoadev.com/index.pl?CocoaBridges.<br />
<br />
A second approach is to extend the host language so that it can directly interface with Objective-C code using new language constructs. A list of such language extensions can be found at http://www.cocoadev.com/index.pl?CocoaLanguages. As far as Pascal is concerned, a first proposal for Objective-Pascal was made by [http://www.pascal-central.com/cwpascal.html#Extensions%20providing%20compatibili MetroWerks in 1997]. Based on this preliminary proposal (it was never finalised nor implemented by MetroWerks) and on evolutions of the Object Pascal language since that time, we have designed our own Objective-Pascal dialect.<br />
<br />
== PasCocoa wrappers ==<br />
<br />
Before the compiler supported Objective-Pascal (as described below), the primary way for Objective-C interfacing was through ObjFPC wrapper classes. This process is described on the [[PasCocoa]] page, and falls in the ''bridge'' approach mentioned above. This approach is no longer recommended nor maintained.<br />
<br />
== Objective-C FPC Compiler ==<br />
<br />
All Objective-C support is now available in svn trunk. For instructions on how to check it out, see http://www.freepascal.org/develop.var#svn<br />
<br />
For an overview of some conceptual differences between Objective-Pascal and Object Pascal on the one hand, and between Objective-Pascal and Objective-C on the other hand, see [[FPC_PasCocoa/Differences]].<br />
<br />
== Syntax (implemented) ==<br />
<br />
=== Enabling Objective-C/Objective-Pascal ===<br />
<br />
The compiler has mode switches to enable the use of Objective-C-related constructs. To enabled Objective-C 1.0 language features, either add ''{$modeswitch objectivec1}'' to a source file, or using the ''-Mobjectivec1'' command line switch. Similarly, for Objective-C 2.0 language features use ''{$modeswitch objectivec2}'' resp. ''-Mobjectivec2'' (this automatically also enables Objective-C 1.0 features). Note that in the latter case, the resulting program may only work on Mac OS X 10.5 and later. Due to these being mode switches rather than actual syntax modes, they can be used in combination with every general syntax mode (fpc, objfpc, tp, delphi, macpas).<br />
<br />
Note that mode switches are reset when the general syntax mode is changed using, e.g., ''{$mode objfpc}''. So if you have such a statement in a unit, compiling it with ''-Mobjectivec1'' will not change anything. You will have to add ''{$modeswitch objectivec1}'' in the source code after the ''{$mode objfpc}'' in that case.<br />
<br />
Whether or not the compiler has support for Objective-C-related constructs can be checked using ''{$ifdef FPC_HAS_FEATURE_OBJECTIVEC1}''. There will be no separate switches when new Objective-C-related features are implemented. Since all this works happens in FPC trunk, simply expect that people are using the latest version available.<br />
<br />
=== Selectors ===<br />
<br />
To declare a selector for a method, use the ''objcselector()'' statement. It returns a value of the type ''objc.SEL''. It accepts one parameter, which can either be a constant string representing an Objective-C method name, or a method of an Objective-C class.<br />
<br />
<source><br />
{$modeswitch objectivec1}<br />
var<br />
a: SEL;<br />
begin<br />
a:=objcselector('initiWithWidth:andHeight:');<br />
a:=objcselector('myMethod');<br />
end.<br />
</source><br />
<br />
<br />
=== Method declaration ===<br />
<br />
In general methods are declared in the same way as in Object Pascal, with the exception that each objcclass method must also have a messaging name specified:<br />
<br />
<source><br />
NSSomeObject = objcclass(NSObject)<br />
procedure method(params: Integer); message 'method:';<br />
class procedure classmethod(para: char); override; // "message 'classmethod:'" not required, compiler will get this from the parent class<br />
end;<br />
</source><br />
<br />
Every objcclass/objcprotocol/objccategory method must be associated with an Objective-C message name, a.k.a. ''selector''. This can happen in two different ways:<br />
* an inherited method, an implemented protocol method or a method reintroduced by a category will automatically use the message name of the inherited/implemented/reintroduced method. If an explicit message name is specified, it must match the message name specified for the corresponding method.<br />
* in other cases, the ''message'' keyword must be used, followed by a constant string that contains the selector name.<br />
<br />
Instance and class methods correspond respectively to methods preceded with "-" and "+" in Objective-C. Furthermore, every method is by definition ''virtual'' in Objective-C/Pascal.<br />
<br />
'''Note:''' it's common for Objective-C to start method names with a lower case character.<br />
<br />
=== Class declaration ===<br />
<br />
====Regular declaration/definition====<br />
<br />
To declare an Objective-C class, use the keyword ''objcclass''. Objective-C classes must be declared like regular Object Pascal types in a ''type'' block:<br />
<source><br />
type<br />
ObjCClassName = objcclass [external [name 'ExternalClassName']] [(ObjCSuperClassName|ProtocolName [, ProtocolName, ProtocolName])] <br />
[private, protected, public]<br />
[variables declarations]<br />
[method declarations]<br />
end; <br />
</source><br />
<br />
* ''objcclass'': defines an Objective-C class type declaration<br />
* ''external'': many Objective-C classes are implemented in external frameworks, such as Cocoa. The ''external'' modifiers enables you to declare such external classes for use in Pascal code. It is possible to specify a different external name for the class than the identifier used in Pascal code, because the duplicate identifier rules in Objective-C are laxer than those of Pascal (e.g., there are both a class and a protocol called ''NSObject'' in Cocoa, so one of the two has to be renamed in Pascal)<br />
* ObjCSuperClassName: defines parent (or super) class for the class. If name is not specified, the class defines a new root class. See http://wiki.freepascal.org/FPC_PasCocoa/Differences#No_unique_root_class for more information.<br />
<br />
For example:<br />
<source><br />
// NSView is an external class, declared in some external framework<br />
// External classes from Apple's framework<br />
// have all fields in private sections<br />
NSView = objcclass external (NSResponder)<br />
private<br />
_subview : id; // private field<br />
public<br />
function initWithFrame(rect : NSRect): id; message 'initWithFrame:';<br />
procedure addSubview(aview: NSView); message 'addSubview:';<br />
procedure setAutoresizingMask(mask: NSUInteger); message 'setAutoresizingMask:';<br />
procedure setAutoresizesSubviews(flag: LongBool); message 'setAutoresizesSubviews:';<br />
procedure drawRect(dirtyRect: NSRect); message 'drawRect:';<br />
end;<br />
<br />
// MyView is a locally implemented class<br />
// that should be declared in the local unit<br />
// * drawRect_ method is overriden (the 'message' of the inherited method will be reused)<br />
// * customMessage_ is a newly added method<br />
// * data is a newly added field<br />
MyView = objcclass(MSView)<br />
public<br />
data : Integer;<br />
procedure customMessage(dirtyRect: NSRect); message 'customMessage';<br />
procedure drawRect(dirtyRect: NSRect); override;<br />
end;<br />
<br />
... <br />
procedure MyView.customMessage(dirtyRect: NSRect); <br />
begin<br />
end;<br />
<br />
procedure MyView.drawRect(dirtyRect: NSRect); <br />
begin<br />
end;<br />
<br />
<br />
</source><br />
<br />
====Formal declaration====<br />
In Objective-C, a class can also be declared formally using the ''[http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocDefiningClasses.html%23//apple_ref/doc/uid/TP30001163-CH12-SW1 @class SomeClass]'' syntax. This is called a ''forward declaration'' in Objective-C, but because this term has a different meaning in Pascal, we have termed this a ''formal declaration'' in Objective-Pascal.<br />
<br />
A formal declaration of an ''objcclass'' instructs the compiler to assume that somewhere, there is a complete definition of this ''objcclass'' (including fields, methods, etc), but that it is not in this unit. The practical upshot is that it is possible to use such a formal ''objcclass'' type for parameter types, field types, function result types and variable types, but that it is not possible to inherit from them, to send any messages to such instances, nor to access any fields (since the compiler does not know the full definition).<br />
<br />
The compiler will automatically resolve any uses of formal ''objcclass''es to the real declaration when this real declaration is also in scope. Hence, as soon as the unit containing the real declaration is added to the uses clause, the aforementioned restrictions no longer apply and the compiler will treat the occurrences of the formal ''objcclass'' type the same as the actual type.<br />
<br />
To declare a ''formal objcclass'', use the following syntax:<br />
<br />
<source><br />
type<br />
// note:<br />
// * no inheritance is specified<br />
// * the external name (if any) must match the external name of any real definition<br />
// to which this formal definition resolves later on<br />
MyExternalClass = objcclass external;<br />
</source><br />
<br />
Example:<br />
<source><br />
unit ContainerClass;<br />
<br />
{$mode objfpc}<br />
{$modeswitch objectivec1}<br />
<br />
interface<br />
<br />
type<br />
// Formal declaration of MyItemClass, which is defined in another unit<br />
MyItemClass = objcclass external;<br />
<br />
MyContainerClass = objcclass<br />
private<br />
item: MyItemClass;<br />
public<br />
function getItem: MyItemClass; message 'getItem';<br />
end;<br />
<br />
implementation<br />
<br />
function MyContainerClass.getItem: MyItemClass;<br />
begin<br />
// we cannot send any message to item, but<br />
// we can use it in assignments<br />
result:=item;<br />
end;<br />
<br />
end.<br />
<br />
// ======================<br />
// ======================<br />
<br />
unit ItemClass;<br />
<br />
{$mode objfpc}<br />
{$modeswitch objectivec1}<br />
<br />
interface<br />
<br />
<br />
type<br />
// the actual definition of MyItemClass<br />
MyItemClass = objcclass(NSObject)<br />
private<br />
content : longint;<br />
public<br />
function initWithContent(c: longint): MyItemClass; message 'initWithContent:';<br />
function getContent: longint; message 'getContent';<br />
end;<br />
<br />
implementation<br />
<br />
function MyItemClass.initWithContent(c: longint): MyItemClass;<br />
begin<br />
content:=c;<br />
result:=self;<br />
end;<br />
<br />
function MyItemClass.getContent: longint;<br />
begin<br />
result:=content;<br />
end;<br />
<br />
end.<br />
<br />
// ======================<br />
// ======================<br />
<br />
Program test;<br />
<br />
{$mode objfpc}<br />
{$modeswitch objectivec1}<br />
<br />
// regardless of the order of the units in the uses-clause, as soon as<br />
// ItemClass is used then the full declaration of MyItemClass is in<br />
// scope and all uses of the formal declaration are replaced by the<br />
// actual declaration<br />
uses<br />
ItemClass, ContainerClass;<br />
<br />
var<br />
c: MyContainerClass;<br />
l: longint;<br />
begin<br />
c:=MyContainerClass.alloc.init;<br />
...<br />
// even though MyContainerClass.getItem returns a "formal" MyItemClass,<br />
// the fact that the real declaration is in scope means that it can be<br />
// used as a regular MyItemClass instance<br />
l:=c.getItem.getContent;<br />
end.<br />
</source><br />
<br />
====Objective-Pascal class references====<br />
<br />
Just like in Object Pascal, it is possible to declare a class reference type for an Objective-Pascal class. In Objective-C, these are called meta-classes and are represented by the ''pobjc_class'' type. If you wish to mix code using the ''pobjc_class'' type and the Pascal syntax for class references, you have to use typecasts, as shown below.<br />
<br />
<source><br />
{$mode objfpc}<br />
{$modeswitch objectivec1}<br />
<br />
program Test;<br />
<br />
type<br />
TMyClass = objcclass (NSObject)<br />
end;<br />
TMyClassMeta = class of TMyClass; // declare the meta-class type for dynamic allocation<br />
<br />
var<br />
theClass: pobjc_class;<br />
begin<br />
theClass := TMyClass.classClass; // get the meta-class reference for TMyClass; could <br />
TMyClassMeta(theClass).alloc.init; // cast theClass as TMyClassMeta and send messages as normal<br />
end.<br />
</source><br />
<br />
=== Protocol declaration ===<br />
<br />
An Objective-C Protocol is pretty much the same as an ''interface'' in Object Pascal: it lists a number of methods to be implemented by classes that conform to the protocol. The only difference is that protocol methods can be ''optional''. Moreover, unlike in Object Pascal, a protocol can inherit from multiple other protocols:<br />
<br />
<source><br />
type<br />
ObjCProtocolName = objcprotocol [external [name 'ExternalClassName']] [(ObjCParentProtocol1[, ObjCParentProtocol2, ...])] <br />
[required, optional]<br />
[method declarations]<br />
end;<br />
</source><br />
<br />
* ''objcprotocol'': defines an Objective-C protocol type declaration<br />
* ''external'': same as with objcclass<br />
* ''ObjCParentProtocols'': the protocols this protocol inherits from (so a class conforming to this protocol, will also have to implement all methods from those other protocols)<br />
* ''required, optional'': If nothing is specified, the default is ''required''. ''optional'' methods do not have to be implemented by classes conforming to this protocol.<br />
<br />
Example:<br />
<source><br />
type<br />
MyProtocol = objccprotocol<br />
// default is required<br />
procedure aRequiredMethod; message 'aRequiredMethod';<br />
optional<br />
procedure anOptionalMethodWithPara(para: longint); message 'anOptionalMethodWithPara:';<br />
procedure anotherOptionalMethod; message 'anotherOptionalMethod';<br />
required<br />
function aSecondRequiredMethod: longint; message 'aSecondRequiredMethod';<br />
end;<br />
<br />
MyClassImplementingProtocol = objcclass(NSObject,MyProtocol)<br />
// the "message 'xxx'" modifiers can be repeated, but this is not required<br />
procedure aRequiredMethod;<br />
procedure anOptionalMethodWithPara(para: longint);<br />
function aSecondRequiredMethod: longint;<br />
end;<br />
</source><br />
<br />
Similar to ''objcclass''es, ''objcprotocol''s can be external in case they are implemented in e.g. the Cocoa framework.<br />
<br />
=== Category declaration ===<br />
<br />
An Objective-C category is similar to a ''class helper'' in Object Pascal: it allows adding methods to an existing class, without inheriting from that class. In Objective-C, this functionality goes even further: multiple categories can be in scope at the same time for a particular class, and a category can also replace existing methods in another class rather than only add new ones. Since all methods are virtual in Objective-C, this also means that this method changes for all classes that inherit from the class in which the method was replaced (unless they override it). An Objective-C category can also implement protocols.<br />
<br />
Note that a category cannot extend another category. Furthermore, if two categories add/replace a method with the same selector in the same class, it is undefined which method will actually be called at run time. This would depend on the order in which the categories are registered with the Objective-C run time.<br />
<br />
<source><br />
type<br />
ObjCCategoryName = objccategory [external [name 'ExternalCategoryName']] (ExtendedObjCClass[,ObjCProtocol1, ObjCProtocol2, ...])<br />
[method declarations]<br />
end;<br />
</source><br />
<br />
* ''objccategory'': defines an Objective-C category type declaration<br />
* ''external'': same as with objcclass. As of Objective-C 2.0, the name of a category is optional. ''Not yet implemented'': to declare an external category without a name, use an empty string.<br />
* ''method declarations'': the methods that this category adds or replaces in the extended class. These can be both class and instance methods. Note that when replacing a method in the extended class, you must mark this new method as ''reintroduce''. The reason that we do not use ''override'' here, is that the method is really replaced in the original class. This means, e.g., that if you call ''inherited'' from the new method, that you will call this method in the parent class of the extended class, and not the replaced method. The replaced method is "lost".<br />
* ''ObjCParentProtocols'': the protocols this category implements. The category will have to implement all required methods from these protocols.<br />
<br />
Example:<br />
<source><br />
type<br />
MyProtocol = objcprotocol<br />
procedure protocolmethod; message 'protocolmethod';<br />
end;<br />
<br />
MyCategory = objccategory(NSObject,MyProtocol)<br />
// method replaced in NSObject. This means that every objcclass that does not<br />
// override the hash function will now use this method instead. <br />
function hash: cuint; reintroduce;<br />
<br />
// we have to implement this method, since we declare that we implement the<br />
// MyProtocol protocol. This method is added to NSObject afterwards.<br />
procedure protocolmethod;<br />
<br />
// a random class methods added to NSObject<br />
class procedure newmethod; message 'newmethod';<br />
end;<br />
<br />
</source><br />
<br />
Similar to ''objcclass''es, ''objccategory''s can be external in case they are implemented in e.g. the Cocoa framework.<br />
<br />
=== The ''id'' type ===<br />
<br />
The ''id'' type is special in Objective-C/Pascal. It is assignment-compatible with instances of every objcclass and objcprotocol type, in two directions. This means that you can assign variables of any objcclass/objcprotocol type to a variable of the type ''id'', but also that you can assign these ''id'' variables to variables of any particular objcclass/objcprotocol type. In neither case an explicit typecast is required.<br />
<br />
Furthermore, it is possible to call any Objective-C method declared in an objcclass or objccategory that's in scope using an ''id''-typed variable. If, at run time, the objcclass instance stored in the ''id''-typed variable does not respond to the sent message, the program will terminate with a run time error.<br />
<br />
When there are multiple methods with the same Pascal identifier, the compiler will use the standard overload resolution logic to pick the most appropriate method. In this process, it will behave as if all objcclass/objccategory methods in scope have been declared as global procedures/functions with the ''overload'' specifier. If the compiler cannot determine which overloaded method to call, it will print an error. If you compile with -vh, it will print a list of all methods that could be used to implement the call when it cannot determine the appropriate overloaded method. In this case, you will have to use an explicit type cast to clarify the class type from which you wish to call a method.<br />
<br />
=== Fast enumeration ===<br />
<br />
''Fast enumeration'' is a convention that enables enumerating the elements in a Cocoa container class in a generic yet fast way. The syntax used for this feature is the ''for-in'' construct, both in Objective-C and in Objective-Pascal. This feature behaves identically in both languages. It requires the Objective-C 2.0 mode switch to be activated.<br />
<br />
Example:<br />
<source><br />
{$mode delphi}<br />
{$modeswitch objectivec2}<br />
<br />
uses<br />
CocoaAll;<br />
<br />
var<br />
arr: NSMutableArray;<br />
element: NSString;<br />
pool: NSAutoreleasePool;<br />
i: longint;<br />
begin<br />
pool:=NSAutoreleasePool.alloc.init;<br />
arr:=NSMutableArray.arrayWithObjects(<br />
NSSTR('One'),<br />
NSSTR('Two'),<br />
NSSTR('Three'),<br />
NSSTR('Four'),<br />
NSSTR('Five'),<br />
NSSTR('Six'),<br />
NSSTR('Seven'),<br />
nil);<br />
<br />
i:=0;<br />
for element in arr do<br />
begin<br />
inc(i);<br />
if i=2 then<br />
continue;<br />
if i=5 then<br />
break;<br />
if i in [2,5..10] then<br />
halt(1);<br />
NSLog(NSSTR('element: %@'),element);<br />
end;<br />
pool.release;<br />
end.<br />
</source><br />
<br />
== Syntax (proposed) ==<br />
<br />
== todo: == <br />
<br />
a) how to declare a constant NSString/CFString in Pascal (the @"somestring" from Objective-C)<br />
<br />
-- the dollar sign could work... ex. $theString<br />
<br />
== ObjectiveP Examples ==<br />
<br />
=== Creating and running application with one menu item ===<br />
<br />
Please note, that for the creation of the menu, the application must be located in the application bundle. Lazarus may create the bundle for you.<br />
<br />
<source><br />
program project1;<br />
<br />
{$mode objfpc}{$H+}<br />
{$modeswitch objectivec1}<br />
<br />
uses<br />
CocoaAll;<br />
<br />
type<br />
{ MyCallback }<br />
MyCallback = objcclass(NSObject)<br />
public<br />
procedure haltMenuEvent(sender: id); message 'haltMenuEvent:';<br />
end;<br />
<br />
var<br />
pool : NSAutoreleasePool;<br />
filemenu : NSMenu;<br />
subitem : NSMenuItem;<br />
app : NSApplication;<br />
callback : MyCallback;<br />
<br />
function NSStr(const s: AnsiString): NSString;<br />
begin<br />
if s='' then Result:=NSString.alloc.init<br />
else Result:=NSString.alloc.initWithCString(@s[1]);<br />
end;<br />
<br />
{ MyCallback }<br />
<br />
procedure MyCallback.haltMenuEvent(sender:id);<br />
begin<br />
WriteLn('HALT!');<br />
app.stop(self);<br />
end;<br />
<br />
procedure initMenus;<br />
var<br />
root : NSMenu;<br />
rootitem : NSMenuItem;<br />
begin<br />
root:=NSMenu.alloc.init;<br />
rootitem:=root.addItemWithTitle_action_keyEquivalent(NSStr(''), nil, NSStr(''));<br />
filemenu:=NSMenu.alloc.initWithTitle(NSStr('File'));<br />
rootitem.setSubmenu(filemenu);<br />
rootitem.setEnabled(true);<br />
subitem:=filemenu.addItemWithTitle_action_keyEquivalent(NSStr('Halt'), nil, NSStr(''));<br />
subitem.setEnabled(true);<br />
app.setMainMenu(root);<br />
end;<br />
<br />
procedure InitCallback;<br />
begin<br />
callback:=MyCallback.alloc;<br />
subitem.setAction(ObjCSelector(callback.haltMenuEvent));<br />
subitem.setTarget(callback);<br />
end;<br />
<br />
begin<br />
pool:=NSAutoreleasePool.alloc.init;<br />
app:=NSApplication.sharedApplication;<br />
initMenus;<br />
initCallback;<br />
app.run;<br />
pool.release;<br />
end.<br />
</source><br />
<br />
===Application with a single window and no menus===<br />
<br />
<source><br />
program simplewindow;<br />
<br />
{$mode objfpc}{$H+}<br />
{$modeswitch objectivec2}<br />
<br />
uses<br />
CocoaAll;<br />
<br />
var<br />
appName: NSString;<br />
window: NSWindow;<br />
pool: NSAutoreleasePool;<br />
begin<br />
pool := NSAutoreleasePool.new;<br />
NSApp := NSApplication.sharedApplication;<br />
NSApp.setActivationPolicy(NSApplicationActivationPolicyRegular);<br />
appName := NSProcessInfo.processInfo.processName;<br />
window := NSWindow.alloc.initWithContentRect_styleMask_backing_defer(NSMakeRect(0, 0, 200, 200),<br />
NSTitledWindowMask, NSBackingStoreBuffered, False).autorelease;<br />
window.center;<br />
window.setTitle(appName);<br />
window.makeKeyAndOrderFront(nil);<br />
NSApp.activateIgnoringOtherApps(true);<br />
NSApp.run;<br />
end.<br />
</source><br />
<br />
===Application with a simple window and menus===<br />
<br />
<source><br />
program simplewindow;<br />
<br />
{$mode objfpc}{$H+}<br />
{$modeswitch objectivec2}<br />
<br />
uses<br />
CocoaAll;<br />
<br />
var<br />
{menubar: NSMenu;<br />
appMenu: NSMenu;}<br />
appName: NSString;<br />
{quitMenuItem: NSMenuItem;<br />
appMenuItem: NSMenuItem;<br />
quitTitle: NSString;}<br />
window: NSWindow;<br />
pool: NSAutoreleasePool;<br />
begin<br />
pool := NSAutoreleasePool.new;<br />
NSApp := NSApplication.sharedApplication;<br />
NSApp.setActivationPolicy(NSApplicationActivationPolicyRegular);<br />
menubar := NSMenu.alloc.autorelease;<br />
appMenuItem := NSMenuItem.alloc.autorelease;<br />
menubar.addItem(appMenuItem);<br />
NSApp.setMainMenu(Menubar);<br />
appMenu := NSMenu.new.autorelease;<br />
appName := NSProcessInfo.processInfo.processName;<br />
quitTitle := NSSTR('Quit').stringByAppendingString(appName);<br />
quitMenuItem := NSMenuItem.alloc.initWithTitle_action_keyEquivalent(quitTitle,<br />
sel_registerName(PChar('terminate:')),<br />
NSSTR('q'));<br />
appMenu.addItem(quitMenuItem);<br />
appMenuitem.setSubmenu(appMenu);<br />
window := NSWindow.alloc.initWithContentRect_styleMask_backing_defer(NSMakeRect(0, 0, 200, 200),<br />
NSTitledWindowMask, NSBackingStoreBuffered, False).autorelease;<br />
window.center;<br />
window.setTitle(appName);<br />
window.makeKeyAndOrderFront(nil);<br />
NSApp.activateIgnoringOtherApps(true);<br />
NSApp.run;<br />
end.<br />
</source><br />
<br />
===Simple window and a non-editable text field inside it===<br />
<br />
This shows how to create and position a sub-control in a window:<br />
<br />
<source><br />
program simplewindow;<br />
<br />
{$mode objfpc}{$H+}<br />
{$modeswitch objectivec2}<br />
<br />
uses<br />
CocoaAll;<br />
<br />
var<br />
appName: NSString;<br />
window: NSWindow;<br />
pool: NSAutoreleasePool;<br />
lText: NSTextField;<br />
begin<br />
// Autorelease pool, app and window creation<br />
pool := NSAutoreleasePool.new;<br />
NSApp := NSApplication.sharedApplication;<br />
NSApp.setActivationPolicy(NSApplicationActivationPolicyRegular);<br />
appName := NSProcessInfo.processInfo.processName;<br />
window := NSWindow.alloc.initWithContentRect_styleMask_backing_defer(NSMakeRect(0, 0, 200, 200),<br />
NSTitledWindowMask or NSClosableWindowMask or NSMiniaturizableWindowMask,<br />
NSBackingStoreBuffered, False).autorelease;<br />
<br />
// text label<br />
lText := NSTextField.alloc.initWithFrame(NSMakeRect(50, 50, 200, 50)).autorelease;<br />
lText.setBezeled(False);<br />
lText.setDrawsBackground(False);<br />
lText.setEditable(False);<br />
lText.setSelectable(False);<br />
lText.setStringValue(NSSTR('NSTextField'));<br />
window.contentView.addSubview(lText);<br />
<br />
// Window showing and app running<br />
window.center;<br />
window.setTitle(appName);<br />
window.makeKeyAndOrderFront(nil);<br />
NSApp.activateIgnoringOtherApps(true);<br />
NSApp.run;<br />
end.<br />
</source><br />
<br />
[[Category:Objective-C]]<br />
[[Category:Objective Pascal]]<br />
[[Category:Mac OS X]]<br />
[[Category:Headers and Bindings]]<br />
[[Category:iOS]]<br />
[[Category:Cocoa]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=FPC_PasCocoa&diff=87765FPC PasCocoa2015-04-04T11:07:59Z<p>Sekelsenmat: /* Creating and running application with one menu item */</p>
<hr />
<div>{{Platform only|Mac OS X|Mac OS X|Mac OS X}}<br />
{{Platform only|iOS|iOS|iOS}}<br />
== Introduction ==<br />
<br />
A large and growing fraction of the Mac OS X system frameworks are written in Objective-C and only offer an Objective-C interface. This makes it unwieldy to use them directly from other programming languages. The Objective-C run time library, which is used for everything from defining classes to sending messages (calling methods), has a public procedural C interface however, which makes it possible to integrate other languages directly with Objective-C code. Two general approaches exist.<br />
<br />
The first approach is to create a ''bridge''. In this case calls to the Objective-C run time helpers are wrapped in host language constructs and helpers. The host language itself is generally not modified. A number of examples of Cocoa bridges can be found at http://www.cocoadev.com/index.pl?CocoaBridges.<br />
<br />
A second approach is to extend the host language so that it can directly interface with Objective-C code using new language constructs. A list of such language extensions can be found at http://www.cocoadev.com/index.pl?CocoaLanguages. As far as Pascal is concerned, a first proposal for Objective-Pascal was made by [http://www.pascal-central.com/cwpascal.html#Extensions%20providing%20compatibili MetroWerks in 1997]. Based on this preliminary proposal (it was never finalised nor implemented by MetroWerks) and on evolutions of the Object Pascal language since that time, we have designed our own Objective-Pascal dialect.<br />
<br />
== PasCocoa wrappers ==<br />
<br />
Before the compiler supported Objective-Pascal (as described below), the primary way for Objective-C interfacing was through ObjFPC wrapper classes. This process is described on the [[PasCocoa]] page, and falls in the ''bridge'' approach mentioned above. This approach is no longer recommended nor maintained.<br />
<br />
== Objective-C FPC Compiler ==<br />
<br />
All Objective-C support is now available in svn trunk. For instructions on how to check it out, see http://www.freepascal.org/develop.var#svn<br />
<br />
For an overview of some conceptual differences between Objective-Pascal and Object Pascal on the one hand, and between Objective-Pascal and Objective-C on the other hand, see [[FPC_PasCocoa/Differences]].<br />
<br />
== Syntax (implemented) ==<br />
<br />
=== Enabling Objective-C/Objective-Pascal ===<br />
<br />
The compiler has mode switches to enable the use of Objective-C-related constructs. To enabled Objective-C 1.0 language features, either add ''{$modeswitch objectivec1}'' to a source file, or using the ''-Mobjectivec1'' command line switch. Similarly, for Objective-C 2.0 language features use ''{$modeswitch objectivec2}'' resp. ''-Mobjectivec2'' (this automatically also enables Objective-C 1.0 features). Note that in the latter case, the resulting program may only work on Mac OS X 10.5 and later. Due to these being mode switches rather than actual syntax modes, they can be used in combination with every general syntax mode (fpc, objfpc, tp, delphi, macpas).<br />
<br />
Note that mode switches are reset when the general syntax mode is changed using, e.g., ''{$mode objfpc}''. So if you have such a statement in a unit, compiling it with ''-Mobjectivec1'' will not change anything. You will have to add ''{$modeswitch objectivec1}'' in the source code after the ''{$mode objfpc}'' in that case.<br />
<br />
Whether or not the compiler has support for Objective-C-related constructs can be checked using ''{$ifdef FPC_HAS_FEATURE_OBJECTIVEC1}''. There will be no separate switches when new Objective-C-related features are implemented. Since all this works happens in FPC trunk, simply expect that people are using the latest version available.<br />
<br />
=== Selectors ===<br />
<br />
To declare a selector for a method, use the ''objcselector()'' statement. It returns a value of the type ''objc.SEL''. It accepts one parameter, which can either be a constant string representing an Objective-C method name, or a method of an Objective-C class.<br />
<br />
<source><br />
{$modeswitch objectivec1}<br />
var<br />
a: SEL;<br />
begin<br />
a:=objcselector('initiWithWidth:andHeight:');<br />
a:=objcselector('myMethod');<br />
end.<br />
</source><br />
<br />
<br />
=== Method declaration ===<br />
<br />
In general methods are declared in the same way as in Object Pascal, with the exception that each objcclass method must also have a messaging name specified:<br />
<br />
<source><br />
NSSomeObject = objcclass(NSObject)<br />
procedure method(params: Integer); message 'method:';<br />
class procedure classmethod(para: char); override; // "message 'classmethod:'" not required, compiler will get this from the parent class<br />
end;<br />
</source><br />
<br />
Every objcclass/objcprotocol/objccategory method must be associated with an Objective-C message name, a.k.a. ''selector''. This can happen in two different ways:<br />
* an inherited method, an implemented protocol method or a method reintroduced by a category will automatically use the message name of the inherited/implemented/reintroduced method. If an explicit message name is specified, it must match the message name specified for the corresponding method.<br />
* in other cases, the ''message'' keyword must be used, followed by a constant string that contains the selector name.<br />
<br />
Instance and class methods correspond respectively to methods preceded with "-" and "+" in Objective-C. Furthermore, every method is by definition ''virtual'' in Objective-C/Pascal.<br />
<br />
'''Note:''' it's common for Objective-C to start method names with a lower case character.<br />
<br />
=== Class declaration ===<br />
<br />
====Regular declaration/definition====<br />
<br />
To declare an Objective-C class, use the keyword ''objcclass''. Objective-C classes must be declared like regular Object Pascal types in a ''type'' block:<br />
<source><br />
type<br />
ObjCClassName = objcclass [external [name 'ExternalClassName']] [(ObjCSuperClassName|ProtocolName [, ProtocolName, ProtocolName])] <br />
[private, protected, public]<br />
[variables declarations]<br />
[method declarations]<br />
end; <br />
</source><br />
<br />
* ''objcclass'': defines an Objective-C class type declaration<br />
* ''external'': many Objective-C classes are implemented in external frameworks, such as Cocoa. The ''external'' modifiers enables you to declare such external classes for use in Pascal code. It is possible to specify a different external name for the class than the identifier used in Pascal code, because the duplicate identifier rules in Objective-C are laxer than those of Pascal (e.g., there are both a class and a protocol called ''NSObject'' in Cocoa, so one of the two has to be renamed in Pascal)<br />
* ObjCSuperClassName: defines parent (or super) class for the class. If name is not specified, the class defines a new root class. See http://wiki.freepascal.org/FPC_PasCocoa/Differences#No_unique_root_class for more information.<br />
<br />
For example:<br />
<source><br />
// NSView is an external class, declared in some external framework<br />
// External classes from Apple's framework<br />
// have all fields in private sections<br />
NSView = objcclass external (NSResponder)<br />
private<br />
_subview : id; // private field<br />
public<br />
function initWithFrame(rect : NSRect): id; message 'initWithFrame:';<br />
procedure addSubview(aview: NSView); message 'addSubview:';<br />
procedure setAutoresizingMask(mask: NSUInteger); message 'setAutoresizingMask:';<br />
procedure setAutoresizesSubviews(flag: LongBool); message 'setAutoresizesSubviews:';<br />
procedure drawRect(dirtyRect: NSRect); message 'drawRect:';<br />
end;<br />
<br />
// MyView is a locally implemented class<br />
// that should be declared in the local unit<br />
// * drawRect_ method is overriden (the 'message' of the inherited method will be reused)<br />
// * customMessage_ is a newly added method<br />
// * data is a newly added field<br />
MyView = objcclass(MSView)<br />
public<br />
data : Integer;<br />
procedure customMessage(dirtyRect: NSRect); message 'customMessage';<br />
procedure drawRect(dirtyRect: NSRect); override;<br />
end;<br />
<br />
... <br />
procedure MyView.customMessage(dirtyRect: NSRect); <br />
begin<br />
end;<br />
<br />
procedure MyView.drawRect(dirtyRect: NSRect); <br />
begin<br />
end;<br />
<br />
<br />
</source><br />
<br />
====Formal declaration====<br />
In Objective-C, a class can also be declared formally using the ''[http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocDefiningClasses.html%23//apple_ref/doc/uid/TP30001163-CH12-SW1 @class SomeClass]'' syntax. This is called a ''forward declaration'' in Objective-C, but because this term has a different meaning in Pascal, we have termed this a ''formal declaration'' in Objective-Pascal.<br />
<br />
A formal declaration of an ''objcclass'' instructs the compiler to assume that somewhere, there is a complete definition of this ''objcclass'' (including fields, methods, etc), but that it is not in this unit. The practical upshot is that it is possible to use such a formal ''objcclass'' type for parameter types, field types, function result types and variable types, but that it is not possible to inherit from them, to send any messages to such instances, nor to access any fields (since the compiler does not know the full definition).<br />
<br />
The compiler will automatically resolve any uses of formal ''objcclass''es to the real declaration when this real declaration is also in scope. Hence, as soon as the unit containing the real declaration is added to the uses clause, the aforementioned restrictions no longer apply and the compiler will treat the occurrences of the formal ''objcclass'' type the same as the actual type.<br />
<br />
To declare a ''formal objcclass'', use the following syntax:<br />
<br />
<source><br />
type<br />
// note:<br />
// * no inheritance is specified<br />
// * the external name (if any) must match the external name of any real definition<br />
// to which this formal definition resolves later on<br />
MyExternalClass = objcclass external;<br />
</source><br />
<br />
Example:<br />
<source><br />
unit ContainerClass;<br />
<br />
{$mode objfpc}<br />
{$modeswitch objectivec1}<br />
<br />
interface<br />
<br />
type<br />
// Formal declaration of MyItemClass, which is defined in another unit<br />
MyItemClass = objcclass external;<br />
<br />
MyContainerClass = objcclass<br />
private<br />
item: MyItemClass;<br />
public<br />
function getItem: MyItemClass; message 'getItem';<br />
end;<br />
<br />
implementation<br />
<br />
function MyContainerClass.getItem: MyItemClass;<br />
begin<br />
// we cannot send any message to item, but<br />
// we can use it in assignments<br />
result:=item;<br />
end;<br />
<br />
end.<br />
<br />
// ======================<br />
// ======================<br />
<br />
unit ItemClass;<br />
<br />
{$mode objfpc}<br />
{$modeswitch objectivec1}<br />
<br />
interface<br />
<br />
<br />
type<br />
// the actual definition of MyItemClass<br />
MyItemClass = objcclass(NSObject)<br />
private<br />
content : longint;<br />
public<br />
function initWithContent(c: longint): MyItemClass; message 'initWithContent:';<br />
function getContent: longint; message 'getContent';<br />
end;<br />
<br />
implementation<br />
<br />
function MyItemClass.initWithContent(c: longint): MyItemClass;<br />
begin<br />
content:=c;<br />
result:=self;<br />
end;<br />
<br />
function MyItemClass.getContent: longint;<br />
begin<br />
result:=content;<br />
end;<br />
<br />
end.<br />
<br />
// ======================<br />
// ======================<br />
<br />
Program test;<br />
<br />
{$mode objfpc}<br />
{$modeswitch objectivec1}<br />
<br />
// regardless of the order of the units in the uses-clause, as soon as<br />
// ItemClass is used then the full declaration of MyItemClass is in<br />
// scope and all uses of the formal declaration are replaced by the<br />
// actual declaration<br />
uses<br />
ItemClass, ContainerClass;<br />
<br />
var<br />
c: MyContainerClass;<br />
l: longint;<br />
begin<br />
c:=MyContainerClass.alloc.init;<br />
...<br />
// even though MyContainerClass.getItem returns a "formal" MyItemClass,<br />
// the fact that the real declaration is in scope means that it can be<br />
// used as a regular MyItemClass instance<br />
l:=c.getItem.getContent;<br />
end.<br />
</source><br />
<br />
====Objective-Pascal class references====<br />
<br />
Just like in Object Pascal, it is possible to declare a class reference type for an Objective-Pascal class. In Objective-C, these are called meta-classes and are represented by the ''pobjc_class'' type. If you wish to mix code using the ''pobjc_class'' type and the Pascal syntax for class references, you have to use typecasts, as shown below.<br />
<br />
<source><br />
{$mode objfpc}<br />
{$modeswitch objectivec1}<br />
<br />
program Test;<br />
<br />
type<br />
TMyClass = objcclass (NSObject)<br />
end;<br />
TMyClassMeta = class of TMyClass; // declare the meta-class type for dynamic allocation<br />
<br />
var<br />
theClass: pobjc_class;<br />
begin<br />
theClass := TMyClass.classClass; // get the meta-class reference for TMyClass; could <br />
TMyClassMeta(theClass).alloc.init; // cast theClass as TMyClassMeta and send messages as normal<br />
end.<br />
</source><br />
<br />
=== Protocol declaration ===<br />
<br />
An Objective-C Protocol is pretty much the same as an ''interface'' in Object Pascal: it lists a number of methods to be implemented by classes that conform to the protocol. The only difference is that protocol methods can be ''optional''. Moreover, unlike in Object Pascal, a protocol can inherit from multiple other protocols:<br />
<br />
<source><br />
type<br />
ObjCProtocolName = objcprotocol [external [name 'ExternalClassName']] [(ObjCParentProtocol1[, ObjCParentProtocol2, ...])] <br />
[required, optional]<br />
[method declarations]<br />
end;<br />
</source><br />
<br />
* ''objcprotocol'': defines an Objective-C protocol type declaration<br />
* ''external'': same as with objcclass<br />
* ''ObjCParentProtocols'': the protocols this protocol inherits from (so a class conforming to this protocol, will also have to implement all methods from those other protocols)<br />
* ''required, optional'': If nothing is specified, the default is ''required''. ''optional'' methods do not have to be implemented by classes conforming to this protocol.<br />
<br />
Example:<br />
<source><br />
type<br />
MyProtocol = objccprotocol<br />
// default is required<br />
procedure aRequiredMethod; message 'aRequiredMethod';<br />
optional<br />
procedure anOptionalMethodWithPara(para: longint); message 'anOptionalMethodWithPara:';<br />
procedure anotherOptionalMethod; message 'anotherOptionalMethod';<br />
required<br />
function aSecondRequiredMethod: longint; message 'aSecondRequiredMethod';<br />
end;<br />
<br />
MyClassImplementingProtocol = objcclass(NSObject,MyProtocol)<br />
// the "message 'xxx'" modifiers can be repeated, but this is not required<br />
procedure aRequiredMethod;<br />
procedure anOptionalMethodWithPara(para: longint);<br />
function aSecondRequiredMethod: longint;<br />
end;<br />
</source><br />
<br />
Similar to ''objcclass''es, ''objcprotocol''s can be external in case they are implemented in e.g. the Cocoa framework.<br />
<br />
=== Category declaration ===<br />
<br />
An Objective-C category is similar to a ''class helper'' in Object Pascal: it allows adding methods to an existing class, without inheriting from that class. In Objective-C, this functionality goes even further: multiple categories can be in scope at the same time for a particular class, and a category can also replace existing methods in another class rather than only add new ones. Since all methods are virtual in Objective-C, this also means that this method changes for all classes that inherit from the class in which the method was replaced (unless they override it). An Objective-C category can also implement protocols.<br />
<br />
Note that a category cannot extend another category. Furthermore, if two categories add/replace a method with the same selector in the same class, it is undefined which method will actually be called at run time. This would depend on the order in which the categories are registered with the Objective-C run time.<br />
<br />
<source><br />
type<br />
ObjCCategoryName = objccategory [external [name 'ExternalCategoryName']] (ExtendedObjCClass[,ObjCProtocol1, ObjCProtocol2, ...])<br />
[method declarations]<br />
end;<br />
</source><br />
<br />
* ''objccategory'': defines an Objective-C category type declaration<br />
* ''external'': same as with objcclass. As of Objective-C 2.0, the name of a category is optional. ''Not yet implemented'': to declare an external category without a name, use an empty string.<br />
* ''method declarations'': the methods that this category adds or replaces in the extended class. These can be both class and instance methods. Note that when replacing a method in the extended class, you must mark this new method as ''reintroduce''. The reason that we do not use ''override'' here, is that the method is really replaced in the original class. This means, e.g., that if you call ''inherited'' from the new method, that you will call this method in the parent class of the extended class, and not the replaced method. The replaced method is "lost".<br />
* ''ObjCParentProtocols'': the protocols this category implements. The category will have to implement all required methods from these protocols.<br />
<br />
Example:<br />
<source><br />
type<br />
MyProtocol = objcprotocol<br />
procedure protocolmethod; message 'protocolmethod';<br />
end;<br />
<br />
MyCategory = objccategory(NSObject,MyProtocol)<br />
// method replaced in NSObject. This means that every objcclass that does not<br />
// override the hash function will now use this method instead. <br />
function hash: cuint; reintroduce;<br />
<br />
// we have to implement this method, since we declare that we implement the<br />
// MyProtocol protocol. This method is added to NSObject afterwards.<br />
procedure protocolmethod;<br />
<br />
// a random class methods added to NSObject<br />
class procedure newmethod; message 'newmethod';<br />
end;<br />
<br />
</source><br />
<br />
Similar to ''objcclass''es, ''objccategory''s can be external in case they are implemented in e.g. the Cocoa framework.<br />
<br />
=== The ''id'' type ===<br />
<br />
The ''id'' type is special in Objective-C/Pascal. It is assignment-compatible with instances of every objcclass and objcprotocol type, in two directions. This means that you can assign variables of any objcclass/objcprotocol type to a variable of the type ''id'', but also that you can assign these ''id'' variables to variables of any particular objcclass/objcprotocol type. In neither case an explicit typecast is required.<br />
<br />
Furthermore, it is possible to call any Objective-C method declared in an objcclass or objccategory that's in scope using an ''id''-typed variable. If, at run time, the objcclass instance stored in the ''id''-typed variable does not respond to the sent message, the program will terminate with a run time error.<br />
<br />
When there are multiple methods with the same Pascal identifier, the compiler will use the standard overload resolution logic to pick the most appropriate method. In this process, it will behave as if all objcclass/objccategory methods in scope have been declared as global procedures/functions with the ''overload'' specifier. If the compiler cannot determine which overloaded method to call, it will print an error. If you compile with -vh, it will print a list of all methods that could be used to implement the call when it cannot determine the appropriate overloaded method. In this case, you will have to use an explicit type cast to clarify the class type from which you wish to call a method.<br />
<br />
=== Fast enumeration ===<br />
<br />
''Fast enumeration'' is a convention that enables enumerating the elements in a Cocoa container class in a generic yet fast way. The syntax used for this feature is the ''for-in'' construct, both in Objective-C and in Objective-Pascal. This feature behaves identically in both languages. It requires the Objective-C 2.0 mode switch to be activated.<br />
<br />
Example:<br />
<source><br />
{$mode delphi}<br />
{$modeswitch objectivec2}<br />
<br />
uses<br />
CocoaAll;<br />
<br />
var<br />
arr: NSMutableArray;<br />
element: NSString;<br />
pool: NSAutoreleasePool;<br />
i: longint;<br />
begin<br />
pool:=NSAutoreleasePool.alloc.init;<br />
arr:=NSMutableArray.arrayWithObjects(<br />
NSSTR('One'),<br />
NSSTR('Two'),<br />
NSSTR('Three'),<br />
NSSTR('Four'),<br />
NSSTR('Five'),<br />
NSSTR('Six'),<br />
NSSTR('Seven'),<br />
nil);<br />
<br />
i:=0;<br />
for element in arr do<br />
begin<br />
inc(i);<br />
if i=2 then<br />
continue;<br />
if i=5 then<br />
break;<br />
if i in [2,5..10] then<br />
halt(1);<br />
NSLog(NSSTR('element: %@'),element);<br />
end;<br />
pool.release;<br />
end.<br />
</source><br />
<br />
== Syntax (proposed) ==<br />
<br />
== todo: == <br />
<br />
a) how to declare a constant NSString/CFString in Pascal (the @"somestring" from Objective-C)<br />
<br />
-- the dollar sign could work... ex. $theString<br />
<br />
== ObjectiveP Examples ==<br />
<br />
=== Creating and running application with one menu item ===<br />
<br />
Please note, that for the creation of the menu, the application must be located in the application bundle. Lazarus may create the bundle for you.<br />
<br />
<source><br />
program project1;<br />
<br />
{$mode objfpc}{$H+}<br />
{$modeswitch objectivec1}<br />
<br />
uses<br />
CocoaAll;<br />
<br />
type<br />
{ MyCallback }<br />
MyCallback = objcclass(NSObject)<br />
public<br />
procedure haltMenuEvent(sender: id); message 'haltMenuEvent:';<br />
end;<br />
<br />
var<br />
pool : NSAutoreleasePool;<br />
filemenu : NSMenu;<br />
subitem : NSMenuItem;<br />
app : NSApplication;<br />
callback : MyCallback;<br />
<br />
function NSStr(const s: AnsiString): NSString;<br />
begin<br />
if s='' then Result:=NSString.alloc.init<br />
else Result:=NSString.alloc.initWithCString(@s[1]);<br />
end;<br />
<br />
{ MyCallback }<br />
<br />
procedure MyCallback.haltMenuEvent(sender:id);<br />
begin<br />
WriteLn('HALT!');<br />
app.stop(self);<br />
end;<br />
<br />
procedure initMenus;<br />
var<br />
root : NSMenu;<br />
rootitem : NSMenuItem;<br />
begin<br />
root:=NSMenu.alloc.init;<br />
rootitem:=root.addItemWithTitle_action_keyEquivalent(NSStr(''), nil, NSStr(''));<br />
filemenu:=NSMenu.alloc.initWithTitle(NSStr('File'));<br />
rootitem.setSubmenu(filemenu);<br />
rootitem.setEnabled(true);<br />
subitem:=filemenu.addItemWithTitle_action_keyEquivalent(NSStr('Halt'), nil, NSStr(''));<br />
subitem.setEnabled(true);<br />
app.setMainMenu(root);<br />
end;<br />
<br />
procedure InitCallback;<br />
begin<br />
callback:=MyCallback.alloc;<br />
subitem.setAction(ObjCSelector(callback.haltMenuEvent));<br />
subitem.setTarget(callback);<br />
end;<br />
<br />
begin<br />
pool:=NSAutoreleasePool.alloc.init;<br />
app:=NSApplication.sharedApplication;<br />
initMenus;<br />
initCallback;<br />
app.run;<br />
pool.release;<br />
end.<br />
</source><br />
<br />
===Application with a single window and no menus===<br />
<br />
<source><br />
program simplewindow;<br />
<br />
{$mode objfpc}{$H+}<br />
{$modeswitch objectivec2}<br />
<br />
uses<br />
CocoaAll;<br />
<br />
var<br />
appName: NSString;<br />
window: NSWindow;<br />
pool: NSAutoreleasePool;<br />
begin<br />
pool := NSAutoreleasePool.new;<br />
NSApp := NSApplication.sharedApplication;<br />
NSApp.setActivationPolicy(NSApplicationActivationPolicyRegular);<br />
appName := NSProcessInfo.processInfo.processName;<br />
window := NSWindow.alloc.initWithContentRect_styleMask_backing_defer(NSMakeRect(0, 0, 200, 200),<br />
NSTitledWindowMask, NSBackingStoreBuffered, False).autorelease;<br />
window.center;<br />
window.setTitle(appName);<br />
window.makeKeyAndOrderFront(nil);<br />
NSApp.activateIgnoringOtherApps(true);<br />
NSApp.run;<br />
end.<br />
</source><br />
<br />
===Application with a simple window and menus===<br />
<br />
<source><br />
program simplewindow;<br />
<br />
{$mode objfpc}{$H+}<br />
{$modeswitch objectivec2}<br />
<br />
uses<br />
CocoaAll;<br />
<br />
var<br />
{menubar: NSMenu;<br />
appMenu: NSMenu;}<br />
appName: NSString;<br />
{quitMenuItem: NSMenuItem;<br />
appMenuItem: NSMenuItem;<br />
quitTitle: NSString;}<br />
window: NSWindow;<br />
pool: NSAutoreleasePool;<br />
begin<br />
pool := NSAutoreleasePool.new;<br />
NSApp := NSApplication.sharedApplication;<br />
NSApp.setActivationPolicy(NSApplicationActivationPolicyRegular);<br />
menubar := NSMenu.alloc.autorelease;<br />
appMenuItem := NSMenuItem.alloc.autorelease;<br />
menubar.addItem(appMenuItem);<br />
NSApp.setMainMenu(Menubar);<br />
appMenu := NSMenu.new.autorelease;<br />
appName := NSProcessInfo.processInfo.processName;<br />
quitTitle := NSSTR('Quit').stringByAppendingString(appName);<br />
quitMenuItem := NSMenuItem.alloc.initWithTitle_action_keyEquivalent(quitTitle,<br />
sel_registerName(PChar('terminate:')),<br />
NSSTR('q'));<br />
appMenu.addItem(quitMenuItem);<br />
appMenuitem.setSubmenu(appMenu);<br />
window := NSWindow.alloc.initWithContentRect_styleMask_backing_defer(NSMakeRect(0, 0, 200, 200),<br />
NSTitledWindowMask, NSBackingStoreBuffered, False).autorelease;<br />
window.center;<br />
window.setTitle(appName);<br />
window.makeKeyAndOrderFront(nil);<br />
NSApp.activateIgnoringOtherApps(true);<br />
NSApp.run;<br />
end.<br />
</source><br />
<br />
[[Category:Objective-C]]<br />
[[Category:Objective Pascal]]<br />
[[Category:Mac OS X]]<br />
[[Category:Headers and Bindings]]<br />
[[Category:iOS]]<br />
[[Category:Cocoa]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=Contests&diff=86928Contests2015-03-03T10:30:37Z<p>Sekelsenmat: /* Lazarus and Free Pascal (2015) */</p>
<hr />
<div>__TOC__<br />
<br />
This page collects information about subscribing Lazarus and other Pascal software in contests, offering application models and other resources.<br />
<br />
==Qt Center Contest==<br />
<br />
Website:<br />
<br />
http://www.qtcentre.org/contest-<br />
<br />
Duration:<br />
<br />
The contest starts on April 7, 2008 and lasts until September 30, 2008. Registration closes on May 31, 2008.<br />
<br />
===The Lazarus Qt Interface===<br />
<br />
Category:<br />
<br />
Demo<br />
<br />
Description:<br />
<br />
Lazarus is a cross platform Visual Integrated development environment (IDE) which provides Rapid Application Development (RAD) for Pascal and Object Pascal developers. It is developed for and supported by the Free Pascal compiler.<br />
<br />
Lazarus offers a cross-platform library called LCL (Lazarus Component Library), with which the IDE and applications developed with Lazarus are built. This library supports using several different widgetset interfaces. For examples, there are LCL interfaces for: Windows API, Windows CE API, Gtk+, Carbon (Mac OS X), Cocoa (Mac OS X), etc.<br />
<br />
The project is the development of a LCL Interface for Qt 4, using the Qt4 Pascal bindings developed by Den Jean. With a high quality LCL-Qt interface, the Lazarus IDE is able to run purely on Qt, and any LCL written application can also be recompiled to run over Qt.<br />
<br />
==Google Summer of Code==<br />
<br />
===Application models===<br />
<br />
====Free Pascal and Lazarus (2008)====<br />
<br />
1 - What is your Organization's Name?<br />
<br />
Free Pascal and Lazarus<br />
<br />
2 - What is your Organization's Homepage?<br />
<br />
www.freepascal.org<br />
<br />
3 - Describe your organization<br />
<br />
FPC/Lazarus is the joined effort of two development teams to provide a compiler, class libraries and an IDE to allow the development of Pascal programs on all interesting platforms. Currently we support several architectures (x86, Amd64/x86_64, PowerPC, Sparc and ARM), and several operating systems<br />
(Windows, Windows CE, Linux, FreeBSD, Mac OS X, Mac OS classic, DOS,<br />
Win32, OS/2, Netware, MorphOS and others). We, the maintainers of the<br />
FreePascal and Lazarus projects would like to apply as a single<br />
organization (called FPC/Lazarus) since our projects are very closely<br />
related.<br />
<br />
FreePascal (http://www.freepascal.org/) develops a 32 and 64 bit professional Pascal compiler and the runtime environment. The FreePascal project is<br />
already a very long-running OSS project, it has been developed in 1993<br />
with a first release in 1996 and since then<br />
has evolved in a rather large project, already supporting a lot of<br />
platforms on several different processor families.<br />
<br />
Lazarus (http://www.lazarus.freepascal.org) is both the class libraries for Free Pascal that emulates Delphi and a modern and efficient IDE. Lazarus and Free Pascal strive for the write once compile anywhere philosophy. Since the exact same compiler and class library are available on several platforms, no recoding is necessary to produce identical products for them.<br />
<br />
4 - Why is your organization applying to participate in GSoC 2008? What do you hope to gain by participating?<br />
<br />
The FreePascal team would like to take this opportunity to extend the compiler and improve its quality even more. A collection of ideas for students working on the FreePascal can be found at<br />
http://wiki.freepascal.org/index.php/Open_tasks . Of course we are willing to provide more exact requirements for each particular task if required.<br />
<br />
The Lazarus team hopes that this project will allow us to improve our<br />
project, add new features, and make it an even better cross-platform<br />
development environment. There is a collection of ideas to be<br />
implemented here: http://wiki.freepascal.org/Feature_Ideas<br />
<br />
7 - What license does your project use?<br />
<br />
Both the compiler and IDE are provided under the GPL, while the<br />
runtime libraries are provided under the LGPL with the explicit<br />
permission for static linking with proprietary software.<br />
<br />
8 - URL for your ideas page<br />
<br />
http://wiki.freepascal.org/Feature_Ideas<br />
<br />
9 - What is the main development mailing list for your organization?<br />
<br />
fpc-devel here: http://www.freepascal.org/maillist.var<br />
<br />
10 - Where is the main IRC channel for your organization?<br />
<br />
<pre>#fpc on FreeNode server</pre><br />
<br />
About mentors<br />
<br />
1 - What criteria did you use to select these individuals as mentors? Please be as specific as possible.<br />
<br />
All the selected individuals have greatly contributed to our projects.<br />
For a short example, Florian started the Free Pascal compiler, Paul greatly improved several areas of our GUI library and Almindor works on the FreeBSD port.<br />
<br />
Several of the developers have experience with teaching students or work as professional software engineers, so we think that the mentored students will be able to learn a lot about software development besides the experience they can get when participating the Summer of Code.<br />
<br />
2 - Who will your mentors be? Please enter their Google Account address separated by commas. If your organization is accepted we will email each mentor to invite them to take part. (optional)<br />
<br />
almindor at gmail.com, paul.ishenin at gmail.com, florian.klaempfl at gmail.com<br />
<br />
About the program:<br />
<br />
1 - What is your plan for dealing with disappearing students?<br />
<br />
We hope to have a good enough selection so that our students won't disappear.<br />
<br />
2- What is your plan for dealing with disappearing mentors?<br />
<br />
All mentors have worked for many years with Free Pascal and/or<br />
Lazarus. If, nevertheless, any of them disappear, we have many<br />
competent people on our project, and we can nominate a new mentor.<br />
<br />
3 - What steps will you take to encourage students to interact with your project's community before, during and after the program?<br />
<br />
We expect students to interact with the project's community by participating on our mailing list. We hope that the Summer of Code will be a very positive experience for them, which would drive continued participation even after the end of this year's Summer of Code.<br />
<br />
4 - What will you do to ensure that your accepted students stick with the project after GSoC concludes?<br />
<br />
We consider that developing relevant software with FPC and Lazarus is<br />
the best way to encourage people to stick to the project once Summer<br />
of Code ends, because that leads to a natural desire of improving the<br />
tools you use, and we will encourage our students to do so.<br />
<br />
====Virtual Magnifying Glass (2008)====<br />
<br />
1 - What is your Organization's Name?<br />
<br />
Virtual Magnifying Glass<br />
<br />
2 - What is your Organization's Homepage?<br />
<br />
http://magnifier.sourceforge.net/<br />
<br />
3 - Describe your organization<br />
<br />
Virtual Magnifying Glass is designed for visually-impaired and others who need to magnify a part of the screen. Unlike most similar programs it does not open a separate window for the magnification but instead puts a movable magnifying glass on screen.<br />
<br />
With more then 100.000 downloads per year, the Virtual Magnifying Glass is a widely used software which greatly helps visually-impaired and others to use the computer.<br />
<br />
4 - Why is your organization applying to participate in GSoC 2008? What do you hope to gain by participating?<br />
<br />
We have a mission of offering the best magnification tool possible for everyone, but some difficulties like the lack of resources is holding the progress of the some features like the Dynamic Mode and the improvement of the support for Unixes, PDAs and other platforms. So we decided to apply to participate in Google Summer of Code in the hope of gaining the necessary resources to improve this software even further.<br />
<br />
7 - What license does your project use?<br />
<br />
GNU GENERAL PUBLIC LICENSE Version 2, June 1991<br />
<br />
8 - URL for your ideas page<br />
<br />
http://sourceforge.net/tracker/?group_id=60638&atid=494774<br />
<br />
9 - What is the main development mailing list for your organization?<br />
<br />
We don't use a mailing list, but rather a forum: http://sourceforge.net/forum/?group_id=60638<br />
<br />
10 - Where is the main IRC channel for your organization?<br />
<br />
We don't use IRC.<br />
<br />
<br />
About mentors<br />
<br />
1 - What criteria did you use to select these individuals as mentors? Please be as specific as possible.<br />
<br />
All selected individuals have greatly contribute for the Virtual Magnifying Glass in the past.<br />
<br />
About the program:<br />
<br />
1 - What is your plan for dealing with disappearing students?<br />
<br />
We hope to have a good enough selection so that our students won't disappear.<br />
<br />
2- What is your plan for dealing with disappearing mentors?<br />
<br />
In the event of a disappearing mentor, we can call more people from our project to assume the position.<br />
<br />
3 - What steps will you take to encourage students to interact with your project's community before, during and after the program?<br />
<br />
We will expect students to participate on our forums and read the bug tracker as a way to interact with the community.<br />
<br />
4 - What will you do to ensure that your accepted students stick with the project after GSoC concludes?<br />
<br />
We believe that continued work on the project will come naturally due to it's noble objective of improving the quality of life of the visually impaired. Other factors that would influence that are if the student uses the glass personally, or knows personally people that do, or if he develops scientific research based on it.<br />
<br />
<br />
====Lazarus and Free Pascal (2012)====<br />
<br />
1 - Organization name<br />
<br />
Lazarus and Free Pascal<br />
<br />
2 - Organization description<br />
<br />
FreePascal (http://www.freepascal.org/) develops a 32 and 64 bit professional Pascal compiler and the runtime environment. The FreePascal project is already a very long-running OSS project, it has been developed since 1993 with a first release in 1996 and since then has evolved in a rather large project, already supporting a lot of platforms (Android, iOS, PlayStation Portable, Windows, Windows CE, Linux, FreeBSD, Mac OS X, Mac OS classic, DOS, Win32, OS/2, Netware, MorphOS and others) on several different processor families (x86, Amd64/x86_64, PowerPC, Sparc and ARM).<br />
<br />
Lazarus (http://www.lazarus.freepascal.org) is is a modern and efficient IDE which comes with powerful code completion features and a form designer for the Lazarus Component Library, which is a cross-platform GUI toolkit which supports Windows, Linux, Mac OS X, Android, MeeGo, Windows CE and other platforms. Many popular applications are written in Lazarus, such as Double Commander, PeaZip, LazPaint the Virtual Magnifying Glass. <br />
<br />
Lazarus and Free Pascal strive for the write once compile anywhere philosophy. As the exact same compiler and class library are available on several platforms, no recoding is necessary to produce identical products for them. Since our projects are very closely related and interdependent we would like to apply as a single mentoring organization.<br />
<br />
3 - Organization home page url*<br />
<br />
www.lazarus.freepascal.org<br />
<br />
4 - What is the URL for your Ideas page?<br />
<br />
http://wiki.lazarus.freepascal.org/Projects_for_the_Google_Summer_of_Code<br />
<br />
5 - URL for your ideas page<br />
<br />
http://wiki.freepascal.org/Feature_Ideas<br />
<br />
6 - What is the main development mailing list for your organization?<br />
<br />
fpc-devel here: http://www.freepascal.org/maillist.var<br />
<br />
7 - Where is the main IRC channel for your organization?<br />
<br />
<pre>#lazarus-ide and #fpc on FreeNode server</pre><br />
<br />
8 - Why is your organization applying to participate in Google Summer of Code 2012? What do you hope to gain by participating?<br />
<br />
In Lazarus and Free Pascal we are working very hard to push forward our incredible set of Pascal development tools, but even while dozens of core contributors and hundreds of minor ones work very hard in our free times, some sponsoring would help us a lot. It would help us get some much necessary task moving forwards and will also help us be more recognized and in contact with the wider free software community.<br />
<br />
9 - Did your organization participate in past Google Summer of Codes? If so, please summarize your involvement and the successes and challenges of your participation.<br />
<br />
No.<br />
<br />
10 - If your organization has not previously participated in Google Summer of Code, have you applied in the past? If so, for what year(s)?<br />
<br />
We applyed in 2008 and 2009 but our application was rejected without any reason given.<br />
<br />
11 - Does your organization have an application template you would like to see students use? If so, please provide it now.<br />
<br />
http://wiki.lazarus.freepascal.org/Google_Summer_of_Code_Application_Template<br />
<br />
12 - What criteria did you use to select your mentors for this year's program? Please be as specific as possible.<br />
<br />
All the selected individuals have greatly contributed to our projects.<br />
<br />
For a short example, Florian started the Free Pascal compiler and Paul and Felipe greatly improved several areas of our GUI library.<br />
<br />
Several of the developers have experience with teaching students or work as professional software engineers, so we think that the mentored students will be able to learn a lot about software development besides the experience they can get when participating the Summer of Code.<br />
<br />
13 - What is your plan for dealing with disappearing students?<br />
<br />
We will select backup students which can take the spot.<br />
<br />
14 - What is your plan for dealing with disappearing mentors?<br />
<br />
All mentors have worked for many years with Free Pascal and/or Lazarus and it is extremely unlikely that they will disappear. If, nevertheless, any of them disappear, we have many<br />
competent people on our project, and we can nominate a new mentor.<br />
<br />
15 - What steps will you take to encourage students to interact with your project's community before, during and after the program?<br />
<br />
We will select students which enjoy programming in Pascal, enjoy writting free software and have free time to help us beyond the duration of the program. We expect students to interact with the project's community by participating on our mailing list. We hope that the Summer of Code will be a very positive experience for them, which would drive continued participation even after the end of this year's Summer of Code.<br />
<br />
====Lazarus and Free Pascal (2015)====<br />
<br />
Most question fields were the same as for 2012.<br />
<br />
10 - If your organization has not previously participated in Google Summer of Code, have you applied in the past? If so, for what year(s)?<br />
<br />
We applyed in 2008, 2009, 2011 and 2012.<br />
<br />
Reason for rejection:<br />
<br />
"Specifically, we rejected you because your Ideas page was thin compared with a number of other orgs. It inluded a lot of ideas which is good, but other orgs provided more detailed information for students."<br />
<br />
Note:<br />
<br />
2 Administrators were necessary for applying!!! Mischi was the second one.<br />
<br />
===Google Summer of Code 2011===<br />
Page for ideas to be implemented in the Google Summer of Code: [[Projects for the Google Summer of Code]]<br />
<br />
===External Links===<br />
* [http://code.google.com/soc/2008/ Google Summer of Code 2008]<br />
* [http://code.google.com/soc/2008/faqs.html#0.1_about_gsoc Google Summer of Code - Frequently Asked Questions (FAQ)]<br />
* [http://groups.google.com/group/google-summer-of-code-announce/web/notes-on-organization-selection-criteria Notes on Organizations Selection Criteria]<br />
<br />
[[Category:Promotion]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=Contests&diff=86927Contests2015-03-03T10:30:10Z<p>Sekelsenmat: /* Lazarus and Free Pascal (2015) */</p>
<hr />
<div>__TOC__<br />
<br />
This page collects information about subscribing Lazarus and other Pascal software in contests, offering application models and other resources.<br />
<br />
==Qt Center Contest==<br />
<br />
Website:<br />
<br />
http://www.qtcentre.org/contest-<br />
<br />
Duration:<br />
<br />
The contest starts on April 7, 2008 and lasts until September 30, 2008. Registration closes on May 31, 2008.<br />
<br />
===The Lazarus Qt Interface===<br />
<br />
Category:<br />
<br />
Demo<br />
<br />
Description:<br />
<br />
Lazarus is a cross platform Visual Integrated development environment (IDE) which provides Rapid Application Development (RAD) for Pascal and Object Pascal developers. It is developed for and supported by the Free Pascal compiler.<br />
<br />
Lazarus offers a cross-platform library called LCL (Lazarus Component Library), with which the IDE and applications developed with Lazarus are built. This library supports using several different widgetset interfaces. For examples, there are LCL interfaces for: Windows API, Windows CE API, Gtk+, Carbon (Mac OS X), Cocoa (Mac OS X), etc.<br />
<br />
The project is the development of a LCL Interface for Qt 4, using the Qt4 Pascal bindings developed by Den Jean. With a high quality LCL-Qt interface, the Lazarus IDE is able to run purely on Qt, and any LCL written application can also be recompiled to run over Qt.<br />
<br />
==Google Summer of Code==<br />
<br />
===Application models===<br />
<br />
====Free Pascal and Lazarus (2008)====<br />
<br />
1 - What is your Organization's Name?<br />
<br />
Free Pascal and Lazarus<br />
<br />
2 - What is your Organization's Homepage?<br />
<br />
www.freepascal.org<br />
<br />
3 - Describe your organization<br />
<br />
FPC/Lazarus is the joined effort of two development teams to provide a compiler, class libraries and an IDE to allow the development of Pascal programs on all interesting platforms. Currently we support several architectures (x86, Amd64/x86_64, PowerPC, Sparc and ARM), and several operating systems<br />
(Windows, Windows CE, Linux, FreeBSD, Mac OS X, Mac OS classic, DOS,<br />
Win32, OS/2, Netware, MorphOS and others). We, the maintainers of the<br />
FreePascal and Lazarus projects would like to apply as a single<br />
organization (called FPC/Lazarus) since our projects are very closely<br />
related.<br />
<br />
FreePascal (http://www.freepascal.org/) develops a 32 and 64 bit professional Pascal compiler and the runtime environment. The FreePascal project is<br />
already a very long-running OSS project, it has been developed in 1993<br />
with a first release in 1996 and since then<br />
has evolved in a rather large project, already supporting a lot of<br />
platforms on several different processor families.<br />
<br />
Lazarus (http://www.lazarus.freepascal.org) is both the class libraries for Free Pascal that emulates Delphi and a modern and efficient IDE. Lazarus and Free Pascal strive for the write once compile anywhere philosophy. Since the exact same compiler and class library are available on several platforms, no recoding is necessary to produce identical products for them.<br />
<br />
4 - Why is your organization applying to participate in GSoC 2008? What do you hope to gain by participating?<br />
<br />
The FreePascal team would like to take this opportunity to extend the compiler and improve its quality even more. A collection of ideas for students working on the FreePascal can be found at<br />
http://wiki.freepascal.org/index.php/Open_tasks . Of course we are willing to provide more exact requirements for each particular task if required.<br />
<br />
The Lazarus team hopes that this project will allow us to improve our<br />
project, add new features, and make it an even better cross-platform<br />
development environment. There is a collection of ideas to be<br />
implemented here: http://wiki.freepascal.org/Feature_Ideas<br />
<br />
7 - What license does your project use?<br />
<br />
Both the compiler and IDE are provided under the GPL, while the<br />
runtime libraries are provided under the LGPL with the explicit<br />
permission for static linking with proprietary software.<br />
<br />
8 - URL for your ideas page<br />
<br />
http://wiki.freepascal.org/Feature_Ideas<br />
<br />
9 - What is the main development mailing list for your organization?<br />
<br />
fpc-devel here: http://www.freepascal.org/maillist.var<br />
<br />
10 - Where is the main IRC channel for your organization?<br />
<br />
<pre>#fpc on FreeNode server</pre><br />
<br />
About mentors<br />
<br />
1 - What criteria did you use to select these individuals as mentors? Please be as specific as possible.<br />
<br />
All the selected individuals have greatly contributed to our projects.<br />
For a short example, Florian started the Free Pascal compiler, Paul greatly improved several areas of our GUI library and Almindor works on the FreeBSD port.<br />
<br />
Several of the developers have experience with teaching students or work as professional software engineers, so we think that the mentored students will be able to learn a lot about software development besides the experience they can get when participating the Summer of Code.<br />
<br />
2 - Who will your mentors be? Please enter their Google Account address separated by commas. If your organization is accepted we will email each mentor to invite them to take part. (optional)<br />
<br />
almindor at gmail.com, paul.ishenin at gmail.com, florian.klaempfl at gmail.com<br />
<br />
About the program:<br />
<br />
1 - What is your plan for dealing with disappearing students?<br />
<br />
We hope to have a good enough selection so that our students won't disappear.<br />
<br />
2- What is your plan for dealing with disappearing mentors?<br />
<br />
All mentors have worked for many years with Free Pascal and/or<br />
Lazarus. If, nevertheless, any of them disappear, we have many<br />
competent people on our project, and we can nominate a new mentor.<br />
<br />
3 - What steps will you take to encourage students to interact with your project's community before, during and after the program?<br />
<br />
We expect students to interact with the project's community by participating on our mailing list. We hope that the Summer of Code will be a very positive experience for them, which would drive continued participation even after the end of this year's Summer of Code.<br />
<br />
4 - What will you do to ensure that your accepted students stick with the project after GSoC concludes?<br />
<br />
We consider that developing relevant software with FPC and Lazarus is<br />
the best way to encourage people to stick to the project once Summer<br />
of Code ends, because that leads to a natural desire of improving the<br />
tools you use, and we will encourage our students to do so.<br />
<br />
====Virtual Magnifying Glass (2008)====<br />
<br />
1 - What is your Organization's Name?<br />
<br />
Virtual Magnifying Glass<br />
<br />
2 - What is your Organization's Homepage?<br />
<br />
http://magnifier.sourceforge.net/<br />
<br />
3 - Describe your organization<br />
<br />
Virtual Magnifying Glass is designed for visually-impaired and others who need to magnify a part of the screen. Unlike most similar programs it does not open a separate window for the magnification but instead puts a movable magnifying glass on screen.<br />
<br />
With more then 100.000 downloads per year, the Virtual Magnifying Glass is a widely used software which greatly helps visually-impaired and others to use the computer.<br />
<br />
4 - Why is your organization applying to participate in GSoC 2008? What do you hope to gain by participating?<br />
<br />
We have a mission of offering the best magnification tool possible for everyone, but some difficulties like the lack of resources is holding the progress of the some features like the Dynamic Mode and the improvement of the support for Unixes, PDAs and other platforms. So we decided to apply to participate in Google Summer of Code in the hope of gaining the necessary resources to improve this software even further.<br />
<br />
7 - What license does your project use?<br />
<br />
GNU GENERAL PUBLIC LICENSE Version 2, June 1991<br />
<br />
8 - URL for your ideas page<br />
<br />
http://sourceforge.net/tracker/?group_id=60638&atid=494774<br />
<br />
9 - What is the main development mailing list for your organization?<br />
<br />
We don't use a mailing list, but rather a forum: http://sourceforge.net/forum/?group_id=60638<br />
<br />
10 - Where is the main IRC channel for your organization?<br />
<br />
We don't use IRC.<br />
<br />
<br />
About mentors<br />
<br />
1 - What criteria did you use to select these individuals as mentors? Please be as specific as possible.<br />
<br />
All selected individuals have greatly contribute for the Virtual Magnifying Glass in the past.<br />
<br />
About the program:<br />
<br />
1 - What is your plan for dealing with disappearing students?<br />
<br />
We hope to have a good enough selection so that our students won't disappear.<br />
<br />
2- What is your plan for dealing with disappearing mentors?<br />
<br />
In the event of a disappearing mentor, we can call more people from our project to assume the position.<br />
<br />
3 - What steps will you take to encourage students to interact with your project's community before, during and after the program?<br />
<br />
We will expect students to participate on our forums and read the bug tracker as a way to interact with the community.<br />
<br />
4 - What will you do to ensure that your accepted students stick with the project after GSoC concludes?<br />
<br />
We believe that continued work on the project will come naturally due to it's noble objective of improving the quality of life of the visually impaired. Other factors that would influence that are if the student uses the glass personally, or knows personally people that do, or if he develops scientific research based on it.<br />
<br />
<br />
====Lazarus and Free Pascal (2012)====<br />
<br />
1 - Organization name<br />
<br />
Lazarus and Free Pascal<br />
<br />
2 - Organization description<br />
<br />
FreePascal (http://www.freepascal.org/) develops a 32 and 64 bit professional Pascal compiler and the runtime environment. The FreePascal project is already a very long-running OSS project, it has been developed since 1993 with a first release in 1996 and since then has evolved in a rather large project, already supporting a lot of platforms (Android, iOS, PlayStation Portable, Windows, Windows CE, Linux, FreeBSD, Mac OS X, Mac OS classic, DOS, Win32, OS/2, Netware, MorphOS and others) on several different processor families (x86, Amd64/x86_64, PowerPC, Sparc and ARM).<br />
<br />
Lazarus (http://www.lazarus.freepascal.org) is is a modern and efficient IDE which comes with powerful code completion features and a form designer for the Lazarus Component Library, which is a cross-platform GUI toolkit which supports Windows, Linux, Mac OS X, Android, MeeGo, Windows CE and other platforms. Many popular applications are written in Lazarus, such as Double Commander, PeaZip, LazPaint the Virtual Magnifying Glass. <br />
<br />
Lazarus and Free Pascal strive for the write once compile anywhere philosophy. As the exact same compiler and class library are available on several platforms, no recoding is necessary to produce identical products for them. Since our projects are very closely related and interdependent we would like to apply as a single mentoring organization.<br />
<br />
3 - Organization home page url*<br />
<br />
www.lazarus.freepascal.org<br />
<br />
4 - What is the URL for your Ideas page?<br />
<br />
http://wiki.lazarus.freepascal.org/Projects_for_the_Google_Summer_of_Code<br />
<br />
5 - URL for your ideas page<br />
<br />
http://wiki.freepascal.org/Feature_Ideas<br />
<br />
6 - What is the main development mailing list for your organization?<br />
<br />
fpc-devel here: http://www.freepascal.org/maillist.var<br />
<br />
7 - Where is the main IRC channel for your organization?<br />
<br />
<pre>#lazarus-ide and #fpc on FreeNode server</pre><br />
<br />
8 - Why is your organization applying to participate in Google Summer of Code 2012? What do you hope to gain by participating?<br />
<br />
In Lazarus and Free Pascal we are working very hard to push forward our incredible set of Pascal development tools, but even while dozens of core contributors and hundreds of minor ones work very hard in our free times, some sponsoring would help us a lot. It would help us get some much necessary task moving forwards and will also help us be more recognized and in contact with the wider free software community.<br />
<br />
9 - Did your organization participate in past Google Summer of Codes? If so, please summarize your involvement and the successes and challenges of your participation.<br />
<br />
No.<br />
<br />
10 - If your organization has not previously participated in Google Summer of Code, have you applied in the past? If so, for what year(s)?<br />
<br />
We applyed in 2008 and 2009 but our application was rejected without any reason given.<br />
<br />
11 - Does your organization have an application template you would like to see students use? If so, please provide it now.<br />
<br />
http://wiki.lazarus.freepascal.org/Google_Summer_of_Code_Application_Template<br />
<br />
12 - What criteria did you use to select your mentors for this year's program? Please be as specific as possible.<br />
<br />
All the selected individuals have greatly contributed to our projects.<br />
<br />
For a short example, Florian started the Free Pascal compiler and Paul and Felipe greatly improved several areas of our GUI library.<br />
<br />
Several of the developers have experience with teaching students or work as professional software engineers, so we think that the mentored students will be able to learn a lot about software development besides the experience they can get when participating the Summer of Code.<br />
<br />
13 - What is your plan for dealing with disappearing students?<br />
<br />
We will select backup students which can take the spot.<br />
<br />
14 - What is your plan for dealing with disappearing mentors?<br />
<br />
All mentors have worked for many years with Free Pascal and/or Lazarus and it is extremely unlikely that they will disappear. If, nevertheless, any of them disappear, we have many<br />
competent people on our project, and we can nominate a new mentor.<br />
<br />
15 - What steps will you take to encourage students to interact with your project's community before, during and after the program?<br />
<br />
We will select students which enjoy programming in Pascal, enjoy writting free software and have free time to help us beyond the duration of the program. We expect students to interact with the project's community by participating on our mailing list. We hope that the Summer of Code will be a very positive experience for them, which would drive continued participation even after the end of this year's Summer of Code.<br />
<br />
====Lazarus and Free Pascal (2015)====<br />
<br />
10 - If your organization has not previously participated in Google Summer of Code, have you applied in the past? If so, for what year(s)?<br />
<br />
We applyed in 2008, 2009, 2011 and 2012.<br />
<br />
Reason for rejection:<br />
<br />
"Specifically, we rejected you because your Ideas page was thin compared with a number of other orgs. It inluded a lot of ideas which is good, but other orgs provided more detailed information for students."<br />
<br />
Note:<br />
<br />
2 Administrators were necessary for applying!!! Mischi was the second one.<br />
<br />
===Google Summer of Code 2011===<br />
Page for ideas to be implemented in the Google Summer of Code: [[Projects for the Google Summer of Code]]<br />
<br />
===External Links===<br />
* [http://code.google.com/soc/2008/ Google Summer of Code 2008]<br />
* [http://code.google.com/soc/2008/faqs.html#0.1_about_gsoc Google Summer of Code - Frequently Asked Questions (FAQ)]<br />
* [http://groups.google.com/group/google-summer-of-code-announce/web/notes-on-organization-selection-criteria Notes on Organizations Selection Criteria]<br />
<br />
[[Category:Promotion]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=Contests&diff=86926Contests2015-03-03T10:27:30Z<p>Sekelsenmat: /* Lazarus and Free Pascal (2015) */</p>
<hr />
<div>__TOC__<br />
<br />
This page collects information about subscribing Lazarus and other Pascal software in contests, offering application models and other resources.<br />
<br />
==Qt Center Contest==<br />
<br />
Website:<br />
<br />
http://www.qtcentre.org/contest-<br />
<br />
Duration:<br />
<br />
The contest starts on April 7, 2008 and lasts until September 30, 2008. Registration closes on May 31, 2008.<br />
<br />
===The Lazarus Qt Interface===<br />
<br />
Category:<br />
<br />
Demo<br />
<br />
Description:<br />
<br />
Lazarus is a cross platform Visual Integrated development environment (IDE) which provides Rapid Application Development (RAD) for Pascal and Object Pascal developers. It is developed for and supported by the Free Pascal compiler.<br />
<br />
Lazarus offers a cross-platform library called LCL (Lazarus Component Library), with which the IDE and applications developed with Lazarus are built. This library supports using several different widgetset interfaces. For examples, there are LCL interfaces for: Windows API, Windows CE API, Gtk+, Carbon (Mac OS X), Cocoa (Mac OS X), etc.<br />
<br />
The project is the development of a LCL Interface for Qt 4, using the Qt4 Pascal bindings developed by Den Jean. With a high quality LCL-Qt interface, the Lazarus IDE is able to run purely on Qt, and any LCL written application can also be recompiled to run over Qt.<br />
<br />
==Google Summer of Code==<br />
<br />
===Application models===<br />
<br />
====Free Pascal and Lazarus (2008)====<br />
<br />
1 - What is your Organization's Name?<br />
<br />
Free Pascal and Lazarus<br />
<br />
2 - What is your Organization's Homepage?<br />
<br />
www.freepascal.org<br />
<br />
3 - Describe your organization<br />
<br />
FPC/Lazarus is the joined effort of two development teams to provide a compiler, class libraries and an IDE to allow the development of Pascal programs on all interesting platforms. Currently we support several architectures (x86, Amd64/x86_64, PowerPC, Sparc and ARM), and several operating systems<br />
(Windows, Windows CE, Linux, FreeBSD, Mac OS X, Mac OS classic, DOS,<br />
Win32, OS/2, Netware, MorphOS and others). We, the maintainers of the<br />
FreePascal and Lazarus projects would like to apply as a single<br />
organization (called FPC/Lazarus) since our projects are very closely<br />
related.<br />
<br />
FreePascal (http://www.freepascal.org/) develops a 32 and 64 bit professional Pascal compiler and the runtime environment. The FreePascal project is<br />
already a very long-running OSS project, it has been developed in 1993<br />
with a first release in 1996 and since then<br />
has evolved in a rather large project, already supporting a lot of<br />
platforms on several different processor families.<br />
<br />
Lazarus (http://www.lazarus.freepascal.org) is both the class libraries for Free Pascal that emulates Delphi and a modern and efficient IDE. Lazarus and Free Pascal strive for the write once compile anywhere philosophy. Since the exact same compiler and class library are available on several platforms, no recoding is necessary to produce identical products for them.<br />
<br />
4 - Why is your organization applying to participate in GSoC 2008? What do you hope to gain by participating?<br />
<br />
The FreePascal team would like to take this opportunity to extend the compiler and improve its quality even more. A collection of ideas for students working on the FreePascal can be found at<br />
http://wiki.freepascal.org/index.php/Open_tasks . Of course we are willing to provide more exact requirements for each particular task if required.<br />
<br />
The Lazarus team hopes that this project will allow us to improve our<br />
project, add new features, and make it an even better cross-platform<br />
development environment. There is a collection of ideas to be<br />
implemented here: http://wiki.freepascal.org/Feature_Ideas<br />
<br />
7 - What license does your project use?<br />
<br />
Both the compiler and IDE are provided under the GPL, while the<br />
runtime libraries are provided under the LGPL with the explicit<br />
permission for static linking with proprietary software.<br />
<br />
8 - URL for your ideas page<br />
<br />
http://wiki.freepascal.org/Feature_Ideas<br />
<br />
9 - What is the main development mailing list for your organization?<br />
<br />
fpc-devel here: http://www.freepascal.org/maillist.var<br />
<br />
10 - Where is the main IRC channel for your organization?<br />
<br />
<pre>#fpc on FreeNode server</pre><br />
<br />
About mentors<br />
<br />
1 - What criteria did you use to select these individuals as mentors? Please be as specific as possible.<br />
<br />
All the selected individuals have greatly contributed to our projects.<br />
For a short example, Florian started the Free Pascal compiler, Paul greatly improved several areas of our GUI library and Almindor works on the FreeBSD port.<br />
<br />
Several of the developers have experience with teaching students or work as professional software engineers, so we think that the mentored students will be able to learn a lot about software development besides the experience they can get when participating the Summer of Code.<br />
<br />
2 - Who will your mentors be? Please enter their Google Account address separated by commas. If your organization is accepted we will email each mentor to invite them to take part. (optional)<br />
<br />
almindor at gmail.com, paul.ishenin at gmail.com, florian.klaempfl at gmail.com<br />
<br />
About the program:<br />
<br />
1 - What is your plan for dealing with disappearing students?<br />
<br />
We hope to have a good enough selection so that our students won't disappear.<br />
<br />
2- What is your plan for dealing with disappearing mentors?<br />
<br />
All mentors have worked for many years with Free Pascal and/or<br />
Lazarus. If, nevertheless, any of them disappear, we have many<br />
competent people on our project, and we can nominate a new mentor.<br />
<br />
3 - What steps will you take to encourage students to interact with your project's community before, during and after the program?<br />
<br />
We expect students to interact with the project's community by participating on our mailing list. We hope that the Summer of Code will be a very positive experience for them, which would drive continued participation even after the end of this year's Summer of Code.<br />
<br />
4 - What will you do to ensure that your accepted students stick with the project after GSoC concludes?<br />
<br />
We consider that developing relevant software with FPC and Lazarus is<br />
the best way to encourage people to stick to the project once Summer<br />
of Code ends, because that leads to a natural desire of improving the<br />
tools you use, and we will encourage our students to do so.<br />
<br />
====Virtual Magnifying Glass (2008)====<br />
<br />
1 - What is your Organization's Name?<br />
<br />
Virtual Magnifying Glass<br />
<br />
2 - What is your Organization's Homepage?<br />
<br />
http://magnifier.sourceforge.net/<br />
<br />
3 - Describe your organization<br />
<br />
Virtual Magnifying Glass is designed for visually-impaired and others who need to magnify a part of the screen. Unlike most similar programs it does not open a separate window for the magnification but instead puts a movable magnifying glass on screen.<br />
<br />
With more then 100.000 downloads per year, the Virtual Magnifying Glass is a widely used software which greatly helps visually-impaired and others to use the computer.<br />
<br />
4 - Why is your organization applying to participate in GSoC 2008? What do you hope to gain by participating?<br />
<br />
We have a mission of offering the best magnification tool possible for everyone, but some difficulties like the lack of resources is holding the progress of the some features like the Dynamic Mode and the improvement of the support for Unixes, PDAs and other platforms. So we decided to apply to participate in Google Summer of Code in the hope of gaining the necessary resources to improve this software even further.<br />
<br />
7 - What license does your project use?<br />
<br />
GNU GENERAL PUBLIC LICENSE Version 2, June 1991<br />
<br />
8 - URL for your ideas page<br />
<br />
http://sourceforge.net/tracker/?group_id=60638&atid=494774<br />
<br />
9 - What is the main development mailing list for your organization?<br />
<br />
We don't use a mailing list, but rather a forum: http://sourceforge.net/forum/?group_id=60638<br />
<br />
10 - Where is the main IRC channel for your organization?<br />
<br />
We don't use IRC.<br />
<br />
<br />
About mentors<br />
<br />
1 - What criteria did you use to select these individuals as mentors? Please be as specific as possible.<br />
<br />
All selected individuals have greatly contribute for the Virtual Magnifying Glass in the past.<br />
<br />
About the program:<br />
<br />
1 - What is your plan for dealing with disappearing students?<br />
<br />
We hope to have a good enough selection so that our students won't disappear.<br />
<br />
2- What is your plan for dealing with disappearing mentors?<br />
<br />
In the event of a disappearing mentor, we can call more people from our project to assume the position.<br />
<br />
3 - What steps will you take to encourage students to interact with your project's community before, during and after the program?<br />
<br />
We will expect students to participate on our forums and read the bug tracker as a way to interact with the community.<br />
<br />
4 - What will you do to ensure that your accepted students stick with the project after GSoC concludes?<br />
<br />
We believe that continued work on the project will come naturally due to it's noble objective of improving the quality of life of the visually impaired. Other factors that would influence that are if the student uses the glass personally, or knows personally people that do, or if he develops scientific research based on it.<br />
<br />
<br />
====Lazarus and Free Pascal (2012)====<br />
<br />
1 - Organization name<br />
<br />
Lazarus and Free Pascal<br />
<br />
2 - Organization description<br />
<br />
FreePascal (http://www.freepascal.org/) develops a 32 and 64 bit professional Pascal compiler and the runtime environment. The FreePascal project is already a very long-running OSS project, it has been developed since 1993 with a first release in 1996 and since then has evolved in a rather large project, already supporting a lot of platforms (Android, iOS, PlayStation Portable, Windows, Windows CE, Linux, FreeBSD, Mac OS X, Mac OS classic, DOS, Win32, OS/2, Netware, MorphOS and others) on several different processor families (x86, Amd64/x86_64, PowerPC, Sparc and ARM).<br />
<br />
Lazarus (http://www.lazarus.freepascal.org) is is a modern and efficient IDE which comes with powerful code completion features and a form designer for the Lazarus Component Library, which is a cross-platform GUI toolkit which supports Windows, Linux, Mac OS X, Android, MeeGo, Windows CE and other platforms. Many popular applications are written in Lazarus, such as Double Commander, PeaZip, LazPaint the Virtual Magnifying Glass. <br />
<br />
Lazarus and Free Pascal strive for the write once compile anywhere philosophy. As the exact same compiler and class library are available on several platforms, no recoding is necessary to produce identical products for them. Since our projects are very closely related and interdependent we would like to apply as a single mentoring organization.<br />
<br />
3 - Organization home page url*<br />
<br />
www.lazarus.freepascal.org<br />
<br />
4 - What is the URL for your Ideas page?<br />
<br />
http://wiki.lazarus.freepascal.org/Projects_for_the_Google_Summer_of_Code<br />
<br />
5 - URL for your ideas page<br />
<br />
http://wiki.freepascal.org/Feature_Ideas<br />
<br />
6 - What is the main development mailing list for your organization?<br />
<br />
fpc-devel here: http://www.freepascal.org/maillist.var<br />
<br />
7 - Where is the main IRC channel for your organization?<br />
<br />
<pre>#lazarus-ide and #fpc on FreeNode server</pre><br />
<br />
8 - Why is your organization applying to participate in Google Summer of Code 2012? What do you hope to gain by participating?<br />
<br />
In Lazarus and Free Pascal we are working very hard to push forward our incredible set of Pascal development tools, but even while dozens of core contributors and hundreds of minor ones work very hard in our free times, some sponsoring would help us a lot. It would help us get some much necessary task moving forwards and will also help us be more recognized and in contact with the wider free software community.<br />
<br />
9 - Did your organization participate in past Google Summer of Codes? If so, please summarize your involvement and the successes and challenges of your participation.<br />
<br />
No.<br />
<br />
10 - If your organization has not previously participated in Google Summer of Code, have you applied in the past? If so, for what year(s)?<br />
<br />
We applyed in 2008 and 2009 but our application was rejected without any reason given.<br />
<br />
11 - Does your organization have an application template you would like to see students use? If so, please provide it now.<br />
<br />
http://wiki.lazarus.freepascal.org/Google_Summer_of_Code_Application_Template<br />
<br />
12 - What criteria did you use to select your mentors for this year's program? Please be as specific as possible.<br />
<br />
All the selected individuals have greatly contributed to our projects.<br />
<br />
For a short example, Florian started the Free Pascal compiler and Paul and Felipe greatly improved several areas of our GUI library.<br />
<br />
Several of the developers have experience with teaching students or work as professional software engineers, so we think that the mentored students will be able to learn a lot about software development besides the experience they can get when participating the Summer of Code.<br />
<br />
13 - What is your plan for dealing with disappearing students?<br />
<br />
We will select backup students which can take the spot.<br />
<br />
14 - What is your plan for dealing with disappearing mentors?<br />
<br />
All mentors have worked for many years with Free Pascal and/or Lazarus and it is extremely unlikely that they will disappear. If, nevertheless, any of them disappear, we have many<br />
competent people on our project, and we can nominate a new mentor.<br />
<br />
15 - What steps will you take to encourage students to interact with your project's community before, during and after the program?<br />
<br />
We will select students which enjoy programming in Pascal, enjoy writting free software and have free time to help us beyond the duration of the program. We expect students to interact with the project's community by participating on our mailing list. We hope that the Summer of Code will be a very positive experience for them, which would drive continued participation even after the end of this year's Summer of Code.<br />
<br />
====Lazarus and Free Pascal (2015)====<br />
<br />
10 - If your organization has not previously participated in Google Summer of Code, have you applied in the past? If so, for what year(s)?<br />
<br />
We applyed in 2008, 2009 and 2012.<br />
<br />
Reason for rejection:<br />
<br />
"Specifically, we rejected you because your Ideas page was thin compared with a number of other orgs. It inluded a lot of ideas which is good, but other orgs provided more detailed information for students."<br />
<br />
Note:<br />
<br />
2 Administrators were necessary for applying!!! Mischi was the second one.<br />
<br />
===Google Summer of Code 2011===<br />
Page for ideas to be implemented in the Google Summer of Code: [[Projects for the Google Summer of Code]]<br />
<br />
===External Links===<br />
* [http://code.google.com/soc/2008/ Google Summer of Code 2008]<br />
* [http://code.google.com/soc/2008/faqs.html#0.1_about_gsoc Google Summer of Code - Frequently Asked Questions (FAQ)]<br />
* [http://groups.google.com/group/google-summer-of-code-announce/web/notes-on-organization-selection-criteria Notes on Organizations Selection Criteria]<br />
<br />
[[Category:Promotion]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=Contests&diff=86925Contests2015-03-03T10:26:16Z<p>Sekelsenmat: /* Lazarus and Free Pascal (2012) */</p>
<hr />
<div>__TOC__<br />
<br />
This page collects information about subscribing Lazarus and other Pascal software in contests, offering application models and other resources.<br />
<br />
==Qt Center Contest==<br />
<br />
Website:<br />
<br />
http://www.qtcentre.org/contest-<br />
<br />
Duration:<br />
<br />
The contest starts on April 7, 2008 and lasts until September 30, 2008. Registration closes on May 31, 2008.<br />
<br />
===The Lazarus Qt Interface===<br />
<br />
Category:<br />
<br />
Demo<br />
<br />
Description:<br />
<br />
Lazarus is a cross platform Visual Integrated development environment (IDE) which provides Rapid Application Development (RAD) for Pascal and Object Pascal developers. It is developed for and supported by the Free Pascal compiler.<br />
<br />
Lazarus offers a cross-platform library called LCL (Lazarus Component Library), with which the IDE and applications developed with Lazarus are built. This library supports using several different widgetset interfaces. For examples, there are LCL interfaces for: Windows API, Windows CE API, Gtk+, Carbon (Mac OS X), Cocoa (Mac OS X), etc.<br />
<br />
The project is the development of a LCL Interface for Qt 4, using the Qt4 Pascal bindings developed by Den Jean. With a high quality LCL-Qt interface, the Lazarus IDE is able to run purely on Qt, and any LCL written application can also be recompiled to run over Qt.<br />
<br />
==Google Summer of Code==<br />
<br />
===Application models===<br />
<br />
====Free Pascal and Lazarus (2008)====<br />
<br />
1 - What is your Organization's Name?<br />
<br />
Free Pascal and Lazarus<br />
<br />
2 - What is your Organization's Homepage?<br />
<br />
www.freepascal.org<br />
<br />
3 - Describe your organization<br />
<br />
FPC/Lazarus is the joined effort of two development teams to provide a compiler, class libraries and an IDE to allow the development of Pascal programs on all interesting platforms. Currently we support several architectures (x86, Amd64/x86_64, PowerPC, Sparc and ARM), and several operating systems<br />
(Windows, Windows CE, Linux, FreeBSD, Mac OS X, Mac OS classic, DOS,<br />
Win32, OS/2, Netware, MorphOS and others). We, the maintainers of the<br />
FreePascal and Lazarus projects would like to apply as a single<br />
organization (called FPC/Lazarus) since our projects are very closely<br />
related.<br />
<br />
FreePascal (http://www.freepascal.org/) develops a 32 and 64 bit professional Pascal compiler and the runtime environment. The FreePascal project is<br />
already a very long-running OSS project, it has been developed in 1993<br />
with a first release in 1996 and since then<br />
has evolved in a rather large project, already supporting a lot of<br />
platforms on several different processor families.<br />
<br />
Lazarus (http://www.lazarus.freepascal.org) is both the class libraries for Free Pascal that emulates Delphi and a modern and efficient IDE. Lazarus and Free Pascal strive for the write once compile anywhere philosophy. Since the exact same compiler and class library are available on several platforms, no recoding is necessary to produce identical products for them.<br />
<br />
4 - Why is your organization applying to participate in GSoC 2008? What do you hope to gain by participating?<br />
<br />
The FreePascal team would like to take this opportunity to extend the compiler and improve its quality even more. A collection of ideas for students working on the FreePascal can be found at<br />
http://wiki.freepascal.org/index.php/Open_tasks . Of course we are willing to provide more exact requirements for each particular task if required.<br />
<br />
The Lazarus team hopes that this project will allow us to improve our<br />
project, add new features, and make it an even better cross-platform<br />
development environment. There is a collection of ideas to be<br />
implemented here: http://wiki.freepascal.org/Feature_Ideas<br />
<br />
7 - What license does your project use?<br />
<br />
Both the compiler and IDE are provided under the GPL, while the<br />
runtime libraries are provided under the LGPL with the explicit<br />
permission for static linking with proprietary software.<br />
<br />
8 - URL for your ideas page<br />
<br />
http://wiki.freepascal.org/Feature_Ideas<br />
<br />
9 - What is the main development mailing list for your organization?<br />
<br />
fpc-devel here: http://www.freepascal.org/maillist.var<br />
<br />
10 - Where is the main IRC channel for your organization?<br />
<br />
<pre>#fpc on FreeNode server</pre><br />
<br />
About mentors<br />
<br />
1 - What criteria did you use to select these individuals as mentors? Please be as specific as possible.<br />
<br />
All the selected individuals have greatly contributed to our projects.<br />
For a short example, Florian started the Free Pascal compiler, Paul greatly improved several areas of our GUI library and Almindor works on the FreeBSD port.<br />
<br />
Several of the developers have experience with teaching students or work as professional software engineers, so we think that the mentored students will be able to learn a lot about software development besides the experience they can get when participating the Summer of Code.<br />
<br />
2 - Who will your mentors be? Please enter their Google Account address separated by commas. If your organization is accepted we will email each mentor to invite them to take part. (optional)<br />
<br />
almindor at gmail.com, paul.ishenin at gmail.com, florian.klaempfl at gmail.com<br />
<br />
About the program:<br />
<br />
1 - What is your plan for dealing with disappearing students?<br />
<br />
We hope to have a good enough selection so that our students won't disappear.<br />
<br />
2- What is your plan for dealing with disappearing mentors?<br />
<br />
All mentors have worked for many years with Free Pascal and/or<br />
Lazarus. If, nevertheless, any of them disappear, we have many<br />
competent people on our project, and we can nominate a new mentor.<br />
<br />
3 - What steps will you take to encourage students to interact with your project's community before, during and after the program?<br />
<br />
We expect students to interact with the project's community by participating on our mailing list. We hope that the Summer of Code will be a very positive experience for them, which would drive continued participation even after the end of this year's Summer of Code.<br />
<br />
4 - What will you do to ensure that your accepted students stick with the project after GSoC concludes?<br />
<br />
We consider that developing relevant software with FPC and Lazarus is<br />
the best way to encourage people to stick to the project once Summer<br />
of Code ends, because that leads to a natural desire of improving the<br />
tools you use, and we will encourage our students to do so.<br />
<br />
====Virtual Magnifying Glass (2008)====<br />
<br />
1 - What is your Organization's Name?<br />
<br />
Virtual Magnifying Glass<br />
<br />
2 - What is your Organization's Homepage?<br />
<br />
http://magnifier.sourceforge.net/<br />
<br />
3 - Describe your organization<br />
<br />
Virtual Magnifying Glass is designed for visually-impaired and others who need to magnify a part of the screen. Unlike most similar programs it does not open a separate window for the magnification but instead puts a movable magnifying glass on screen.<br />
<br />
With more then 100.000 downloads per year, the Virtual Magnifying Glass is a widely used software which greatly helps visually-impaired and others to use the computer.<br />
<br />
4 - Why is your organization applying to participate in GSoC 2008? What do you hope to gain by participating?<br />
<br />
We have a mission of offering the best magnification tool possible for everyone, but some difficulties like the lack of resources is holding the progress of the some features like the Dynamic Mode and the improvement of the support for Unixes, PDAs and other platforms. So we decided to apply to participate in Google Summer of Code in the hope of gaining the necessary resources to improve this software even further.<br />
<br />
7 - What license does your project use?<br />
<br />
GNU GENERAL PUBLIC LICENSE Version 2, June 1991<br />
<br />
8 - URL for your ideas page<br />
<br />
http://sourceforge.net/tracker/?group_id=60638&atid=494774<br />
<br />
9 - What is the main development mailing list for your organization?<br />
<br />
We don't use a mailing list, but rather a forum: http://sourceforge.net/forum/?group_id=60638<br />
<br />
10 - Where is the main IRC channel for your organization?<br />
<br />
We don't use IRC.<br />
<br />
<br />
About mentors<br />
<br />
1 - What criteria did you use to select these individuals as mentors? Please be as specific as possible.<br />
<br />
All selected individuals have greatly contribute for the Virtual Magnifying Glass in the past.<br />
<br />
About the program:<br />
<br />
1 - What is your plan for dealing with disappearing students?<br />
<br />
We hope to have a good enough selection so that our students won't disappear.<br />
<br />
2- What is your plan for dealing with disappearing mentors?<br />
<br />
In the event of a disappearing mentor, we can call more people from our project to assume the position.<br />
<br />
3 - What steps will you take to encourage students to interact with your project's community before, during and after the program?<br />
<br />
We will expect students to participate on our forums and read the bug tracker as a way to interact with the community.<br />
<br />
4 - What will you do to ensure that your accepted students stick with the project after GSoC concludes?<br />
<br />
We believe that continued work on the project will come naturally due to it's noble objective of improving the quality of life of the visually impaired. Other factors that would influence that are if the student uses the glass personally, or knows personally people that do, or if he develops scientific research based on it.<br />
<br />
<br />
====Lazarus and Free Pascal (2012)====<br />
<br />
1 - Organization name<br />
<br />
Lazarus and Free Pascal<br />
<br />
2 - Organization description<br />
<br />
FreePascal (http://www.freepascal.org/) develops a 32 and 64 bit professional Pascal compiler and the runtime environment. The FreePascal project is already a very long-running OSS project, it has been developed since 1993 with a first release in 1996 and since then has evolved in a rather large project, already supporting a lot of platforms (Android, iOS, PlayStation Portable, Windows, Windows CE, Linux, FreeBSD, Mac OS X, Mac OS classic, DOS, Win32, OS/2, Netware, MorphOS and others) on several different processor families (x86, Amd64/x86_64, PowerPC, Sparc and ARM).<br />
<br />
Lazarus (http://www.lazarus.freepascal.org) is is a modern and efficient IDE which comes with powerful code completion features and a form designer for the Lazarus Component Library, which is a cross-platform GUI toolkit which supports Windows, Linux, Mac OS X, Android, MeeGo, Windows CE and other platforms. Many popular applications are written in Lazarus, such as Double Commander, PeaZip, LazPaint the Virtual Magnifying Glass. <br />
<br />
Lazarus and Free Pascal strive for the write once compile anywhere philosophy. As the exact same compiler and class library are available on several platforms, no recoding is necessary to produce identical products for them. Since our projects are very closely related and interdependent we would like to apply as a single mentoring organization.<br />
<br />
3 - Organization home page url*<br />
<br />
www.lazarus.freepascal.org<br />
<br />
4 - What is the URL for your Ideas page?<br />
<br />
http://wiki.lazarus.freepascal.org/Projects_for_the_Google_Summer_of_Code<br />
<br />
5 - URL for your ideas page<br />
<br />
http://wiki.freepascal.org/Feature_Ideas<br />
<br />
6 - What is the main development mailing list for your organization?<br />
<br />
fpc-devel here: http://www.freepascal.org/maillist.var<br />
<br />
7 - Where is the main IRC channel for your organization?<br />
<br />
<pre>#lazarus-ide and #fpc on FreeNode server</pre><br />
<br />
8 - Why is your organization applying to participate in Google Summer of Code 2012? What do you hope to gain by participating?<br />
<br />
In Lazarus and Free Pascal we are working very hard to push forward our incredible set of Pascal development tools, but even while dozens of core contributors and hundreds of minor ones work very hard in our free times, some sponsoring would help us a lot. It would help us get some much necessary task moving forwards and will also help us be more recognized and in contact with the wider free software community.<br />
<br />
9 - Did your organization participate in past Google Summer of Codes? If so, please summarize your involvement and the successes and challenges of your participation.<br />
<br />
No.<br />
<br />
10 - If your organization has not previously participated in Google Summer of Code, have you applied in the past? If so, for what year(s)?<br />
<br />
We applyed in 2008 and 2009 but our application was rejected without any reason given.<br />
<br />
11 - Does your organization have an application template you would like to see students use? If so, please provide it now.<br />
<br />
http://wiki.lazarus.freepascal.org/Google_Summer_of_Code_Application_Template<br />
<br />
12 - What criteria did you use to select your mentors for this year's program? Please be as specific as possible.<br />
<br />
All the selected individuals have greatly contributed to our projects.<br />
<br />
For a short example, Florian started the Free Pascal compiler and Paul and Felipe greatly improved several areas of our GUI library.<br />
<br />
Several of the developers have experience with teaching students or work as professional software engineers, so we think that the mentored students will be able to learn a lot about software development besides the experience they can get when participating the Summer of Code.<br />
<br />
13 - What is your plan for dealing with disappearing students?<br />
<br />
We will select backup students which can take the spot.<br />
<br />
14 - What is your plan for dealing with disappearing mentors?<br />
<br />
All mentors have worked for many years with Free Pascal and/or Lazarus and it is extremely unlikely that they will disappear. If, nevertheless, any of them disappear, we have many<br />
competent people on our project, and we can nominate a new mentor.<br />
<br />
15 - What steps will you take to encourage students to interact with your project's community before, during and after the program?<br />
<br />
We will select students which enjoy programming in Pascal, enjoy writting free software and have free time to help us beyond the duration of the program. We expect students to interact with the project's community by participating on our mailing list. We hope that the Summer of Code will be a very positive experience for them, which would drive continued participation even after the end of this year's Summer of Code.<br />
<br />
====Lazarus and Free Pascal (2015)====<br />
<br />
10 - If your organization has not previously participated in Google Summer of Code, have you applied in the past? If so, for what year(s)?<br />
<br />
We applyed in 2008, 2009 and 2012.<br />
<br />
Reason for rejection:<br />
<br />
Idea pages was too thin, therefore we should work on it.<br />
<br />
Note:<br />
<br />
2 Administrators were necessary for applying!!! Mischi was the second one.<br />
<br />
===Google Summer of Code 2011===<br />
Page for ideas to be implemented in the Google Summer of Code: [[Projects for the Google Summer of Code]]<br />
<br />
===External Links===<br />
* [http://code.google.com/soc/2008/ Google Summer of Code 2008]<br />
* [http://code.google.com/soc/2008/faqs.html#0.1_about_gsoc Google Summer of Code - Frequently Asked Questions (FAQ)]<br />
* [http://groups.google.com/group/google-summer-of-code-announce/web/notes-on-organization-selection-criteria Notes on Organizations Selection Criteria]<br />
<br />
[[Category:Promotion]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=Roadmap&diff=86486Roadmap2015-02-16T10:16:03Z<p>Sekelsenmat: /* Status of TCustomControl based controls on each widgetset */</p>
<hr />
<div>{{Roadmap}}<br />
<br />
This document gives an idea of the current status of the various parts of Lazarus and also helps new contributors to find a suitable place where they can help. It also shows the people implementing the various parts and the targets.<br />
<br />
__TOC__<br />
<br />
{{Template:Development Status}}<br />
<br />
==General status of widgetsets==<br />
<br />
{{Template:Widgetset Roadmap}}<br />
<br />
==Current status of the various parts of Lazarus==<br />
<br />
<br />
{| class="wikitable sortable"<br />
! Unit !! Item !! State !! Target !! Skills !! Responsible !! Comments<br />
|---- class="working"<br />
|IDE||TCollection Editor||working||0.9.x||FCL, RTTI, IDE||-||A generic TCollection editor for the various TCollections in the LCL/FCL.<br />
|---- class="working"<br />
|IDE||TActionList||working||0.9.x||-||-||-<br />
|---- class="working"<br />
|IDE||Doc Editor||working||-||fpdoc||-||The doc editor will be an integrated fpDoc editor similar to fpde. It will be a process of its own, so that it can show help for dialogs as well. It should also be able to write help for packages.<br />
|---- class="working"<br />
|IDE||Export LFM as xml||working||-||-||-||Load and save LFM files to XML.<br />
|---- class="partial"<br />
|IDE||[[Icon Editor Roadmap]]||in progress||post 1.0||-||-||A simple icon editor with the ability to create lrs files. It will be a good example and can help newbies to create icons for their components.<br />
|---- class="working"<br />
|LCL||Borderspacing||working||0.9.x||-||-||for aligned controls<br />
|---- class="working"<br />
|LCL||Drag&Drop||working||||-||-||<br />
|---- class="working"<br />
|LCL||Port to Darwin Power PC, Mac OS X||working||0.9.x||-||-||depends on FPC 1.9.5<br />
|---- class="working"<br />
|LCL||Port to Mac OS X x86||working||-||-||-||depends on FPC 2.1.1<br />
|---- class="working"<br />
|LCL||TSplitter||working||0.9.x||easy||-||-<br />
|---- class="working"<br />
|LCL||TFindDialog||working||-||-||-||Implemented in 0.9.16<br />
|---- class="working"<br />
|LCL||TReplaceDialog||working||-||-||-||Implemented in 0.9.16<br />
|---- class="working"<br />
|LCL||TControl.Font||in progress||0.9.x||-||-||-<br />
|---- class="working"<br />
|LCL||TTabControl||in progress||0.9.x||-||-||-<br />
|---- class="partial"<br />
|LCL||Docking (= the combination of forms)||partially working, in progress||post 1.0||deep LCL and interfaces||Mattias||-<br />
|---- class="working"<br />
|LCL||Frames (= forms as children)||working||0.9.28||deep knowledge of LCL||Mattias, Paul||-<br />
|---- class="working"<br />
|IDE||Visual Form Inheritence||working||post 1.0||IDE||Mattias||Properties are not yet propagated to open descendants<br />
|---- class="partial"<br />
|LCL||MDI - Multiple Documents Interfaces Putting fo ...||in progress||1.2||deep LCL and interfaces||[[User:Zeljan|Zeljan]]||An MDI LCL emulator for widgetsets which does not support MDI, also native implementation of MDI for qt and win32/64. Currently only qt has full MDI support, others are in progress.<br />
|---- class="not"<br />
|LCL||Palette support||not implemented||-||-||-||Required to correctly show colors on a 256 colors display<br />
|---- class="partial"<br />
|LCL||TCoolBar||partially working, in progress||post 1.0||LCL and anchoring||[[User:JuhaManninen|Juha]]||-<br />
|---- class="partial"<br />
|LCL||TControlBar||skeleton implementation to prevent errors in Delphi conversion, in progress||post 1.0||LCL and anchoring||[[User:JuhaManninen|Juha]]||-<br />
|---- class="working"<br />
|LCL||TMaskEdit||working||-||-||[[User:Bart|Bart]]||-<br />
|---- class="not"<br />
|LCL||TDirectoryTreeView||not implemented||-||-||-||-<br />
|---- class="not"<br />
|LCL||Constrain maximization to specific area||not implemented||-||winapi, gtk||-||When maximizing a window, the left, top, width and height can all be constrained to a specific rectangular area on the screen/desktop. After this is done, constrain the source editor and maybe other windows<br />
|---- class="working"<br />
|Components||TIcon||working||0.9.26||-||Marc||-<br />
|---- class="working"<br />
|Components||CUPS Package||working||0.9.x||easy||-||<br />
|---- class="working"<br />
|}<br />
<br />
==Status of features on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|Accelerator Keys<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Caret<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Clipboard<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|Cursors<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Drag & Drop<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|[[Drop files event]]<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|MDI Support<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Printing<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Regions<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="partial"|Partially Implemented||class="working"|Working<br />
|----<br />
|TCustomControl descendents<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|Unicode Support<br />
|class="working"|Working||class="not"|Impossible to Implement||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|[[BidiMode]]<br />
|class="working"|Working||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Application||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TTimer||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TApplication.QueueAsyncCall||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|TThread.Synchronize||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class="unknown"|Unknown<br />
|class="working"|Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|PostMessage||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class=""unknown"|Unknown<br />
|class="not"|Not Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|PostThreadMessage||class="working"|Working||class="unknown"|Unknown||class="unknown"|Unknown<br />
|class="unknown"|Unknown||class="unknown"|Unknown||class="unknown"|Unknown<br />
|class="unknown"|Unknown||class="unknown"|Unknown||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of Graphics on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBitmap/TPixmap/TIcon/etc||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TBrush||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TFont||class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TPen||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|ExtTextOut||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="unknown"|Unknown||class="working"|Working<br />
|}<br />
<br />
==Status of native controls on each widgetset==<br />
Native controls are TWinControl descendants which do not descend from TCustomControl.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBitBtn||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TCalendar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TCheckBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TCheckGroup||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TCheckListBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TComboBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TEdit||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TForm||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TGroupBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TIdleTimer||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TImageList||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working|| class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TListBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TListView||class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TMainMenu||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TMemo||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TMenuItem||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TPageControl and TTabSheet||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TPairSplitter||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TPanel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TPopupMenu||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TProgressBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TRadioButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|----<br />
|TRadioGroup||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="partial"|Partially Implemented||class="not"|Not Implemented<br />
|----<br />
|TScrollBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TScrollBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TSpinEdit||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|----<br />
|TSplitter||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TStaticText||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TStatusBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TToggleBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TTrackbar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TTrayIcon||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of dialogs on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|LCLIntf.MessageBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="working"|Working<br />
|class="working"|Working||class="unknown"|Unknown||class="partial"|Implemented for Android<br />
|----<br />
|Application.MessageBox, MessageDlg, LCLIntf.PromptUser||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="unknown"|Unknown||class="partial"|Implemented for Android<br />
|----<br />
|LCLIntf.AskUser||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|TColorDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TFontDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TOpenDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TPrinterSetupDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TSaveDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of TCustomControl based controls on each widgetset==<br />
Note that being a TCustomControl descendant does not guarantee that a control has no widgetset implementation. TArrow has it, although it has a good default implementation. TNotebook is fully implemented in the LCL.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TArrow ||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TNoteBook||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TUpDown||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TStringGrid||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TDrawGrid||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TToolBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TTreeView||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TValueListEditor||class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of TGraphicControl based controls on each widgetset==<br />
'''Note:''' These are for LCL wrapped components only, '''not''' for the specific GUI toolkit features itself.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBevel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TLabel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="partial"|Implemented for Android<br />
|----<br />
|TShape||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TSpeedButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TPaintBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TImage||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|}<br />
<br />
==Status of LazDeviceAPIs on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! customdrawn-android<br />
|----<br />
|Accelerometer||class="working"|Working<br />
|----<br />
|Messaging (SMS, MMS and E-Mail)||class="partial"|SMS Implemented<br />
|----<br />
|PositionInfo||class="working"|Working<br />
|}<br />
<br />
==See Also==<br />
<br />
*[[LCL Internals]]<br />
*[[TAChart Roadmap]]<br />
<br />
[[Category:Lazarus]]<br />
[[Category:Roadmaps]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=Roadmap&diff=86485Roadmap2015-02-16T10:14:13Z<p>Sekelsenmat: /* Status of features on each widgetset */</p>
<hr />
<div>{{Roadmap}}<br />
<br />
This document gives an idea of the current status of the various parts of Lazarus and also helps new contributors to find a suitable place where they can help. It also shows the people implementing the various parts and the targets.<br />
<br />
__TOC__<br />
<br />
{{Template:Development Status}}<br />
<br />
==General status of widgetsets==<br />
<br />
{{Template:Widgetset Roadmap}}<br />
<br />
==Current status of the various parts of Lazarus==<br />
<br />
<br />
{| class="wikitable sortable"<br />
! Unit !! Item !! State !! Target !! Skills !! Responsible !! Comments<br />
|---- class="working"<br />
|IDE||TCollection Editor||working||0.9.x||FCL, RTTI, IDE||-||A generic TCollection editor for the various TCollections in the LCL/FCL.<br />
|---- class="working"<br />
|IDE||TActionList||working||0.9.x||-||-||-<br />
|---- class="working"<br />
|IDE||Doc Editor||working||-||fpdoc||-||The doc editor will be an integrated fpDoc editor similar to fpde. It will be a process of its own, so that it can show help for dialogs as well. It should also be able to write help for packages.<br />
|---- class="working"<br />
|IDE||Export LFM as xml||working||-||-||-||Load and save LFM files to XML.<br />
|---- class="partial"<br />
|IDE||[[Icon Editor Roadmap]]||in progress||post 1.0||-||-||A simple icon editor with the ability to create lrs files. It will be a good example and can help newbies to create icons for their components.<br />
|---- class="working"<br />
|LCL||Borderspacing||working||0.9.x||-||-||for aligned controls<br />
|---- class="working"<br />
|LCL||Drag&Drop||working||||-||-||<br />
|---- class="working"<br />
|LCL||Port to Darwin Power PC, Mac OS X||working||0.9.x||-||-||depends on FPC 1.9.5<br />
|---- class="working"<br />
|LCL||Port to Mac OS X x86||working||-||-||-||depends on FPC 2.1.1<br />
|---- class="working"<br />
|LCL||TSplitter||working||0.9.x||easy||-||-<br />
|---- class="working"<br />
|LCL||TFindDialog||working||-||-||-||Implemented in 0.9.16<br />
|---- class="working"<br />
|LCL||TReplaceDialog||working||-||-||-||Implemented in 0.9.16<br />
|---- class="working"<br />
|LCL||TControl.Font||in progress||0.9.x||-||-||-<br />
|---- class="working"<br />
|LCL||TTabControl||in progress||0.9.x||-||-||-<br />
|---- class="partial"<br />
|LCL||Docking (= the combination of forms)||partially working, in progress||post 1.0||deep LCL and interfaces||Mattias||-<br />
|---- class="working"<br />
|LCL||Frames (= forms as children)||working||0.9.28||deep knowledge of LCL||Mattias, Paul||-<br />
|---- class="working"<br />
|IDE||Visual Form Inheritence||working||post 1.0||IDE||Mattias||Properties are not yet propagated to open descendants<br />
|---- class="partial"<br />
|LCL||MDI - Multiple Documents Interfaces Putting fo ...||in progress||1.2||deep LCL and interfaces||[[User:Zeljan|Zeljan]]||An MDI LCL emulator for widgetsets which does not support MDI, also native implementation of MDI for qt and win32/64. Currently only qt has full MDI support, others are in progress.<br />
|---- class="not"<br />
|LCL||Palette support||not implemented||-||-||-||Required to correctly show colors on a 256 colors display<br />
|---- class="partial"<br />
|LCL||TCoolBar||partially working, in progress||post 1.0||LCL and anchoring||[[User:JuhaManninen|Juha]]||-<br />
|---- class="partial"<br />
|LCL||TControlBar||skeleton implementation to prevent errors in Delphi conversion, in progress||post 1.0||LCL and anchoring||[[User:JuhaManninen|Juha]]||-<br />
|---- class="working"<br />
|LCL||TMaskEdit||working||-||-||[[User:Bart|Bart]]||-<br />
|---- class="not"<br />
|LCL||TDirectoryTreeView||not implemented||-||-||-||-<br />
|---- class="not"<br />
|LCL||Constrain maximization to specific area||not implemented||-||winapi, gtk||-||When maximizing a window, the left, top, width and height can all be constrained to a specific rectangular area on the screen/desktop. After this is done, constrain the source editor and maybe other windows<br />
|---- class="working"<br />
|Components||TIcon||working||0.9.26||-||Marc||-<br />
|---- class="working"<br />
|Components||CUPS Package||working||0.9.x||easy||-||<br />
|---- class="working"<br />
|}<br />
<br />
==Status of features on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|Accelerator Keys<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Caret<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Clipboard<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|Cursors<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Drag & Drop<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|[[Drop files event]]<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|MDI Support<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Printing<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Regions<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="partial"|Partially Implemented||class="working"|Working<br />
|----<br />
|TCustomControl descendents<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|Unicode Support<br />
|class="working"|Working||class="not"|Impossible to Implement||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|[[BidiMode]]<br />
|class="working"|Working||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Application||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TTimer||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TApplication.QueueAsyncCall||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|TThread.Synchronize||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class="unknown"|Unknown<br />
|class="working"|Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|PostMessage||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class=""unknown"|Unknown<br />
|class="not"|Not Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|PostThreadMessage||class="working"|Working||class="unknown"|Unknown||class="unknown"|Unknown<br />
|class="unknown"|Unknown||class="unknown"|Unknown||class="unknown"|Unknown<br />
|class="unknown"|Unknown||class="unknown"|Unknown||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of Graphics on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBitmap/TPixmap/TIcon/etc||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TBrush||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TFont||class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TPen||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|ExtTextOut||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="unknown"|Unknown||class="working"|Working<br />
|}<br />
<br />
==Status of native controls on each widgetset==<br />
Native controls are TWinControl descendants which do not descend from TCustomControl.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBitBtn||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TCalendar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TCheckBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TCheckGroup||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TCheckListBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TComboBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TEdit||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TForm||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TGroupBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TIdleTimer||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TImageList||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working|| class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TListBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TListView||class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TMainMenu||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TMemo||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TMenuItem||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TPageControl and TTabSheet||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TPairSplitter||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TPanel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TPopupMenu||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TProgressBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TRadioButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|----<br />
|TRadioGroup||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="partial"|Partially Implemented||class="not"|Not Implemented<br />
|----<br />
|TScrollBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TScrollBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TSpinEdit||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|----<br />
|TSplitter||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TStaticText||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TStatusBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TToggleBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TTrackbar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TTrayIcon||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of dialogs on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|LCLIntf.MessageBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="working"|Working<br />
|class="working"|Working||class="unknown"|Unknown||class="partial"|Implemented for Android<br />
|----<br />
|Application.MessageBox, MessageDlg, LCLIntf.PromptUser||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="unknown"|Unknown||class="partial"|Implemented for Android<br />
|----<br />
|LCLIntf.AskUser||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|TColorDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TFontDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TOpenDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TPrinterSetupDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TSaveDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of TCustomControl based controls on each widgetset==<br />
Note that being a TCustomControl descendant does not guarantee that a control has no widgetset implementation. TArrow has it, although it has a good default implementation. TNotebook is fully implemented in the LCL.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TArrow ||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TNoteBook||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TUpDown||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TStringGrid||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TDrawGrid||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TToolBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TTreeView||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TValueListEditor||class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of TGraphicControl based controls on each widgetset==<br />
'''Note:''' These are for LCL wrapped components only, '''not''' for the specific GUI toolkit features itself.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBevel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TLabel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="partial"|Implemented for Android<br />
|----<br />
|TShape||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TSpeedButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TPaintBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TImage||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|}<br />
<br />
==Status of LazDeviceAPIs on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! customdrawn-android<br />
|----<br />
|Accelerometer||class="working"|Working<br />
|----<br />
|Messaging (SMS, MMS and E-Mail)||class="partial"|SMS Implemented<br />
|----<br />
|PositionInfo||class="working"|Working<br />
|}<br />
<br />
==See Also==<br />
<br />
*[[LCL Internals]]<br />
*[[TAChart Roadmap]]<br />
<br />
[[Category:Lazarus]]<br />
[[Category:Roadmaps]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=Roadmap&diff=86484Roadmap2015-02-16T10:13:33Z<p>Sekelsenmat: /* Status of native controls on each widgetset */</p>
<hr />
<div>{{Roadmap}}<br />
<br />
This document gives an idea of the current status of the various parts of Lazarus and also helps new contributors to find a suitable place where they can help. It also shows the people implementing the various parts and the targets.<br />
<br />
__TOC__<br />
<br />
{{Template:Development Status}}<br />
<br />
==General status of widgetsets==<br />
<br />
{{Template:Widgetset Roadmap}}<br />
<br />
==Current status of the various parts of Lazarus==<br />
<br />
<br />
{| class="wikitable sortable"<br />
! Unit !! Item !! State !! Target !! Skills !! Responsible !! Comments<br />
|---- class="working"<br />
|IDE||TCollection Editor||working||0.9.x||FCL, RTTI, IDE||-||A generic TCollection editor for the various TCollections in the LCL/FCL.<br />
|---- class="working"<br />
|IDE||TActionList||working||0.9.x||-||-||-<br />
|---- class="working"<br />
|IDE||Doc Editor||working||-||fpdoc||-||The doc editor will be an integrated fpDoc editor similar to fpde. It will be a process of its own, so that it can show help for dialogs as well. It should also be able to write help for packages.<br />
|---- class="working"<br />
|IDE||Export LFM as xml||working||-||-||-||Load and save LFM files to XML.<br />
|---- class="partial"<br />
|IDE||[[Icon Editor Roadmap]]||in progress||post 1.0||-||-||A simple icon editor with the ability to create lrs files. It will be a good example and can help newbies to create icons for their components.<br />
|---- class="working"<br />
|LCL||Borderspacing||working||0.9.x||-||-||for aligned controls<br />
|---- class="working"<br />
|LCL||Drag&Drop||working||||-||-||<br />
|---- class="working"<br />
|LCL||Port to Darwin Power PC, Mac OS X||working||0.9.x||-||-||depends on FPC 1.9.5<br />
|---- class="working"<br />
|LCL||Port to Mac OS X x86||working||-||-||-||depends on FPC 2.1.1<br />
|---- class="working"<br />
|LCL||TSplitter||working||0.9.x||easy||-||-<br />
|---- class="working"<br />
|LCL||TFindDialog||working||-||-||-||Implemented in 0.9.16<br />
|---- class="working"<br />
|LCL||TReplaceDialog||working||-||-||-||Implemented in 0.9.16<br />
|---- class="working"<br />
|LCL||TControl.Font||in progress||0.9.x||-||-||-<br />
|---- class="working"<br />
|LCL||TTabControl||in progress||0.9.x||-||-||-<br />
|---- class="partial"<br />
|LCL||Docking (= the combination of forms)||partially working, in progress||post 1.0||deep LCL and interfaces||Mattias||-<br />
|---- class="working"<br />
|LCL||Frames (= forms as children)||working||0.9.28||deep knowledge of LCL||Mattias, Paul||-<br />
|---- class="working"<br />
|IDE||Visual Form Inheritence||working||post 1.0||IDE||Mattias||Properties are not yet propagated to open descendants<br />
|---- class="partial"<br />
|LCL||MDI - Multiple Documents Interfaces Putting fo ...||in progress||1.2||deep LCL and interfaces||[[User:Zeljan|Zeljan]]||An MDI LCL emulator for widgetsets which does not support MDI, also native implementation of MDI for qt and win32/64. Currently only qt has full MDI support, others are in progress.<br />
|---- class="not"<br />
|LCL||Palette support||not implemented||-||-||-||Required to correctly show colors on a 256 colors display<br />
|---- class="partial"<br />
|LCL||TCoolBar||partially working, in progress||post 1.0||LCL and anchoring||[[User:JuhaManninen|Juha]]||-<br />
|---- class="partial"<br />
|LCL||TControlBar||skeleton implementation to prevent errors in Delphi conversion, in progress||post 1.0||LCL and anchoring||[[User:JuhaManninen|Juha]]||-<br />
|---- class="working"<br />
|LCL||TMaskEdit||working||-||-||[[User:Bart|Bart]]||-<br />
|---- class="not"<br />
|LCL||TDirectoryTreeView||not implemented||-||-||-||-<br />
|---- class="not"<br />
|LCL||Constrain maximization to specific area||not implemented||-||winapi, gtk||-||When maximizing a window, the left, top, width and height can all be constrained to a specific rectangular area on the screen/desktop. After this is done, constrain the source editor and maybe other windows<br />
|---- class="working"<br />
|Components||TIcon||working||0.9.26||-||Marc||-<br />
|---- class="working"<br />
|Components||CUPS Package||working||0.9.x||easy||-||<br />
|---- class="working"<br />
|}<br />
<br />
==Status of features on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|Accelerator Keys<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Caret<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Clipboard<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|Cursors<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Drag & Drop<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|[[Drop files event]]<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|MDI Support<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Printing<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Regions<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TCustomControl descendents<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|Unicode Support<br />
|class="working"|Working||class="not"|Impossible to Implement||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|[[BidiMode]]<br />
|class="working"|Working||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Application||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TTimer||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TApplication.QueueAsyncCall||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|TThread.Synchronize||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class="unknown"|Unknown<br />
|class="working"|Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|PostMessage||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class=""unknown"|Unknown<br />
|class="not"|Not Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|PostThreadMessage||class="working"|Working||class="unknown"|Unknown||class="unknown"|Unknown<br />
|class="unknown"|Unknown||class="unknown"|Unknown||class="unknown"|Unknown<br />
|class="unknown"|Unknown||class="unknown"|Unknown||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of Graphics on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBitmap/TPixmap/TIcon/etc||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TBrush||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TFont||class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TPen||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|ExtTextOut||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="unknown"|Unknown||class="working"|Working<br />
|}<br />
<br />
==Status of native controls on each widgetset==<br />
Native controls are TWinControl descendants which do not descend from TCustomControl.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBitBtn||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TCalendar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TCheckBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TCheckGroup||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TCheckListBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TComboBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TEdit||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TForm||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TGroupBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TIdleTimer||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TImageList||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working|| class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TListBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TListView||class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TMainMenu||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TMemo||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TMenuItem||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TPageControl and TTabSheet||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TPairSplitter||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TPanel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TPopupMenu||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TProgressBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TRadioButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|----<br />
|TRadioGroup||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="partial"|Partially Implemented||class="not"|Not Implemented<br />
|----<br />
|TScrollBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TScrollBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TSpinEdit||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|----<br />
|TSplitter||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TStaticText||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TStatusBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TToggleBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TTrackbar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TTrayIcon||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of dialogs on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|LCLIntf.MessageBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="working"|Working<br />
|class="working"|Working||class="unknown"|Unknown||class="partial"|Implemented for Android<br />
|----<br />
|Application.MessageBox, MessageDlg, LCLIntf.PromptUser||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="unknown"|Unknown||class="partial"|Implemented for Android<br />
|----<br />
|LCLIntf.AskUser||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|TColorDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TFontDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TOpenDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TPrinterSetupDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TSaveDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of TCustomControl based controls on each widgetset==<br />
Note that being a TCustomControl descendant does not guarantee that a control has no widgetset implementation. TArrow has it, although it has a good default implementation. TNotebook is fully implemented in the LCL.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TArrow ||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TNoteBook||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TUpDown||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TStringGrid||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TDrawGrid||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TToolBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TTreeView||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TValueListEditor||class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of TGraphicControl based controls on each widgetset==<br />
'''Note:''' These are for LCL wrapped components only, '''not''' for the specific GUI toolkit features itself.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBevel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TLabel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="partial"|Implemented for Android<br />
|----<br />
|TShape||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TSpeedButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TPaintBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TImage||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|}<br />
<br />
==Status of LazDeviceAPIs on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! customdrawn-android<br />
|----<br />
|Accelerometer||class="working"|Working<br />
|----<br />
|Messaging (SMS, MMS and E-Mail)||class="partial"|SMS Implemented<br />
|----<br />
|PositionInfo||class="working"|Working<br />
|}<br />
<br />
==See Also==<br />
<br />
*[[LCL Internals]]<br />
*[[TAChart Roadmap]]<br />
<br />
[[Category:Lazarus]]<br />
[[Category:Roadmaps]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=Roadmap&diff=86482Roadmap2015-02-16T10:12:39Z<p>Sekelsenmat: /* Status of native controls on each widgetset */</p>
<hr />
<div>{{Roadmap}}<br />
<br />
This document gives an idea of the current status of the various parts of Lazarus and also helps new contributors to find a suitable place where they can help. It also shows the people implementing the various parts and the targets.<br />
<br />
__TOC__<br />
<br />
{{Template:Development Status}}<br />
<br />
==General status of widgetsets==<br />
<br />
{{Template:Widgetset Roadmap}}<br />
<br />
==Current status of the various parts of Lazarus==<br />
<br />
<br />
{| class="wikitable sortable"<br />
! Unit !! Item !! State !! Target !! Skills !! Responsible !! Comments<br />
|---- class="working"<br />
|IDE||TCollection Editor||working||0.9.x||FCL, RTTI, IDE||-||A generic TCollection editor for the various TCollections in the LCL/FCL.<br />
|---- class="working"<br />
|IDE||TActionList||working||0.9.x||-||-||-<br />
|---- class="working"<br />
|IDE||Doc Editor||working||-||fpdoc||-||The doc editor will be an integrated fpDoc editor similar to fpde. It will be a process of its own, so that it can show help for dialogs as well. It should also be able to write help for packages.<br />
|---- class="working"<br />
|IDE||Export LFM as xml||working||-||-||-||Load and save LFM files to XML.<br />
|---- class="partial"<br />
|IDE||[[Icon Editor Roadmap]]||in progress||post 1.0||-||-||A simple icon editor with the ability to create lrs files. It will be a good example and can help newbies to create icons for their components.<br />
|---- class="working"<br />
|LCL||Borderspacing||working||0.9.x||-||-||for aligned controls<br />
|---- class="working"<br />
|LCL||Drag&Drop||working||||-||-||<br />
|---- class="working"<br />
|LCL||Port to Darwin Power PC, Mac OS X||working||0.9.x||-||-||depends on FPC 1.9.5<br />
|---- class="working"<br />
|LCL||Port to Mac OS X x86||working||-||-||-||depends on FPC 2.1.1<br />
|---- class="working"<br />
|LCL||TSplitter||working||0.9.x||easy||-||-<br />
|---- class="working"<br />
|LCL||TFindDialog||working||-||-||-||Implemented in 0.9.16<br />
|---- class="working"<br />
|LCL||TReplaceDialog||working||-||-||-||Implemented in 0.9.16<br />
|---- class="working"<br />
|LCL||TControl.Font||in progress||0.9.x||-||-||-<br />
|---- class="working"<br />
|LCL||TTabControl||in progress||0.9.x||-||-||-<br />
|---- class="partial"<br />
|LCL||Docking (= the combination of forms)||partially working, in progress||post 1.0||deep LCL and interfaces||Mattias||-<br />
|---- class="working"<br />
|LCL||Frames (= forms as children)||working||0.9.28||deep knowledge of LCL||Mattias, Paul||-<br />
|---- class="working"<br />
|IDE||Visual Form Inheritence||working||post 1.0||IDE||Mattias||Properties are not yet propagated to open descendants<br />
|---- class="partial"<br />
|LCL||MDI - Multiple Documents Interfaces Putting fo ...||in progress||1.2||deep LCL and interfaces||[[User:Zeljan|Zeljan]]||An MDI LCL emulator for widgetsets which does not support MDI, also native implementation of MDI for qt and win32/64. Currently only qt has full MDI support, others are in progress.<br />
|---- class="not"<br />
|LCL||Palette support||not implemented||-||-||-||Required to correctly show colors on a 256 colors display<br />
|---- class="partial"<br />
|LCL||TCoolBar||partially working, in progress||post 1.0||LCL and anchoring||[[User:JuhaManninen|Juha]]||-<br />
|---- class="partial"<br />
|LCL||TControlBar||skeleton implementation to prevent errors in Delphi conversion, in progress||post 1.0||LCL and anchoring||[[User:JuhaManninen|Juha]]||-<br />
|---- class="working"<br />
|LCL||TMaskEdit||working||-||-||[[User:Bart|Bart]]||-<br />
|---- class="not"<br />
|LCL||TDirectoryTreeView||not implemented||-||-||-||-<br />
|---- class="not"<br />
|LCL||Constrain maximization to specific area||not implemented||-||winapi, gtk||-||When maximizing a window, the left, top, width and height can all be constrained to a specific rectangular area on the screen/desktop. After this is done, constrain the source editor and maybe other windows<br />
|---- class="working"<br />
|Components||TIcon||working||0.9.26||-||Marc||-<br />
|---- class="working"<br />
|Components||CUPS Package||working||0.9.x||easy||-||<br />
|---- class="working"<br />
|}<br />
<br />
==Status of features on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|Accelerator Keys<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Caret<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Clipboard<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|Cursors<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Drag & Drop<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|[[Drop files event]]<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|MDI Support<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Printing<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Regions<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TCustomControl descendents<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|Unicode Support<br />
|class="working"|Working||class="not"|Impossible to Implement||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|[[BidiMode]]<br />
|class="working"|Working||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Application||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TTimer||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TApplication.QueueAsyncCall||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|TThread.Synchronize||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class="unknown"|Unknown<br />
|class="working"|Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|PostMessage||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class=""unknown"|Unknown<br />
|class="not"|Not Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|PostThreadMessage||class="working"|Working||class="unknown"|Unknown||class="unknown"|Unknown<br />
|class="unknown"|Unknown||class="unknown"|Unknown||class="unknown"|Unknown<br />
|class="unknown"|Unknown||class="unknown"|Unknown||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of Graphics on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBitmap/TPixmap/TIcon/etc||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TBrush||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TFont||class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TPen||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|ExtTextOut||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="unknown"|Unknown||class="working"|Working<br />
|}<br />
<br />
==Status of native controls on each widgetset==<br />
Native controls are TWinControl descendants which do not descend from TCustomControl.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBitBtn||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TCalendar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TCheckBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TCheckGroup||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TCheckListBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TComboBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TEdit||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TForm||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TGroupBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TIdleTimer||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TImageList||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working|| class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TListBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TListView||class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TMainMenu||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TMemo||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TMenuItem||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TPageControl and TTabSheet||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TPairSplitter||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TPanel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TPopupMenu||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TProgressBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TRadioButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|----<br />
|TRadioGroup||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="partial"|Partially Implemented||class="not"|Not Implemented<br />
|----<br />
|TScrollBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TScrollBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TSpinEdit||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TSplitter||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TStaticText||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TStatusBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TToggleBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TTrackbar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TTrayIcon||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of dialogs on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|LCLIntf.MessageBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="working"|Working<br />
|class="working"|Working||class="unknown"|Unknown||class="partial"|Implemented for Android<br />
|----<br />
|Application.MessageBox, MessageDlg, LCLIntf.PromptUser||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="unknown"|Unknown||class="partial"|Implemented for Android<br />
|----<br />
|LCLIntf.AskUser||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|TColorDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TFontDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TOpenDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TPrinterSetupDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TSaveDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of TCustomControl based controls on each widgetset==<br />
Note that being a TCustomControl descendant does not guarantee that a control has no widgetset implementation. TArrow has it, although it has a good default implementation. TNotebook is fully implemented in the LCL.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TArrow ||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TNoteBook||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TUpDown||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TStringGrid||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TDrawGrid||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TToolBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TTreeView||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TValueListEditor||class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of TGraphicControl based controls on each widgetset==<br />
'''Note:''' These are for LCL wrapped components only, '''not''' for the specific GUI toolkit features itself.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBevel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TLabel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="partial"|Implemented for Android<br />
|----<br />
|TShape||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TSpeedButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TPaintBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TImage||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|}<br />
<br />
==Status of LazDeviceAPIs on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! customdrawn-android<br />
|----<br />
|Accelerometer||class="working"|Working<br />
|----<br />
|Messaging (SMS, MMS and E-Mail)||class="partial"|SMS Implemented<br />
|----<br />
|PositionInfo||class="working"|Working<br />
|}<br />
<br />
==See Also==<br />
<br />
*[[LCL Internals]]<br />
*[[TAChart Roadmap]]<br />
<br />
[[Category:Lazarus]]<br />
[[Category:Roadmaps]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=Roadmap&diff=86481Roadmap2015-02-16T09:52:59Z<p>Sekelsenmat: /* Status of native controls on each widgetset */</p>
<hr />
<div>{{Roadmap}}<br />
<br />
This document gives an idea of the current status of the various parts of Lazarus and also helps new contributors to find a suitable place where they can help. It also shows the people implementing the various parts and the targets.<br />
<br />
__TOC__<br />
<br />
{{Template:Development Status}}<br />
<br />
==General status of widgetsets==<br />
<br />
{{Template:Widgetset Roadmap}}<br />
<br />
==Current status of the various parts of Lazarus==<br />
<br />
<br />
{| class="wikitable sortable"<br />
! Unit !! Item !! State !! Target !! Skills !! Responsible !! Comments<br />
|---- class="working"<br />
|IDE||TCollection Editor||working||0.9.x||FCL, RTTI, IDE||-||A generic TCollection editor for the various TCollections in the LCL/FCL.<br />
|---- class="working"<br />
|IDE||TActionList||working||0.9.x||-||-||-<br />
|---- class="working"<br />
|IDE||Doc Editor||working||-||fpdoc||-||The doc editor will be an integrated fpDoc editor similar to fpde. It will be a process of its own, so that it can show help for dialogs as well. It should also be able to write help for packages.<br />
|---- class="working"<br />
|IDE||Export LFM as xml||working||-||-||-||Load and save LFM files to XML.<br />
|---- class="partial"<br />
|IDE||[[Icon Editor Roadmap]]||in progress||post 1.0||-||-||A simple icon editor with the ability to create lrs files. It will be a good example and can help newbies to create icons for their components.<br />
|---- class="working"<br />
|LCL||Borderspacing||working||0.9.x||-||-||for aligned controls<br />
|---- class="working"<br />
|LCL||Drag&Drop||working||||-||-||<br />
|---- class="working"<br />
|LCL||Port to Darwin Power PC, Mac OS X||working||0.9.x||-||-||depends on FPC 1.9.5<br />
|---- class="working"<br />
|LCL||Port to Mac OS X x86||working||-||-||-||depends on FPC 2.1.1<br />
|---- class="working"<br />
|LCL||TSplitter||working||0.9.x||easy||-||-<br />
|---- class="working"<br />
|LCL||TFindDialog||working||-||-||-||Implemented in 0.9.16<br />
|---- class="working"<br />
|LCL||TReplaceDialog||working||-||-||-||Implemented in 0.9.16<br />
|---- class="working"<br />
|LCL||TControl.Font||in progress||0.9.x||-||-||-<br />
|---- class="working"<br />
|LCL||TTabControl||in progress||0.9.x||-||-||-<br />
|---- class="partial"<br />
|LCL||Docking (= the combination of forms)||partially working, in progress||post 1.0||deep LCL and interfaces||Mattias||-<br />
|---- class="working"<br />
|LCL||Frames (= forms as children)||working||0.9.28||deep knowledge of LCL||Mattias, Paul||-<br />
|---- class="working"<br />
|IDE||Visual Form Inheritence||working||post 1.0||IDE||Mattias||Properties are not yet propagated to open descendants<br />
|---- class="partial"<br />
|LCL||MDI - Multiple Documents Interfaces Putting fo ...||in progress||1.2||deep LCL and interfaces||[[User:Zeljan|Zeljan]]||An MDI LCL emulator for widgetsets which does not support MDI, also native implementation of MDI for qt and win32/64. Currently only qt has full MDI support, others are in progress.<br />
|---- class="not"<br />
|LCL||Palette support||not implemented||-||-||-||Required to correctly show colors on a 256 colors display<br />
|---- class="partial"<br />
|LCL||TCoolBar||partially working, in progress||post 1.0||LCL and anchoring||[[User:JuhaManninen|Juha]]||-<br />
|---- class="partial"<br />
|LCL||TControlBar||skeleton implementation to prevent errors in Delphi conversion, in progress||post 1.0||LCL and anchoring||[[User:JuhaManninen|Juha]]||-<br />
|---- class="working"<br />
|LCL||TMaskEdit||working||-||-||[[User:Bart|Bart]]||-<br />
|---- class="not"<br />
|LCL||TDirectoryTreeView||not implemented||-||-||-||-<br />
|---- class="not"<br />
|LCL||Constrain maximization to specific area||not implemented||-||winapi, gtk||-||When maximizing a window, the left, top, width and height can all be constrained to a specific rectangular area on the screen/desktop. After this is done, constrain the source editor and maybe other windows<br />
|---- class="working"<br />
|Components||TIcon||working||0.9.26||-||Marc||-<br />
|---- class="working"<br />
|Components||CUPS Package||working||0.9.x||easy||-||<br />
|---- class="working"<br />
|}<br />
<br />
==Status of features on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|Accelerator Keys<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Caret<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Clipboard<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|Cursors<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Drag & Drop<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|[[Drop files event]]<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|MDI Support<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Printing<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Regions<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TCustomControl descendents<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|Unicode Support<br />
|class="working"|Working||class="not"|Impossible to Implement||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|[[BidiMode]]<br />
|class="working"|Working||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Application||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TTimer||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TApplication.QueueAsyncCall||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|TThread.Synchronize||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class="unknown"|Unknown<br />
|class="working"|Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|PostMessage||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class=""unknown"|Unknown<br />
|class="not"|Not Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|PostThreadMessage||class="working"|Working||class="unknown"|Unknown||class="unknown"|Unknown<br />
|class="unknown"|Unknown||class="unknown"|Unknown||class="unknown"|Unknown<br />
|class="unknown"|Unknown||class="unknown"|Unknown||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of Graphics on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBitmap/TPixmap/TIcon/etc||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TBrush||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TFont||class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TPen||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|ExtTextOut||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="unknown"|Unknown||class="working"|Working<br />
|}<br />
<br />
==Status of native controls on each widgetset==<br />
Native controls are TWinControl descendants which do not descend from TCustomControl.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBitBtn||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TCalendar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TCheckBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TCheckGroup||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TCheckListBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TComboBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TEdit||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TForm||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TGroupBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TIdleTimer||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TImageList||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working|| class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TListBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TListView||class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TMainMenu||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TMemo||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TMenuItem||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TPageControl and TTabSheet||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TPairSplitter||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TPanel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TPopupMenu||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TProgressBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TRadioButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|----<br />
|TRadioGroup||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="partial"|Partially Implemented||class="not"|Not Implemented<br />
|----<br />
|TScrollBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TScrollBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TSpinEdit||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TSplitter||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TStaticText||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TStatusBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TToggleBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TTrackbar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TTrayIcon||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of dialogs on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|LCLIntf.MessageBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="working"|Working<br />
|class="working"|Working||class="unknown"|Unknown||class="partial"|Implemented for Android<br />
|----<br />
|Application.MessageBox, MessageDlg, LCLIntf.PromptUser||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="unknown"|Unknown||class="partial"|Implemented for Android<br />
|----<br />
|LCLIntf.AskUser||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|TColorDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TFontDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TOpenDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TPrinterSetupDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TSaveDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of TCustomControl based controls on each widgetset==<br />
Note that being a TCustomControl descendant does not guarantee that a control has no widgetset implementation. TArrow has it, although it has a good default implementation. TNotebook is fully implemented in the LCL.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TArrow ||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TNoteBook||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TUpDown||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TStringGrid||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TDrawGrid||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TToolBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TTreeView||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TValueListEditor||class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of TGraphicControl based controls on each widgetset==<br />
'''Note:''' These are for LCL wrapped components only, '''not''' for the specific GUI toolkit features itself.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBevel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TLabel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="partial"|Implemented for Android<br />
|----<br />
|TShape||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TSpeedButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TPaintBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TImage||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|}<br />
<br />
==Status of LazDeviceAPIs on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! customdrawn-android<br />
|----<br />
|Accelerometer||class="working"|Working<br />
|----<br />
|Messaging (SMS, MMS and E-Mail)||class="partial"|SMS Implemented<br />
|----<br />
|PositionInfo||class="working"|Working<br />
|}<br />
<br />
==See Also==<br />
<br />
*[[LCL Internals]]<br />
*[[TAChart Roadmap]]<br />
<br />
[[Category:Lazarus]]<br />
[[Category:Roadmaps]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=Roadmap&diff=86480Roadmap2015-02-16T09:43:00Z<p>Sekelsenmat: /* Status of features on each widgetset */</p>
<hr />
<div>{{Roadmap}}<br />
<br />
This document gives an idea of the current status of the various parts of Lazarus and also helps new contributors to find a suitable place where they can help. It also shows the people implementing the various parts and the targets.<br />
<br />
__TOC__<br />
<br />
{{Template:Development Status}}<br />
<br />
==General status of widgetsets==<br />
<br />
{{Template:Widgetset Roadmap}}<br />
<br />
==Current status of the various parts of Lazarus==<br />
<br />
<br />
{| class="wikitable sortable"<br />
! Unit !! Item !! State !! Target !! Skills !! Responsible !! Comments<br />
|---- class="working"<br />
|IDE||TCollection Editor||working||0.9.x||FCL, RTTI, IDE||-||A generic TCollection editor for the various TCollections in the LCL/FCL.<br />
|---- class="working"<br />
|IDE||TActionList||working||0.9.x||-||-||-<br />
|---- class="working"<br />
|IDE||Doc Editor||working||-||fpdoc||-||The doc editor will be an integrated fpDoc editor similar to fpde. It will be a process of its own, so that it can show help for dialogs as well. It should also be able to write help for packages.<br />
|---- class="working"<br />
|IDE||Export LFM as xml||working||-||-||-||Load and save LFM files to XML.<br />
|---- class="partial"<br />
|IDE||[[Icon Editor Roadmap]]||in progress||post 1.0||-||-||A simple icon editor with the ability to create lrs files. It will be a good example and can help newbies to create icons for their components.<br />
|---- class="working"<br />
|LCL||Borderspacing||working||0.9.x||-||-||for aligned controls<br />
|---- class="working"<br />
|LCL||Drag&Drop||working||||-||-||<br />
|---- class="working"<br />
|LCL||Port to Darwin Power PC, Mac OS X||working||0.9.x||-||-||depends on FPC 1.9.5<br />
|---- class="working"<br />
|LCL||Port to Mac OS X x86||working||-||-||-||depends on FPC 2.1.1<br />
|---- class="working"<br />
|LCL||TSplitter||working||0.9.x||easy||-||-<br />
|---- class="working"<br />
|LCL||TFindDialog||working||-||-||-||Implemented in 0.9.16<br />
|---- class="working"<br />
|LCL||TReplaceDialog||working||-||-||-||Implemented in 0.9.16<br />
|---- class="working"<br />
|LCL||TControl.Font||in progress||0.9.x||-||-||-<br />
|---- class="working"<br />
|LCL||TTabControl||in progress||0.9.x||-||-||-<br />
|---- class="partial"<br />
|LCL||Docking (= the combination of forms)||partially working, in progress||post 1.0||deep LCL and interfaces||Mattias||-<br />
|---- class="working"<br />
|LCL||Frames (= forms as children)||working||0.9.28||deep knowledge of LCL||Mattias, Paul||-<br />
|---- class="working"<br />
|IDE||Visual Form Inheritence||working||post 1.0||IDE||Mattias||Properties are not yet propagated to open descendants<br />
|---- class="partial"<br />
|LCL||MDI - Multiple Documents Interfaces Putting fo ...||in progress||1.2||deep LCL and interfaces||[[User:Zeljan|Zeljan]]||An MDI LCL emulator for widgetsets which does not support MDI, also native implementation of MDI for qt and win32/64. Currently only qt has full MDI support, others are in progress.<br />
|---- class="not"<br />
|LCL||Palette support||not implemented||-||-||-||Required to correctly show colors on a 256 colors display<br />
|---- class="partial"<br />
|LCL||TCoolBar||partially working, in progress||post 1.0||LCL and anchoring||[[User:JuhaManninen|Juha]]||-<br />
|---- class="partial"<br />
|LCL||TControlBar||skeleton implementation to prevent errors in Delphi conversion, in progress||post 1.0||LCL and anchoring||[[User:JuhaManninen|Juha]]||-<br />
|---- class="working"<br />
|LCL||TMaskEdit||working||-||-||[[User:Bart|Bart]]||-<br />
|---- class="not"<br />
|LCL||TDirectoryTreeView||not implemented||-||-||-||-<br />
|---- class="not"<br />
|LCL||Constrain maximization to specific area||not implemented||-||winapi, gtk||-||When maximizing a window, the left, top, width and height can all be constrained to a specific rectangular area on the screen/desktop. After this is done, constrain the source editor and maybe other windows<br />
|---- class="working"<br />
|Components||TIcon||working||0.9.26||-||Marc||-<br />
|---- class="working"<br />
|Components||CUPS Package||working||0.9.x||easy||-||<br />
|---- class="working"<br />
|}<br />
<br />
==Status of features on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|Accelerator Keys<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Caret<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Clipboard<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|Cursors<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Drag & Drop<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|[[Drop files event]]<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|MDI Support<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Printing<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Regions<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TCustomControl descendents<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|Unicode Support<br />
|class="working"|Working||class="not"|Impossible to Implement||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|[[BidiMode]]<br />
|class="working"|Working||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Application||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TTimer||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TApplication.QueueAsyncCall||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|TThread.Synchronize||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class="unknown"|Unknown<br />
|class="working"|Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|PostMessage||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class=""unknown"|Unknown<br />
|class="not"|Not Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|PostThreadMessage||class="working"|Working||class="unknown"|Unknown||class="unknown"|Unknown<br />
|class="unknown"|Unknown||class="unknown"|Unknown||class="unknown"|Unknown<br />
|class="unknown"|Unknown||class="unknown"|Unknown||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of Graphics on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBitmap/TPixmap/TIcon/etc||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TBrush||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TFont||class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TPen||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|ExtTextOut||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="unknown"|Unknown||class="working"|Working<br />
|}<br />
<br />
==Status of native controls on each widgetset==<br />
Native controls are TWinControl descendants which do not descend from TCustomControl.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBitBtn||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TCalendar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TCheckBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TCheckGroup||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TCheckListBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TComboBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TEdit||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TForm||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TGroupBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TIdleTimer||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TImageList||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working|| class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TListBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TListView||class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TMainMenu||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TMemo||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TMenuItem||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TPageControl and TTabSheet||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TPairSplitter||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TPanel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TPopupMenu||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TProgressBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TRadioButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TRadioGroup||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TScrollBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TScrollBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TSpinEdit||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TSplitter||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TStaticText||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TStatusBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TToggleBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TTrackbar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TTrayIcon||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of dialogs on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|LCLIntf.MessageBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="working"|Working<br />
|class="working"|Working||class="unknown"|Unknown||class="partial"|Implemented for Android<br />
|----<br />
|Application.MessageBox, MessageDlg, LCLIntf.PromptUser||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="unknown"|Unknown||class="partial"|Implemented for Android<br />
|----<br />
|LCLIntf.AskUser||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|TColorDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TFontDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TOpenDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TPrinterSetupDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TSaveDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of TCustomControl based controls on each widgetset==<br />
Note that being a TCustomControl descendant does not guarantee that a control has no widgetset implementation. TArrow has it, although it has a good default implementation. TNotebook is fully implemented in the LCL.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TArrow ||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TNoteBook||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TUpDown||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TStringGrid||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TDrawGrid||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TToolBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TTreeView||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TValueListEditor||class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of TGraphicControl based controls on each widgetset==<br />
'''Note:''' These are for LCL wrapped components only, '''not''' for the specific GUI toolkit features itself.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBevel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TLabel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="partial"|Implemented for Android<br />
|----<br />
|TShape||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TSpeedButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TPaintBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TImage||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|}<br />
<br />
==Status of LazDeviceAPIs on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! customdrawn-android<br />
|----<br />
|Accelerometer||class="working"|Working<br />
|----<br />
|Messaging (SMS, MMS and E-Mail)||class="partial"|SMS Implemented<br />
|----<br />
|PositionInfo||class="working"|Working<br />
|}<br />
<br />
==See Also==<br />
<br />
*[[LCL Internals]]<br />
*[[TAChart Roadmap]]<br />
<br />
[[Category:Lazarus]]<br />
[[Category:Roadmaps]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=Roadmap&diff=86457Roadmap2015-02-15T17:47:10Z<p>Sekelsenmat: /* Status of features on each widgetset */</p>
<hr />
<div>{{Roadmap}}<br />
<br />
This document gives an idea of the current status of the various parts of Lazarus and also helps new contributors to find a suitable place where they can help. It also shows the people implementing the various parts and the targets.<br />
<br />
__TOC__<br />
<br />
{{Template:Development Status}}<br />
<br />
==General status of widgetsets==<br />
<br />
{{Template:Widgetset Roadmap}}<br />
<br />
==Current status of the various parts of Lazarus==<br />
<br />
<br />
{| class="wikitable sortable"<br />
! Unit !! Item !! State !! Target !! Skills !! Responsible !! Comments<br />
|---- class="working"<br />
|IDE||TCollection Editor||working||0.9.x||FCL, RTTI, IDE||-||A generic TCollection editor for the various TCollections in the LCL/FCL.<br />
|---- class="working"<br />
|IDE||TActionList||working||0.9.x||-||-||-<br />
|---- class="working"<br />
|IDE||Doc Editor||working||-||fpdoc||-||The doc editor will be an integrated fpDoc editor similar to fpde. It will be a process of its own, so that it can show help for dialogs as well. It should also be able to write help for packages.<br />
|---- class="working"<br />
|IDE||Export LFM as xml||working||-||-||-||Load and save LFM files to XML.<br />
|---- class="partial"<br />
|IDE||[[Icon Editor Roadmap]]||in progress||post 1.0||-||-||A simple icon editor with the ability to create lrs files. It will be a good example and can help newbies to create icons for their components.<br />
|---- class="working"<br />
|LCL||Borderspacing||working||0.9.x||-||-||for aligned controls<br />
|---- class="working"<br />
|LCL||Drag&Drop||working||||-||-||<br />
|---- class="working"<br />
|LCL||Port to Darwin Power PC, Mac OS X||working||0.9.x||-||-||depends on FPC 1.9.5<br />
|---- class="working"<br />
|LCL||Port to Mac OS X x86||working||-||-||-||depends on FPC 2.1.1<br />
|---- class="working"<br />
|LCL||TSplitter||working||0.9.x||easy||-||-<br />
|---- class="working"<br />
|LCL||TFindDialog||working||-||-||-||Implemented in 0.9.16<br />
|---- class="working"<br />
|LCL||TReplaceDialog||working||-||-||-||Implemented in 0.9.16<br />
|---- class="working"<br />
|LCL||TControl.Font||in progress||0.9.x||-||-||-<br />
|---- class="working"<br />
|LCL||TTabControl||in progress||0.9.x||-||-||-<br />
|---- class="partial"<br />
|LCL||Docking (= the combination of forms)||partially working, in progress||post 1.0||deep LCL and interfaces||Mattias||-<br />
|---- class="working"<br />
|LCL||Frames (= forms as children)||working||0.9.28||deep knowledge of LCL||Mattias, Paul||-<br />
|---- class="working"<br />
|IDE||Visual Form Inheritence||working||post 1.0||IDE||Mattias||Properties are not yet propagated to open descendants<br />
|---- class="partial"<br />
|LCL||MDI - Multiple Documents Interfaces Putting fo ...||in progress||1.2||deep LCL and interfaces||[[User:Zeljan|Zeljan]]||An MDI LCL emulator for widgetsets which does not support MDI, also native implementation of MDI for qt and win32/64. Currently only qt has full MDI support, others are in progress.<br />
|---- class="not"<br />
|LCL||Palette support||not implemented||-||-||-||Required to correctly show colors on a 256 colors display<br />
|---- class="partial"<br />
|LCL||TCoolBar||partially working, in progress||post 1.0||LCL and anchoring||[[User:JuhaManninen|Juha]]||-<br />
|---- class="partial"<br />
|LCL||TControlBar||skeleton implementation to prevent errors in Delphi conversion, in progress||post 1.0||LCL and anchoring||[[User:JuhaManninen|Juha]]||-<br />
|---- class="working"<br />
|LCL||TMaskEdit||working||-||-||[[User:Bart|Bart]]||-<br />
|---- class="not"<br />
|LCL||TDirectoryTreeView||not implemented||-||-||-||-<br />
|---- class="not"<br />
|LCL||Constrain maximization to specific area||not implemented||-||winapi, gtk||-||When maximizing a window, the left, top, width and height can all be constrained to a specific rectangular area on the screen/desktop. After this is done, constrain the source editor and maybe other windows<br />
|---- class="working"<br />
|Components||TIcon||working||0.9.26||-||Marc||-<br />
|---- class="working"<br />
|Components||CUPS Package||working||0.9.x||easy||-||<br />
|---- class="working"<br />
|}<br />
<br />
==Status of features on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|Accelerator Keys<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Caret<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Clipboard<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="partial"|Partially Implemented||class="partial"|Implemented in Android<br />
|----<br />
|Cursors<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Drag & Drop<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|[[Drop files event]]<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|MDI Support<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Printing<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Regions<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TCustomControl descendents<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|Unicode Support<br />
|class="working"|Working||class="not"|Impossible to Implement||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|[[BidiMode]]<br />
|class="working"|Working||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Application||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TTimer||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TApplication.QueueAsyncCall||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|TThread.Synchronize||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class="unknown"|Unknown<br />
|class="working"|Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|PostMessage||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class=""unknown"|Unknown<br />
|class="not"|Not Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|PostThreadMessage||class="working"|Working||class="unknown"|Unknown||class="unknown"|Unknown<br />
|class="unknown"|Unknown||class="unknown"|Unknown||class="unknown"|Unknown<br />
|class="unknown"|Unknown||class="unknown"|Unknown||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of Graphics on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBitmap/TPixmap/TIcon/etc||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TBrush||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TFont||class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TPen||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|ExtTextOut||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="unknown"|Unknown||class="working"|Working<br />
|}<br />
<br />
==Status of native controls on each widgetset==<br />
Native controls are TWinControl descendants which do not descend from TCustomControl.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBitBtn||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TCalendar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TCheckBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TCheckGroup||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TCheckListBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TComboBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TEdit||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TForm||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TGroupBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TIdleTimer||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TImageList||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working|| class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TListBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TListView||class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TMainMenu||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TMemo||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TMenuItem||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TPageControl and TTabSheet||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TPairSplitter||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TPanel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TPopupMenu||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TProgressBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TRadioButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TRadioGroup||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TScrollBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TScrollBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TSpinEdit||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TSplitter||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TStaticText||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TStatusBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TToggleBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TTrackbar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TTrayIcon||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of dialogs on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|LCLIntf.MessageBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="working"|Working<br />
|class="working"|Working||class="unknown"|Unknown||class="partial"|Implemented for Android<br />
|----<br />
|Application.MessageBox, MessageDlg, LCLIntf.PromptUser||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="unknown"|Unknown||class="partial"|Implemented for Android<br />
|----<br />
|LCLIntf.AskUser||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|TColorDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TFontDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TOpenDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TPrinterSetupDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TSaveDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of TCustomControl based controls on each widgetset==<br />
Note that being a TCustomControl descendant does not guarantee that a control has no widgetset implementation. TArrow has it, although it has a good default implementation. TNotebook is fully implemented in the LCL.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TArrow ||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TNoteBook||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TUpDown||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TStringGrid||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TDrawGrid||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TToolBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TTreeView||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TValueListEditor||class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of TGraphicControl based controls on each widgetset==<br />
'''Note:''' These are for LCL wrapped components only, '''not''' for the specific GUI toolkit features itself.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBevel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TLabel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="partial"|Implemented for Android<br />
|----<br />
|TShape||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TSpeedButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TPaintBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TImage||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|}<br />
<br />
==Status of LazDeviceAPIs on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! customdrawn-android<br />
|----<br />
|Accelerometer||class="working"|Working<br />
|----<br />
|Messaging (SMS, MMS and E-Mail)||class="partial"|SMS Implemented<br />
|----<br />
|PositionInfo||class="working"|Working<br />
|}<br />
<br />
==See Also==<br />
<br />
*[[LCL Internals]]<br />
*[[TAChart Roadmap]]<br />
<br />
[[Category:Lazarus]]<br />
[[Category:Roadmaps]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=LCL_Internals&diff=86447LCL Internals2015-02-15T10:42:19Z<p>Sekelsenmat: /* Clipboard */</p>
<hr />
<div>{{LCL Internals}}<br />
<br />
{{Other_Interfaces}}<br />
<br />
== Minimum Toolkit versions ==<br />
<br />
{| class="wikitable sortable"<br />
! Lazarus version !! Min. FPC !! Min. Gtk 2 !! Min. Qt 4 !! Min. Windows !! Min. Windows CE !! Min. Mac OS X (Carbon) !! Min. Mac OS X (Cocoa) !! Min. Req. of LCL-CustomDrawn<br />
|-<br />
|0.9.24<br />
|2.2.0<br />
|2.6+<br />
|4.2+<br />
|Windows 98+<br />
|Recommended 4.0+<br />
|10.4<br />
|N/A<br />
|N/A<br />
|-<br />
|0.9.26<br />
|2.2.2<br />
|2.6+<br />
|4.3+<br />
|Windows 98+<br />
|Recommended 4.0+<br />
|10.4<br />
|N/A<br />
|N/A<br />
|-<br />
|0.9.28<br />
|2.2.4<br />
|2.8+<br />
|4.5+<br />
|Windows 98+<br />
|Recommended 4.0+<br />
|10.4<br />
|N/A<br />
|N/A<br />
|-<br />
|0.9.30<br />
|2.4.0<br />
|2.8+<br />
|4.5+<br />
|Windows 98+<br />
|Recommended 5.0+<br />
|10.4<br />
|N/A<br />
|N/A<br />
|-<br />
|0.9.31<br />
|2.4.4<br />
|2.8+<br />
|4.5+<br />
|Windows 98+<br />
|Recommended 5.0+<br />
|10.4<br />
|10.6<br />
|Android 2.2+, Windows 2000+, X11, Mac OS X 10.6+<br />
|-<br />
|1.2.6<br />
|2.6.4<br />
|2.8+<br />
|4.5+*<br />
|Windows 98+<br />
|Recommended 5.0+<br />
|10.4<br />
|10.6<br />
|Android 2.2+, Windows 2000+, X11, Mac OS X 10.6+<br />
|}<br />
<br />
* - Actually 4.5.0 ...4.8.4 with pre-built Qt4Pas.dll, 4.8.5+ requires a different Qt4Pas.dll<br />
<br />
See Also: [[Installing_Lazarus_on_MacOS_X#Compatibility]]<br />
<br />
== Internals of the LCL ==<br />
<br />
There is the LCL, and the "interface". The LCL is the part that is platform independent, and it resides in the lazarus/lcl/ directory. This directory contains mainly class definitions. Many of the different controls are actually implemented in the lazarus/lcl/include/ directory in the various .inc files. This is to find the implementation of a specific control, TCustomMemo for example, faster (which is in custommemo.inc). Every .inc starts with a line {%MainUnit ...} to define where it is included.<br />
<br />
Then there is the "interface" which lives in a subdirectory of the lazarus/lcl/interfaces/ directory. The gtk interface is in gtk/, win32 in win32/, etc. They all have a Interfaces unit, which is used by the lcl and creates the main interface object. Usually the main interface object is defined in XXint.pp (win32int.pp), and implemented in various inc files, XXobject.inc, for the interface specific methods, XXwinapi.inc for winapi implementation methods, XXlistsl.inc for implementation of the stringlist used by the TComboBox, TListBox, and other such controls, XXcallback.inc for handling of widget events and taking appropriate action to notify the LCL.<br />
<br />
Every control has a WidgetSetClass property which is of the 'mirror' class in the interfaces directory, for example: mirror of TCustomEdit is TWSCustomEdit, which methods are implemented by TWin32WSCustomEdit in win32wsstdctrls. This is the way the LCL communicates with the interface, and how it lets the interface do things.<br />
<br />
Communication of interface back to LCL is mostly done by sending messages, usually 'DeliverMessage' which calls TControl.Perform(<message_id>, wparam, lparam) with wparam and lparam being the extra info for the message.<br />
<br />
=== Pie and RadialPie ===<br />
The LCLIntf unit contains two functions to draw pie-shapes:<br />
function [[doc:lcl/lclintf/pie.html|Pie]](DC: HDC; x1, y1, x2, y2, sx, sy, ex, ey: Integer): Boolean;<br />
function [[doc:lcl/lclintf/radialpie.html|RadialPie]](DC: HDC; x1, y1, x2, y2, Angle1, Angle2: Integer): Boolean; <br />
<br />
The Pie function uses a two points (sx,sy) and (ex,ey) to indicate start and end of the arc. RadialPie uses Angles to indicate start and end of the arc.<br />
<br />
Pie calls TWidgetSet.Pie and RadialPie calls TWidgetSet.RadialPie. The default implementation of TWidgetSet.Pie is to convert the parameters to angles and to call TWidgetSet.RadialPie. TWidgetSet.RadialPie creates an array of points for the arc and calls TWidgetSet.Polygon.<br />
<br />
The win32 widgetset overrides TWidgetSet.Pie to call the Windows Pie function directly.<br />
<br />
{{Note| in older versions of Lazarus there existed RadialPie with angles which did the same as the current RadialPie and RadialPie, which does the same as our Pie. Those functions have been removed in Lazarus 0.9.21.}}<br />
<br />
===Interfaces===<br />
<br />
{{Interfaces}}<br />
<br />
===Adding a new unit to the LCL===<br />
First add the new unit name into allclunits.pp.<br />
<br />
To make sure the unit is registered in the components palette see the files RegisterLCL.pas and pkgfileslcl.inc, they are located in lazarus/packager.<br />
<br />
== How to create a new Widgetset ==<br />
This is a step-by-step tutorial of developing a new [[Widgetset|widgetset]]. It is based on my experience creating the basics of the new qt4 interface.<br />
<br />
To start with, why would someone want to add an Widgetset? The answer is to be able to port existing lazarus software to more platforms, without modifying their code.<br />
<br />
Now, let´s write the widgetset. First of all, you need to have pascal bindings for the widget and know how to use it. Normally this is not hard. A few hours doing basic tutorials available on the internet should be enougth to get started. If the bindings do not exist already, you need to create them. If the tutorials are on another language, translate them to pascal and make them work.<br />
<br />
Now, for Qt I utilized Den Jean qt4 bindings for pascal, and created a very basic Qt program using them:<br />
<br />
<syntaxhighlight>program qttest;<br />
<br />
uses qt4;<br />
<br />
var<br />
App: QApplicationH;<br />
MainWindow: QMainWindowH;<br />
begin<br />
App := QApplication_Create(@argc,argv);<br />
<br />
MainWindow := QMainWindow_Create;<br />
<br />
QWidget_show(MainWindow);<br />
<br />
QApplication_Exec;<br />
end.</syntaxhighlight><br />
<br />
The above project compiles and creates a qt4 program. Now we will use its code to write a new widgetset. After we are done, the lazarus program below will compile fine into a qt4 software:<br />
<br />
<syntaxhighlight>program qttest;<br />
<br />
{$mode objfpc}{$H+}<br />
<br />
uses<br />
Interfaces, Classes, Forms,<br />
{ Add your units here }<br />
qtform;<br />
<br />
begin<br />
Application.Initialize;<br />
Application.CreateForm(TForm1, Form1);<br />
Application.Run;<br />
end.</syntaxhighlight><br />
<br />
Where the form is maintained by Lazarus IDE and designed visually.<br />
<br />
The first thing to do on a new widgetset is add an empty skeleton for it. Very early development widgetsets, like qt and carbon, can serve as an skeleton.<br />
<br />
Looking at the files on the many widgets you can see the first file to be called by the lcl: Interfaces.pas This file just calls another called QtInt.pas or similar. QtInt.pas has the code for the TWidgetSet class, which we must implement. On an empty skeleton you can see that the class has various functions it must implement:<br />
<br />
<syntaxhighlight> TQtWidgetSet = Class(TWidgetSet)<br />
private<br />
App: QApplicationH;<br />
public<br />
{$I qtwinapih.inc}<br />
{$I qtlclintfh.inc}<br />
public<br />
// Application<br />
procedure AppInit(var ScreenInfo: TScreenInfo); override;<br />
procedure AppRun(const ALoop: TApplicationMainLoop); override;<br />
procedure AppWaitMessage; override;<br />
procedure AppProcessMessages; override;<br />
procedure AppTerminate; override;<br />
procedure AppMinimize; override;<br />
procedure AppBringToFront; override;<br />
public<br />
constructor Create;<br />
destructor Destroy; override;<br />
function DCGetPixel(CanvasHandle: HDC; X, Y: integer): TGraphicsColor; override;<br />
procedure DCSetPixel(CanvasHandle: HDC; X, Y: integer; AColor: TGraphicsColor); override;<br />
procedure DCRedraw(CanvasHandle: HDC); override;<br />
procedure SetDesigning(AComponent: TComponent); override;<br />
<br />
function InitHintFont(HintFont: TObject): Boolean; override;<br />
<br />
// create and destroy<br />
function CreateComponent(Sender : TObject): THandle; override; // deprecated<br />
function CreateTimer(Interval: integer; TimerFunc: TFNTimerProc): integer; override;<br />
function DestroyTimer(TimerHandle: integer): boolean; override;<br />
end;</syntaxhighlight><br />
<br />
=== How to implement a new windowed component ===<br />
<br />
Windowed components are all descendents from TWinControl. Those controls have a Handle and thus, should be created by the Widgetset. It's easy to add new windowed components to a widgetset.<br />
<br />
Let's say you want to add TQtWSCustomEdit to Qt Widgetset. To start with TCustomEdit is a descendent of TWinControl and is located on the StdCtrls unit.<br />
<br />
Now, go to QtWSStrCtrls unit and look for the declaration of TQtWSCustomEdit.<br />
<br />
<syntaxhighlight> TQtWSCustomEdit = class(TWSCustomEdit)<br />
private<br />
protected<br />
public<br />
end;</syntaxhighlight><br />
<br />
Add static methods that are declared on TWSCustomEdit and override them. The code should now look like this:<br />
<br />
<syntaxhighlight> TQtWSCustomEdit = class(TWSCustomEdit)<br />
private<br />
protected<br />
public<br />
class function CreateHandle(const AWinControl: TWinControl;<br />
const AParams: TCreateParams): HWND; override;<br />
class procedure DestroyHandle(const AWinControl: TWinControl); override;<br />
{ class function GetSelStart(const ACustomEdit: TCustomEdit): integer; override;<br />
class function GetSelLength(const ACustomEdit: TCustomEdit): integer; override;<br />
<br />
class procedure SetCharCase(const ACustomEdit: TCustomEdit; NewCase: TEditCharCase); override;<br />
class procedure SetEchoMode(const ACustomEdit: TCustomEdit; NewMode: TEchoMode); override;<br />
class procedure SetMaxLength(const ACustomEdit: TCustomEdit; NewLength: integer); override;<br />
class procedure SetPasswordChar(const ACustomEdit: TCustomEdit; NewChar: char); override;<br />
class procedure SetReadOnly(const ACustomEdit: TCustomEdit; NewReadOnly: boolean); override;<br />
class procedure SetSelStart(const ACustomEdit: TCustomEdit; NewStart: integer); override;<br />
class procedure SetSelLength(const ACustomEdit: TCustomEdit; NewLength: integer); override;<br />
<br />
class procedure GetPreferredSize(const AWinControl: TWinControl;<br />
var PreferredWidth, PreferredHeight: integer); override;}<br />
end;</syntaxhighlight><br />
<br />
The commented part of the code are procedures you need to implement for TCustomEdit to be fully functional, but just CreateHandle and DestroyHandle should be enough for it to be show on the form and be editable, so it fits our needs in this article.<br />
<br />
Hit CTRL+SHIFT+C to code complete and the implement CreateHandle and DestroyHandle. In the case of Qt4 the code will be like this:<br />
<br />
<syntaxhighlight>{ TQtWSCustomEdit }<br />
<br />
class function TQtWSCustomEdit.CreateHandle(const AWinControl: TWinControl;<br />
const AParams: TCreateParams): HWND;<br />
var<br />
Widget: QWidgetH;<br />
Str: WideString;<br />
begin<br />
// Creates the widget<br />
WriteLn('Calling QTextDocument_create');<br />
Str := WideString((AWinControl as TCustomMemo).Lines.Text);<br />
Widget := QTextEdit_create(@Str, QWidgetH(AWinControl.Parent.Handle));<br />
<br />
// Sets it's initial properties<br />
QWidget_setGeometry(Widget, AWinControl.Left, AWinControl.Top,<br />
AWinControl.Width, AWinControl.Height);<br />
<br />
QWidget_show(Widget);<br />
<br />
Result := THandle(Widget);<br />
end;<br />
<br />
class procedure TQtWSCustomEdit.DestroyHandle(const AWinControl: TWinControl);<br />
begin<br />
QTextEdit_destroy(QTextEditH(AWinControl.Handle));<br />
end;</syntaxhighlight><br />
<br />
Now uncomment the like "RegisterWSComponent(TCustomEdit, TQtWSCustomEdit);" on the bottom of the unit and that's it!<br />
<br />
You can now drop a TCustomEdit on the bottom of a form and expect it to work. :^) <br />
<br />
=== Implementing TBitmap ===<br />
<br />
To implement TBitmap it is necessary to understand TRawImage and TLazIntfImage as explained here: [[Developing with Graphics#Working with TLazIntfImage.2C TRawImage and TLazCanvas]]<br />
<br />
So, let's say you want to compile the following code:<br />
<br />
<syntaxhighlight><br />
procedure TMyForm.HandleOnPaint(Sender: TObject);<br />
var<br />
Bitmap: TBitmap;<br />
begin<br />
Bitmap := TBitmap.Create;<br />
try<br />
Bitmap.LoadFromFile('myfile.bmp');<br />
Canvas.Draw(0, 0, Bitmap);<br />
finally<br />
Bitmap.Free;<br />
end;<br />
end;</syntaxhighlight><br />
<br />
Below is the order on which functions from the widgetset interface are called when executing that code:<br />
<br />
1 - BeginPaint<br />
<br />
This will be called only if the OnPaint event sends zero as the DC for the paint event<br />
<br />
2 - GetDC(0);<br />
<br />
Just create a device context.<br />
<br />
3 - TCDWidgetSet.RawImage_QueryDescription <br />
<br />
The default implementation of this routine is good for most widgetsets<br />
<br />
4 - TCDWidgetSet.RawImage_CreateBitmaps<br />
<br />
Here you need to create a native image object and load it from RawData.Data where the information is stored based on your description of the pixel format on item 2.<br />
<br />
5 - CreateCompatibleDC(0)<br />
<br />
This creates a temporary DC just to store the image, but at this point there is no information about the image so at this point this DC is really dummy<br />
<br />
6 - SelectObject<br />
<br />
With the image as the object to be selected and the DC just created above as target DC.<br />
<br />
7 - StretchMaskBlt<br />
<br />
Finally the drawing function! DestDC is the DC allocated on BeginPaint.<br />
<br />
8 - EndPaint<br />
<br />
Again, not always utilized.<br />
<br />
=== TBitmap.LoadFromDevice for screenshot taking ===<br />
<br />
It is recomended that you first implement TBitmap before trying this step.<br />
<br />
On LCL you can use the following code takes a screenshot from the entire screen and paints it on the canvas:<br />
<br />
<syntaxhighlight>var<br />
ScreenDC: HDC;<br />
Bitmap: TBitmap;<br />
begin<br />
Bitmap := TBitmap.Create;<br />
try<br />
ScreenDC := GetDC(0);<br />
Bitmap.LoadFromDevice(ScreenDC);<br />
ReleaseDC(0, ScreenDC);<br />
Canvas.Draw(0, 0, Bitmap);<br />
finally<br />
Bitmap.Free;<br />
end;<br />
end;</syntaxhighlight><br />
<br />
If you already implemented TBitmap, there are only 2 new functions to be implemented for LoadFromDevice: GetDeviceSize and GetRawImageFromDevice<br />
<br />
Below is a big trace, covering all widgetset functions being called on a OnPaint event that takes a screenshot and paints it on the screen. This trace was taken with Qt widgetset, and may have some imperfections. The Handle numbers should be used to check which object is being utilized on the functions.<br />
<br />
<br />
[WinAPI BeginPaint] Result=-1220713544<br />
<br />
[WinAPI GetClientBounds]<br />
<br />
[WinAPI SetWindowOrgEx] DC: -1220713544 NewX: 0 NewY: 0<br />
<br />
<syntaxhighlight>Enters on Paint event<br />
<br />
Bitmap := TBitmap.Create;<br />
try<br />
ScreenDC := GetDC(0);</syntaxhighlight><br />
<br />
[WinAPI GetDC] hWnd: 0 Result: -1220712920<br />
<br />
<syntaxhighlight> Bitmap.LoadFromDevice(ScreenDC);</syntaxhighlight><br />
<br />
[WinAPI GetDeviceSize]<br />
<br />
[WinAPI GetRawImageFromDevice] SrcDC: -1220712920 SrcWidth: 0 SrcHeight: 0<br />
<br />
[WinAPI CreateBitmapFromRawImage] Width:1024 Height:768 DataSize: 3145728 CreateMask: False Bitmap:-1220746696<br />
<br />
[WinAPI GetObject] GDIObj: -1220746696 Result=84 ObjectType=Image<br />
<br />
<syntaxhighlight> ReleaseDC(0, ScreenDC);</syntaxhighlight><br />
<br />
[WinAPI ReleaseDC] hWnd: 0 DC: -1220712920<br />
<br />
<syntaxhighlight> Canvas.Draw(0, 0, Bitmap);</syntaxhighlight><br />
<br />
[WinAPI CreateCompatibleDC] DC: 0<br />
<br />
[WinAPI GetDC] hWnd: 0 Result: -1220712920<br />
<br />
[WinAPI SelectObject] DC=-1220712920 GDIObj=-1220746696 Result=0 ObjectType=Image<br />
<br />
[WinAPI StretchMaskBlt] DestDC:-1220713544 SrcDC:-1220712920 Image:137185120 X:0 Y:0 W:1024 H:768 XSrc:0 YSrc:0 WSrc:1024 HSrc:768<br />
<br />
<syntaxhighlight>finally<br />
Bitmap.Free;<br />
end;</syntaxhighlight><br />
<br />
[WinAPI SelectObject] DC=-1220712920 GDIObj=0 Invalid GDI Object<br />
<br />
[WinAPI DeleteObject] GDIObject: -1220746696 Result=False ObjectType=Image<br />
<br />
<pre><br />
Now exited the OnPaint event<br />
</pre><br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
[WinAPI SetWindowOrgEx] DC: -1220713544 NewX: -152 NewY: -246<br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
TWidgetSet.InitializeCriticalSection<br />
<br />
TWidgetSet.EnterCriticalSection<br />
<br />
[WinAPI SelectObject] DC=-1220713544 GDIObj=0 Invalid GDI Object<br />
<br />
[WinAPI MoveToEx] DC:-1220713544 X:0 Y:0<br />
<br />
[WinAPI SelectObject] DC=-1220713544 GDIObj=-1220746760 Result=-1220746856 ObjectType=Brush<br />
<br />
[WinAPI SelectObject] DC=-1220713544 GDIObj=-1220746856 Result=-1220746856 ObjectType=Brush<br />
<br />
TWidgetSet.LeaveCriticalSection<br />
<br />
[WinAPI SetWindowOrgEx] DC: -1220713544 NewX: 0 NewY: 0<br />
<br />
[WinAPI EndPaint] Handle: -1220611768 PS.HDC: -1220713544<br />
<br />
=== Implementing drawing in the OnPaint event of a form or another control ===<br />
<br />
For drawing in the OnPaint event of a form, the event itself comes from the underlaying widgetset library. The LCL interface should handle this event and create an appropriate DC object on the event handler and then call LCLSendPaintMsg. Besides that one should also implement the corresponding drawing methods, such as Rectangle or ExtTextOut. Pen, Brush and Font related routines might also be useful.<br />
<br />
Here is the OnPaint event handler from the Cocoa widgetset which shows how it calls LCLSentPaintMsg:<br />
<br />
<syntaxhighlight><br />
procedure TLCLCommonCallback.Draw(ControlContext: NSGraphicsContext;<br />
const bounds, dirty:NSRect);<br />
var<br />
struct : TPaintStruct;<br />
begin<br />
if not Assigned(Context) then Context:=TCocoaContext.Create;<br />
<br />
Context.ctx:=ControlContext;<br />
if Context.InitDraw(Round(bounds.size.width), Round(bounds.size.height)) then<br />
begin<br />
FillChar(struct, SizeOf(TPaintStruct), 0);<br />
struct.hdc := HDC(Context);<br />
{$IFDEF VerboseWinAPI}<br />
DebugLn(Format('[TLCLCommonCallback.Draw] OnPaint event started context: %x', [HDC(context)]));<br />
{$ENDIF}<br />
LCLSendPaintMsg(Target, HDC(Context), @struct);<br />
{$IFDEF VerboseWinAPI}<br />
DebugLn('[TLCLCommonCallback.Draw] OnPaint event ended');<br />
{$ENDIF}<br />
end;<br />
end;<br />
</syntaxhighlight><br />
<br />
And a list of WinAPI routines which were called when running this event:<br />
<br />
<pre><br />
[TCocoaWidgetSet.GetDC] hWnd: 0 Result: 12400C0<br />
[TLCLCommonCallback.Draw] OnPaint event started context: 1240340<br />
TCocoaWidgetSet.CreatePenIndirect<br />
TCocoaWidgetSet.SelectObject DC: 1240340 GDIObj: 10EC460<br />
TCocoaWidgetSet.SelectObject Result: 0<br />
TCocoaWidgetSet.SelectObject DC: 1240340 GDIObj: 10EBF00<br />
TCocoaWidgetSet.SelectObject Result: 0<br />
[TCocoaWidgetSet.Rectangle] DC: 1240340 X1: 100 Y1: 100 X2: 200 Y2: 200<br />
TCocoaWidgetSet.SelectObject DC: 1240340 GDIObj: 10EC4A0<br />
TCocoaWidgetSet.SelectObject Result: 0<br />
[TCocoaWidgetSet.GetTextExtentPoint] DC: 1240340 Str: Some text Count: 9<br />
[TCocoaWidgetSet.GetTextExtentPoint] Size: 65,17<br />
[TLCLCommonCallback.Draw] OnPaint event ended<br />
</pre><br />
<br />
=== Implementing TLabel ===<br />
<br />
Implementing TLabel is particularly hard, despite it being such a basic component, because it requires that almost all painting be implemented. TLabel is not a windowed control, instead it depends on paint messages to be drawn directly into the form canvas.<br />
<br />
Before trying to get TLabel working it is recomended to test if drawing functions such as Rectangle work inside a form's OnPaint event.<br />
<br />
Several WinAPI methods need to be implemented, particularly:<br />
<br />
'''Device Context Methods'''<br />
<br />
BeginPaint, GetDC, EndPaint, ReleaseDC, CreateCompatibleDC<br />
<br />
see [[Device Contexts and GDI objects in the LCL interfaces]]<br />
<br />
'''GDI Objects Methods'''<br />
<br />
SelectObject, DeleteObject, CreateFontIndirect, CreateFontIndirectEx<br />
<br />
'''Miscelaneous functions'''<br />
<br />
InvalidateRect, GetClientBounds, SetWindowOrgEx<br />
<br />
'''Text drawing Methods'''<br />
<br />
DrawText. Instead of implementing DrawText one can also use the default TWidgetSet.DrawText, like the Carbon and Cocoa widgetsets do. But in this case it is necessary that one implements at least GetTextMetrics, GetTextExtentPoint and ExtTextOut. Without GetTextMetrics a form with a label will crash because the autosize will not be able to calculate the appropriate size for the label.<br />
<br />
'''Region functions to determine if the control is behind another'''<br />
<br />
CombineRgn, CreateRectRgn, GetClipRGN, RectVisible<br />
<br />
<br />
Below is the order in which paint procedures are called on a form with only one TLabel, to better understand the painting sequence:<br />
<br />
1 - GetDC is called once on software startup with hWnd = 0<br />
<br />
2 - The form is shown<br />
<br />
3 - GetDC is called again (this wouldn't happen without the label). A<br />
few font related functions are called, as well as DrawText with<br />
CalcRect set to True to calculate the size of the label.<br />
<br />
4 - InvalidateRect is called on the form canvas<br />
<br />
5 - Control goes back to the operating system until a paint message comes from the widgetset<br />
<br />
6 - BeginPaint is called, and at this point code on OnPaint event of the form will be executed<br />
<br />
7 - DrawText is called again with CalcRect set to false<br />
<br />
8 - The Painting ends.<br />
<br />
=== Implementing visibility for forms and controls and window state===<br />
<br />
The code that controls visibility is split between visibility for forms, and for controls<br />
<br />
'''Visibility for forms and window state'''<br />
<br />
This part also controls the state of the window (minimized, maximized or normal). It is implemented as a copy of the Windows API function ShowWindow, so you must implemente the TMyWidgetset.ShowWindow on the file mywinapi.inc Don´t forget to also add a header to the file mywinapih.inc<br />
<br />
Below is code that implements this function on the Qt widgetset. It should be very easy to understand, copy and implement on your own widgetset. You can also take a look how Gtk implements this. On Windows, the Windows API is called directly, of course, so there is no code to look at.<br />
<br />
<syntaxhighlight>{------------------------------------------------------------------------------<br />
function ShowWindow(hWnd: HWND; nCmdShow: Integer): Boolean;<br />
<br />
nCmdShow:<br />
SW_SHOWNORMAL, SW_MINIMIZE, SW_SHOWMAXIMIZED<br />
------------------------------------------------------------------------------}<br />
function TQtWidgetSet.ShowWindow(hWnd: HWND; nCmdShow: Integer): Boolean;<br />
var<br />
Widget: QWidgetH;<br />
begin<br />
{$ifdef VerboseQtWinAPI}<br />
WriteLn('WinAPI ShowWindow');<br />
{$endif}<br />
<br />
Result := False;<br />
<br />
Widget := QWidgetH(hWnd);<br />
<br />
// if Widget = nil then RaiseException('TQtWidgetSet.ShowWindow hWnd is nil');<br />
<br />
case nCmdShow of<br />
<br />
SW_SHOW: QWidget_setVisible(Widget, True);<br />
<br />
SW_SHOWNORMAL: QWidget_showNormal(Widget);<br />
<br />
SW_MINIMIZE: QWidget_setWindowState(Widget, QtWindowMinimized);<br />
<br />
SW_SHOWMINIMIZED: QWidget_showMinimized(Widget);<br />
<br />
SW_SHOWMAXIMIZED: QWidget_showMaximized(Widget);<br />
<br />
SW_HIDE: QWidget_setVisible(Widget, False);<br />
<br />
end;<br />
<br />
Result := True;<br />
end;</syntaxhighlight><br />
<br />
'''Visibility for controls'''<br />
<br />
For controls inside a form you need to implement TMyWSWinControl.ShowHide class function that resides on the TMyWSWinControl class on the file mywscontrols.pp<br />
<br />
Remember that most controls are descendent from TWinControl, so implementing this function there will guarantee that the Visible property is implemented for all standard controls that have it. Below is a sample code for Qt widgetset.<br />
<br />
<syntaxhighlight>{------------------------------------------------------------------------------<br />
Method: TQtWSWinControl.ShowHide<br />
Params: AWinControl - the calling object<br />
<br />
Returns: Nothing<br />
<br />
Shows or hides a widget.<br />
------------------------------------------------------------------------------}<br />
class procedure TQtWSWinControl.ShowHide(const AWinControl: TWinControl);<br />
begin<br />
if AWinControl = nil then exit;<br />
<br />
if not AWinControl.HandleAllocated then exit;<br />
<br />
if AWinControl.HandleObjectShouldBeVisible then<br />
QWidget_setVisible(TQtWidget(AWinControl.Handle).Widget, True)<br />
else QWidget_setVisible(TQtWidget(AWinControl.Handle).Widget, False);<br />
end;</syntaxhighlight><br />
<br />
=== Implementing TStrings based Components===<br />
Some components use a TStrings to store the information they display, such as: TCustomMemo, TCustomListBox and TCustomComboBox.<br />
<br />
To implement those it is not enougth to only implement their functions on the TQtCustomMemo class for example. One of the functions to implement will be called GetStrings, which looks like this:<br />
<br />
<syntaxhighlight>class function TQtWSCustomListBox.GetStrings(const ACustomListBox: TCustomListBox): TStrings;<br />
var<br />
ListWidgetH: QListWidgetH;<br />
begin<br />
ListWidgetH := QListWidgetH((TQtWidget(ACustomListBox.Handle).Widget));<br />
Result := TQtListStrings.Create(ListWidgetH, ACustomListBox);<br />
end;</syntaxhighlight><br />
<br />
This function must return a TStrings descendent designed to detect when strings are added to or removed from the string list and to send this information to the widgetset to update the control. For example, the following declaration shows what TQtListStrings looks like:<br />
<br />
<syntaxhighlight> TQtListStrings = class(TStrings)<br />
private<br />
FListChanged: Boolean; // StringList and QtListWidget out of sync<br />
FStringList: TStringList; // Holds the items to show<br />
FQtListWidget: QListWidgetH; // Qt Widget<br />
FOwner: TWinControl; // Lazarus Control Owning ListStrings<br />
FUpdating: Boolean; // We're changing Qt Widget<br />
procedure InternalUpdate;<br />
procedure ExternalUpdate(var Astr: TStringList; Clear: Boolean = True);<br />
procedure IsChanged; // OnChange triggered by program action<br />
protected<br />
function GetTextStr: string; override;<br />
function GetCount: integer; override;<br />
function Get(Index : Integer) : string; override;<br />
//procedure SetSorted(Val : boolean); virtual;<br />
public<br />
constructor Create(ListWidgetH : QListWidgetH; TheOwner: TWinControl);<br />
destructor Destroy; override;<br />
procedure Assign(Source : TPersistent); override;<br />
procedure Clear; override;<br />
procedure Delete(Index : integer); override;<br />
procedure Insert(Index : integer; const S: string); override;<br />
procedure SetText(TheText: PChar); override;<br />
//procedure Sort; virtual;<br />
public<br />
//property Sorted: boolean read FSorted write SetSorted;<br />
property Owner: TWinControl read FOwner;<br />
function ListChangedHandler(Sender: QObjectH; Event: QEventH): Boolean; cdecl;<br />
end;</syntaxhighlight><br />
<br />
You can see its implementation in the qtobjects.pas unit of the qt interface<br />
<br />
===Implementing Menus===<br />
<br />
Menus are available on the LCL to create main menus or popup menus. A TMenu is the owner of a larger menu structure with many items. Items can have subitems, and don't need extra TMenus.<br />
<br />
Also remember that on LCL the handle is only created when needed and at that time all properties of the controls are already initialized. This helps a lot on widgetsets where depending on the properties of a menu item it can be of one class or another, like Qt.<br />
<br />
The following things need to be implemented in order for the menus to work:<br />
<br />
1) All methods on the QtWSMenus unit, which will implement menu creation and modification<br />
<br />
2) function TWinCEWidgetSet.SetMenu(AWindowHandle: HWND; AMenuHandle: HMENU): Boolean; from the wincewinapi.inc file, which will implement support for a main menu associated with a window.<br />
<br />
====Menu Creation Order====<br />
<br />
<br />
One important thing to understand when implementing menus, is in which order they are created. For example, we want to create the following menu structure:<br />
<br />
[[Image:Menu_creation_order.png]]<br />
<br />
And when our application is executed, there will be a 'Creating MenuItem' message with the caption of the menu each time TQtWSMenuItem.CreateHandle is called, and a 'Creating Menu' message with the name of the menu (TMenu descendents don't have a caption), each time TQtWSMenu.CreateHandle is called.<br />
<br />
Here is the resulting output of such software:<br />
<br />
<pre><br />
Creating Menu. Name: MainMenu1<br />
Creating MenuItem: Item1 Parent=Menu.Items : TMenuItem<br />
Creating MenuItem: SubItem11 Parent=Item1 : TMenuItem<br />
Creating MenuItem: SubItem12 Parent=Item1 : TMenuItem<br />
Creating MenuItem: SubItem13 Parent=Item1 : TMenuItem<br />
Creating MenuItem: SubItem14 Parent=Item1 : TMenuItem<br />
Creating MenuItem: SubSubItem141 Parent=SubItem14 : TMenuItem<br />
Creating MenuItem: SubSubItem142 Parent=SubItem14 : TMenuItem<br />
Creating MenuItem: SubSubItem143 Parent=SubItem14 : TMenuItem<br />
Creating MenuItem: SubSubItem144 Parent=SubItem14 : TMenuItem<br />
Creating MenuItem: Item2 Parent=Menu.Items : TMenuItem<br />
Creating MenuItem: SubItem21 Parent=Item2 : TMenuItem<br />
Creating MenuItem: SubItem22 Parent=Item2 : TMenuItem<br />
Creating MenuItem: SubItem23 Parent=Item2 : TMenuItem<br />
Creating MenuItem: Item3 Parent=Menu.Items : TMenuItem<br />
Creating MenuItem: Item4 Parent=Menu.Items : TMenuItem<br />
</pre><br />
<br />
For all MenuItems one can use GetParentMenu to get their parent owner: Menu (TMainMenu).<br />
<br />
===Control enabling/disabling===<br />
<br />
The current way to set control enabling/disabling is by implementing the winapi EnableWindow. This API should work generically on any control. It should enable/disable mouse and keyboard input for the specified window or control, but also mark it as uneditable by the user, by making it greyed for example.<br />
<br />
<syntaxhighlight>{------------------------------------------------------------------------------<br />
Method: EnableWindow<br />
Params: HWnd - handle to window<br />
BEnable - whether to enable the window<br />
Returns: If the window was previously disabled<br />
<br />
Enables or disables mouse and keyboard input to the specified window or<br />
control.<br />
------------------------------------------------------------------------------}<br />
function TWin32WidgetSet.EnableWindow(hWnd: HWND; bEnable: Boolean): Boolean;</syntaxhighlight><br />
<br />
===Shaped Windows===<br />
<br />
Windows can be shaped based on a TBitmap or on a TRegion. The region is the visible part.<br />
<br />
To implement shaped windows based on a TBitmap, implement TWSWinControl.setShape<br />
<br />
To implement shaped windows based on a TRegion implement LCLIntf.SetWindowRgn<br />
<br />
See also: [[LCL Tips#Creating a non-rectangular window or control]]<br />
<br />
===System colors===<br />
<br />
Some color constants are actually system colors, like clBtnFace, clForm, clWindow, etc, etc.<br />
<br />
To implement support for system colors the WinAPI routine GetSysColor should be implemented:<br />
<br />
function GetSysColor(nIndex: Integer): DWORD; override;<br />
<br />
And here is a snip of the color constants which should be supported. Check LCLType for the latest values:<br />
<br />
<syntaxhighlight><br />
//==============================================<br />
// API system Color constants pbd<br />
// note these are usually shown ORed with<br />
// $80000000 as these would have interfered with<br />
// other MS color enumerations<br />
// GetSysColor and SetSysColor expects the values<br />
// below<br />
//==============================================<br />
<br />
type<br />
COLORREF = LongInt;<br />
TColorRef = COLORREF;<br />
<br />
const<br />
CLR_INVALID = TColorRef($FFFFFFFF);<br />
<br />
COLOR_SCROLLBAR = 0;<br />
COLOR_BACKGROUND = 1;<br />
COLOR_ACTIVECAPTION = 2;<br />
COLOR_INACTIVECAPTION = 3;<br />
COLOR_MENU = 4;<br />
COLOR_WINDOW = 5;<br />
COLOR_WINDOWFRAME = 6;<br />
COLOR_MENUTEXT = 7;<br />
COLOR_WINDOWTEXT = 8;<br />
COLOR_CAPTIONTEXT = 9;<br />
COLOR_ACTIVEBORDER = 10;<br />
COLOR_INACTIVEBORDER = 11;<br />
COLOR_APPWORKSPACE = 12;<br />
COLOR_HIGHLIGHT = 13;<br />
COLOR_HIGHLIGHTTEXT = 14;<br />
COLOR_BTNFACE = 15;<br />
COLOR_BTNSHADOW = 16;<br />
COLOR_GRAYTEXT = 17;<br />
COLOR_BTNTEXT = 18;<br />
COLOR_INACTIVECAPTIONTEXT = 19;<br />
COLOR_BTNHIGHLIGHT = 20;<br />
COLOR_3DDKSHADOW = 21;<br />
COLOR_3DLIGHT = 22;<br />
COLOR_INFOTEXT = 23;<br />
COLOR_INFOBK = 24;<br />
// PBD: 25 is unassigned in all the docs I can find<br />
// if someone finds what this is supposed to be then fill it in<br />
// note defaults below, and cl[ColorConst] in graphics<br />
COLOR_HOTLIGHT = 26;<br />
COLOR_GRADIENTACTIVECAPTION = 27;<br />
COLOR_GRADIENTINACTIVECAPTION = 28;<br />
COLOR_MENUHILIGHT = 29;<br />
COLOR_MENUBAR = 30;<br />
<br />
COLOR_FORM = 31;<br />
<br />
COLOR_ENDCOLORS = COLOR_FORM;<br />
<br />
COLOR_DESKTOP = COLOR_BACKGROUND;<br />
COLOR_3DFACE = COLOR_BTNFACE;<br />
COLOR_3DSHADOW = COLOR_BTNSHADOW;<br />
COLOR_3DHIGHLIGHT = COLOR_BTNHIGHLIGHT;<br />
COLOR_3DHILIGHT = COLOR_BTNHIGHLIGHT;<br />
COLOR_BTNHILIGHT = COLOR_BTNHIGHLIGHT;<br />
<br />
MAX_SYS_COLORS = COLOR_ENDCOLORS;<br />
SYS_COLOR_BASE = TColorRef($80000000);</syntaxhighlight><br />
<br />
===ShowMessage===<br />
<br />
These standard dialogs are implemented purely in the LCL in the following places:<br />
<br />
* Class TPromptDialog file lcl/include/promptdialog.inc<br />
<br />
===SpinEdit===<br />
<br />
Both TFloatSpinEdit and TSpinEdit are implemented in the class TWSFloatSpinEdit.<br />
<br />
===Clipboard===<br />
<br />
Clipboard support is implemented in lclintf by implementing Windows API routines. The routines are:<br />
<br />
<syntaxhighlight>function ClipboardFormatToMimeType(FormatID: TClipboardFormat): string; {$IFDEF IF_BASE_MEMBER}virtual;{$ENDIF}<br />
function ClipboardGetData(ClipboardType: TClipboardType;<br />
FormatID: TClipboardFormat; Stream: TStream): boolean; {$IFDEF IF_BASE_MEMBER}virtual;{$ENDIF}<br />
// ! ClipboardGetFormats: List will be created. You must free it yourself with FreeMem(List) !<br />
function ClipboardGetFormats(ClipboardType: TClipboardType;<br />
var Count: integer; var List: PClipboardFormat): boolean; {$IFDEF IF_BASE_MEMBER}virtual;{$ENDIF}<br />
function ClipboardGetOwnerShip(ClipboardType: TClipboardType;<br />
OnRequestProc: TClipboardRequestEvent; FormatCount: integer;<br />
Formats: PClipboardFormat): boolean; {$IFDEF IF_BASE_MEMBER}virtual;{$ENDIF}<br />
function ClipboardRegisterFormat(const AMimeType: string): TClipboardFormat; {$IFDEF IF_BASE_MEMBER}virtual;{$ENDIF}</syntaxhighlight><br />
<br />
Sequence of calls during program startup:<br />
<br />
<syntaxhighlight>TCocoaWidgetSet.ClipboardRegisterFormat AMimeType=image/bmp Result=51027040<br />
TCocoaWidgetSet.ClipboardRegisterFormat AMimeType=image/delphi.bitmap Result=0<br />
TCocoaWidgetSet.ClipboardRegisterFormat AMimeType=image/xpm Result=0<br />
TCocoaWidgetSet.ClipboardRegisterFormat AMimeType=image/png Result=0<br />
TCocoaWidgetSet.ClipboardRegisterFormat AMimeType=image/jpeg Result=0</syntaxhighlight><br />
<br />
Sequence of calls during "Caption := Clipboard.AsText":<br />
<br />
<syntaxhighlight>TCocoaWidgetSet.ClipboardRegisterFormat AMimeType=text/plain Result=51026976<br />
TCocoaWidgetSet.ClipboardGetData ClipboardType=clipboard FormatID: 51026976</syntaxhighlight><br />
<br />
===TSpeedButton===<br />
<br />
This control is a TGraphicControl descendent, so it has no handle and paints itself. To retain native look, it uses the function LCLIntf.DrawFrameControl to paint itself, so implement this function to have this control working. Naturally, lot's of other DC, WindowOrg, Text Drawing and Painting routines will have to be working, as explained for TLabel.<br />
<br />
===TRadioButton and TCheckButton===<br />
<br />
'''Messages:'''<br />
<br />
Basically the Widgetset must do:<br />
<br />
*Send LM_CHANGE when a radio button is unchecked/checked (LCL will take care if OnClick will be called or not)<br />
*Dont send LM_CHANGE when TWSCustomCheckBox.SetState is called (SetChecked)<br />
<br />
See also this bug report: http://bugs.freepascal.org/view.php?id=13939<br />
<br />
===FullScreen support===<br />
<br />
FullScreen is implemented as a Windows state wsFullScreen, and as such is implemented in LCLIntf.ShowWindow where the constant SW_SHOWFULLSCREEN should be handled.<br />
<br />
== An example of how the LCL interfaces work ==<br />
<br />
Below is a simple example. Suppose you have developed a trayicon component. How would you implement it in the LCL to work correctly on the various different supported platforms?<br />
<br />
You would need to generate the following files:<br />
<br />
\trayicon.pas<br />
<br />
\wstrayicon.pas<br />
<br />
\gtk\gtkwstrayicon.pas<br />
<br />
\gtk\trayintf.pas<br />
<br />
\win32\win32wstrayicon.pas<br />
<br />
\win32\trayintf.pas<br />
<br />
<br />
Providing separate wsXXX.pas and \$(LCLWidgetType)\XXXintf.pas files avoids the need for ifdefs altogether. You will need to add as a unit path $(LCLWidgetType) to the XXXintf.pas file in order initialize the correct trayintf.pas file, which in turn initializes the correct WS Tray class.<br />
<br />
Inside trayicon.pas you include wstrayicon. Derive your main class from an LCL class, and only use wstrayicon in its implementation. All LCL classes that communicate with a widgetset, must be derived from [[doc:/lcl/lclclasses/tlclcomponent.html|TLCLComponent]] declared in the [[doc:/lcl/lclclasses|LCLClasses]] unit.<br />
<br />
<syntaxhighlight>unit TrayIcon;<br />
<br />
interface<br />
<br />
type<br />
TTrayIcon = class(TLCLComponent)<br />
public<br />
procedure DoTray;<br />
end;<br />
<br />
implementation<br />
<br />
uses wstrayicon;<br />
<br />
procedure TTrayIcon.DoTray;<br />
begin<br />
// Call wstrayicon<br />
end;<br />
<br />
end.</syntaxhighlight><br />
<br />
in trayintf you use gtkwstrayicon or win32trayicon depending on which<br />
trayintf file it is.<br />
<br />
in wstrayicon you create a class like so:<br />
<br />
<syntaxhighlight>unit WSTrayIcon;<br />
<br />
uses WSLCLClasses, Controls, TrayIcon; // and other things as well<br />
<br />
TWSTrayIconClass = class of TWSTrayIcon;<br />
TWSTrayIcon = class(TWSWinControl);<br />
public<br />
class procedure EmbedTrayIcon(const ATrayIcon: TCustomTrayIcon);<br />
virtual; // these must all be virtual and class procedures!!<br />
class procedure RemoveTrayIcon(const ATrayIcon: TCustomTrayIcon); virtual;<br />
....<br />
end;<br />
...<br />
<br />
implementation<br />
<br />
procedure TWSTrayIcon.EmbedTrayIcon(const ATrayIcon: TCustomTrayIcon);<br />
begin<br />
//do nothing<br />
end;<br />
<br />
procedure TWSTrayIcon.RemoveTrayIcon(const ATrayIcon: TCustomTrayIcon);<br />
begin<br />
//do nothing<br />
end;</syntaxhighlight><br />
<br />
now in gtkwstrayicon.pas do this:<br />
<br />
<syntaxhighlight>uses WSTrayIcon, WSLCLClasses, Controls, TrayIcon, gtk, gdk;<br />
<br />
<br />
TGtkWSTrayIcon = class(TWSTrayIcon);<br />
private<br />
class function FindSystemTray(const ATrayIcon: TCustomTrayIcon):<br />
TWindow; virtual;<br />
public<br />
class procedure EmbedTrayIcon(const ATrayIcon: TCustomTrayIcon); override;<br />
class procedure RemoveTrayIcon(const ATrayIcon: TCustomTrayIcon);<br />
override;<br />
class function CreateHandle(const AWinControl: TWinControl; const<br />
AParams: TCreateParams): HWND; override;<br />
....<br />
end;<br />
...<br />
<br />
implementation<br />
<br />
procedure TGtkWSTrayIcon.CreateHandle(const AWinControl: TWinControl;<br />
const AParams: TCreateParams): HWND;<br />
var<br />
WidgetInfo: PWidgetInfo;<br />
begin<br />
<br />
Result := gtk_plug_new;<br />
WidgetInfo := CreateWidgetInfo(AWinControl, Result); // it's something<br />
like this anyway<br />
TGtkWSWincontrolClass(WidgetSetClass).SetCallbacks(AWinControl);<br />
// and more stuff<br />
end;<br />
<br />
function TGtkWSTrayIcon.FindSystemTray(const ATrayIcon:<br />
TCustomTrayIcon): TWindow;<br />
begin<br />
// do something<br />
end;<br />
<br />
<br />
procedure TGtkWSTrayIcon.EmbedTrayIcon(const ATrayIcon: TCustomTrayIcon);<br />
var<br />
SystemTray: TWindow;<br />
begin<br />
SystemTray := FindSystemTray(ATrayIcon);<br />
//do something<br />
end;<br />
<br />
procedure TGtkWSTrayIcon.RemoveTrayIcon(const ATrayIcon: TCustomTrayIcon);<br />
begin<br />
//do something<br />
end;<br />
<br />
......<br />
<br />
initialization<br />
<br />
RegisterWSComponent(TCustomTrayIcon, TGtkWSTrayIcon); //this is very<br />
important!!!<br />
<br />
end.</syntaxhighlight><br />
<br />
then finally in trayicon.pas you go as normal<br />
<br />
<syntaxhighlight>uses WSTrayIcon; //etc. you DON'T include GtkWSTrayIcon here!<br />
<br />
TCustomTrayIcon = class(TWinControl)<br />
public<br />
procedure EmbedControl;<br />
....<br />
end;<br />
<br />
...<br />
procedure TTrayIcon.EmbedControl;<br />
begin<br />
TWSTrayIconClass(WidgetSetClass).EmbedControl(Self);<br />
<br />
end;</syntaxhighlight><br />
<br />
----<br />
This document is work in progress. You can help by writing sections of this document. If you cannot find the information you are looking for in this document, please add your question to the [[Talk:LCL Internals|discussion page]]. This will help us to write documentation at a level that is neither too simple nor too complicated, and fully cover the areas that people want to know about.<br />
<br />
[[Category:LCL]]<br />
[[Category:Lazarus internals]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=Roadmap&diff=86439Roadmap2015-02-14T20:16:17Z<p>Sekelsenmat: /* Status of dialogs on each widgetset */</p>
<hr />
<div>{{Roadmap}}<br />
<br />
This document gives an idea of the current status of the various parts of Lazarus and also helps new contributors to find a suitable place where they can help. It also shows the people implementing the various parts and the targets.<br />
<br />
__TOC__<br />
<br />
{{Template:Development Status}}<br />
<br />
==General status of widgetsets==<br />
<br />
{{Template:Widgetset Roadmap}}<br />
<br />
==Current status of the various parts of Lazarus==<br />
<br />
<br />
{| class="wikitable sortable"<br />
! Unit !! Item !! State !! Target !! Skills !! Responsible !! Comments<br />
|---- class="working"<br />
|IDE||TCollection Editor||working||0.9.x||FCL, RTTI, IDE||-||A generic TCollection editor for the various TCollections in the LCL/FCL.<br />
|---- class="working"<br />
|IDE||TActionList||working||0.9.x||-||-||-<br />
|---- class="working"<br />
|IDE||Doc Editor||working||-||fpdoc||-||The doc editor will be an integrated fpDoc editor similar to fpde. It will be a process of its own, so that it can show help for dialogs as well. It should also be able to write help for packages.<br />
|---- class="working"<br />
|IDE||Export LFM as xml||working||-||-||-||Load and save LFM files to XML.<br />
|---- class="partial"<br />
|IDE||[[Icon Editor Roadmap]]||in progress||post 1.0||-||-||A simple icon editor with the ability to create lrs files. It will be a good example and can help newbies to create icons for their components.<br />
|---- class="working"<br />
|LCL||Borderspacing||working||0.9.x||-||-||for aligned controls<br />
|---- class="working"<br />
|LCL||Drag&Drop||working||||-||-||<br />
|---- class="working"<br />
|LCL||Port to Darwin Power PC, Mac OS X||working||0.9.x||-||-||depends on FPC 1.9.5<br />
|---- class="working"<br />
|LCL||Port to Mac OS X x86||working||-||-||-||depends on FPC 2.1.1<br />
|---- class="working"<br />
|LCL||TSplitter||working||0.9.x||easy||-||-<br />
|---- class="working"<br />
|LCL||TFindDialog||working||-||-||-||Implemented in 0.9.16<br />
|---- class="working"<br />
|LCL||TReplaceDialog||working||-||-||-||Implemented in 0.9.16<br />
|---- class="working"<br />
|LCL||TControl.Font||in progress||0.9.x||-||-||-<br />
|---- class="working"<br />
|LCL||TTabControl||in progress||0.9.x||-||-||-<br />
|---- class="partial"<br />
|LCL||Docking (= the combination of forms)||partially working, in progress||post 1.0||deep LCL and interfaces||Mattias||-<br />
|---- class="working"<br />
|LCL||Frames (= forms as children)||working||0.9.28||deep knowledge of LCL||Mattias, Paul||-<br />
|---- class="working"<br />
|IDE||Visual Form Inheritence||working||post 1.0||IDE||Mattias||Properties are not yet propagated to open descendants<br />
|---- class="partial"<br />
|LCL||MDI - Multiple Documents Interfaces Putting fo ...||in progress||1.2||deep LCL and interfaces||[[User:Zeljan|Zeljan]]||An MDI LCL emulator for widgetsets which does not support MDI, also native implementation of MDI for qt and win32/64. Currently only qt has full MDI support, others are in progress.<br />
|---- class="not"<br />
|LCL||Palette support||not implemented||-||-||-||Required to correctly show colors on a 256 colors display<br />
|---- class="partial"<br />
|LCL||TCoolBar||partially working, in progress||post 1.0||LCL and anchoring||[[User:JuhaManninen|Juha]]||-<br />
|---- class="partial"<br />
|LCL||TControlBar||skeleton implementation to prevent errors in Delphi conversion, in progress||post 1.0||LCL and anchoring||[[User:JuhaManninen|Juha]]||-<br />
|---- class="working"<br />
|LCL||TMaskEdit||working||-||-||[[User:Bart|Bart]]||-<br />
|---- class="not"<br />
|LCL||TDirectoryTreeView||not implemented||-||-||-||-<br />
|---- class="not"<br />
|LCL||Constrain maximization to specific area||not implemented||-||winapi, gtk||-||When maximizing a window, the left, top, width and height can all be constrained to a specific rectangular area on the screen/desktop. After this is done, constrain the source editor and maybe other windows<br />
|---- class="working"<br />
|Components||TIcon||working||0.9.26||-||Marc||-<br />
|---- class="working"<br />
|Components||CUPS Package||working||0.9.x||easy||-||<br />
|---- class="working"<br />
|}<br />
<br />
==Status of features on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|Accelerator Keys<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Caret<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Clipboard<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Implemented in Android<br />
|----<br />
|Cursors<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Drag & Drop<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|[[Drop files event]]<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|MDI Support<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Printing<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Regions<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TCustomControl descendents<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|Unicode Support<br />
|class="working"|Working||class="not"|Impossible to Implement||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|[[BidiMode]]<br />
|class="working"|Working||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Application||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="working"|Working<br />
|----<br />
|TTimer||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TApplication.QueueAsyncCall||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|TThread.Synchronize||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class="unknown"|Unknown<br />
|class="working"|Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|PostMessage||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class=""unknown"|Unknown<br />
|class="not"|Not Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|PostThreadMessage||class="working"|Working||class="unknown"|Unknown||class="unknown"|Unknown<br />
|class="unknown"|Unknown||class="unknown"|Unknown||class="unknown"|Unknown<br />
|class="unknown"|Unknown||class="unknown"|Unknown||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of Graphics on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBitmap/TPixmap/TIcon/etc||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TBrush||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TFont||class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TPen||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|ExtTextOut||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="unknown"|Unknown||class="working"|Working<br />
|}<br />
<br />
==Status of native controls on each widgetset==<br />
Native controls are TWinControl descendants which do not descend from TCustomControl.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBitBtn||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TCalendar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TCheckBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TCheckGroup||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TCheckListBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TComboBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TEdit||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TForm||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TGroupBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TIdleTimer||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TImageList||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working|| class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TListBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TListView||class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TMainMenu||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TMemo||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TMenuItem||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TPageControl and TTabSheet||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TPairSplitter||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TPanel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TPopupMenu||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TProgressBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TRadioButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TRadioGroup||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TScrollBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TScrollBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TSpinEdit||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TSplitter||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TStaticText||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TStatusBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TToggleBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TTrackbar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TTrayIcon||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of dialogs on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|LCLIntf.MessageBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="working"|Working<br />
|class="working"|Working||class="unknown"|Unknown||class="partial"|Implemented for Android<br />
|----<br />
|Application.MessageBox, MessageDlg, LCLIntf.PromptUser||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="unknown"|Unknown||class="partial"|Implemented for Android<br />
|----<br />
|LCLIntf.AskUser||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|TColorDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TFontDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TOpenDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TPrinterSetupDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TSaveDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of TCustomControl based controls on each widgetset==<br />
Note that being a TCustomControl descendant does not guarantee that a control has no widgetset implementation. TArrow has it, although it has a good default implementation. TNotebook is fully implemented in the LCL.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TArrow ||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TNoteBook||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TUpDown||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TStringGrid||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TDrawGrid||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TToolBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TTreeView||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TValueListEditor||class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of TGraphicControl based controls on each widgetset==<br />
'''Note:''' These are for LCL wrapped components only, '''not''' for the specific GUI toolkit features itself.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBevel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TLabel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="partial"|Implemented for Android<br />
|----<br />
|TShape||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TSpeedButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TPaintBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TImage||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|}<br />
<br />
==Status of LazDeviceAPIs on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! customdrawn-android<br />
|----<br />
|Accelerometer||class="working"|Working<br />
|----<br />
|Messaging (SMS, MMS and E-Mail)||class="partial"|SMS Implemented<br />
|----<br />
|PositionInfo||class="working"|Working<br />
|}<br />
<br />
==See Also==<br />
<br />
*[[LCL Internals]]<br />
*[[TAChart Roadmap]]<br />
<br />
[[Category:Lazarus]]<br />
[[Category:Roadmaps]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=Roadmap&diff=86438Roadmap2015-02-14T20:15:25Z<p>Sekelsenmat: /* Status of dialogs on each widgetset */</p>
<hr />
<div>{{Roadmap}}<br />
<br />
This document gives an idea of the current status of the various parts of Lazarus and also helps new contributors to find a suitable place where they can help. It also shows the people implementing the various parts and the targets.<br />
<br />
__TOC__<br />
<br />
{{Template:Development Status}}<br />
<br />
==General status of widgetsets==<br />
<br />
{{Template:Widgetset Roadmap}}<br />
<br />
==Current status of the various parts of Lazarus==<br />
<br />
<br />
{| class="wikitable sortable"<br />
! Unit !! Item !! State !! Target !! Skills !! Responsible !! Comments<br />
|---- class="working"<br />
|IDE||TCollection Editor||working||0.9.x||FCL, RTTI, IDE||-||A generic TCollection editor for the various TCollections in the LCL/FCL.<br />
|---- class="working"<br />
|IDE||TActionList||working||0.9.x||-||-||-<br />
|---- class="working"<br />
|IDE||Doc Editor||working||-||fpdoc||-||The doc editor will be an integrated fpDoc editor similar to fpde. It will be a process of its own, so that it can show help for dialogs as well. It should also be able to write help for packages.<br />
|---- class="working"<br />
|IDE||Export LFM as xml||working||-||-||-||Load and save LFM files to XML.<br />
|---- class="partial"<br />
|IDE||[[Icon Editor Roadmap]]||in progress||post 1.0||-||-||A simple icon editor with the ability to create lrs files. It will be a good example and can help newbies to create icons for their components.<br />
|---- class="working"<br />
|LCL||Borderspacing||working||0.9.x||-||-||for aligned controls<br />
|---- class="working"<br />
|LCL||Drag&Drop||working||||-||-||<br />
|---- class="working"<br />
|LCL||Port to Darwin Power PC, Mac OS X||working||0.9.x||-||-||depends on FPC 1.9.5<br />
|---- class="working"<br />
|LCL||Port to Mac OS X x86||working||-||-||-||depends on FPC 2.1.1<br />
|---- class="working"<br />
|LCL||TSplitter||working||0.9.x||easy||-||-<br />
|---- class="working"<br />
|LCL||TFindDialog||working||-||-||-||Implemented in 0.9.16<br />
|---- class="working"<br />
|LCL||TReplaceDialog||working||-||-||-||Implemented in 0.9.16<br />
|---- class="working"<br />
|LCL||TControl.Font||in progress||0.9.x||-||-||-<br />
|---- class="working"<br />
|LCL||TTabControl||in progress||0.9.x||-||-||-<br />
|---- class="partial"<br />
|LCL||Docking (= the combination of forms)||partially working, in progress||post 1.0||deep LCL and interfaces||Mattias||-<br />
|---- class="working"<br />
|LCL||Frames (= forms as children)||working||0.9.28||deep knowledge of LCL||Mattias, Paul||-<br />
|---- class="working"<br />
|IDE||Visual Form Inheritence||working||post 1.0||IDE||Mattias||Properties are not yet propagated to open descendants<br />
|---- class="partial"<br />
|LCL||MDI - Multiple Documents Interfaces Putting fo ...||in progress||1.2||deep LCL and interfaces||[[User:Zeljan|Zeljan]]||An MDI LCL emulator for widgetsets which does not support MDI, also native implementation of MDI for qt and win32/64. Currently only qt has full MDI support, others are in progress.<br />
|---- class="not"<br />
|LCL||Palette support||not implemented||-||-||-||Required to correctly show colors on a 256 colors display<br />
|---- class="partial"<br />
|LCL||TCoolBar||partially working, in progress||post 1.0||LCL and anchoring||[[User:JuhaManninen|Juha]]||-<br />
|---- class="partial"<br />
|LCL||TControlBar||skeleton implementation to prevent errors in Delphi conversion, in progress||post 1.0||LCL and anchoring||[[User:JuhaManninen|Juha]]||-<br />
|---- class="working"<br />
|LCL||TMaskEdit||working||-||-||[[User:Bart|Bart]]||-<br />
|---- class="not"<br />
|LCL||TDirectoryTreeView||not implemented||-||-||-||-<br />
|---- class="not"<br />
|LCL||Constrain maximization to specific area||not implemented||-||winapi, gtk||-||When maximizing a window, the left, top, width and height can all be constrained to a specific rectangular area on the screen/desktop. After this is done, constrain the source editor and maybe other windows<br />
|---- class="working"<br />
|Components||TIcon||working||0.9.26||-||Marc||-<br />
|---- class="working"<br />
|Components||CUPS Package||working||0.9.x||easy||-||<br />
|---- class="working"<br />
|}<br />
<br />
==Status of features on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|Accelerator Keys<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Caret<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Clipboard<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Implemented in Android<br />
|----<br />
|Cursors<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Drag & Drop<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|[[Drop files event]]<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|MDI Support<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Printing<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Regions<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TCustomControl descendents<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|Unicode Support<br />
|class="working"|Working||class="not"|Impossible to Implement||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|[[BidiMode]]<br />
|class="working"|Working||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Application||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="working"|Working<br />
|----<br />
|TTimer||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TApplication.QueueAsyncCall||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|TThread.Synchronize||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class="unknown"|Unknown<br />
|class="working"|Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|PostMessage||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class=""unknown"|Unknown<br />
|class="not"|Not Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|PostThreadMessage||class="working"|Working||class="unknown"|Unknown||class="unknown"|Unknown<br />
|class="unknown"|Unknown||class="unknown"|Unknown||class="unknown"|Unknown<br />
|class="unknown"|Unknown||class="unknown"|Unknown||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of Graphics on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBitmap/TPixmap/TIcon/etc||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TBrush||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TFont||class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TPen||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|ExtTextOut||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="unknown"|Unknown||class="working"|Working<br />
|}<br />
<br />
==Status of native controls on each widgetset==<br />
Native controls are TWinControl descendants which do not descend from TCustomControl.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBitBtn||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TCalendar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TCheckBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TCheckGroup||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TCheckListBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TComboBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TEdit||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TForm||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TGroupBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TIdleTimer||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TImageList||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working|| class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TListBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TListView||class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TMainMenu||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TMemo||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TMenuItem||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TPageControl and TTabSheet||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TPairSplitter||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TPanel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TPopupMenu||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TProgressBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TRadioButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TRadioGroup||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TScrollBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TScrollBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TSpinEdit||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TSplitter||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TStaticText||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TStatusBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TToggleBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TTrackbar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TTrayIcon||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of dialogs on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|LCLIntf.MessageBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="working"|Working<br />
|class="working"|Working||class="unknown"|Unknown||class="partial"|Implemented for Android<br />
|----<br />
|Application.MessageBox, MessageDlg, LCLIntf.PromptUser||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="unknown"|Unknown||class="partial"|Implemented for Android<br />
|----<br />
|LCLIntf.AskUser||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|TColorDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TFontDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TOpenDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TPrinterSetupDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TSaveDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="not"|Not Implemented||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of TCustomControl based controls on each widgetset==<br />
Note that being a TCustomControl descendant does not guarantee that a control has no widgetset implementation. TArrow has it, although it has a good default implementation. TNotebook is fully implemented in the LCL.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TArrow ||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TNoteBook||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TUpDown||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TStringGrid||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TDrawGrid||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TToolBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TTreeView||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TValueListEditor||class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of TGraphicControl based controls on each widgetset==<br />
'''Note:''' These are for LCL wrapped components only, '''not''' for the specific GUI toolkit features itself.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBevel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TLabel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="partial"|Implemented for Android<br />
|----<br />
|TShape||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TSpeedButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TPaintBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TImage||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|}<br />
<br />
==Status of LazDeviceAPIs on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! customdrawn-android<br />
|----<br />
|Accelerometer||class="working"|Working<br />
|----<br />
|Messaging (SMS, MMS and E-Mail)||class="partial"|SMS Implemented<br />
|----<br />
|PositionInfo||class="working"|Working<br />
|}<br />
<br />
==See Also==<br />
<br />
*[[LCL Internals]]<br />
*[[TAChart Roadmap]]<br />
<br />
[[Category:Lazarus]]<br />
[[Category:Roadmaps]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=Roadmap&diff=86437Roadmap2015-02-14T20:14:33Z<p>Sekelsenmat: /* Status of features on each widgetset */</p>
<hr />
<div>{{Roadmap}}<br />
<br />
This document gives an idea of the current status of the various parts of Lazarus and also helps new contributors to find a suitable place where they can help. It also shows the people implementing the various parts and the targets.<br />
<br />
__TOC__<br />
<br />
{{Template:Development Status}}<br />
<br />
==General status of widgetsets==<br />
<br />
{{Template:Widgetset Roadmap}}<br />
<br />
==Current status of the various parts of Lazarus==<br />
<br />
<br />
{| class="wikitable sortable"<br />
! Unit !! Item !! State !! Target !! Skills !! Responsible !! Comments<br />
|---- class="working"<br />
|IDE||TCollection Editor||working||0.9.x||FCL, RTTI, IDE||-||A generic TCollection editor for the various TCollections in the LCL/FCL.<br />
|---- class="working"<br />
|IDE||TActionList||working||0.9.x||-||-||-<br />
|---- class="working"<br />
|IDE||Doc Editor||working||-||fpdoc||-||The doc editor will be an integrated fpDoc editor similar to fpde. It will be a process of its own, so that it can show help for dialogs as well. It should also be able to write help for packages.<br />
|---- class="working"<br />
|IDE||Export LFM as xml||working||-||-||-||Load and save LFM files to XML.<br />
|---- class="partial"<br />
|IDE||[[Icon Editor Roadmap]]||in progress||post 1.0||-||-||A simple icon editor with the ability to create lrs files. It will be a good example and can help newbies to create icons for their components.<br />
|---- class="working"<br />
|LCL||Borderspacing||working||0.9.x||-||-||for aligned controls<br />
|---- class="working"<br />
|LCL||Drag&Drop||working||||-||-||<br />
|---- class="working"<br />
|LCL||Port to Darwin Power PC, Mac OS X||working||0.9.x||-||-||depends on FPC 1.9.5<br />
|---- class="working"<br />
|LCL||Port to Mac OS X x86||working||-||-||-||depends on FPC 2.1.1<br />
|---- class="working"<br />
|LCL||TSplitter||working||0.9.x||easy||-||-<br />
|---- class="working"<br />
|LCL||TFindDialog||working||-||-||-||Implemented in 0.9.16<br />
|---- class="working"<br />
|LCL||TReplaceDialog||working||-||-||-||Implemented in 0.9.16<br />
|---- class="working"<br />
|LCL||TControl.Font||in progress||0.9.x||-||-||-<br />
|---- class="working"<br />
|LCL||TTabControl||in progress||0.9.x||-||-||-<br />
|---- class="partial"<br />
|LCL||Docking (= the combination of forms)||partially working, in progress||post 1.0||deep LCL and interfaces||Mattias||-<br />
|---- class="working"<br />
|LCL||Frames (= forms as children)||working||0.9.28||deep knowledge of LCL||Mattias, Paul||-<br />
|---- class="working"<br />
|IDE||Visual Form Inheritence||working||post 1.0||IDE||Mattias||Properties are not yet propagated to open descendants<br />
|---- class="partial"<br />
|LCL||MDI - Multiple Documents Interfaces Putting fo ...||in progress||1.2||deep LCL and interfaces||[[User:Zeljan|Zeljan]]||An MDI LCL emulator for widgetsets which does not support MDI, also native implementation of MDI for qt and win32/64. Currently only qt has full MDI support, others are in progress.<br />
|---- class="not"<br />
|LCL||Palette support||not implemented||-||-||-||Required to correctly show colors on a 256 colors display<br />
|---- class="partial"<br />
|LCL||TCoolBar||partially working, in progress||post 1.0||LCL and anchoring||[[User:JuhaManninen|Juha]]||-<br />
|---- class="partial"<br />
|LCL||TControlBar||skeleton implementation to prevent errors in Delphi conversion, in progress||post 1.0||LCL and anchoring||[[User:JuhaManninen|Juha]]||-<br />
|---- class="working"<br />
|LCL||TMaskEdit||working||-||-||[[User:Bart|Bart]]||-<br />
|---- class="not"<br />
|LCL||TDirectoryTreeView||not implemented||-||-||-||-<br />
|---- class="not"<br />
|LCL||Constrain maximization to specific area||not implemented||-||winapi, gtk||-||When maximizing a window, the left, top, width and height can all be constrained to a specific rectangular area on the screen/desktop. After this is done, constrain the source editor and maybe other windows<br />
|---- class="working"<br />
|Components||TIcon||working||0.9.26||-||Marc||-<br />
|---- class="working"<br />
|Components||CUPS Package||working||0.9.x||easy||-||<br />
|---- class="working"<br />
|}<br />
<br />
==Status of features on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|Accelerator Keys<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Caret<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Clipboard<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Implemented in Android<br />
|----<br />
|Cursors<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Drag & Drop<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|[[Drop files event]]<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|MDI Support<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Printing<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Regions<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TCustomControl descendents<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|Unicode Support<br />
|class="working"|Working||class="not"|Impossible to Implement||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|[[BidiMode]]<br />
|class="working"|Working||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Application||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="working"|Working<br />
|----<br />
|TTimer||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TApplication.QueueAsyncCall||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|TThread.Synchronize||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class="unknown"|Unknown<br />
|class="working"|Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|PostMessage||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class=""unknown"|Unknown<br />
|class="not"|Not Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|PostThreadMessage||class="working"|Working||class="unknown"|Unknown||class="unknown"|Unknown<br />
|class="unknown"|Unknown||class="unknown"|Unknown||class="unknown"|Unknown<br />
|class="unknown"|Unknown||class="unknown"|Unknown||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of Graphics on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBitmap/TPixmap/TIcon/etc||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TBrush||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TFont||class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TPen||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|ExtTextOut||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="unknown"|Unknown||class="working"|Working<br />
|}<br />
<br />
==Status of native controls on each widgetset==<br />
Native controls are TWinControl descendants which do not descend from TCustomControl.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBitBtn||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TCalendar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TCheckBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TCheckGroup||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TCheckListBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TComboBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TEdit||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TForm||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TGroupBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TIdleTimer||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TImageList||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working|| class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TListBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TListView||class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TMainMenu||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TMemo||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TMenuItem||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TPageControl and TTabSheet||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TPairSplitter||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TPanel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TPopupMenu||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TProgressBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TRadioButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TRadioGroup||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TScrollBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TScrollBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TSpinEdit||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TSplitter||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TStaticText||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TStatusBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TToggleBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TTrackbar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TTrayIcon||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of dialogs on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|LCLIntf.MessageBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="working"|Working<br />
|class="working"|Working||class="unknown"|Unknown||class="partial"|Implemented for Android<br />
|----<br />
|Application.MessageBox, MessageDlg, LCLIntf.PromptUser||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="unknown"|Unknown||class="partial"|Implemented for Android<br />
|----<br />
|LCLIntf.AskUser||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|TColorDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TFontDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TOpenDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TPrinterSetupDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TSaveDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="not"|Not Implemented||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of TCustomControl based controls on each widgetset==<br />
Note that being a TCustomControl descendant does not guarantee that a control has no widgetset implementation. TArrow has it, although it has a good default implementation. TNotebook is fully implemented in the LCL.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TArrow ||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TNoteBook||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TUpDown||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TStringGrid||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TDrawGrid||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TToolBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TTreeView||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TValueListEditor||class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of TGraphicControl based controls on each widgetset==<br />
'''Note:''' These are for LCL wrapped components only, '''not''' for the specific GUI toolkit features itself.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBevel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TLabel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="partial"|Implemented for Android<br />
|----<br />
|TShape||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TSpeedButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TPaintBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TImage||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|}<br />
<br />
==Status of LazDeviceAPIs on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! customdrawn-android<br />
|----<br />
|Accelerometer||class="working"|Working<br />
|----<br />
|Messaging (SMS, MMS and E-Mail)||class="partial"|SMS Implemented<br />
|----<br />
|PositionInfo||class="working"|Working<br />
|}<br />
<br />
==See Also==<br />
<br />
*[[LCL Internals]]<br />
*[[TAChart Roadmap]]<br />
<br />
[[Category:Lazarus]]<br />
[[Category:Roadmaps]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=Roadmap&diff=86436Roadmap2015-02-14T20:13:02Z<p>Sekelsenmat: /* Status of native controls on each widgetset */</p>
<hr />
<div>{{Roadmap}}<br />
<br />
This document gives an idea of the current status of the various parts of Lazarus and also helps new contributors to find a suitable place where they can help. It also shows the people implementing the various parts and the targets.<br />
<br />
__TOC__<br />
<br />
{{Template:Development Status}}<br />
<br />
==General status of widgetsets==<br />
<br />
{{Template:Widgetset Roadmap}}<br />
<br />
==Current status of the various parts of Lazarus==<br />
<br />
<br />
{| class="wikitable sortable"<br />
! Unit !! Item !! State !! Target !! Skills !! Responsible !! Comments<br />
|---- class="working"<br />
|IDE||TCollection Editor||working||0.9.x||FCL, RTTI, IDE||-||A generic TCollection editor for the various TCollections in the LCL/FCL.<br />
|---- class="working"<br />
|IDE||TActionList||working||0.9.x||-||-||-<br />
|---- class="working"<br />
|IDE||Doc Editor||working||-||fpdoc||-||The doc editor will be an integrated fpDoc editor similar to fpde. It will be a process of its own, so that it can show help for dialogs as well. It should also be able to write help for packages.<br />
|---- class="working"<br />
|IDE||Export LFM as xml||working||-||-||-||Load and save LFM files to XML.<br />
|---- class="partial"<br />
|IDE||[[Icon Editor Roadmap]]||in progress||post 1.0||-||-||A simple icon editor with the ability to create lrs files. It will be a good example and can help newbies to create icons for their components.<br />
|---- class="working"<br />
|LCL||Borderspacing||working||0.9.x||-||-||for aligned controls<br />
|---- class="working"<br />
|LCL||Drag&Drop||working||||-||-||<br />
|---- class="working"<br />
|LCL||Port to Darwin Power PC, Mac OS X||working||0.9.x||-||-||depends on FPC 1.9.5<br />
|---- class="working"<br />
|LCL||Port to Mac OS X x86||working||-||-||-||depends on FPC 2.1.1<br />
|---- class="working"<br />
|LCL||TSplitter||working||0.9.x||easy||-||-<br />
|---- class="working"<br />
|LCL||TFindDialog||working||-||-||-||Implemented in 0.9.16<br />
|---- class="working"<br />
|LCL||TReplaceDialog||working||-||-||-||Implemented in 0.9.16<br />
|---- class="working"<br />
|LCL||TControl.Font||in progress||0.9.x||-||-||-<br />
|---- class="working"<br />
|LCL||TTabControl||in progress||0.9.x||-||-||-<br />
|---- class="partial"<br />
|LCL||Docking (= the combination of forms)||partially working, in progress||post 1.0||deep LCL and interfaces||Mattias||-<br />
|---- class="working"<br />
|LCL||Frames (= forms as children)||working||0.9.28||deep knowledge of LCL||Mattias, Paul||-<br />
|---- class="working"<br />
|IDE||Visual Form Inheritence||working||post 1.0||IDE||Mattias||Properties are not yet propagated to open descendants<br />
|---- class="partial"<br />
|LCL||MDI - Multiple Documents Interfaces Putting fo ...||in progress||1.2||deep LCL and interfaces||[[User:Zeljan|Zeljan]]||An MDI LCL emulator for widgetsets which does not support MDI, also native implementation of MDI for qt and win32/64. Currently only qt has full MDI support, others are in progress.<br />
|---- class="not"<br />
|LCL||Palette support||not implemented||-||-||-||Required to correctly show colors on a 256 colors display<br />
|---- class="partial"<br />
|LCL||TCoolBar||partially working, in progress||post 1.0||LCL and anchoring||[[User:JuhaManninen|Juha]]||-<br />
|---- class="partial"<br />
|LCL||TControlBar||skeleton implementation to prevent errors in Delphi conversion, in progress||post 1.0||LCL and anchoring||[[User:JuhaManninen|Juha]]||-<br />
|---- class="working"<br />
|LCL||TMaskEdit||working||-||-||[[User:Bart|Bart]]||-<br />
|---- class="not"<br />
|LCL||TDirectoryTreeView||not implemented||-||-||-||-<br />
|---- class="not"<br />
|LCL||Constrain maximization to specific area||not implemented||-||winapi, gtk||-||When maximizing a window, the left, top, width and height can all be constrained to a specific rectangular area on the screen/desktop. After this is done, constrain the source editor and maybe other windows<br />
|---- class="working"<br />
|Components||TIcon||working||0.9.26||-||Marc||-<br />
|---- class="working"<br />
|Components||CUPS Package||working||0.9.x||easy||-||<br />
|---- class="working"<br />
|}<br />
<br />
==Status of features on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|Accelerator Keys<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Caret<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Clipboard<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Implemented in Android<br />
|----<br />
|Cursors<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Drag & Drop<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|[[Drop files event]]<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|MDI Support<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Printing<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Regions<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TCustomControl descendents<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|Unicode Support<br />
|class="working"|Working||class="not"|Impossible to Implement||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|[[BidiMode]]<br />
|class="working"|Working||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Application||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="working"|Working<br />
|----<br />
|TTimer||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TApplication.QueueAsyncCall||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|TThread.Synchronize||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class="unknown"|Unknown<br />
|class="working"|Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|PostMessage||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class=""unknown"|Unknown<br />
|class="not"|Not Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|PostThreadMessage||class="working"|Working||class="unknown"|Unknown||class="unknown"|Unknown<br />
|class="unknown"|Unknown||class="unknown"|Unknown||class="unknown"|Unknown<br />
|class="unknown"|Unknown||class="unknown"|Unknown||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of Graphics on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBitmap/TPixmap/TIcon/etc||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TBrush||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TFont||class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TPen||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|ExtTextOut||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="unknown"|Unknown||class="working"|Working<br />
|}<br />
<br />
==Status of native controls on each widgetset==<br />
Native controls are TWinControl descendants which do not descend from TCustomControl.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBitBtn||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TCalendar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TCheckBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TCheckGroup||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TCheckListBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TComboBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TEdit||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TForm||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TGroupBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TIdleTimer||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TImageList||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working|| class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TListBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TListView||class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TMainMenu||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TMemo||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TMenuItem||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TPageControl and TTabSheet||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TPairSplitter||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TPanel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TPopupMenu||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TProgressBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TRadioButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TRadioGroup||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TScrollBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TScrollBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TSpinEdit||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TSplitter||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TStaticText||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TStatusBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TToggleBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TTrackbar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TTrayIcon||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of dialogs on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|LCLIntf.MessageBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="working"|Working<br />
|class="working"|Working||class="unknown"|Unknown||class="partial"|Implemented for Android<br />
|----<br />
|Application.MessageBox, MessageDlg, LCLIntf.PromptUser||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="unknown"|Unknown||class="partial"|Implemented for Android<br />
|----<br />
|LCLIntf.AskUser||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|TColorDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TFontDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TOpenDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TPrinterSetupDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TSaveDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="not"|Not Implemented||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of TCustomControl based controls on each widgetset==<br />
Note that being a TCustomControl descendant does not guarantee that a control has no widgetset implementation. TArrow has it, although it has a good default implementation. TNotebook is fully implemented in the LCL.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TArrow ||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TNoteBook||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TUpDown||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TStringGrid||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TDrawGrid||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TToolBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TTreeView||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TValueListEditor||class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of TGraphicControl based controls on each widgetset==<br />
'''Note:''' These are for LCL wrapped components only, '''not''' for the specific GUI toolkit features itself.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBevel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TLabel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="partial"|Implemented for Android<br />
|----<br />
|TShape||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TSpeedButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TPaintBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TImage||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|}<br />
<br />
==Status of LazDeviceAPIs on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! customdrawn-android<br />
|----<br />
|Accelerometer||class="working"|Working<br />
|----<br />
|Messaging (SMS, MMS and E-Mail)||class="partial"|SMS Implemented<br />
|----<br />
|PositionInfo||class="working"|Working<br />
|}<br />
<br />
==See Also==<br />
<br />
*[[LCL Internals]]<br />
*[[TAChart Roadmap]]<br />
<br />
[[Category:Lazarus]]<br />
[[Category:Roadmaps]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=Roadmap&diff=86435Roadmap2015-02-14T20:05:29Z<p>Sekelsenmat: /* Status of native controls on each widgetset */</p>
<hr />
<div>{{Roadmap}}<br />
<br />
This document gives an idea of the current status of the various parts of Lazarus and also helps new contributors to find a suitable place where they can help. It also shows the people implementing the various parts and the targets.<br />
<br />
__TOC__<br />
<br />
{{Template:Development Status}}<br />
<br />
==General status of widgetsets==<br />
<br />
{{Template:Widgetset Roadmap}}<br />
<br />
==Current status of the various parts of Lazarus==<br />
<br />
<br />
{| class="wikitable sortable"<br />
! Unit !! Item !! State !! Target !! Skills !! Responsible !! Comments<br />
|---- class="working"<br />
|IDE||TCollection Editor||working||0.9.x||FCL, RTTI, IDE||-||A generic TCollection editor for the various TCollections in the LCL/FCL.<br />
|---- class="working"<br />
|IDE||TActionList||working||0.9.x||-||-||-<br />
|---- class="working"<br />
|IDE||Doc Editor||working||-||fpdoc||-||The doc editor will be an integrated fpDoc editor similar to fpde. It will be a process of its own, so that it can show help for dialogs as well. It should also be able to write help for packages.<br />
|---- class="working"<br />
|IDE||Export LFM as xml||working||-||-||-||Load and save LFM files to XML.<br />
|---- class="partial"<br />
|IDE||[[Icon Editor Roadmap]]||in progress||post 1.0||-||-||A simple icon editor with the ability to create lrs files. It will be a good example and can help newbies to create icons for their components.<br />
|---- class="working"<br />
|LCL||Borderspacing||working||0.9.x||-||-||for aligned controls<br />
|---- class="working"<br />
|LCL||Drag&Drop||working||||-||-||<br />
|---- class="working"<br />
|LCL||Port to Darwin Power PC, Mac OS X||working||0.9.x||-||-||depends on FPC 1.9.5<br />
|---- class="working"<br />
|LCL||Port to Mac OS X x86||working||-||-||-||depends on FPC 2.1.1<br />
|---- class="working"<br />
|LCL||TSplitter||working||0.9.x||easy||-||-<br />
|---- class="working"<br />
|LCL||TFindDialog||working||-||-||-||Implemented in 0.9.16<br />
|---- class="working"<br />
|LCL||TReplaceDialog||working||-||-||-||Implemented in 0.9.16<br />
|---- class="working"<br />
|LCL||TControl.Font||in progress||0.9.x||-||-||-<br />
|---- class="working"<br />
|LCL||TTabControl||in progress||0.9.x||-||-||-<br />
|---- class="partial"<br />
|LCL||Docking (= the combination of forms)||partially working, in progress||post 1.0||deep LCL and interfaces||Mattias||-<br />
|---- class="working"<br />
|LCL||Frames (= forms as children)||working||0.9.28||deep knowledge of LCL||Mattias, Paul||-<br />
|---- class="working"<br />
|IDE||Visual Form Inheritence||working||post 1.0||IDE||Mattias||Properties are not yet propagated to open descendants<br />
|---- class="partial"<br />
|LCL||MDI - Multiple Documents Interfaces Putting fo ...||in progress||1.2||deep LCL and interfaces||[[User:Zeljan|Zeljan]]||An MDI LCL emulator for widgetsets which does not support MDI, also native implementation of MDI for qt and win32/64. Currently only qt has full MDI support, others are in progress.<br />
|---- class="not"<br />
|LCL||Palette support||not implemented||-||-||-||Required to correctly show colors on a 256 colors display<br />
|---- class="partial"<br />
|LCL||TCoolBar||partially working, in progress||post 1.0||LCL and anchoring||[[User:JuhaManninen|Juha]]||-<br />
|---- class="partial"<br />
|LCL||TControlBar||skeleton implementation to prevent errors in Delphi conversion, in progress||post 1.0||LCL and anchoring||[[User:JuhaManninen|Juha]]||-<br />
|---- class="working"<br />
|LCL||TMaskEdit||working||-||-||[[User:Bart|Bart]]||-<br />
|---- class="not"<br />
|LCL||TDirectoryTreeView||not implemented||-||-||-||-<br />
|---- class="not"<br />
|LCL||Constrain maximization to specific area||not implemented||-||winapi, gtk||-||When maximizing a window, the left, top, width and height can all be constrained to a specific rectangular area on the screen/desktop. After this is done, constrain the source editor and maybe other windows<br />
|---- class="working"<br />
|Components||TIcon||working||0.9.26||-||Marc||-<br />
|---- class="working"<br />
|Components||CUPS Package||working||0.9.x||easy||-||<br />
|---- class="working"<br />
|}<br />
<br />
==Status of features on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|Accelerator Keys<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Caret<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Clipboard<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Implemented in Android<br />
|----<br />
|Cursors<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Drag & Drop<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|[[Drop files event]]<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|MDI Support<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Printing<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Regions<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TCustomControl descendents<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|Unicode Support<br />
|class="working"|Working||class="not"|Impossible to Implement||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|[[BidiMode]]<br />
|class="working"|Working||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Application||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="working"|Working<br />
|----<br />
|TTimer||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TApplication.QueueAsyncCall||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|TThread.Synchronize||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class="unknown"|Unknown<br />
|class="working"|Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|PostMessage||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class=""unknown"|Unknown<br />
|class="not"|Not Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|PostThreadMessage||class="working"|Working||class="unknown"|Unknown||class="unknown"|Unknown<br />
|class="unknown"|Unknown||class="unknown"|Unknown||class="unknown"|Unknown<br />
|class="unknown"|Unknown||class="unknown"|Unknown||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of Graphics on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBitmap/TPixmap/TIcon/etc||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TBrush||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TFont||class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TPen||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|ExtTextOut||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="unknown"|Unknown||class="working"|Working<br />
|}<br />
<br />
==Status of native controls on each widgetset==<br />
Native controls are TWinControl descendants which do not descend from TCustomControl.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBitBtn||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TCalendar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TCheckBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TCheckGroup||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TCheckListBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TComboBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TEdit||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TForm||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TGroupBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TIdleTimer||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TImageList||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working|| class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TListBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TListView||class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TMainMenu||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TMemo||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TMenuItem||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TPageControl and TTabSheet||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TPairSplitter||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TPanel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TPopupMenu||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TProgressBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TRadioButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TRadioGroup||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TScrollBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TScrollBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TSpinEdit||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TSplitter||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TStaticText||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TStatusBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TToggleBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TTrackbar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TTrayIcon||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of dialogs on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|LCLIntf.MessageBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="working"|Working<br />
|class="working"|Working||class="unknown"|Unknown||class="partial"|Implemented for Android<br />
|----<br />
|Application.MessageBox, MessageDlg, LCLIntf.PromptUser||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="unknown"|Unknown||class="partial"|Implemented for Android<br />
|----<br />
|LCLIntf.AskUser||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|TColorDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TFontDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TOpenDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TPrinterSetupDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TSaveDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="not"|Not Implemented||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of TCustomControl based controls on each widgetset==<br />
Note that being a TCustomControl descendant does not guarantee that a control has no widgetset implementation. TArrow has it, although it has a good default implementation. TNotebook is fully implemented in the LCL.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TArrow ||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TNoteBook||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TUpDown||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TStringGrid||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TDrawGrid||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TToolBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TTreeView||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TValueListEditor||class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of TGraphicControl based controls on each widgetset==<br />
'''Note:''' These are for LCL wrapped components only, '''not''' for the specific GUI toolkit features itself.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBevel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TLabel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="partial"|Implemented for Android<br />
|----<br />
|TShape||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TSpeedButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TPaintBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TImage||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|}<br />
<br />
==Status of LazDeviceAPIs on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! customdrawn-android<br />
|----<br />
|Accelerometer||class="working"|Working<br />
|----<br />
|Messaging (SMS, MMS and E-Mail)||class="partial"|SMS Implemented<br />
|----<br />
|PositionInfo||class="working"|Working<br />
|}<br />
<br />
==See Also==<br />
<br />
*[[LCL Internals]]<br />
*[[TAChart Roadmap]]<br />
<br />
[[Category:Lazarus]]<br />
[[Category:Roadmaps]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=Roadmap&diff=86434Roadmap2015-02-14T20:03:13Z<p>Sekelsenmat: /* Status of Graphics on each widgetset */</p>
<hr />
<div>{{Roadmap}}<br />
<br />
This document gives an idea of the current status of the various parts of Lazarus and also helps new contributors to find a suitable place where they can help. It also shows the people implementing the various parts and the targets.<br />
<br />
__TOC__<br />
<br />
{{Template:Development Status}}<br />
<br />
==General status of widgetsets==<br />
<br />
{{Template:Widgetset Roadmap}}<br />
<br />
==Current status of the various parts of Lazarus==<br />
<br />
<br />
{| class="wikitable sortable"<br />
! Unit !! Item !! State !! Target !! Skills !! Responsible !! Comments<br />
|---- class="working"<br />
|IDE||TCollection Editor||working||0.9.x||FCL, RTTI, IDE||-||A generic TCollection editor for the various TCollections in the LCL/FCL.<br />
|---- class="working"<br />
|IDE||TActionList||working||0.9.x||-||-||-<br />
|---- class="working"<br />
|IDE||Doc Editor||working||-||fpdoc||-||The doc editor will be an integrated fpDoc editor similar to fpde. It will be a process of its own, so that it can show help for dialogs as well. It should also be able to write help for packages.<br />
|---- class="working"<br />
|IDE||Export LFM as xml||working||-||-||-||Load and save LFM files to XML.<br />
|---- class="partial"<br />
|IDE||[[Icon Editor Roadmap]]||in progress||post 1.0||-||-||A simple icon editor with the ability to create lrs files. It will be a good example and can help newbies to create icons for their components.<br />
|---- class="working"<br />
|LCL||Borderspacing||working||0.9.x||-||-||for aligned controls<br />
|---- class="working"<br />
|LCL||Drag&Drop||working||||-||-||<br />
|---- class="working"<br />
|LCL||Port to Darwin Power PC, Mac OS X||working||0.9.x||-||-||depends on FPC 1.9.5<br />
|---- class="working"<br />
|LCL||Port to Mac OS X x86||working||-||-||-||depends on FPC 2.1.1<br />
|---- class="working"<br />
|LCL||TSplitter||working||0.9.x||easy||-||-<br />
|---- class="working"<br />
|LCL||TFindDialog||working||-||-||-||Implemented in 0.9.16<br />
|---- class="working"<br />
|LCL||TReplaceDialog||working||-||-||-||Implemented in 0.9.16<br />
|---- class="working"<br />
|LCL||TControl.Font||in progress||0.9.x||-||-||-<br />
|---- class="working"<br />
|LCL||TTabControl||in progress||0.9.x||-||-||-<br />
|---- class="partial"<br />
|LCL||Docking (= the combination of forms)||partially working, in progress||post 1.0||deep LCL and interfaces||Mattias||-<br />
|---- class="working"<br />
|LCL||Frames (= forms as children)||working||0.9.28||deep knowledge of LCL||Mattias, Paul||-<br />
|---- class="working"<br />
|IDE||Visual Form Inheritence||working||post 1.0||IDE||Mattias||Properties are not yet propagated to open descendants<br />
|---- class="partial"<br />
|LCL||MDI - Multiple Documents Interfaces Putting fo ...||in progress||1.2||deep LCL and interfaces||[[User:Zeljan|Zeljan]]||An MDI LCL emulator for widgetsets which does not support MDI, also native implementation of MDI for qt and win32/64. Currently only qt has full MDI support, others are in progress.<br />
|---- class="not"<br />
|LCL||Palette support||not implemented||-||-||-||Required to correctly show colors on a 256 colors display<br />
|---- class="partial"<br />
|LCL||TCoolBar||partially working, in progress||post 1.0||LCL and anchoring||[[User:JuhaManninen|Juha]]||-<br />
|---- class="partial"<br />
|LCL||TControlBar||skeleton implementation to prevent errors in Delphi conversion, in progress||post 1.0||LCL and anchoring||[[User:JuhaManninen|Juha]]||-<br />
|---- class="working"<br />
|LCL||TMaskEdit||working||-||-||[[User:Bart|Bart]]||-<br />
|---- class="not"<br />
|LCL||TDirectoryTreeView||not implemented||-||-||-||-<br />
|---- class="not"<br />
|LCL||Constrain maximization to specific area||not implemented||-||winapi, gtk||-||When maximizing a window, the left, top, width and height can all be constrained to a specific rectangular area on the screen/desktop. After this is done, constrain the source editor and maybe other windows<br />
|---- class="working"<br />
|Components||TIcon||working||0.9.26||-||Marc||-<br />
|---- class="working"<br />
|Components||CUPS Package||working||0.9.x||easy||-||<br />
|---- class="working"<br />
|}<br />
<br />
==Status of features on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|Accelerator Keys<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Caret<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Clipboard<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Implemented in Android<br />
|----<br />
|Cursors<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Drag & Drop<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|[[Drop files event]]<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|MDI Support<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Printing<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Regions<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TCustomControl descendents<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|Unicode Support<br />
|class="working"|Working||class="not"|Impossible to Implement||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|[[BidiMode]]<br />
|class="working"|Working||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Application||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="working"|Working<br />
|----<br />
|TTimer||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TApplication.QueueAsyncCall||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|TThread.Synchronize||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class="unknown"|Unknown<br />
|class="working"|Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|PostMessage||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class=""unknown"|Unknown<br />
|class="not"|Not Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|PostThreadMessage||class="working"|Working||class="unknown"|Unknown||class="unknown"|Unknown<br />
|class="unknown"|Unknown||class="unknown"|Unknown||class="unknown"|Unknown<br />
|class="unknown"|Unknown||class="unknown"|Unknown||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of Graphics on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBitmap/TPixmap/TIcon/etc||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TBrush||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TFont||class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TPen||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|ExtTextOut||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="unknown"|Unknown||class="working"|Working<br />
|}<br />
<br />
==Status of native controls on each widgetset==<br />
Native controls are TWinControl descendants which do not descend from TCustomControl.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBitBtn||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TCalendar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TCheckBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TCheckGroup||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TCheckListBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TComboBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TEdit||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TForm||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TGroupBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TIdleTimer||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TImageList||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working|| class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TListBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TListView||class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TMainMenu||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TMemo||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TMenuItem||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TPageControl and TTabSheet||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TPairSplitter||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TPanel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TPopupMenu||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TProgressBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TRadioButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TRadioGroup||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TScrollBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TScrollBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TSpinEdit||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TSplitter||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TStaticText||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TStatusBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TToggleBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TTrackbar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TTrayIcon||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of dialogs on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|LCLIntf.MessageBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="working"|Working<br />
|class="working"|Working||class="unknown"|Unknown||class="partial"|Implemented for Android<br />
|----<br />
|Application.MessageBox, MessageDlg, LCLIntf.PromptUser||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="unknown"|Unknown||class="partial"|Implemented for Android<br />
|----<br />
|LCLIntf.AskUser||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|TColorDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TFontDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TOpenDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TPrinterSetupDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TSaveDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="not"|Not Implemented||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of TCustomControl based controls on each widgetset==<br />
Note that being a TCustomControl descendant does not guarantee that a control has no widgetset implementation. TArrow has it, although it has a good default implementation. TNotebook is fully implemented in the LCL.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TArrow ||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TNoteBook||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TUpDown||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TStringGrid||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TDrawGrid||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TToolBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TTreeView||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TValueListEditor||class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of TGraphicControl based controls on each widgetset==<br />
'''Note:''' These are for LCL wrapped components only, '''not''' for the specific GUI toolkit features itself.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBevel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TLabel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="partial"|Implemented for Android<br />
|----<br />
|TShape||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TSpeedButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TPaintBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TImage||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|}<br />
<br />
==Status of LazDeviceAPIs on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! customdrawn-android<br />
|----<br />
|Accelerometer||class="working"|Working<br />
|----<br />
|Messaging (SMS, MMS and E-Mail)||class="partial"|SMS Implemented<br />
|----<br />
|PositionInfo||class="working"|Working<br />
|}<br />
<br />
==See Also==<br />
<br />
*[[LCL Internals]]<br />
*[[TAChart Roadmap]]<br />
<br />
[[Category:Lazarus]]<br />
[[Category:Roadmaps]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=Roadmap&diff=86433Roadmap2015-02-14T20:02:08Z<p>Sekelsenmat: /* Status of features on each widgetset */</p>
<hr />
<div>{{Roadmap}}<br />
<br />
This document gives an idea of the current status of the various parts of Lazarus and also helps new contributors to find a suitable place where they can help. It also shows the people implementing the various parts and the targets.<br />
<br />
__TOC__<br />
<br />
{{Template:Development Status}}<br />
<br />
==General status of widgetsets==<br />
<br />
{{Template:Widgetset Roadmap}}<br />
<br />
==Current status of the various parts of Lazarus==<br />
<br />
<br />
{| class="wikitable sortable"<br />
! Unit !! Item !! State !! Target !! Skills !! Responsible !! Comments<br />
|---- class="working"<br />
|IDE||TCollection Editor||working||0.9.x||FCL, RTTI, IDE||-||A generic TCollection editor for the various TCollections in the LCL/FCL.<br />
|---- class="working"<br />
|IDE||TActionList||working||0.9.x||-||-||-<br />
|---- class="working"<br />
|IDE||Doc Editor||working||-||fpdoc||-||The doc editor will be an integrated fpDoc editor similar to fpde. It will be a process of its own, so that it can show help for dialogs as well. It should also be able to write help for packages.<br />
|---- class="working"<br />
|IDE||Export LFM as xml||working||-||-||-||Load and save LFM files to XML.<br />
|---- class="partial"<br />
|IDE||[[Icon Editor Roadmap]]||in progress||post 1.0||-||-||A simple icon editor with the ability to create lrs files. It will be a good example and can help newbies to create icons for their components.<br />
|---- class="working"<br />
|LCL||Borderspacing||working||0.9.x||-||-||for aligned controls<br />
|---- class="working"<br />
|LCL||Drag&Drop||working||||-||-||<br />
|---- class="working"<br />
|LCL||Port to Darwin Power PC, Mac OS X||working||0.9.x||-||-||depends on FPC 1.9.5<br />
|---- class="working"<br />
|LCL||Port to Mac OS X x86||working||-||-||-||depends on FPC 2.1.1<br />
|---- class="working"<br />
|LCL||TSplitter||working||0.9.x||easy||-||-<br />
|---- class="working"<br />
|LCL||TFindDialog||working||-||-||-||Implemented in 0.9.16<br />
|---- class="working"<br />
|LCL||TReplaceDialog||working||-||-||-||Implemented in 0.9.16<br />
|---- class="working"<br />
|LCL||TControl.Font||in progress||0.9.x||-||-||-<br />
|---- class="working"<br />
|LCL||TTabControl||in progress||0.9.x||-||-||-<br />
|---- class="partial"<br />
|LCL||Docking (= the combination of forms)||partially working, in progress||post 1.0||deep LCL and interfaces||Mattias||-<br />
|---- class="working"<br />
|LCL||Frames (= forms as children)||working||0.9.28||deep knowledge of LCL||Mattias, Paul||-<br />
|---- class="working"<br />
|IDE||Visual Form Inheritence||working||post 1.0||IDE||Mattias||Properties are not yet propagated to open descendants<br />
|---- class="partial"<br />
|LCL||MDI - Multiple Documents Interfaces Putting fo ...||in progress||1.2||deep LCL and interfaces||[[User:Zeljan|Zeljan]]||An MDI LCL emulator for widgetsets which does not support MDI, also native implementation of MDI for qt and win32/64. Currently only qt has full MDI support, others are in progress.<br />
|---- class="not"<br />
|LCL||Palette support||not implemented||-||-||-||Required to correctly show colors on a 256 colors display<br />
|---- class="partial"<br />
|LCL||TCoolBar||partially working, in progress||post 1.0||LCL and anchoring||[[User:JuhaManninen|Juha]]||-<br />
|---- class="partial"<br />
|LCL||TControlBar||skeleton implementation to prevent errors in Delphi conversion, in progress||post 1.0||LCL and anchoring||[[User:JuhaManninen|Juha]]||-<br />
|---- class="working"<br />
|LCL||TMaskEdit||working||-||-||[[User:Bart|Bart]]||-<br />
|---- class="not"<br />
|LCL||TDirectoryTreeView||not implemented||-||-||-||-<br />
|---- class="not"<br />
|LCL||Constrain maximization to specific area||not implemented||-||winapi, gtk||-||When maximizing a window, the left, top, width and height can all be constrained to a specific rectangular area on the screen/desktop. After this is done, constrain the source editor and maybe other windows<br />
|---- class="working"<br />
|Components||TIcon||working||0.9.26||-||Marc||-<br />
|---- class="working"<br />
|Components||CUPS Package||working||0.9.x||easy||-||<br />
|---- class="working"<br />
|}<br />
<br />
==Status of features on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|Accelerator Keys<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Caret<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Clipboard<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Implemented in Android<br />
|----<br />
|Cursors<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Drag & Drop<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|[[Drop files event]]<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|MDI Support<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Printing<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Regions<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TCustomControl descendents<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|Unicode Support<br />
|class="working"|Working||class="not"|Impossible to Implement||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|[[BidiMode]]<br />
|class="working"|Working||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Application||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="working"|Working<br />
|----<br />
|TTimer||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TApplication.QueueAsyncCall||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|TThread.Synchronize||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class="unknown"|Unknown<br />
|class="working"|Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|PostMessage||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class=""unknown"|Unknown<br />
|class="not"|Not Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|PostThreadMessage||class="working"|Working||class="unknown"|Unknown||class="unknown"|Unknown<br />
|class="unknown"|Unknown||class="unknown"|Unknown||class="unknown"|Unknown<br />
|class="unknown"|Unknown||class="unknown"|Unknown||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of Graphics on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBitmap/TPixmap/TIcon/etc||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TBrush||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TFont||class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TPen||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|ExtTextOut||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="unknown"|Unknown||class="working"|Working<br />
|}<br />
<br />
==Status of native controls on each widgetset==<br />
Native controls are TWinControl descendants which do not descend from TCustomControl.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBitBtn||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TCalendar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TCheckBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TCheckGroup||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TCheckListBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TComboBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TEdit||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TForm||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TGroupBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TIdleTimer||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TImageList||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working|| class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TListBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TListView||class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TMainMenu||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TMemo||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TMenuItem||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TPageControl and TTabSheet||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TPairSplitter||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TPanel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TPopupMenu||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TProgressBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TRadioButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TRadioGroup||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TScrollBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TScrollBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TSpinEdit||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TSplitter||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TStaticText||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TStatusBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TToggleBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TTrackbar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TTrayIcon||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of dialogs on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|LCLIntf.MessageBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="working"|Working<br />
|class="working"|Working||class="unknown"|Unknown||class="partial"|Implemented for Android<br />
|----<br />
|Application.MessageBox, MessageDlg, LCLIntf.PromptUser||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="unknown"|Unknown||class="partial"|Implemented for Android<br />
|----<br />
|LCLIntf.AskUser||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|TColorDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TFontDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TOpenDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TPrinterSetupDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TSaveDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="not"|Not Implemented||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of TCustomControl based controls on each widgetset==<br />
Note that being a TCustomControl descendant does not guarantee that a control has no widgetset implementation. TArrow has it, although it has a good default implementation. TNotebook is fully implemented in the LCL.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TArrow ||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TNoteBook||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TUpDown||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TStringGrid||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TDrawGrid||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TToolBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TTreeView||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TValueListEditor||class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of TGraphicControl based controls on each widgetset==<br />
'''Note:''' These are for LCL wrapped components only, '''not''' for the specific GUI toolkit features itself.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBevel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TLabel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="partial"|Implemented for Android<br />
|----<br />
|TShape||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TSpeedButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TPaintBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TImage||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|}<br />
<br />
==Status of LazDeviceAPIs on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! customdrawn-android<br />
|----<br />
|Accelerometer||class="working"|Working<br />
|----<br />
|Messaging (SMS, MMS and E-Mail)||class="partial"|SMS Implemented<br />
|----<br />
|PositionInfo||class="working"|Working<br />
|}<br />
<br />
==See Also==<br />
<br />
*[[LCL Internals]]<br />
*[[TAChart Roadmap]]<br />
<br />
[[Category:Lazarus]]<br />
[[Category:Roadmaps]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=LCL_Internals&diff=86377LCL Internals2015-02-13T13:01:17Z<p>Sekelsenmat: /* Minimum Toolkit versions */</p>
<hr />
<div>{{LCL Internals}}<br />
<br />
{{Other_Interfaces}}<br />
<br />
== Minimum Toolkit versions ==<br />
<br />
{| class="wikitable sortable"<br />
! Lazarus version !! Min. FPC !! Min. Gtk 2 !! Min. Qt 4 !! Min. Windows !! Min. Windows CE !! Min. Mac OS X (Carbon) !! Min. Mac OS X (Cocoa) !! Min. Req. of LCL-CustomDrawn<br />
|-<br />
|0.9.24<br />
|2.2.0<br />
|2.6+<br />
|4.2+<br />
|Windows 98+<br />
|Recommended 4.0+<br />
|10.4<br />
|N/A<br />
|N/A<br />
|-<br />
|0.9.26<br />
|2.2.2<br />
|2.6+<br />
|4.3+<br />
|Windows 98+<br />
|Recommended 4.0+<br />
|10.4<br />
|N/A<br />
|N/A<br />
|-<br />
|0.9.28<br />
|2.2.4<br />
|2.8+<br />
|4.5+<br />
|Windows 98+<br />
|Recommended 4.0+<br />
|10.4<br />
|N/A<br />
|N/A<br />
|-<br />
|0.9.30<br />
|2.4.0<br />
|2.8+<br />
|4.5+<br />
|Windows 98+<br />
|Recommended 5.0+<br />
|10.4<br />
|N/A<br />
|N/A<br />
|-<br />
|0.9.31<br />
|2.4.4<br />
|2.8+<br />
|4.5+<br />
|Windows 98+<br />
|Recommended 5.0+<br />
|10.4<br />
|10.6<br />
|Android 2.2+, Windows 2000+, X11, Mac OS X 10.6+<br />
|-<br />
|1.2.6<br />
|2.6.4<br />
|2.8+<br />
|4.5+*<br />
|Windows 98+<br />
|Recommended 5.0+<br />
|10.4<br />
|10.6<br />
|Android 2.2+, Windows 2000+, X11, Mac OS X 10.6+<br />
|}<br />
<br />
* - Actually 4.5.0 ...4.8.4 with pre-built Qt4Pas.dll, 4.8.5+ requires a different Qt4Pas.dll<br />
<br />
See Also: [[Installing_Lazarus_on_MacOS_X#Compatibility]]<br />
<br />
== Internals of the LCL ==<br />
<br />
There is the LCL, and the "interface". The LCL is the part that is platform independent, and it resides in the lazarus/lcl/ directory. This directory contains mainly class definitions. Many of the different controls are actually implemented in the lazarus/lcl/include/ directory in the various .inc files. This is to find the implementation of a specific control, TCustomMemo for example, faster (which is in custommemo.inc). Every .inc starts with a line {%MainUnit ...} to define where it is included.<br />
<br />
Then there is the "interface" which lives in a subdirectory of the lazarus/lcl/interfaces/ directory. The gtk interface is in gtk/, win32 in win32/, etc. They all have a Interfaces unit, which is used by the lcl and creates the main interface object. Usually the main interface object is defined in XXint.pp (win32int.pp), and implemented in various inc files, XXobject.inc, for the interface specific methods, XXwinapi.inc for winapi implementation methods, XXlistsl.inc for implementation of the stringlist used by the TComboBox, TListBox, and other such controls, XXcallback.inc for handling of widget events and taking appropriate action to notify the LCL.<br />
<br />
Every control has a WidgetSetClass property which is of the 'mirror' class in the interfaces directory, for example: mirror of TCustomEdit is TWSCustomEdit, which methods are implemented by TWin32WSCustomEdit in win32wsstdctrls. This is the way the LCL communicates with the interface, and how it lets the interface do things.<br />
<br />
Communication of interface back to LCL is mostly done by sending messages, usually 'DeliverMessage' which calls TControl.Perform(<message_id>, wparam, lparam) with wparam and lparam being the extra info for the message.<br />
<br />
=== Pie and RadialPie ===<br />
The LCLIntf unit contains two functions to draw pie-shapes:<br />
function [[doc:lcl/lclintf/pie.html|Pie]](DC: HDC; x1, y1, x2, y2, sx, sy, ex, ey: Integer): Boolean;<br />
function [[doc:lcl/lclintf/radialpie.html|RadialPie]](DC: HDC; x1, y1, x2, y2, Angle1, Angle2: Integer): Boolean; <br />
<br />
The Pie function uses a two points (sx,sy) and (ex,ey) to indicate start and end of the arc. RadialPie uses Angles to indicate start and end of the arc.<br />
<br />
Pie calls TWidgetSet.Pie and RadialPie calls TWidgetSet.RadialPie. The default implementation of TWidgetSet.Pie is to convert the parameters to angles and to call TWidgetSet.RadialPie. TWidgetSet.RadialPie creates an array of points for the arc and calls TWidgetSet.Polygon.<br />
<br />
The win32 widgetset overrides TWidgetSet.Pie to call the Windows Pie function directly.<br />
<br />
{{Note| in older versions of Lazarus there existed RadialPie with angles which did the same as the current RadialPie and RadialPie, which does the same as our Pie. Those functions have been removed in Lazarus 0.9.21.}}<br />
<br />
===Interfaces===<br />
<br />
{{Interfaces}}<br />
<br />
===Adding a new unit to the LCL===<br />
First add the new unit name into allclunits.pp.<br />
<br />
To make sure the unit is registered in the components palette see the files RegisterLCL.pas and pkgfileslcl.inc, they are located in lazarus/packager.<br />
<br />
== How to create a new Widgetset ==<br />
This is a step-by-step tutorial of developing a new [[Widgetset|widgetset]]. It is based on my experience creating the basics of the new qt4 interface.<br />
<br />
To start with, why would someone want to add an Widgetset? The answer is to be able to port existing lazarus software to more platforms, without modifying their code.<br />
<br />
Now, let´s write the widgetset. First of all, you need to have pascal bindings for the widget and know how to use it. Normally this is not hard. A few hours doing basic tutorials available on the internet should be enougth to get started. If the bindings do not exist already, you need to create them. If the tutorials are on another language, translate them to pascal and make them work.<br />
<br />
Now, for Qt I utilized Den Jean qt4 bindings for pascal, and created a very basic Qt program using them:<br />
<br />
<syntaxhighlight>program qttest;<br />
<br />
uses qt4;<br />
<br />
var<br />
App: QApplicationH;<br />
MainWindow: QMainWindowH;<br />
begin<br />
App := QApplication_Create(@argc,argv);<br />
<br />
MainWindow := QMainWindow_Create;<br />
<br />
QWidget_show(MainWindow);<br />
<br />
QApplication_Exec;<br />
end.</syntaxhighlight><br />
<br />
The above project compiles and creates a qt4 program. Now we will use its code to write a new widgetset. After we are done, the lazarus program below will compile fine into a qt4 software:<br />
<br />
<syntaxhighlight>program qttest;<br />
<br />
{$mode objfpc}{$H+}<br />
<br />
uses<br />
Interfaces, Classes, Forms,<br />
{ Add your units here }<br />
qtform;<br />
<br />
begin<br />
Application.Initialize;<br />
Application.CreateForm(TForm1, Form1);<br />
Application.Run;<br />
end.</syntaxhighlight><br />
<br />
Where the form is maintained by Lazarus IDE and designed visually.<br />
<br />
The first thing to do on a new widgetset is add an empty skeleton for it. Very early development widgetsets, like qt and carbon, can serve as an skeleton.<br />
<br />
Looking at the files on the many widgets you can see the first file to be called by the lcl: Interfaces.pas This file just calls another called QtInt.pas or similar. QtInt.pas has the code for the TWidgetSet class, which we must implement. On an empty skeleton you can see that the class has various functions it must implement:<br />
<br />
<syntaxhighlight> TQtWidgetSet = Class(TWidgetSet)<br />
private<br />
App: QApplicationH;<br />
public<br />
{$I qtwinapih.inc}<br />
{$I qtlclintfh.inc}<br />
public<br />
// Application<br />
procedure AppInit(var ScreenInfo: TScreenInfo); override;<br />
procedure AppRun(const ALoop: TApplicationMainLoop); override;<br />
procedure AppWaitMessage; override;<br />
procedure AppProcessMessages; override;<br />
procedure AppTerminate; override;<br />
procedure AppMinimize; override;<br />
procedure AppBringToFront; override;<br />
public<br />
constructor Create;<br />
destructor Destroy; override;<br />
function DCGetPixel(CanvasHandle: HDC; X, Y: integer): TGraphicsColor; override;<br />
procedure DCSetPixel(CanvasHandle: HDC; X, Y: integer; AColor: TGraphicsColor); override;<br />
procedure DCRedraw(CanvasHandle: HDC); override;<br />
procedure SetDesigning(AComponent: TComponent); override;<br />
<br />
function InitHintFont(HintFont: TObject): Boolean; override;<br />
<br />
// create and destroy<br />
function CreateComponent(Sender : TObject): THandle; override; // deprecated<br />
function CreateTimer(Interval: integer; TimerFunc: TFNTimerProc): integer; override;<br />
function DestroyTimer(TimerHandle: integer): boolean; override;<br />
end;</syntaxhighlight><br />
<br />
=== How to implement a new windowed component ===<br />
<br />
Windowed components are all descendents from TWinControl. Those controls have a Handle and thus, should be created by the Widgetset. It's easy to add new windowed components to a widgetset.<br />
<br />
Let's say you want to add TQtWSCustomEdit to Qt Widgetset. To start with TCustomEdit is a descendent of TWinControl and is located on the StdCtrls unit.<br />
<br />
Now, go to QtWSStrCtrls unit and look for the declaration of TQtWSCustomEdit.<br />
<br />
<syntaxhighlight> TQtWSCustomEdit = class(TWSCustomEdit)<br />
private<br />
protected<br />
public<br />
end;</syntaxhighlight><br />
<br />
Add static methods that are declared on TWSCustomEdit and override them. The code should now look like this:<br />
<br />
<syntaxhighlight> TQtWSCustomEdit = class(TWSCustomEdit)<br />
private<br />
protected<br />
public<br />
class function CreateHandle(const AWinControl: TWinControl;<br />
const AParams: TCreateParams): HWND; override;<br />
class procedure DestroyHandle(const AWinControl: TWinControl); override;<br />
{ class function GetSelStart(const ACustomEdit: TCustomEdit): integer; override;<br />
class function GetSelLength(const ACustomEdit: TCustomEdit): integer; override;<br />
<br />
class procedure SetCharCase(const ACustomEdit: TCustomEdit; NewCase: TEditCharCase); override;<br />
class procedure SetEchoMode(const ACustomEdit: TCustomEdit; NewMode: TEchoMode); override;<br />
class procedure SetMaxLength(const ACustomEdit: TCustomEdit; NewLength: integer); override;<br />
class procedure SetPasswordChar(const ACustomEdit: TCustomEdit; NewChar: char); override;<br />
class procedure SetReadOnly(const ACustomEdit: TCustomEdit; NewReadOnly: boolean); override;<br />
class procedure SetSelStart(const ACustomEdit: TCustomEdit; NewStart: integer); override;<br />
class procedure SetSelLength(const ACustomEdit: TCustomEdit; NewLength: integer); override;<br />
<br />
class procedure GetPreferredSize(const AWinControl: TWinControl;<br />
var PreferredWidth, PreferredHeight: integer); override;}<br />
end;</syntaxhighlight><br />
<br />
The commented part of the code are procedures you need to implement for TCustomEdit to be fully functional, but just CreateHandle and DestroyHandle should be enough for it to be show on the form and be editable, so it fits our needs in this article.<br />
<br />
Hit CTRL+SHIFT+C to code complete and the implement CreateHandle and DestroyHandle. In the case of Qt4 the code will be like this:<br />
<br />
<syntaxhighlight>{ TQtWSCustomEdit }<br />
<br />
class function TQtWSCustomEdit.CreateHandle(const AWinControl: TWinControl;<br />
const AParams: TCreateParams): HWND;<br />
var<br />
Widget: QWidgetH;<br />
Str: WideString;<br />
begin<br />
// Creates the widget<br />
WriteLn('Calling QTextDocument_create');<br />
Str := WideString((AWinControl as TCustomMemo).Lines.Text);<br />
Widget := QTextEdit_create(@Str, QWidgetH(AWinControl.Parent.Handle));<br />
<br />
// Sets it's initial properties<br />
QWidget_setGeometry(Widget, AWinControl.Left, AWinControl.Top,<br />
AWinControl.Width, AWinControl.Height);<br />
<br />
QWidget_show(Widget);<br />
<br />
Result := THandle(Widget);<br />
end;<br />
<br />
class procedure TQtWSCustomEdit.DestroyHandle(const AWinControl: TWinControl);<br />
begin<br />
QTextEdit_destroy(QTextEditH(AWinControl.Handle));<br />
end;</syntaxhighlight><br />
<br />
Now uncomment the like "RegisterWSComponent(TCustomEdit, TQtWSCustomEdit);" on the bottom of the unit and that's it!<br />
<br />
You can now drop a TCustomEdit on the bottom of a form and expect it to work. :^) <br />
<br />
=== Implementing TBitmap ===<br />
<br />
To implement TBitmap it is necessary to understand TRawImage and TLazIntfImage as explained here: [[Developing with Graphics#Working with TLazIntfImage.2C TRawImage and TLazCanvas]]<br />
<br />
So, let's say you want to compile the following code:<br />
<br />
<syntaxhighlight><br />
procedure TMyForm.HandleOnPaint(Sender: TObject);<br />
var<br />
Bitmap: TBitmap;<br />
begin<br />
Bitmap := TBitmap.Create;<br />
try<br />
Bitmap.LoadFromFile('myfile.bmp');<br />
Canvas.Draw(0, 0, Bitmap);<br />
finally<br />
Bitmap.Free;<br />
end;<br />
end;</syntaxhighlight><br />
<br />
Below is the order on which functions from the widgetset interface are called when executing that code:<br />
<br />
1 - BeginPaint<br />
<br />
This will be called only if the OnPaint event sends zero as the DC for the paint event<br />
<br />
2 - GetDC(0);<br />
<br />
Just create a device context.<br />
<br />
3 - TCDWidgetSet.RawImage_QueryDescription <br />
<br />
The default implementation of this routine is good for most widgetsets<br />
<br />
4 - TCDWidgetSet.RawImage_CreateBitmaps<br />
<br />
Here you need to create a native image object and load it from RawData.Data where the information is stored based on your description of the pixel format on item 2.<br />
<br />
5 - CreateCompatibleDC(0)<br />
<br />
This creates a temporary DC just to store the image, but at this point there is no information about the image so at this point this DC is really dummy<br />
<br />
6 - SelectObject<br />
<br />
With the image as the object to be selected and the DC just created above as target DC.<br />
<br />
7 - StretchMaskBlt<br />
<br />
Finally the drawing function! DestDC is the DC allocated on BeginPaint.<br />
<br />
8 - EndPaint<br />
<br />
Again, not always utilized.<br />
<br />
=== TBitmap.LoadFromDevice for screenshot taking ===<br />
<br />
It is recomended that you first implement TBitmap before trying this step.<br />
<br />
On LCL you can use the following code takes a screenshot from the entire screen and paints it on the canvas:<br />
<br />
<syntaxhighlight>var<br />
ScreenDC: HDC;<br />
Bitmap: TBitmap;<br />
begin<br />
Bitmap := TBitmap.Create;<br />
try<br />
ScreenDC := GetDC(0);<br />
Bitmap.LoadFromDevice(ScreenDC);<br />
ReleaseDC(0, ScreenDC);<br />
Canvas.Draw(0, 0, Bitmap);<br />
finally<br />
Bitmap.Free;<br />
end;<br />
end;</syntaxhighlight><br />
<br />
If you already implemented TBitmap, there are only 2 new functions to be implemented for LoadFromDevice: GetDeviceSize and GetRawImageFromDevice<br />
<br />
Below is a big trace, covering all widgetset functions being called on a OnPaint event that takes a screenshot and paints it on the screen. This trace was taken with Qt widgetset, and may have some imperfections. The Handle numbers should be used to check which object is being utilized on the functions.<br />
<br />
<br />
[WinAPI BeginPaint] Result=-1220713544<br />
<br />
[WinAPI GetClientBounds]<br />
<br />
[WinAPI SetWindowOrgEx] DC: -1220713544 NewX: 0 NewY: 0<br />
<br />
<syntaxhighlight>Enters on Paint event<br />
<br />
Bitmap := TBitmap.Create;<br />
try<br />
ScreenDC := GetDC(0);</syntaxhighlight><br />
<br />
[WinAPI GetDC] hWnd: 0 Result: -1220712920<br />
<br />
<syntaxhighlight> Bitmap.LoadFromDevice(ScreenDC);</syntaxhighlight><br />
<br />
[WinAPI GetDeviceSize]<br />
<br />
[WinAPI GetRawImageFromDevice] SrcDC: -1220712920 SrcWidth: 0 SrcHeight: 0<br />
<br />
[WinAPI CreateBitmapFromRawImage] Width:1024 Height:768 DataSize: 3145728 CreateMask: False Bitmap:-1220746696<br />
<br />
[WinAPI GetObject] GDIObj: -1220746696 Result=84 ObjectType=Image<br />
<br />
<syntaxhighlight> ReleaseDC(0, ScreenDC);</syntaxhighlight><br />
<br />
[WinAPI ReleaseDC] hWnd: 0 DC: -1220712920<br />
<br />
<syntaxhighlight> Canvas.Draw(0, 0, Bitmap);</syntaxhighlight><br />
<br />
[WinAPI CreateCompatibleDC] DC: 0<br />
<br />
[WinAPI GetDC] hWnd: 0 Result: -1220712920<br />
<br />
[WinAPI SelectObject] DC=-1220712920 GDIObj=-1220746696 Result=0 ObjectType=Image<br />
<br />
[WinAPI StretchMaskBlt] DestDC:-1220713544 SrcDC:-1220712920 Image:137185120 X:0 Y:0 W:1024 H:768 XSrc:0 YSrc:0 WSrc:1024 HSrc:768<br />
<br />
<syntaxhighlight>finally<br />
Bitmap.Free;<br />
end;</syntaxhighlight><br />
<br />
[WinAPI SelectObject] DC=-1220712920 GDIObj=0 Invalid GDI Object<br />
<br />
[WinAPI DeleteObject] GDIObject: -1220746696 Result=False ObjectType=Image<br />
<br />
<pre><br />
Now exited the OnPaint event<br />
</pre><br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
[WinAPI SetWindowOrgEx] DC: -1220713544 NewX: -152 NewY: -246<br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
TWidgetSet.InitializeCriticalSection<br />
<br />
TWidgetSet.EnterCriticalSection<br />
<br />
[WinAPI SelectObject] DC=-1220713544 GDIObj=0 Invalid GDI Object<br />
<br />
[WinAPI MoveToEx] DC:-1220713544 X:0 Y:0<br />
<br />
[WinAPI SelectObject] DC=-1220713544 GDIObj=-1220746760 Result=-1220746856 ObjectType=Brush<br />
<br />
[WinAPI SelectObject] DC=-1220713544 GDIObj=-1220746856 Result=-1220746856 ObjectType=Brush<br />
<br />
TWidgetSet.LeaveCriticalSection<br />
<br />
[WinAPI SetWindowOrgEx] DC: -1220713544 NewX: 0 NewY: 0<br />
<br />
[WinAPI EndPaint] Handle: -1220611768 PS.HDC: -1220713544<br />
<br />
=== Implementing drawing in the OnPaint event of a form or another control ===<br />
<br />
For drawing in the OnPaint event of a form, the event itself comes from the underlaying widgetset library. The LCL interface should handle this event and create an appropriate DC object on the event handler and then call LCLSendPaintMsg. Besides that one should also implement the corresponding drawing methods, such as Rectangle or ExtTextOut. Pen, Brush and Font related routines might also be useful.<br />
<br />
Here is the OnPaint event handler from the Cocoa widgetset which shows how it calls LCLSentPaintMsg:<br />
<br />
<syntaxhighlight><br />
procedure TLCLCommonCallback.Draw(ControlContext: NSGraphicsContext;<br />
const bounds, dirty:NSRect);<br />
var<br />
struct : TPaintStruct;<br />
begin<br />
if not Assigned(Context) then Context:=TCocoaContext.Create;<br />
<br />
Context.ctx:=ControlContext;<br />
if Context.InitDraw(Round(bounds.size.width), Round(bounds.size.height)) then<br />
begin<br />
FillChar(struct, SizeOf(TPaintStruct), 0);<br />
struct.hdc := HDC(Context);<br />
{$IFDEF VerboseWinAPI}<br />
DebugLn(Format('[TLCLCommonCallback.Draw] OnPaint event started context: %x', [HDC(context)]));<br />
{$ENDIF}<br />
LCLSendPaintMsg(Target, HDC(Context), @struct);<br />
{$IFDEF VerboseWinAPI}<br />
DebugLn('[TLCLCommonCallback.Draw] OnPaint event ended');<br />
{$ENDIF}<br />
end;<br />
end;<br />
</syntaxhighlight><br />
<br />
And a list of WinAPI routines which were called when running this event:<br />
<br />
<pre><br />
[TCocoaWidgetSet.GetDC] hWnd: 0 Result: 12400C0<br />
[TLCLCommonCallback.Draw] OnPaint event started context: 1240340<br />
TCocoaWidgetSet.CreatePenIndirect<br />
TCocoaWidgetSet.SelectObject DC: 1240340 GDIObj: 10EC460<br />
TCocoaWidgetSet.SelectObject Result: 0<br />
TCocoaWidgetSet.SelectObject DC: 1240340 GDIObj: 10EBF00<br />
TCocoaWidgetSet.SelectObject Result: 0<br />
[TCocoaWidgetSet.Rectangle] DC: 1240340 X1: 100 Y1: 100 X2: 200 Y2: 200<br />
TCocoaWidgetSet.SelectObject DC: 1240340 GDIObj: 10EC4A0<br />
TCocoaWidgetSet.SelectObject Result: 0<br />
[TCocoaWidgetSet.GetTextExtentPoint] DC: 1240340 Str: Some text Count: 9<br />
[TCocoaWidgetSet.GetTextExtentPoint] Size: 65,17<br />
[TLCLCommonCallback.Draw] OnPaint event ended<br />
</pre><br />
<br />
=== Implementing TLabel ===<br />
<br />
Implementing TLabel is particularly hard, despite it being such a basic component, because it requires that almost all painting be implemented. TLabel is not a windowed control, instead it depends on paint messages to be drawn directly into the form canvas.<br />
<br />
Before trying to get TLabel working it is recomended to test if drawing functions such as Rectangle work inside a form's OnPaint event.<br />
<br />
Several WinAPI methods need to be implemented, particularly:<br />
<br />
'''Device Context Methods'''<br />
<br />
BeginPaint, GetDC, EndPaint, ReleaseDC, CreateCompatibleDC<br />
<br />
see [[Device Contexts and GDI objects in the LCL interfaces]]<br />
<br />
'''GDI Objects Methods'''<br />
<br />
SelectObject, DeleteObject, CreateFontIndirect, CreateFontIndirectEx<br />
<br />
'''Miscelaneous functions'''<br />
<br />
InvalidateRect, GetClientBounds, SetWindowOrgEx<br />
<br />
'''Text drawing Methods'''<br />
<br />
DrawText. Instead of implementing DrawText one can also use the default TWidgetSet.DrawText, like the Carbon and Cocoa widgetsets do. But in this case it is necessary that one implements at least GetTextMetrics, GetTextExtentPoint and ExtTextOut. Without GetTextMetrics a form with a label will crash because the autosize will not be able to calculate the appropriate size for the label.<br />
<br />
'''Region functions to determine if the control is behind another'''<br />
<br />
CombineRgn, CreateRectRgn, GetClipRGN, RectVisible<br />
<br />
<br />
Below is the order in which paint procedures are called on a form with only one TLabel, to better understand the painting sequence:<br />
<br />
1 - GetDC is called once on software startup with hWnd = 0<br />
<br />
2 - The form is shown<br />
<br />
3 - GetDC is called again (this wouldn't happen without the label). A<br />
few font related functions are called, as well as DrawText with<br />
CalcRect set to True to calculate the size of the label.<br />
<br />
4 - InvalidateRect is called on the form canvas<br />
<br />
5 - Control goes back to the operating system until a paint message comes from the widgetset<br />
<br />
6 - BeginPaint is called, and at this point code on OnPaint event of the form will be executed<br />
<br />
7 - DrawText is called again with CalcRect set to false<br />
<br />
8 - The Painting ends.<br />
<br />
=== Implementing visibility for forms and controls and window state===<br />
<br />
The code that controls visibility is split between visibility for forms, and for controls<br />
<br />
'''Visibility for forms and window state'''<br />
<br />
This part also controls the state of the window (minimized, maximized or normal). It is implemented as a copy of the Windows API function ShowWindow, so you must implemente the TMyWidgetset.ShowWindow on the file mywinapi.inc Don´t forget to also add a header to the file mywinapih.inc<br />
<br />
Below is code that implements this function on the Qt widgetset. It should be very easy to understand, copy and implement on your own widgetset. You can also take a look how Gtk implements this. On Windows, the Windows API is called directly, of course, so there is no code to look at.<br />
<br />
<syntaxhighlight>{------------------------------------------------------------------------------<br />
function ShowWindow(hWnd: HWND; nCmdShow: Integer): Boolean;<br />
<br />
nCmdShow:<br />
SW_SHOWNORMAL, SW_MINIMIZE, SW_SHOWMAXIMIZED<br />
------------------------------------------------------------------------------}<br />
function TQtWidgetSet.ShowWindow(hWnd: HWND; nCmdShow: Integer): Boolean;<br />
var<br />
Widget: QWidgetH;<br />
begin<br />
{$ifdef VerboseQtWinAPI}<br />
WriteLn('WinAPI ShowWindow');<br />
{$endif}<br />
<br />
Result := False;<br />
<br />
Widget := QWidgetH(hWnd);<br />
<br />
// if Widget = nil then RaiseException('TQtWidgetSet.ShowWindow hWnd is nil');<br />
<br />
case nCmdShow of<br />
<br />
SW_SHOW: QWidget_setVisible(Widget, True);<br />
<br />
SW_SHOWNORMAL: QWidget_showNormal(Widget);<br />
<br />
SW_MINIMIZE: QWidget_setWindowState(Widget, QtWindowMinimized);<br />
<br />
SW_SHOWMINIMIZED: QWidget_showMinimized(Widget);<br />
<br />
SW_SHOWMAXIMIZED: QWidget_showMaximized(Widget);<br />
<br />
SW_HIDE: QWidget_setVisible(Widget, False);<br />
<br />
end;<br />
<br />
Result := True;<br />
end;</syntaxhighlight><br />
<br />
'''Visibility for controls'''<br />
<br />
For controls inside a form you need to implement TMyWSWinControl.ShowHide class function that resides on the TMyWSWinControl class on the file mywscontrols.pp<br />
<br />
Remember that most controls are descendent from TWinControl, so implementing this function there will guarantee that the Visible property is implemented for all standard controls that have it. Below is a sample code for Qt widgetset.<br />
<br />
<syntaxhighlight>{------------------------------------------------------------------------------<br />
Method: TQtWSWinControl.ShowHide<br />
Params: AWinControl - the calling object<br />
<br />
Returns: Nothing<br />
<br />
Shows or hides a widget.<br />
------------------------------------------------------------------------------}<br />
class procedure TQtWSWinControl.ShowHide(const AWinControl: TWinControl);<br />
begin<br />
if AWinControl = nil then exit;<br />
<br />
if not AWinControl.HandleAllocated then exit;<br />
<br />
if AWinControl.HandleObjectShouldBeVisible then<br />
QWidget_setVisible(TQtWidget(AWinControl.Handle).Widget, True)<br />
else QWidget_setVisible(TQtWidget(AWinControl.Handle).Widget, False);<br />
end;</syntaxhighlight><br />
<br />
=== Implementing TStrings based Components===<br />
Some components use a TStrings to store the information they display, such as: TCustomMemo, TCustomListBox and TCustomComboBox.<br />
<br />
To implement those it is not enougth to only implement their functions on the TQtCustomMemo class for example. One of the functions to implement will be called GetStrings, which looks like this:<br />
<br />
<syntaxhighlight>class function TQtWSCustomListBox.GetStrings(const ACustomListBox: TCustomListBox): TStrings;<br />
var<br />
ListWidgetH: QListWidgetH;<br />
begin<br />
ListWidgetH := QListWidgetH((TQtWidget(ACustomListBox.Handle).Widget));<br />
Result := TQtListStrings.Create(ListWidgetH, ACustomListBox);<br />
end;</syntaxhighlight><br />
<br />
This function must return a TStrings descendent designed to detect when strings are added to or removed from the string list and to send this information to the widgetset to update the control. For example, the following declaration shows what TQtListStrings looks like:<br />
<br />
<syntaxhighlight> TQtListStrings = class(TStrings)<br />
private<br />
FListChanged: Boolean; // StringList and QtListWidget out of sync<br />
FStringList: TStringList; // Holds the items to show<br />
FQtListWidget: QListWidgetH; // Qt Widget<br />
FOwner: TWinControl; // Lazarus Control Owning ListStrings<br />
FUpdating: Boolean; // We're changing Qt Widget<br />
procedure InternalUpdate;<br />
procedure ExternalUpdate(var Astr: TStringList; Clear: Boolean = True);<br />
procedure IsChanged; // OnChange triggered by program action<br />
protected<br />
function GetTextStr: string; override;<br />
function GetCount: integer; override;<br />
function Get(Index : Integer) : string; override;<br />
//procedure SetSorted(Val : boolean); virtual;<br />
public<br />
constructor Create(ListWidgetH : QListWidgetH; TheOwner: TWinControl);<br />
destructor Destroy; override;<br />
procedure Assign(Source : TPersistent); override;<br />
procedure Clear; override;<br />
procedure Delete(Index : integer); override;<br />
procedure Insert(Index : integer; const S: string); override;<br />
procedure SetText(TheText: PChar); override;<br />
//procedure Sort; virtual;<br />
public<br />
//property Sorted: boolean read FSorted write SetSorted;<br />
property Owner: TWinControl read FOwner;<br />
function ListChangedHandler(Sender: QObjectH; Event: QEventH): Boolean; cdecl;<br />
end;</syntaxhighlight><br />
<br />
You can see its implementation in the qtobjects.pas unit of the qt interface<br />
<br />
===Implementing Menus===<br />
<br />
Menus are available on the LCL to create main menus or popup menus. A TMenu is the owner of a larger menu structure with many items. Items can have subitems, and don't need extra TMenus.<br />
<br />
Also remember that on LCL the handle is only created when needed and at that time all properties of the controls are already initialized. This helps a lot on widgetsets where depending on the properties of a menu item it can be of one class or another, like Qt.<br />
<br />
The following things need to be implemented in order for the menus to work:<br />
<br />
1) All methods on the QtWSMenus unit, which will implement menu creation and modification<br />
<br />
2) function TWinCEWidgetSet.SetMenu(AWindowHandle: HWND; AMenuHandle: HMENU): Boolean; from the wincewinapi.inc file, which will implement support for a main menu associated with a window.<br />
<br />
====Menu Creation Order====<br />
<br />
<br />
One important thing to understand when implementing menus, is in which order they are created. For example, we want to create the following menu structure:<br />
<br />
[[Image:Menu_creation_order.png]]<br />
<br />
And when our application is executed, there will be a 'Creating MenuItem' message with the caption of the menu each time TQtWSMenuItem.CreateHandle is called, and a 'Creating Menu' message with the name of the menu (TMenu descendents don't have a caption), each time TQtWSMenu.CreateHandle is called.<br />
<br />
Here is the resulting output of such software:<br />
<br />
<pre><br />
Creating Menu. Name: MainMenu1<br />
Creating MenuItem: Item1 Parent=Menu.Items : TMenuItem<br />
Creating MenuItem: SubItem11 Parent=Item1 : TMenuItem<br />
Creating MenuItem: SubItem12 Parent=Item1 : TMenuItem<br />
Creating MenuItem: SubItem13 Parent=Item1 : TMenuItem<br />
Creating MenuItem: SubItem14 Parent=Item1 : TMenuItem<br />
Creating MenuItem: SubSubItem141 Parent=SubItem14 : TMenuItem<br />
Creating MenuItem: SubSubItem142 Parent=SubItem14 : TMenuItem<br />
Creating MenuItem: SubSubItem143 Parent=SubItem14 : TMenuItem<br />
Creating MenuItem: SubSubItem144 Parent=SubItem14 : TMenuItem<br />
Creating MenuItem: Item2 Parent=Menu.Items : TMenuItem<br />
Creating MenuItem: SubItem21 Parent=Item2 : TMenuItem<br />
Creating MenuItem: SubItem22 Parent=Item2 : TMenuItem<br />
Creating MenuItem: SubItem23 Parent=Item2 : TMenuItem<br />
Creating MenuItem: Item3 Parent=Menu.Items : TMenuItem<br />
Creating MenuItem: Item4 Parent=Menu.Items : TMenuItem<br />
</pre><br />
<br />
For all MenuItems one can use GetParentMenu to get their parent owner: Menu (TMainMenu).<br />
<br />
===Control enabling/disabling===<br />
<br />
The current way to set control enabling/disabling is by implementing the winapi EnableWindow. This API should work generically on any control. It should enable/disable mouse and keyboard input for the specified window or control, but also mark it as uneditable by the user, by making it greyed for example.<br />
<br />
<syntaxhighlight>{------------------------------------------------------------------------------<br />
Method: EnableWindow<br />
Params: HWnd - handle to window<br />
BEnable - whether to enable the window<br />
Returns: If the window was previously disabled<br />
<br />
Enables or disables mouse and keyboard input to the specified window or<br />
control.<br />
------------------------------------------------------------------------------}<br />
function TWin32WidgetSet.EnableWindow(hWnd: HWND; bEnable: Boolean): Boolean;</syntaxhighlight><br />
<br />
===Shaped Windows===<br />
<br />
Windows can be shaped based on a TBitmap or on a TRegion. The region is the visible part.<br />
<br />
To implement shaped windows based on a TBitmap, implement TWSWinControl.setShape<br />
<br />
To implement shaped windows based on a TRegion implement LCLIntf.SetWindowRgn<br />
<br />
See also: [[LCL Tips#Creating a non-rectangular window or control]]<br />
<br />
===System colors===<br />
<br />
Some color constants are actually system colors, like clBtnFace, clForm, clWindow, etc, etc.<br />
<br />
To implement support for system colors the WinAPI routine GetSysColor should be implemented:<br />
<br />
function GetSysColor(nIndex: Integer): DWORD; override;<br />
<br />
And here is a snip of the color constants which should be supported. Check LCLType for the latest values:<br />
<br />
<syntaxhighlight><br />
//==============================================<br />
// API system Color constants pbd<br />
// note these are usually shown ORed with<br />
// $80000000 as these would have interfered with<br />
// other MS color enumerations<br />
// GetSysColor and SetSysColor expects the values<br />
// below<br />
//==============================================<br />
<br />
type<br />
COLORREF = LongInt;<br />
TColorRef = COLORREF;<br />
<br />
const<br />
CLR_INVALID = TColorRef($FFFFFFFF);<br />
<br />
COLOR_SCROLLBAR = 0;<br />
COLOR_BACKGROUND = 1;<br />
COLOR_ACTIVECAPTION = 2;<br />
COLOR_INACTIVECAPTION = 3;<br />
COLOR_MENU = 4;<br />
COLOR_WINDOW = 5;<br />
COLOR_WINDOWFRAME = 6;<br />
COLOR_MENUTEXT = 7;<br />
COLOR_WINDOWTEXT = 8;<br />
COLOR_CAPTIONTEXT = 9;<br />
COLOR_ACTIVEBORDER = 10;<br />
COLOR_INACTIVEBORDER = 11;<br />
COLOR_APPWORKSPACE = 12;<br />
COLOR_HIGHLIGHT = 13;<br />
COLOR_HIGHLIGHTTEXT = 14;<br />
COLOR_BTNFACE = 15;<br />
COLOR_BTNSHADOW = 16;<br />
COLOR_GRAYTEXT = 17;<br />
COLOR_BTNTEXT = 18;<br />
COLOR_INACTIVECAPTIONTEXT = 19;<br />
COLOR_BTNHIGHLIGHT = 20;<br />
COLOR_3DDKSHADOW = 21;<br />
COLOR_3DLIGHT = 22;<br />
COLOR_INFOTEXT = 23;<br />
COLOR_INFOBK = 24;<br />
// PBD: 25 is unassigned in all the docs I can find<br />
// if someone finds what this is supposed to be then fill it in<br />
// note defaults below, and cl[ColorConst] in graphics<br />
COLOR_HOTLIGHT = 26;<br />
COLOR_GRADIENTACTIVECAPTION = 27;<br />
COLOR_GRADIENTINACTIVECAPTION = 28;<br />
COLOR_MENUHILIGHT = 29;<br />
COLOR_MENUBAR = 30;<br />
<br />
COLOR_FORM = 31;<br />
<br />
COLOR_ENDCOLORS = COLOR_FORM;<br />
<br />
COLOR_DESKTOP = COLOR_BACKGROUND;<br />
COLOR_3DFACE = COLOR_BTNFACE;<br />
COLOR_3DSHADOW = COLOR_BTNSHADOW;<br />
COLOR_3DHIGHLIGHT = COLOR_BTNHIGHLIGHT;<br />
COLOR_3DHILIGHT = COLOR_BTNHIGHLIGHT;<br />
COLOR_BTNHILIGHT = COLOR_BTNHIGHLIGHT;<br />
<br />
MAX_SYS_COLORS = COLOR_ENDCOLORS;<br />
SYS_COLOR_BASE = TColorRef($80000000);</syntaxhighlight><br />
<br />
===ShowMessage===<br />
<br />
These standard dialogs are implemented purely in the LCL in the following places:<br />
<br />
* Class TPromptDialog file lcl/include/promptdialog.inc<br />
<br />
===SpinEdit===<br />
<br />
Both TFloatSpinEdit and TSpinEdit are implemented in the class TWSFloatSpinEdit.<br />
<br />
===Clipboard===<br />
<br />
Clipboard support is implemented in lclintf by implementing Windows API routines. The routines are:<br />
<br />
<syntaxhighlight>function ClipboardFormatToMimeType(FormatID: TClipboardFormat): string; {$IFDEF IF_BASE_MEMBER}virtual;{$ENDIF}<br />
function ClipboardGetData(ClipboardType: TClipboardType;<br />
FormatID: TClipboardFormat; Stream: TStream): boolean; {$IFDEF IF_BASE_MEMBER}virtual;{$ENDIF}<br />
// ! ClipboardGetFormats: List will be created. You must free it yourself with FreeMem(List) !<br />
function ClipboardGetFormats(ClipboardType: TClipboardType;<br />
var Count: integer; var List: PClipboardFormat): boolean; {$IFDEF IF_BASE_MEMBER}virtual;{$ENDIF}<br />
function ClipboardGetOwnerShip(ClipboardType: TClipboardType;<br />
OnRequestProc: TClipboardRequestEvent; FormatCount: integer;<br />
Formats: PClipboardFormat): boolean; {$IFDEF IF_BASE_MEMBER}virtual;{$ENDIF}<br />
function ClipboardRegisterFormat(const AMimeType: string): TClipboardFormat; {$IFDEF IF_BASE_MEMBER}virtual;{$ENDIF}</syntaxhighlight><br />
<br />
===TSpeedButton===<br />
<br />
This control is a TGraphicControl descendent, so it has no handle and paints itself. To retain native look, it uses the function LCLIntf.DrawFrameControl to paint itself, so implement this function to have this control working. Naturally, lot's of other DC, WindowOrg, Text Drawing and Painting routines will have to be working, as explained for TLabel.<br />
<br />
===TRadioButton and TCheckButton===<br />
<br />
'''Messages:'''<br />
<br />
Basically the Widgetset must do:<br />
<br />
*Send LM_CHANGE when a radio button is unchecked/checked (LCL will take care if OnClick will be called or not)<br />
*Dont send LM_CHANGE when TWSCustomCheckBox.SetState is called (SetChecked)<br />
<br />
See also this bug report: http://bugs.freepascal.org/view.php?id=13939<br />
<br />
===FullScreen support===<br />
<br />
FullScreen is implemented as a Windows state wsFullScreen, and as such is implemented in LCLIntf.ShowWindow where the constant SW_SHOWFULLSCREEN should be handled.<br />
<br />
== An example of how the LCL interfaces work ==<br />
<br />
Below is a simple example. Suppose you have developed a trayicon component. How would you implement it in the LCL to work correctly on the various different supported platforms?<br />
<br />
You would need to generate the following files:<br />
<br />
\trayicon.pas<br />
<br />
\wstrayicon.pas<br />
<br />
\gtk\gtkwstrayicon.pas<br />
<br />
\gtk\trayintf.pas<br />
<br />
\win32\win32wstrayicon.pas<br />
<br />
\win32\trayintf.pas<br />
<br />
<br />
Providing separate wsXXX.pas and \$(LCLWidgetType)\XXXintf.pas files avoids the need for ifdefs altogether. You will need to add as a unit path $(LCLWidgetType) to the XXXintf.pas file in order initialize the correct trayintf.pas file, which in turn initializes the correct WS Tray class.<br />
<br />
Inside trayicon.pas you include wstrayicon. Derive your main class from an LCL class, and only use wstrayicon in its implementation. All LCL classes that communicate with a widgetset, must be derived from [[doc:/lcl/lclclasses/tlclcomponent.html|TLCLComponent]] declared in the [[doc:/lcl/lclclasses|LCLClasses]] unit.<br />
<br />
<syntaxhighlight>unit TrayIcon;<br />
<br />
interface<br />
<br />
type<br />
TTrayIcon = class(TLCLComponent)<br />
public<br />
procedure DoTray;<br />
end;<br />
<br />
implementation<br />
<br />
uses wstrayicon;<br />
<br />
procedure TTrayIcon.DoTray;<br />
begin<br />
// Call wstrayicon<br />
end;<br />
<br />
end.</syntaxhighlight><br />
<br />
in trayintf you use gtkwstrayicon or win32trayicon depending on which<br />
trayintf file it is.<br />
<br />
in wstrayicon you create a class like so:<br />
<br />
<syntaxhighlight>unit WSTrayIcon;<br />
<br />
uses WSLCLClasses, Controls, TrayIcon; // and other things as well<br />
<br />
TWSTrayIconClass = class of TWSTrayIcon;<br />
TWSTrayIcon = class(TWSWinControl);<br />
public<br />
class procedure EmbedTrayIcon(const ATrayIcon: TCustomTrayIcon);<br />
virtual; // these must all be virtual and class procedures!!<br />
class procedure RemoveTrayIcon(const ATrayIcon: TCustomTrayIcon); virtual;<br />
....<br />
end;<br />
...<br />
<br />
implementation<br />
<br />
procedure TWSTrayIcon.EmbedTrayIcon(const ATrayIcon: TCustomTrayIcon);<br />
begin<br />
//do nothing<br />
end;<br />
<br />
procedure TWSTrayIcon.RemoveTrayIcon(const ATrayIcon: TCustomTrayIcon);<br />
begin<br />
//do nothing<br />
end;</syntaxhighlight><br />
<br />
now in gtkwstrayicon.pas do this:<br />
<br />
<syntaxhighlight>uses WSTrayIcon, WSLCLClasses, Controls, TrayIcon, gtk, gdk;<br />
<br />
<br />
TGtkWSTrayIcon = class(TWSTrayIcon);<br />
private<br />
class function FindSystemTray(const ATrayIcon: TCustomTrayIcon):<br />
TWindow; virtual;<br />
public<br />
class procedure EmbedTrayIcon(const ATrayIcon: TCustomTrayIcon); override;<br />
class procedure RemoveTrayIcon(const ATrayIcon: TCustomTrayIcon);<br />
override;<br />
class function CreateHandle(const AWinControl: TWinControl; const<br />
AParams: TCreateParams): HWND; override;<br />
....<br />
end;<br />
...<br />
<br />
implementation<br />
<br />
procedure TGtkWSTrayIcon.CreateHandle(const AWinControl: TWinControl;<br />
const AParams: TCreateParams): HWND;<br />
var<br />
WidgetInfo: PWidgetInfo;<br />
begin<br />
<br />
Result := gtk_plug_new;<br />
WidgetInfo := CreateWidgetInfo(AWinControl, Result); // it's something<br />
like this anyway<br />
TGtkWSWincontrolClass(WidgetSetClass).SetCallbacks(AWinControl);<br />
// and more stuff<br />
end;<br />
<br />
function TGtkWSTrayIcon.FindSystemTray(const ATrayIcon:<br />
TCustomTrayIcon): TWindow;<br />
begin<br />
// do something<br />
end;<br />
<br />
<br />
procedure TGtkWSTrayIcon.EmbedTrayIcon(const ATrayIcon: TCustomTrayIcon);<br />
var<br />
SystemTray: TWindow;<br />
begin<br />
SystemTray := FindSystemTray(ATrayIcon);<br />
//do something<br />
end;<br />
<br />
procedure TGtkWSTrayIcon.RemoveTrayIcon(const ATrayIcon: TCustomTrayIcon);<br />
begin<br />
//do something<br />
end;<br />
<br />
......<br />
<br />
initialization<br />
<br />
RegisterWSComponent(TCustomTrayIcon, TGtkWSTrayIcon); //this is very<br />
important!!!<br />
<br />
end.</syntaxhighlight><br />
<br />
then finally in trayicon.pas you go as normal<br />
<br />
<syntaxhighlight>uses WSTrayIcon; //etc. you DON'T include GtkWSTrayIcon here!<br />
<br />
TCustomTrayIcon = class(TWinControl)<br />
public<br />
procedure EmbedControl;<br />
....<br />
end;<br />
<br />
...<br />
procedure TTrayIcon.EmbedControl;<br />
begin<br />
TWSTrayIconClass(WidgetSetClass).EmbedControl(Self);<br />
<br />
end;</syntaxhighlight><br />
<br />
----<br />
This document is work in progress. You can help by writing sections of this document. If you cannot find the information you are looking for in this document, please add your question to the [[Talk:LCL Internals|discussion page]]. This will help us to write documentation at a level that is neither too simple nor too complicated, and fully cover the areas that people want to know about.<br />
<br />
[[Category:LCL]]<br />
[[Category:Lazarus internals]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=LCL_Internals&diff=86376LCL Internals2015-02-13T12:59:18Z<p>Sekelsenmat: /* Minimum Toolkit versions */</p>
<hr />
<div>{{LCL Internals}}<br />
<br />
{{Other_Interfaces}}<br />
<br />
== Minimum Toolkit versions ==<br />
<br />
{| class="wikitable sortable"<br />
! Lazarus version !! Min. FPC !! Min. Gtk 2 !! Min. Qt 4 !! Min. Windows !! Min. Windows CE !! Min. Mac OS X (Carbon) !! Min. Mac OS X (Cocoa) !! Min. Req. of LCL-CustomDrawn<br />
|-<br />
|0.9.24<br />
|2.2.0<br />
|2.6+<br />
|4.2+<br />
|Windows 98+<br />
|Recommended 4.0+<br />
|10.4<br />
|N/A<br />
|N/A<br />
|-<br />
|0.9.26<br />
|2.2.2<br />
|2.6+<br />
|4.3+<br />
|Windows 98+<br />
|Recommended 4.0+<br />
|10.4<br />
|N/A<br />
|N/A<br />
|-<br />
|0.9.28<br />
|2.2.4<br />
|2.8+<br />
|4.5+<br />
|Windows 98+<br />
|Recommended 4.0+<br />
|10.4<br />
|N/A<br />
|N/A<br />
|-<br />
|0.9.30<br />
|2.4.0<br />
|2.8+<br />
|4.5+<br />
|Windows 98+<br />
|Recommended 5.0+<br />
|10.4<br />
|N/A<br />
|N/A<br />
|-<br />
|0.9.31<br />
|2.4.4<br />
|2.8+<br />
|4.5+<br />
|Windows 98+<br />
|Recommended 5.0+<br />
|10.4<br />
|10.6<br />
|Android 2.2+, Windows 2000+, X11, Mac OS X 10.6+<br />
|-<br />
|1.2.6<br />
|2.6.4<br />
|2.8+<br />
|4.5+*<br />
|Windows 98+<br />
|Recommended 5.0+<br />
|10.4<br />
|10.6<br />
|Android 2.2+, Windows 2000+, X11, Mac OS X 10.6+<br />
|}<br />
<br />
* - Actually 4.5.0 ...4.8.4 with pre-built Qt4Pas.dll, 4.8.5+ requires a different Qt4Pas.dll<br />
<br />
== Internals of the LCL ==<br />
<br />
There is the LCL, and the "interface". The LCL is the part that is platform independent, and it resides in the lazarus/lcl/ directory. This directory contains mainly class definitions. Many of the different controls are actually implemented in the lazarus/lcl/include/ directory in the various .inc files. This is to find the implementation of a specific control, TCustomMemo for example, faster (which is in custommemo.inc). Every .inc starts with a line {%MainUnit ...} to define where it is included.<br />
<br />
Then there is the "interface" which lives in a subdirectory of the lazarus/lcl/interfaces/ directory. The gtk interface is in gtk/, win32 in win32/, etc. They all have a Interfaces unit, which is used by the lcl and creates the main interface object. Usually the main interface object is defined in XXint.pp (win32int.pp), and implemented in various inc files, XXobject.inc, for the interface specific methods, XXwinapi.inc for winapi implementation methods, XXlistsl.inc for implementation of the stringlist used by the TComboBox, TListBox, and other such controls, XXcallback.inc for handling of widget events and taking appropriate action to notify the LCL.<br />
<br />
Every control has a WidgetSetClass property which is of the 'mirror' class in the interfaces directory, for example: mirror of TCustomEdit is TWSCustomEdit, which methods are implemented by TWin32WSCustomEdit in win32wsstdctrls. This is the way the LCL communicates with the interface, and how it lets the interface do things.<br />
<br />
Communication of interface back to LCL is mostly done by sending messages, usually 'DeliverMessage' which calls TControl.Perform(<message_id>, wparam, lparam) with wparam and lparam being the extra info for the message.<br />
<br />
=== Pie and RadialPie ===<br />
The LCLIntf unit contains two functions to draw pie-shapes:<br />
function [[doc:lcl/lclintf/pie.html|Pie]](DC: HDC; x1, y1, x2, y2, sx, sy, ex, ey: Integer): Boolean;<br />
function [[doc:lcl/lclintf/radialpie.html|RadialPie]](DC: HDC; x1, y1, x2, y2, Angle1, Angle2: Integer): Boolean; <br />
<br />
The Pie function uses a two points (sx,sy) and (ex,ey) to indicate start and end of the arc. RadialPie uses Angles to indicate start and end of the arc.<br />
<br />
Pie calls TWidgetSet.Pie and RadialPie calls TWidgetSet.RadialPie. The default implementation of TWidgetSet.Pie is to convert the parameters to angles and to call TWidgetSet.RadialPie. TWidgetSet.RadialPie creates an array of points for the arc and calls TWidgetSet.Polygon.<br />
<br />
The win32 widgetset overrides TWidgetSet.Pie to call the Windows Pie function directly.<br />
<br />
{{Note| in older versions of Lazarus there existed RadialPie with angles which did the same as the current RadialPie and RadialPie, which does the same as our Pie. Those functions have been removed in Lazarus 0.9.21.}}<br />
<br />
===Interfaces===<br />
<br />
{{Interfaces}}<br />
<br />
===Adding a new unit to the LCL===<br />
First add the new unit name into allclunits.pp.<br />
<br />
To make sure the unit is registered in the components palette see the files RegisterLCL.pas and pkgfileslcl.inc, they are located in lazarus/packager.<br />
<br />
== How to create a new Widgetset ==<br />
This is a step-by-step tutorial of developing a new [[Widgetset|widgetset]]. It is based on my experience creating the basics of the new qt4 interface.<br />
<br />
To start with, why would someone want to add an Widgetset? The answer is to be able to port existing lazarus software to more platforms, without modifying their code.<br />
<br />
Now, let´s write the widgetset. First of all, you need to have pascal bindings for the widget and know how to use it. Normally this is not hard. A few hours doing basic tutorials available on the internet should be enougth to get started. If the bindings do not exist already, you need to create them. If the tutorials are on another language, translate them to pascal and make them work.<br />
<br />
Now, for Qt I utilized Den Jean qt4 bindings for pascal, and created a very basic Qt program using them:<br />
<br />
<syntaxhighlight>program qttest;<br />
<br />
uses qt4;<br />
<br />
var<br />
App: QApplicationH;<br />
MainWindow: QMainWindowH;<br />
begin<br />
App := QApplication_Create(@argc,argv);<br />
<br />
MainWindow := QMainWindow_Create;<br />
<br />
QWidget_show(MainWindow);<br />
<br />
QApplication_Exec;<br />
end.</syntaxhighlight><br />
<br />
The above project compiles and creates a qt4 program. Now we will use its code to write a new widgetset. After we are done, the lazarus program below will compile fine into a qt4 software:<br />
<br />
<syntaxhighlight>program qttest;<br />
<br />
{$mode objfpc}{$H+}<br />
<br />
uses<br />
Interfaces, Classes, Forms,<br />
{ Add your units here }<br />
qtform;<br />
<br />
begin<br />
Application.Initialize;<br />
Application.CreateForm(TForm1, Form1);<br />
Application.Run;<br />
end.</syntaxhighlight><br />
<br />
Where the form is maintained by Lazarus IDE and designed visually.<br />
<br />
The first thing to do on a new widgetset is add an empty skeleton for it. Very early development widgetsets, like qt and carbon, can serve as an skeleton.<br />
<br />
Looking at the files on the many widgets you can see the first file to be called by the lcl: Interfaces.pas This file just calls another called QtInt.pas or similar. QtInt.pas has the code for the TWidgetSet class, which we must implement. On an empty skeleton you can see that the class has various functions it must implement:<br />
<br />
<syntaxhighlight> TQtWidgetSet = Class(TWidgetSet)<br />
private<br />
App: QApplicationH;<br />
public<br />
{$I qtwinapih.inc}<br />
{$I qtlclintfh.inc}<br />
public<br />
// Application<br />
procedure AppInit(var ScreenInfo: TScreenInfo); override;<br />
procedure AppRun(const ALoop: TApplicationMainLoop); override;<br />
procedure AppWaitMessage; override;<br />
procedure AppProcessMessages; override;<br />
procedure AppTerminate; override;<br />
procedure AppMinimize; override;<br />
procedure AppBringToFront; override;<br />
public<br />
constructor Create;<br />
destructor Destroy; override;<br />
function DCGetPixel(CanvasHandle: HDC; X, Y: integer): TGraphicsColor; override;<br />
procedure DCSetPixel(CanvasHandle: HDC; X, Y: integer; AColor: TGraphicsColor); override;<br />
procedure DCRedraw(CanvasHandle: HDC); override;<br />
procedure SetDesigning(AComponent: TComponent); override;<br />
<br />
function InitHintFont(HintFont: TObject): Boolean; override;<br />
<br />
// create and destroy<br />
function CreateComponent(Sender : TObject): THandle; override; // deprecated<br />
function CreateTimer(Interval: integer; TimerFunc: TFNTimerProc): integer; override;<br />
function DestroyTimer(TimerHandle: integer): boolean; override;<br />
end;</syntaxhighlight><br />
<br />
=== How to implement a new windowed component ===<br />
<br />
Windowed components are all descendents from TWinControl. Those controls have a Handle and thus, should be created by the Widgetset. It's easy to add new windowed components to a widgetset.<br />
<br />
Let's say you want to add TQtWSCustomEdit to Qt Widgetset. To start with TCustomEdit is a descendent of TWinControl and is located on the StdCtrls unit.<br />
<br />
Now, go to QtWSStrCtrls unit and look for the declaration of TQtWSCustomEdit.<br />
<br />
<syntaxhighlight> TQtWSCustomEdit = class(TWSCustomEdit)<br />
private<br />
protected<br />
public<br />
end;</syntaxhighlight><br />
<br />
Add static methods that are declared on TWSCustomEdit and override them. The code should now look like this:<br />
<br />
<syntaxhighlight> TQtWSCustomEdit = class(TWSCustomEdit)<br />
private<br />
protected<br />
public<br />
class function CreateHandle(const AWinControl: TWinControl;<br />
const AParams: TCreateParams): HWND; override;<br />
class procedure DestroyHandle(const AWinControl: TWinControl); override;<br />
{ class function GetSelStart(const ACustomEdit: TCustomEdit): integer; override;<br />
class function GetSelLength(const ACustomEdit: TCustomEdit): integer; override;<br />
<br />
class procedure SetCharCase(const ACustomEdit: TCustomEdit; NewCase: TEditCharCase); override;<br />
class procedure SetEchoMode(const ACustomEdit: TCustomEdit; NewMode: TEchoMode); override;<br />
class procedure SetMaxLength(const ACustomEdit: TCustomEdit; NewLength: integer); override;<br />
class procedure SetPasswordChar(const ACustomEdit: TCustomEdit; NewChar: char); override;<br />
class procedure SetReadOnly(const ACustomEdit: TCustomEdit; NewReadOnly: boolean); override;<br />
class procedure SetSelStart(const ACustomEdit: TCustomEdit; NewStart: integer); override;<br />
class procedure SetSelLength(const ACustomEdit: TCustomEdit; NewLength: integer); override;<br />
<br />
class procedure GetPreferredSize(const AWinControl: TWinControl;<br />
var PreferredWidth, PreferredHeight: integer); override;}<br />
end;</syntaxhighlight><br />
<br />
The commented part of the code are procedures you need to implement for TCustomEdit to be fully functional, but just CreateHandle and DestroyHandle should be enough for it to be show on the form and be editable, so it fits our needs in this article.<br />
<br />
Hit CTRL+SHIFT+C to code complete and the implement CreateHandle and DestroyHandle. In the case of Qt4 the code will be like this:<br />
<br />
<syntaxhighlight>{ TQtWSCustomEdit }<br />
<br />
class function TQtWSCustomEdit.CreateHandle(const AWinControl: TWinControl;<br />
const AParams: TCreateParams): HWND;<br />
var<br />
Widget: QWidgetH;<br />
Str: WideString;<br />
begin<br />
// Creates the widget<br />
WriteLn('Calling QTextDocument_create');<br />
Str := WideString((AWinControl as TCustomMemo).Lines.Text);<br />
Widget := QTextEdit_create(@Str, QWidgetH(AWinControl.Parent.Handle));<br />
<br />
// Sets it's initial properties<br />
QWidget_setGeometry(Widget, AWinControl.Left, AWinControl.Top,<br />
AWinControl.Width, AWinControl.Height);<br />
<br />
QWidget_show(Widget);<br />
<br />
Result := THandle(Widget);<br />
end;<br />
<br />
class procedure TQtWSCustomEdit.DestroyHandle(const AWinControl: TWinControl);<br />
begin<br />
QTextEdit_destroy(QTextEditH(AWinControl.Handle));<br />
end;</syntaxhighlight><br />
<br />
Now uncomment the like "RegisterWSComponent(TCustomEdit, TQtWSCustomEdit);" on the bottom of the unit and that's it!<br />
<br />
You can now drop a TCustomEdit on the bottom of a form and expect it to work. :^) <br />
<br />
=== Implementing TBitmap ===<br />
<br />
To implement TBitmap it is necessary to understand TRawImage and TLazIntfImage as explained here: [[Developing with Graphics#Working with TLazIntfImage.2C TRawImage and TLazCanvas]]<br />
<br />
So, let's say you want to compile the following code:<br />
<br />
<syntaxhighlight><br />
procedure TMyForm.HandleOnPaint(Sender: TObject);<br />
var<br />
Bitmap: TBitmap;<br />
begin<br />
Bitmap := TBitmap.Create;<br />
try<br />
Bitmap.LoadFromFile('myfile.bmp');<br />
Canvas.Draw(0, 0, Bitmap);<br />
finally<br />
Bitmap.Free;<br />
end;<br />
end;</syntaxhighlight><br />
<br />
Below is the order on which functions from the widgetset interface are called when executing that code:<br />
<br />
1 - BeginPaint<br />
<br />
This will be called only if the OnPaint event sends zero as the DC for the paint event<br />
<br />
2 - GetDC(0);<br />
<br />
Just create a device context.<br />
<br />
3 - TCDWidgetSet.RawImage_QueryDescription <br />
<br />
The default implementation of this routine is good for most widgetsets<br />
<br />
4 - TCDWidgetSet.RawImage_CreateBitmaps<br />
<br />
Here you need to create a native image object and load it from RawData.Data where the information is stored based on your description of the pixel format on item 2.<br />
<br />
5 - CreateCompatibleDC(0)<br />
<br />
This creates a temporary DC just to store the image, but at this point there is no information about the image so at this point this DC is really dummy<br />
<br />
6 - SelectObject<br />
<br />
With the image as the object to be selected and the DC just created above as target DC.<br />
<br />
7 - StretchMaskBlt<br />
<br />
Finally the drawing function! DestDC is the DC allocated on BeginPaint.<br />
<br />
8 - EndPaint<br />
<br />
Again, not always utilized.<br />
<br />
=== TBitmap.LoadFromDevice for screenshot taking ===<br />
<br />
It is recomended that you first implement TBitmap before trying this step.<br />
<br />
On LCL you can use the following code takes a screenshot from the entire screen and paints it on the canvas:<br />
<br />
<syntaxhighlight>var<br />
ScreenDC: HDC;<br />
Bitmap: TBitmap;<br />
begin<br />
Bitmap := TBitmap.Create;<br />
try<br />
ScreenDC := GetDC(0);<br />
Bitmap.LoadFromDevice(ScreenDC);<br />
ReleaseDC(0, ScreenDC);<br />
Canvas.Draw(0, 0, Bitmap);<br />
finally<br />
Bitmap.Free;<br />
end;<br />
end;</syntaxhighlight><br />
<br />
If you already implemented TBitmap, there are only 2 new functions to be implemented for LoadFromDevice: GetDeviceSize and GetRawImageFromDevice<br />
<br />
Below is a big trace, covering all widgetset functions being called on a OnPaint event that takes a screenshot and paints it on the screen. This trace was taken with Qt widgetset, and may have some imperfections. The Handle numbers should be used to check which object is being utilized on the functions.<br />
<br />
<br />
[WinAPI BeginPaint] Result=-1220713544<br />
<br />
[WinAPI GetClientBounds]<br />
<br />
[WinAPI SetWindowOrgEx] DC: -1220713544 NewX: 0 NewY: 0<br />
<br />
<syntaxhighlight>Enters on Paint event<br />
<br />
Bitmap := TBitmap.Create;<br />
try<br />
ScreenDC := GetDC(0);</syntaxhighlight><br />
<br />
[WinAPI GetDC] hWnd: 0 Result: -1220712920<br />
<br />
<syntaxhighlight> Bitmap.LoadFromDevice(ScreenDC);</syntaxhighlight><br />
<br />
[WinAPI GetDeviceSize]<br />
<br />
[WinAPI GetRawImageFromDevice] SrcDC: -1220712920 SrcWidth: 0 SrcHeight: 0<br />
<br />
[WinAPI CreateBitmapFromRawImage] Width:1024 Height:768 DataSize: 3145728 CreateMask: False Bitmap:-1220746696<br />
<br />
[WinAPI GetObject] GDIObj: -1220746696 Result=84 ObjectType=Image<br />
<br />
<syntaxhighlight> ReleaseDC(0, ScreenDC);</syntaxhighlight><br />
<br />
[WinAPI ReleaseDC] hWnd: 0 DC: -1220712920<br />
<br />
<syntaxhighlight> Canvas.Draw(0, 0, Bitmap);</syntaxhighlight><br />
<br />
[WinAPI CreateCompatibleDC] DC: 0<br />
<br />
[WinAPI GetDC] hWnd: 0 Result: -1220712920<br />
<br />
[WinAPI SelectObject] DC=-1220712920 GDIObj=-1220746696 Result=0 ObjectType=Image<br />
<br />
[WinAPI StretchMaskBlt] DestDC:-1220713544 SrcDC:-1220712920 Image:137185120 X:0 Y:0 W:1024 H:768 XSrc:0 YSrc:0 WSrc:1024 HSrc:768<br />
<br />
<syntaxhighlight>finally<br />
Bitmap.Free;<br />
end;</syntaxhighlight><br />
<br />
[WinAPI SelectObject] DC=-1220712920 GDIObj=0 Invalid GDI Object<br />
<br />
[WinAPI DeleteObject] GDIObject: -1220746696 Result=False ObjectType=Image<br />
<br />
<pre><br />
Now exited the OnPaint event<br />
</pre><br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
[WinAPI SetWindowOrgEx] DC: -1220713544 NewX: -152 NewY: -246<br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
TWidgetSet.InitializeCriticalSection<br />
<br />
TWidgetSet.EnterCriticalSection<br />
<br />
[WinAPI SelectObject] DC=-1220713544 GDIObj=0 Invalid GDI Object<br />
<br />
[WinAPI MoveToEx] DC:-1220713544 X:0 Y:0<br />
<br />
[WinAPI SelectObject] DC=-1220713544 GDIObj=-1220746760 Result=-1220746856 ObjectType=Brush<br />
<br />
[WinAPI SelectObject] DC=-1220713544 GDIObj=-1220746856 Result=-1220746856 ObjectType=Brush<br />
<br />
TWidgetSet.LeaveCriticalSection<br />
<br />
[WinAPI SetWindowOrgEx] DC: -1220713544 NewX: 0 NewY: 0<br />
<br />
[WinAPI EndPaint] Handle: -1220611768 PS.HDC: -1220713544<br />
<br />
=== Implementing drawing in the OnPaint event of a form or another control ===<br />
<br />
For drawing in the OnPaint event of a form, the event itself comes from the underlaying widgetset library. The LCL interface should handle this event and create an appropriate DC object on the event handler and then call LCLSendPaintMsg. Besides that one should also implement the corresponding drawing methods, such as Rectangle or ExtTextOut. Pen, Brush and Font related routines might also be useful.<br />
<br />
Here is the OnPaint event handler from the Cocoa widgetset which shows how it calls LCLSentPaintMsg:<br />
<br />
<syntaxhighlight><br />
procedure TLCLCommonCallback.Draw(ControlContext: NSGraphicsContext;<br />
const bounds, dirty:NSRect);<br />
var<br />
struct : TPaintStruct;<br />
begin<br />
if not Assigned(Context) then Context:=TCocoaContext.Create;<br />
<br />
Context.ctx:=ControlContext;<br />
if Context.InitDraw(Round(bounds.size.width), Round(bounds.size.height)) then<br />
begin<br />
FillChar(struct, SizeOf(TPaintStruct), 0);<br />
struct.hdc := HDC(Context);<br />
{$IFDEF VerboseWinAPI}<br />
DebugLn(Format('[TLCLCommonCallback.Draw] OnPaint event started context: %x', [HDC(context)]));<br />
{$ENDIF}<br />
LCLSendPaintMsg(Target, HDC(Context), @struct);<br />
{$IFDEF VerboseWinAPI}<br />
DebugLn('[TLCLCommonCallback.Draw] OnPaint event ended');<br />
{$ENDIF}<br />
end;<br />
end;<br />
</syntaxhighlight><br />
<br />
And a list of WinAPI routines which were called when running this event:<br />
<br />
<pre><br />
[TCocoaWidgetSet.GetDC] hWnd: 0 Result: 12400C0<br />
[TLCLCommonCallback.Draw] OnPaint event started context: 1240340<br />
TCocoaWidgetSet.CreatePenIndirect<br />
TCocoaWidgetSet.SelectObject DC: 1240340 GDIObj: 10EC460<br />
TCocoaWidgetSet.SelectObject Result: 0<br />
TCocoaWidgetSet.SelectObject DC: 1240340 GDIObj: 10EBF00<br />
TCocoaWidgetSet.SelectObject Result: 0<br />
[TCocoaWidgetSet.Rectangle] DC: 1240340 X1: 100 Y1: 100 X2: 200 Y2: 200<br />
TCocoaWidgetSet.SelectObject DC: 1240340 GDIObj: 10EC4A0<br />
TCocoaWidgetSet.SelectObject Result: 0<br />
[TCocoaWidgetSet.GetTextExtentPoint] DC: 1240340 Str: Some text Count: 9<br />
[TCocoaWidgetSet.GetTextExtentPoint] Size: 65,17<br />
[TLCLCommonCallback.Draw] OnPaint event ended<br />
</pre><br />
<br />
=== Implementing TLabel ===<br />
<br />
Implementing TLabel is particularly hard, despite it being such a basic component, because it requires that almost all painting be implemented. TLabel is not a windowed control, instead it depends on paint messages to be drawn directly into the form canvas.<br />
<br />
Before trying to get TLabel working it is recomended to test if drawing functions such as Rectangle work inside a form's OnPaint event.<br />
<br />
Several WinAPI methods need to be implemented, particularly:<br />
<br />
'''Device Context Methods'''<br />
<br />
BeginPaint, GetDC, EndPaint, ReleaseDC, CreateCompatibleDC<br />
<br />
see [[Device Contexts and GDI objects in the LCL interfaces]]<br />
<br />
'''GDI Objects Methods'''<br />
<br />
SelectObject, DeleteObject, CreateFontIndirect, CreateFontIndirectEx<br />
<br />
'''Miscelaneous functions'''<br />
<br />
InvalidateRect, GetClientBounds, SetWindowOrgEx<br />
<br />
'''Text drawing Methods'''<br />
<br />
DrawText. Instead of implementing DrawText one can also use the default TWidgetSet.DrawText, like the Carbon and Cocoa widgetsets do. But in this case it is necessary that one implements at least GetTextMetrics, GetTextExtentPoint and ExtTextOut. Without GetTextMetrics a form with a label will crash because the autosize will not be able to calculate the appropriate size for the label.<br />
<br />
'''Region functions to determine if the control is behind another'''<br />
<br />
CombineRgn, CreateRectRgn, GetClipRGN, RectVisible<br />
<br />
<br />
Below is the order in which paint procedures are called on a form with only one TLabel, to better understand the painting sequence:<br />
<br />
1 - GetDC is called once on software startup with hWnd = 0<br />
<br />
2 - The form is shown<br />
<br />
3 - GetDC is called again (this wouldn't happen without the label). A<br />
few font related functions are called, as well as DrawText with<br />
CalcRect set to True to calculate the size of the label.<br />
<br />
4 - InvalidateRect is called on the form canvas<br />
<br />
5 - Control goes back to the operating system until a paint message comes from the widgetset<br />
<br />
6 - BeginPaint is called, and at this point code on OnPaint event of the form will be executed<br />
<br />
7 - DrawText is called again with CalcRect set to false<br />
<br />
8 - The Painting ends.<br />
<br />
=== Implementing visibility for forms and controls and window state===<br />
<br />
The code that controls visibility is split between visibility for forms, and for controls<br />
<br />
'''Visibility for forms and window state'''<br />
<br />
This part also controls the state of the window (minimized, maximized or normal). It is implemented as a copy of the Windows API function ShowWindow, so you must implemente the TMyWidgetset.ShowWindow on the file mywinapi.inc Don´t forget to also add a header to the file mywinapih.inc<br />
<br />
Below is code that implements this function on the Qt widgetset. It should be very easy to understand, copy and implement on your own widgetset. You can also take a look how Gtk implements this. On Windows, the Windows API is called directly, of course, so there is no code to look at.<br />
<br />
<syntaxhighlight>{------------------------------------------------------------------------------<br />
function ShowWindow(hWnd: HWND; nCmdShow: Integer): Boolean;<br />
<br />
nCmdShow:<br />
SW_SHOWNORMAL, SW_MINIMIZE, SW_SHOWMAXIMIZED<br />
------------------------------------------------------------------------------}<br />
function TQtWidgetSet.ShowWindow(hWnd: HWND; nCmdShow: Integer): Boolean;<br />
var<br />
Widget: QWidgetH;<br />
begin<br />
{$ifdef VerboseQtWinAPI}<br />
WriteLn('WinAPI ShowWindow');<br />
{$endif}<br />
<br />
Result := False;<br />
<br />
Widget := QWidgetH(hWnd);<br />
<br />
// if Widget = nil then RaiseException('TQtWidgetSet.ShowWindow hWnd is nil');<br />
<br />
case nCmdShow of<br />
<br />
SW_SHOW: QWidget_setVisible(Widget, True);<br />
<br />
SW_SHOWNORMAL: QWidget_showNormal(Widget);<br />
<br />
SW_MINIMIZE: QWidget_setWindowState(Widget, QtWindowMinimized);<br />
<br />
SW_SHOWMINIMIZED: QWidget_showMinimized(Widget);<br />
<br />
SW_SHOWMAXIMIZED: QWidget_showMaximized(Widget);<br />
<br />
SW_HIDE: QWidget_setVisible(Widget, False);<br />
<br />
end;<br />
<br />
Result := True;<br />
end;</syntaxhighlight><br />
<br />
'''Visibility for controls'''<br />
<br />
For controls inside a form you need to implement TMyWSWinControl.ShowHide class function that resides on the TMyWSWinControl class on the file mywscontrols.pp<br />
<br />
Remember that most controls are descendent from TWinControl, so implementing this function there will guarantee that the Visible property is implemented for all standard controls that have it. Below is a sample code for Qt widgetset.<br />
<br />
<syntaxhighlight>{------------------------------------------------------------------------------<br />
Method: TQtWSWinControl.ShowHide<br />
Params: AWinControl - the calling object<br />
<br />
Returns: Nothing<br />
<br />
Shows or hides a widget.<br />
------------------------------------------------------------------------------}<br />
class procedure TQtWSWinControl.ShowHide(const AWinControl: TWinControl);<br />
begin<br />
if AWinControl = nil then exit;<br />
<br />
if not AWinControl.HandleAllocated then exit;<br />
<br />
if AWinControl.HandleObjectShouldBeVisible then<br />
QWidget_setVisible(TQtWidget(AWinControl.Handle).Widget, True)<br />
else QWidget_setVisible(TQtWidget(AWinControl.Handle).Widget, False);<br />
end;</syntaxhighlight><br />
<br />
=== Implementing TStrings based Components===<br />
Some components use a TStrings to store the information they display, such as: TCustomMemo, TCustomListBox and TCustomComboBox.<br />
<br />
To implement those it is not enougth to only implement their functions on the TQtCustomMemo class for example. One of the functions to implement will be called GetStrings, which looks like this:<br />
<br />
<syntaxhighlight>class function TQtWSCustomListBox.GetStrings(const ACustomListBox: TCustomListBox): TStrings;<br />
var<br />
ListWidgetH: QListWidgetH;<br />
begin<br />
ListWidgetH := QListWidgetH((TQtWidget(ACustomListBox.Handle).Widget));<br />
Result := TQtListStrings.Create(ListWidgetH, ACustomListBox);<br />
end;</syntaxhighlight><br />
<br />
This function must return a TStrings descendent designed to detect when strings are added to or removed from the string list and to send this information to the widgetset to update the control. For example, the following declaration shows what TQtListStrings looks like:<br />
<br />
<syntaxhighlight> TQtListStrings = class(TStrings)<br />
private<br />
FListChanged: Boolean; // StringList and QtListWidget out of sync<br />
FStringList: TStringList; // Holds the items to show<br />
FQtListWidget: QListWidgetH; // Qt Widget<br />
FOwner: TWinControl; // Lazarus Control Owning ListStrings<br />
FUpdating: Boolean; // We're changing Qt Widget<br />
procedure InternalUpdate;<br />
procedure ExternalUpdate(var Astr: TStringList; Clear: Boolean = True);<br />
procedure IsChanged; // OnChange triggered by program action<br />
protected<br />
function GetTextStr: string; override;<br />
function GetCount: integer; override;<br />
function Get(Index : Integer) : string; override;<br />
//procedure SetSorted(Val : boolean); virtual;<br />
public<br />
constructor Create(ListWidgetH : QListWidgetH; TheOwner: TWinControl);<br />
destructor Destroy; override;<br />
procedure Assign(Source : TPersistent); override;<br />
procedure Clear; override;<br />
procedure Delete(Index : integer); override;<br />
procedure Insert(Index : integer; const S: string); override;<br />
procedure SetText(TheText: PChar); override;<br />
//procedure Sort; virtual;<br />
public<br />
//property Sorted: boolean read FSorted write SetSorted;<br />
property Owner: TWinControl read FOwner;<br />
function ListChangedHandler(Sender: QObjectH; Event: QEventH): Boolean; cdecl;<br />
end;</syntaxhighlight><br />
<br />
You can see its implementation in the qtobjects.pas unit of the qt interface<br />
<br />
===Implementing Menus===<br />
<br />
Menus are available on the LCL to create main menus or popup menus. A TMenu is the owner of a larger menu structure with many items. Items can have subitems, and don't need extra TMenus.<br />
<br />
Also remember that on LCL the handle is only created when needed and at that time all properties of the controls are already initialized. This helps a lot on widgetsets where depending on the properties of a menu item it can be of one class or another, like Qt.<br />
<br />
The following things need to be implemented in order for the menus to work:<br />
<br />
1) All methods on the QtWSMenus unit, which will implement menu creation and modification<br />
<br />
2) function TWinCEWidgetSet.SetMenu(AWindowHandle: HWND; AMenuHandle: HMENU): Boolean; from the wincewinapi.inc file, which will implement support for a main menu associated with a window.<br />
<br />
====Menu Creation Order====<br />
<br />
<br />
One important thing to understand when implementing menus, is in which order they are created. For example, we want to create the following menu structure:<br />
<br />
[[Image:Menu_creation_order.png]]<br />
<br />
And when our application is executed, there will be a 'Creating MenuItem' message with the caption of the menu each time TQtWSMenuItem.CreateHandle is called, and a 'Creating Menu' message with the name of the menu (TMenu descendents don't have a caption), each time TQtWSMenu.CreateHandle is called.<br />
<br />
Here is the resulting output of such software:<br />
<br />
<pre><br />
Creating Menu. Name: MainMenu1<br />
Creating MenuItem: Item1 Parent=Menu.Items : TMenuItem<br />
Creating MenuItem: SubItem11 Parent=Item1 : TMenuItem<br />
Creating MenuItem: SubItem12 Parent=Item1 : TMenuItem<br />
Creating MenuItem: SubItem13 Parent=Item1 : TMenuItem<br />
Creating MenuItem: SubItem14 Parent=Item1 : TMenuItem<br />
Creating MenuItem: SubSubItem141 Parent=SubItem14 : TMenuItem<br />
Creating MenuItem: SubSubItem142 Parent=SubItem14 : TMenuItem<br />
Creating MenuItem: SubSubItem143 Parent=SubItem14 : TMenuItem<br />
Creating MenuItem: SubSubItem144 Parent=SubItem14 : TMenuItem<br />
Creating MenuItem: Item2 Parent=Menu.Items : TMenuItem<br />
Creating MenuItem: SubItem21 Parent=Item2 : TMenuItem<br />
Creating MenuItem: SubItem22 Parent=Item2 : TMenuItem<br />
Creating MenuItem: SubItem23 Parent=Item2 : TMenuItem<br />
Creating MenuItem: Item3 Parent=Menu.Items : TMenuItem<br />
Creating MenuItem: Item4 Parent=Menu.Items : TMenuItem<br />
</pre><br />
<br />
For all MenuItems one can use GetParentMenu to get their parent owner: Menu (TMainMenu).<br />
<br />
===Control enabling/disabling===<br />
<br />
The current way to set control enabling/disabling is by implementing the winapi EnableWindow. This API should work generically on any control. It should enable/disable mouse and keyboard input for the specified window or control, but also mark it as uneditable by the user, by making it greyed for example.<br />
<br />
<syntaxhighlight>{------------------------------------------------------------------------------<br />
Method: EnableWindow<br />
Params: HWnd - handle to window<br />
BEnable - whether to enable the window<br />
Returns: If the window was previously disabled<br />
<br />
Enables or disables mouse and keyboard input to the specified window or<br />
control.<br />
------------------------------------------------------------------------------}<br />
function TWin32WidgetSet.EnableWindow(hWnd: HWND; bEnable: Boolean): Boolean;</syntaxhighlight><br />
<br />
===Shaped Windows===<br />
<br />
Windows can be shaped based on a TBitmap or on a TRegion. The region is the visible part.<br />
<br />
To implement shaped windows based on a TBitmap, implement TWSWinControl.setShape<br />
<br />
To implement shaped windows based on a TRegion implement LCLIntf.SetWindowRgn<br />
<br />
See also: [[LCL Tips#Creating a non-rectangular window or control]]<br />
<br />
===System colors===<br />
<br />
Some color constants are actually system colors, like clBtnFace, clForm, clWindow, etc, etc.<br />
<br />
To implement support for system colors the WinAPI routine GetSysColor should be implemented:<br />
<br />
function GetSysColor(nIndex: Integer): DWORD; override;<br />
<br />
And here is a snip of the color constants which should be supported. Check LCLType for the latest values:<br />
<br />
<syntaxhighlight><br />
//==============================================<br />
// API system Color constants pbd<br />
// note these are usually shown ORed with<br />
// $80000000 as these would have interfered with<br />
// other MS color enumerations<br />
// GetSysColor and SetSysColor expects the values<br />
// below<br />
//==============================================<br />
<br />
type<br />
COLORREF = LongInt;<br />
TColorRef = COLORREF;<br />
<br />
const<br />
CLR_INVALID = TColorRef($FFFFFFFF);<br />
<br />
COLOR_SCROLLBAR = 0;<br />
COLOR_BACKGROUND = 1;<br />
COLOR_ACTIVECAPTION = 2;<br />
COLOR_INACTIVECAPTION = 3;<br />
COLOR_MENU = 4;<br />
COLOR_WINDOW = 5;<br />
COLOR_WINDOWFRAME = 6;<br />
COLOR_MENUTEXT = 7;<br />
COLOR_WINDOWTEXT = 8;<br />
COLOR_CAPTIONTEXT = 9;<br />
COLOR_ACTIVEBORDER = 10;<br />
COLOR_INACTIVEBORDER = 11;<br />
COLOR_APPWORKSPACE = 12;<br />
COLOR_HIGHLIGHT = 13;<br />
COLOR_HIGHLIGHTTEXT = 14;<br />
COLOR_BTNFACE = 15;<br />
COLOR_BTNSHADOW = 16;<br />
COLOR_GRAYTEXT = 17;<br />
COLOR_BTNTEXT = 18;<br />
COLOR_INACTIVECAPTIONTEXT = 19;<br />
COLOR_BTNHIGHLIGHT = 20;<br />
COLOR_3DDKSHADOW = 21;<br />
COLOR_3DLIGHT = 22;<br />
COLOR_INFOTEXT = 23;<br />
COLOR_INFOBK = 24;<br />
// PBD: 25 is unassigned in all the docs I can find<br />
// if someone finds what this is supposed to be then fill it in<br />
// note defaults below, and cl[ColorConst] in graphics<br />
COLOR_HOTLIGHT = 26;<br />
COLOR_GRADIENTACTIVECAPTION = 27;<br />
COLOR_GRADIENTINACTIVECAPTION = 28;<br />
COLOR_MENUHILIGHT = 29;<br />
COLOR_MENUBAR = 30;<br />
<br />
COLOR_FORM = 31;<br />
<br />
COLOR_ENDCOLORS = COLOR_FORM;<br />
<br />
COLOR_DESKTOP = COLOR_BACKGROUND;<br />
COLOR_3DFACE = COLOR_BTNFACE;<br />
COLOR_3DSHADOW = COLOR_BTNSHADOW;<br />
COLOR_3DHIGHLIGHT = COLOR_BTNHIGHLIGHT;<br />
COLOR_3DHILIGHT = COLOR_BTNHIGHLIGHT;<br />
COLOR_BTNHILIGHT = COLOR_BTNHIGHLIGHT;<br />
<br />
MAX_SYS_COLORS = COLOR_ENDCOLORS;<br />
SYS_COLOR_BASE = TColorRef($80000000);</syntaxhighlight><br />
<br />
===ShowMessage===<br />
<br />
These standard dialogs are implemented purely in the LCL in the following places:<br />
<br />
* Class TPromptDialog file lcl/include/promptdialog.inc<br />
<br />
===SpinEdit===<br />
<br />
Both TFloatSpinEdit and TSpinEdit are implemented in the class TWSFloatSpinEdit.<br />
<br />
===Clipboard===<br />
<br />
Clipboard support is implemented in lclintf by implementing Windows API routines. The routines are:<br />
<br />
<syntaxhighlight>function ClipboardFormatToMimeType(FormatID: TClipboardFormat): string; {$IFDEF IF_BASE_MEMBER}virtual;{$ENDIF}<br />
function ClipboardGetData(ClipboardType: TClipboardType;<br />
FormatID: TClipboardFormat; Stream: TStream): boolean; {$IFDEF IF_BASE_MEMBER}virtual;{$ENDIF}<br />
// ! ClipboardGetFormats: List will be created. You must free it yourself with FreeMem(List) !<br />
function ClipboardGetFormats(ClipboardType: TClipboardType;<br />
var Count: integer; var List: PClipboardFormat): boolean; {$IFDEF IF_BASE_MEMBER}virtual;{$ENDIF}<br />
function ClipboardGetOwnerShip(ClipboardType: TClipboardType;<br />
OnRequestProc: TClipboardRequestEvent; FormatCount: integer;<br />
Formats: PClipboardFormat): boolean; {$IFDEF IF_BASE_MEMBER}virtual;{$ENDIF}<br />
function ClipboardRegisterFormat(const AMimeType: string): TClipboardFormat; {$IFDEF IF_BASE_MEMBER}virtual;{$ENDIF}</syntaxhighlight><br />
<br />
===TSpeedButton===<br />
<br />
This control is a TGraphicControl descendent, so it has no handle and paints itself. To retain native look, it uses the function LCLIntf.DrawFrameControl to paint itself, so implement this function to have this control working. Naturally, lot's of other DC, WindowOrg, Text Drawing and Painting routines will have to be working, as explained for TLabel.<br />
<br />
===TRadioButton and TCheckButton===<br />
<br />
'''Messages:'''<br />
<br />
Basically the Widgetset must do:<br />
<br />
*Send LM_CHANGE when a radio button is unchecked/checked (LCL will take care if OnClick will be called or not)<br />
*Dont send LM_CHANGE when TWSCustomCheckBox.SetState is called (SetChecked)<br />
<br />
See also this bug report: http://bugs.freepascal.org/view.php?id=13939<br />
<br />
===FullScreen support===<br />
<br />
FullScreen is implemented as a Windows state wsFullScreen, and as such is implemented in LCLIntf.ShowWindow where the constant SW_SHOWFULLSCREEN should be handled.<br />
<br />
== An example of how the LCL interfaces work ==<br />
<br />
Below is a simple example. Suppose you have developed a trayicon component. How would you implement it in the LCL to work correctly on the various different supported platforms?<br />
<br />
You would need to generate the following files:<br />
<br />
\trayicon.pas<br />
<br />
\wstrayicon.pas<br />
<br />
\gtk\gtkwstrayicon.pas<br />
<br />
\gtk\trayintf.pas<br />
<br />
\win32\win32wstrayicon.pas<br />
<br />
\win32\trayintf.pas<br />
<br />
<br />
Providing separate wsXXX.pas and \$(LCLWidgetType)\XXXintf.pas files avoids the need for ifdefs altogether. You will need to add as a unit path $(LCLWidgetType) to the XXXintf.pas file in order initialize the correct trayintf.pas file, which in turn initializes the correct WS Tray class.<br />
<br />
Inside trayicon.pas you include wstrayicon. Derive your main class from an LCL class, and only use wstrayicon in its implementation. All LCL classes that communicate with a widgetset, must be derived from [[doc:/lcl/lclclasses/tlclcomponent.html|TLCLComponent]] declared in the [[doc:/lcl/lclclasses|LCLClasses]] unit.<br />
<br />
<syntaxhighlight>unit TrayIcon;<br />
<br />
interface<br />
<br />
type<br />
TTrayIcon = class(TLCLComponent)<br />
public<br />
procedure DoTray;<br />
end;<br />
<br />
implementation<br />
<br />
uses wstrayicon;<br />
<br />
procedure TTrayIcon.DoTray;<br />
begin<br />
// Call wstrayicon<br />
end;<br />
<br />
end.</syntaxhighlight><br />
<br />
in trayintf you use gtkwstrayicon or win32trayicon depending on which<br />
trayintf file it is.<br />
<br />
in wstrayicon you create a class like so:<br />
<br />
<syntaxhighlight>unit WSTrayIcon;<br />
<br />
uses WSLCLClasses, Controls, TrayIcon; // and other things as well<br />
<br />
TWSTrayIconClass = class of TWSTrayIcon;<br />
TWSTrayIcon = class(TWSWinControl);<br />
public<br />
class procedure EmbedTrayIcon(const ATrayIcon: TCustomTrayIcon);<br />
virtual; // these must all be virtual and class procedures!!<br />
class procedure RemoveTrayIcon(const ATrayIcon: TCustomTrayIcon); virtual;<br />
....<br />
end;<br />
...<br />
<br />
implementation<br />
<br />
procedure TWSTrayIcon.EmbedTrayIcon(const ATrayIcon: TCustomTrayIcon);<br />
begin<br />
//do nothing<br />
end;<br />
<br />
procedure TWSTrayIcon.RemoveTrayIcon(const ATrayIcon: TCustomTrayIcon);<br />
begin<br />
//do nothing<br />
end;</syntaxhighlight><br />
<br />
now in gtkwstrayicon.pas do this:<br />
<br />
<syntaxhighlight>uses WSTrayIcon, WSLCLClasses, Controls, TrayIcon, gtk, gdk;<br />
<br />
<br />
TGtkWSTrayIcon = class(TWSTrayIcon);<br />
private<br />
class function FindSystemTray(const ATrayIcon: TCustomTrayIcon):<br />
TWindow; virtual;<br />
public<br />
class procedure EmbedTrayIcon(const ATrayIcon: TCustomTrayIcon); override;<br />
class procedure RemoveTrayIcon(const ATrayIcon: TCustomTrayIcon);<br />
override;<br />
class function CreateHandle(const AWinControl: TWinControl; const<br />
AParams: TCreateParams): HWND; override;<br />
....<br />
end;<br />
...<br />
<br />
implementation<br />
<br />
procedure TGtkWSTrayIcon.CreateHandle(const AWinControl: TWinControl;<br />
const AParams: TCreateParams): HWND;<br />
var<br />
WidgetInfo: PWidgetInfo;<br />
begin<br />
<br />
Result := gtk_plug_new;<br />
WidgetInfo := CreateWidgetInfo(AWinControl, Result); // it's something<br />
like this anyway<br />
TGtkWSWincontrolClass(WidgetSetClass).SetCallbacks(AWinControl);<br />
// and more stuff<br />
end;<br />
<br />
function TGtkWSTrayIcon.FindSystemTray(const ATrayIcon:<br />
TCustomTrayIcon): TWindow;<br />
begin<br />
// do something<br />
end;<br />
<br />
<br />
procedure TGtkWSTrayIcon.EmbedTrayIcon(const ATrayIcon: TCustomTrayIcon);<br />
var<br />
SystemTray: TWindow;<br />
begin<br />
SystemTray := FindSystemTray(ATrayIcon);<br />
//do something<br />
end;<br />
<br />
procedure TGtkWSTrayIcon.RemoveTrayIcon(const ATrayIcon: TCustomTrayIcon);<br />
begin<br />
//do something<br />
end;<br />
<br />
......<br />
<br />
initialization<br />
<br />
RegisterWSComponent(TCustomTrayIcon, TGtkWSTrayIcon); //this is very<br />
important!!!<br />
<br />
end.</syntaxhighlight><br />
<br />
then finally in trayicon.pas you go as normal<br />
<br />
<syntaxhighlight>uses WSTrayIcon; //etc. you DON'T include GtkWSTrayIcon here!<br />
<br />
TCustomTrayIcon = class(TWinControl)<br />
public<br />
procedure EmbedControl;<br />
....<br />
end;<br />
<br />
...<br />
procedure TTrayIcon.EmbedControl;<br />
begin<br />
TWSTrayIconClass(WidgetSetClass).EmbedControl(Self);<br />
<br />
end;</syntaxhighlight><br />
<br />
----<br />
This document is work in progress. You can help by writing sections of this document. If you cannot find the information you are looking for in this document, please add your question to the [[Talk:LCL Internals|discussion page]]. This will help us to write documentation at a level that is neither too simple nor too complicated, and fully cover the areas that people want to know about.<br />
<br />
[[Category:LCL]]<br />
[[Category:Lazarus internals]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=LCL_Internals&diff=86375LCL Internals2015-02-13T12:57:24Z<p>Sekelsenmat: /* Minimum Toolkit versions */</p>
<hr />
<div>{{LCL Internals}}<br />
<br />
{{Other_Interfaces}}<br />
<br />
== Minimum Toolkit versions ==<br />
<br />
{| class="wikitable sortable"<br />
! Lazarus version !! Min. FPC !! Min. Gtk 2 !! Min. Qt 4 !! Min. Windows !! Min. Windows CE !! Min. Mac OS X (Carbon) !! Min. Mac OS X (Cocoa) !! Min. Req. of LCL-CustomDrawn<br />
|-<br />
|0.9.24<br />
|2.2.0<br />
|2.6+<br />
|4.2+<br />
|Windows 98+<br />
|Recommended 4.0+<br />
|10.4<br />
|N/A<br />
|N/A<br />
|-<br />
|0.9.26<br />
|2.2.2<br />
|2.6+<br />
|4.3+<br />
|Windows 98+<br />
|Recommended 4.0+<br />
|10.4<br />
|N/A<br />
|N/A<br />
|-<br />
|0.9.28<br />
|2.2.4<br />
|2.8+<br />
|4.5+<br />
|Windows 98+<br />
|Recommended 4.0+<br />
|10.4<br />
|N/A<br />
|N/A<br />
|-<br />
|0.9.30<br />
|2.4.0<br />
|2.8+<br />
|4.5+<br />
|Windows 98+<br />
|Recommended 5.0+<br />
|10.4<br />
|N/A<br />
|N/A<br />
|-<br />
|0.9.31<br />
|2.4.4<br />
|2.8+<br />
|4.5+<br />
|Windows 98+<br />
|Recommended 5.0+<br />
|10.4<br />
|10.6<br />
|Android 2.2+, Windows 2000+, X11, Mac OS X 10.6+<br />
|-<br />
|1.2.6<br />
|2.6.4<br />
|2.8+<br />
|4.5...4.8.4 with pre-built Qt4Pas.dll, 4.8.5+ requires a different Qt4Pas.dll<br />
|Windows 98+<br />
|Recommended 5.0+<br />
|10.4<br />
|10.6<br />
|Android 2.2+, Windows 2000+, X11, Mac OS X 10.6+<br />
|}<br />
<br />
== Internals of the LCL ==<br />
<br />
There is the LCL, and the "interface". The LCL is the part that is platform independent, and it resides in the lazarus/lcl/ directory. This directory contains mainly class definitions. Many of the different controls are actually implemented in the lazarus/lcl/include/ directory in the various .inc files. This is to find the implementation of a specific control, TCustomMemo for example, faster (which is in custommemo.inc). Every .inc starts with a line {%MainUnit ...} to define where it is included.<br />
<br />
Then there is the "interface" which lives in a subdirectory of the lazarus/lcl/interfaces/ directory. The gtk interface is in gtk/, win32 in win32/, etc. They all have a Interfaces unit, which is used by the lcl and creates the main interface object. Usually the main interface object is defined in XXint.pp (win32int.pp), and implemented in various inc files, XXobject.inc, for the interface specific methods, XXwinapi.inc for winapi implementation methods, XXlistsl.inc for implementation of the stringlist used by the TComboBox, TListBox, and other such controls, XXcallback.inc for handling of widget events and taking appropriate action to notify the LCL.<br />
<br />
Every control has a WidgetSetClass property which is of the 'mirror' class in the interfaces directory, for example: mirror of TCustomEdit is TWSCustomEdit, which methods are implemented by TWin32WSCustomEdit in win32wsstdctrls. This is the way the LCL communicates with the interface, and how it lets the interface do things.<br />
<br />
Communication of interface back to LCL is mostly done by sending messages, usually 'DeliverMessage' which calls TControl.Perform(<message_id>, wparam, lparam) with wparam and lparam being the extra info for the message.<br />
<br />
=== Pie and RadialPie ===<br />
The LCLIntf unit contains two functions to draw pie-shapes:<br />
function [[doc:lcl/lclintf/pie.html|Pie]](DC: HDC; x1, y1, x2, y2, sx, sy, ex, ey: Integer): Boolean;<br />
function [[doc:lcl/lclintf/radialpie.html|RadialPie]](DC: HDC; x1, y1, x2, y2, Angle1, Angle2: Integer): Boolean; <br />
<br />
The Pie function uses a two points (sx,sy) and (ex,ey) to indicate start and end of the arc. RadialPie uses Angles to indicate start and end of the arc.<br />
<br />
Pie calls TWidgetSet.Pie and RadialPie calls TWidgetSet.RadialPie. The default implementation of TWidgetSet.Pie is to convert the parameters to angles and to call TWidgetSet.RadialPie. TWidgetSet.RadialPie creates an array of points for the arc and calls TWidgetSet.Polygon.<br />
<br />
The win32 widgetset overrides TWidgetSet.Pie to call the Windows Pie function directly.<br />
<br />
{{Note| in older versions of Lazarus there existed RadialPie with angles which did the same as the current RadialPie and RadialPie, which does the same as our Pie. Those functions have been removed in Lazarus 0.9.21.}}<br />
<br />
===Interfaces===<br />
<br />
{{Interfaces}}<br />
<br />
===Adding a new unit to the LCL===<br />
First add the new unit name into allclunits.pp.<br />
<br />
To make sure the unit is registered in the components palette see the files RegisterLCL.pas and pkgfileslcl.inc, they are located in lazarus/packager.<br />
<br />
== How to create a new Widgetset ==<br />
This is a step-by-step tutorial of developing a new [[Widgetset|widgetset]]. It is based on my experience creating the basics of the new qt4 interface.<br />
<br />
To start with, why would someone want to add an Widgetset? The answer is to be able to port existing lazarus software to more platforms, without modifying their code.<br />
<br />
Now, let´s write the widgetset. First of all, you need to have pascal bindings for the widget and know how to use it. Normally this is not hard. A few hours doing basic tutorials available on the internet should be enougth to get started. If the bindings do not exist already, you need to create them. If the tutorials are on another language, translate them to pascal and make them work.<br />
<br />
Now, for Qt I utilized Den Jean qt4 bindings for pascal, and created a very basic Qt program using them:<br />
<br />
<syntaxhighlight>program qttest;<br />
<br />
uses qt4;<br />
<br />
var<br />
App: QApplicationH;<br />
MainWindow: QMainWindowH;<br />
begin<br />
App := QApplication_Create(@argc,argv);<br />
<br />
MainWindow := QMainWindow_Create;<br />
<br />
QWidget_show(MainWindow);<br />
<br />
QApplication_Exec;<br />
end.</syntaxhighlight><br />
<br />
The above project compiles and creates a qt4 program. Now we will use its code to write a new widgetset. After we are done, the lazarus program below will compile fine into a qt4 software:<br />
<br />
<syntaxhighlight>program qttest;<br />
<br />
{$mode objfpc}{$H+}<br />
<br />
uses<br />
Interfaces, Classes, Forms,<br />
{ Add your units here }<br />
qtform;<br />
<br />
begin<br />
Application.Initialize;<br />
Application.CreateForm(TForm1, Form1);<br />
Application.Run;<br />
end.</syntaxhighlight><br />
<br />
Where the form is maintained by Lazarus IDE and designed visually.<br />
<br />
The first thing to do on a new widgetset is add an empty skeleton for it. Very early development widgetsets, like qt and carbon, can serve as an skeleton.<br />
<br />
Looking at the files on the many widgets you can see the first file to be called by the lcl: Interfaces.pas This file just calls another called QtInt.pas or similar. QtInt.pas has the code for the TWidgetSet class, which we must implement. On an empty skeleton you can see that the class has various functions it must implement:<br />
<br />
<syntaxhighlight> TQtWidgetSet = Class(TWidgetSet)<br />
private<br />
App: QApplicationH;<br />
public<br />
{$I qtwinapih.inc}<br />
{$I qtlclintfh.inc}<br />
public<br />
// Application<br />
procedure AppInit(var ScreenInfo: TScreenInfo); override;<br />
procedure AppRun(const ALoop: TApplicationMainLoop); override;<br />
procedure AppWaitMessage; override;<br />
procedure AppProcessMessages; override;<br />
procedure AppTerminate; override;<br />
procedure AppMinimize; override;<br />
procedure AppBringToFront; override;<br />
public<br />
constructor Create;<br />
destructor Destroy; override;<br />
function DCGetPixel(CanvasHandle: HDC; X, Y: integer): TGraphicsColor; override;<br />
procedure DCSetPixel(CanvasHandle: HDC; X, Y: integer; AColor: TGraphicsColor); override;<br />
procedure DCRedraw(CanvasHandle: HDC); override;<br />
procedure SetDesigning(AComponent: TComponent); override;<br />
<br />
function InitHintFont(HintFont: TObject): Boolean; override;<br />
<br />
// create and destroy<br />
function CreateComponent(Sender : TObject): THandle; override; // deprecated<br />
function CreateTimer(Interval: integer; TimerFunc: TFNTimerProc): integer; override;<br />
function DestroyTimer(TimerHandle: integer): boolean; override;<br />
end;</syntaxhighlight><br />
<br />
=== How to implement a new windowed component ===<br />
<br />
Windowed components are all descendents from TWinControl. Those controls have a Handle and thus, should be created by the Widgetset. It's easy to add new windowed components to a widgetset.<br />
<br />
Let's say you want to add TQtWSCustomEdit to Qt Widgetset. To start with TCustomEdit is a descendent of TWinControl and is located on the StdCtrls unit.<br />
<br />
Now, go to QtWSStrCtrls unit and look for the declaration of TQtWSCustomEdit.<br />
<br />
<syntaxhighlight> TQtWSCustomEdit = class(TWSCustomEdit)<br />
private<br />
protected<br />
public<br />
end;</syntaxhighlight><br />
<br />
Add static methods that are declared on TWSCustomEdit and override them. The code should now look like this:<br />
<br />
<syntaxhighlight> TQtWSCustomEdit = class(TWSCustomEdit)<br />
private<br />
protected<br />
public<br />
class function CreateHandle(const AWinControl: TWinControl;<br />
const AParams: TCreateParams): HWND; override;<br />
class procedure DestroyHandle(const AWinControl: TWinControl); override;<br />
{ class function GetSelStart(const ACustomEdit: TCustomEdit): integer; override;<br />
class function GetSelLength(const ACustomEdit: TCustomEdit): integer; override;<br />
<br />
class procedure SetCharCase(const ACustomEdit: TCustomEdit; NewCase: TEditCharCase); override;<br />
class procedure SetEchoMode(const ACustomEdit: TCustomEdit; NewMode: TEchoMode); override;<br />
class procedure SetMaxLength(const ACustomEdit: TCustomEdit; NewLength: integer); override;<br />
class procedure SetPasswordChar(const ACustomEdit: TCustomEdit; NewChar: char); override;<br />
class procedure SetReadOnly(const ACustomEdit: TCustomEdit; NewReadOnly: boolean); override;<br />
class procedure SetSelStart(const ACustomEdit: TCustomEdit; NewStart: integer); override;<br />
class procedure SetSelLength(const ACustomEdit: TCustomEdit; NewLength: integer); override;<br />
<br />
class procedure GetPreferredSize(const AWinControl: TWinControl;<br />
var PreferredWidth, PreferredHeight: integer); override;}<br />
end;</syntaxhighlight><br />
<br />
The commented part of the code are procedures you need to implement for TCustomEdit to be fully functional, but just CreateHandle and DestroyHandle should be enough for it to be show on the form and be editable, so it fits our needs in this article.<br />
<br />
Hit CTRL+SHIFT+C to code complete and the implement CreateHandle and DestroyHandle. In the case of Qt4 the code will be like this:<br />
<br />
<syntaxhighlight>{ TQtWSCustomEdit }<br />
<br />
class function TQtWSCustomEdit.CreateHandle(const AWinControl: TWinControl;<br />
const AParams: TCreateParams): HWND;<br />
var<br />
Widget: QWidgetH;<br />
Str: WideString;<br />
begin<br />
// Creates the widget<br />
WriteLn('Calling QTextDocument_create');<br />
Str := WideString((AWinControl as TCustomMemo).Lines.Text);<br />
Widget := QTextEdit_create(@Str, QWidgetH(AWinControl.Parent.Handle));<br />
<br />
// Sets it's initial properties<br />
QWidget_setGeometry(Widget, AWinControl.Left, AWinControl.Top,<br />
AWinControl.Width, AWinControl.Height);<br />
<br />
QWidget_show(Widget);<br />
<br />
Result := THandle(Widget);<br />
end;<br />
<br />
class procedure TQtWSCustomEdit.DestroyHandle(const AWinControl: TWinControl);<br />
begin<br />
QTextEdit_destroy(QTextEditH(AWinControl.Handle));<br />
end;</syntaxhighlight><br />
<br />
Now uncomment the like "RegisterWSComponent(TCustomEdit, TQtWSCustomEdit);" on the bottom of the unit and that's it!<br />
<br />
You can now drop a TCustomEdit on the bottom of a form and expect it to work. :^) <br />
<br />
=== Implementing TBitmap ===<br />
<br />
To implement TBitmap it is necessary to understand TRawImage and TLazIntfImage as explained here: [[Developing with Graphics#Working with TLazIntfImage.2C TRawImage and TLazCanvas]]<br />
<br />
So, let's say you want to compile the following code:<br />
<br />
<syntaxhighlight><br />
procedure TMyForm.HandleOnPaint(Sender: TObject);<br />
var<br />
Bitmap: TBitmap;<br />
begin<br />
Bitmap := TBitmap.Create;<br />
try<br />
Bitmap.LoadFromFile('myfile.bmp');<br />
Canvas.Draw(0, 0, Bitmap);<br />
finally<br />
Bitmap.Free;<br />
end;<br />
end;</syntaxhighlight><br />
<br />
Below is the order on which functions from the widgetset interface are called when executing that code:<br />
<br />
1 - BeginPaint<br />
<br />
This will be called only if the OnPaint event sends zero as the DC for the paint event<br />
<br />
2 - GetDC(0);<br />
<br />
Just create a device context.<br />
<br />
3 - TCDWidgetSet.RawImage_QueryDescription <br />
<br />
The default implementation of this routine is good for most widgetsets<br />
<br />
4 - TCDWidgetSet.RawImage_CreateBitmaps<br />
<br />
Here you need to create a native image object and load it from RawData.Data where the information is stored based on your description of the pixel format on item 2.<br />
<br />
5 - CreateCompatibleDC(0)<br />
<br />
This creates a temporary DC just to store the image, but at this point there is no information about the image so at this point this DC is really dummy<br />
<br />
6 - SelectObject<br />
<br />
With the image as the object to be selected and the DC just created above as target DC.<br />
<br />
7 - StretchMaskBlt<br />
<br />
Finally the drawing function! DestDC is the DC allocated on BeginPaint.<br />
<br />
8 - EndPaint<br />
<br />
Again, not always utilized.<br />
<br />
=== TBitmap.LoadFromDevice for screenshot taking ===<br />
<br />
It is recomended that you first implement TBitmap before trying this step.<br />
<br />
On LCL you can use the following code takes a screenshot from the entire screen and paints it on the canvas:<br />
<br />
<syntaxhighlight>var<br />
ScreenDC: HDC;<br />
Bitmap: TBitmap;<br />
begin<br />
Bitmap := TBitmap.Create;<br />
try<br />
ScreenDC := GetDC(0);<br />
Bitmap.LoadFromDevice(ScreenDC);<br />
ReleaseDC(0, ScreenDC);<br />
Canvas.Draw(0, 0, Bitmap);<br />
finally<br />
Bitmap.Free;<br />
end;<br />
end;</syntaxhighlight><br />
<br />
If you already implemented TBitmap, there are only 2 new functions to be implemented for LoadFromDevice: GetDeviceSize and GetRawImageFromDevice<br />
<br />
Below is a big trace, covering all widgetset functions being called on a OnPaint event that takes a screenshot and paints it on the screen. This trace was taken with Qt widgetset, and may have some imperfections. The Handle numbers should be used to check which object is being utilized on the functions.<br />
<br />
<br />
[WinAPI BeginPaint] Result=-1220713544<br />
<br />
[WinAPI GetClientBounds]<br />
<br />
[WinAPI SetWindowOrgEx] DC: -1220713544 NewX: 0 NewY: 0<br />
<br />
<syntaxhighlight>Enters on Paint event<br />
<br />
Bitmap := TBitmap.Create;<br />
try<br />
ScreenDC := GetDC(0);</syntaxhighlight><br />
<br />
[WinAPI GetDC] hWnd: 0 Result: -1220712920<br />
<br />
<syntaxhighlight> Bitmap.LoadFromDevice(ScreenDC);</syntaxhighlight><br />
<br />
[WinAPI GetDeviceSize]<br />
<br />
[WinAPI GetRawImageFromDevice] SrcDC: -1220712920 SrcWidth: 0 SrcHeight: 0<br />
<br />
[WinAPI CreateBitmapFromRawImage] Width:1024 Height:768 DataSize: 3145728 CreateMask: False Bitmap:-1220746696<br />
<br />
[WinAPI GetObject] GDIObj: -1220746696 Result=84 ObjectType=Image<br />
<br />
<syntaxhighlight> ReleaseDC(0, ScreenDC);</syntaxhighlight><br />
<br />
[WinAPI ReleaseDC] hWnd: 0 DC: -1220712920<br />
<br />
<syntaxhighlight> Canvas.Draw(0, 0, Bitmap);</syntaxhighlight><br />
<br />
[WinAPI CreateCompatibleDC] DC: 0<br />
<br />
[WinAPI GetDC] hWnd: 0 Result: -1220712920<br />
<br />
[WinAPI SelectObject] DC=-1220712920 GDIObj=-1220746696 Result=0 ObjectType=Image<br />
<br />
[WinAPI StretchMaskBlt] DestDC:-1220713544 SrcDC:-1220712920 Image:137185120 X:0 Y:0 W:1024 H:768 XSrc:0 YSrc:0 WSrc:1024 HSrc:768<br />
<br />
<syntaxhighlight>finally<br />
Bitmap.Free;<br />
end;</syntaxhighlight><br />
<br />
[WinAPI SelectObject] DC=-1220712920 GDIObj=0 Invalid GDI Object<br />
<br />
[WinAPI DeleteObject] GDIObject: -1220746696 Result=False ObjectType=Image<br />
<br />
<pre><br />
Now exited the OnPaint event<br />
</pre><br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
[WinAPI SetWindowOrgEx] DC: -1220713544 NewX: -152 NewY: -246<br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
[WinAPI DeleteObject] GDIObject: 0<br />
<br />
TWidgetSet.InitializeCriticalSection<br />
<br />
TWidgetSet.EnterCriticalSection<br />
<br />
[WinAPI SelectObject] DC=-1220713544 GDIObj=0 Invalid GDI Object<br />
<br />
[WinAPI MoveToEx] DC:-1220713544 X:0 Y:0<br />
<br />
[WinAPI SelectObject] DC=-1220713544 GDIObj=-1220746760 Result=-1220746856 ObjectType=Brush<br />
<br />
[WinAPI SelectObject] DC=-1220713544 GDIObj=-1220746856 Result=-1220746856 ObjectType=Brush<br />
<br />
TWidgetSet.LeaveCriticalSection<br />
<br />
[WinAPI SetWindowOrgEx] DC: -1220713544 NewX: 0 NewY: 0<br />
<br />
[WinAPI EndPaint] Handle: -1220611768 PS.HDC: -1220713544<br />
<br />
=== Implementing drawing in the OnPaint event of a form or another control ===<br />
<br />
For drawing in the OnPaint event of a form, the event itself comes from the underlaying widgetset library. The LCL interface should handle this event and create an appropriate DC object on the event handler and then call LCLSendPaintMsg. Besides that one should also implement the corresponding drawing methods, such as Rectangle or ExtTextOut. Pen, Brush and Font related routines might also be useful.<br />
<br />
Here is the OnPaint event handler from the Cocoa widgetset which shows how it calls LCLSentPaintMsg:<br />
<br />
<syntaxhighlight><br />
procedure TLCLCommonCallback.Draw(ControlContext: NSGraphicsContext;<br />
const bounds, dirty:NSRect);<br />
var<br />
struct : TPaintStruct;<br />
begin<br />
if not Assigned(Context) then Context:=TCocoaContext.Create;<br />
<br />
Context.ctx:=ControlContext;<br />
if Context.InitDraw(Round(bounds.size.width), Round(bounds.size.height)) then<br />
begin<br />
FillChar(struct, SizeOf(TPaintStruct), 0);<br />
struct.hdc := HDC(Context);<br />
{$IFDEF VerboseWinAPI}<br />
DebugLn(Format('[TLCLCommonCallback.Draw] OnPaint event started context: %x', [HDC(context)]));<br />
{$ENDIF}<br />
LCLSendPaintMsg(Target, HDC(Context), @struct);<br />
{$IFDEF VerboseWinAPI}<br />
DebugLn('[TLCLCommonCallback.Draw] OnPaint event ended');<br />
{$ENDIF}<br />
end;<br />
end;<br />
</syntaxhighlight><br />
<br />
And a list of WinAPI routines which were called when running this event:<br />
<br />
<pre><br />
[TCocoaWidgetSet.GetDC] hWnd: 0 Result: 12400C0<br />
[TLCLCommonCallback.Draw] OnPaint event started context: 1240340<br />
TCocoaWidgetSet.CreatePenIndirect<br />
TCocoaWidgetSet.SelectObject DC: 1240340 GDIObj: 10EC460<br />
TCocoaWidgetSet.SelectObject Result: 0<br />
TCocoaWidgetSet.SelectObject DC: 1240340 GDIObj: 10EBF00<br />
TCocoaWidgetSet.SelectObject Result: 0<br />
[TCocoaWidgetSet.Rectangle] DC: 1240340 X1: 100 Y1: 100 X2: 200 Y2: 200<br />
TCocoaWidgetSet.SelectObject DC: 1240340 GDIObj: 10EC4A0<br />
TCocoaWidgetSet.SelectObject Result: 0<br />
[TCocoaWidgetSet.GetTextExtentPoint] DC: 1240340 Str: Some text Count: 9<br />
[TCocoaWidgetSet.GetTextExtentPoint] Size: 65,17<br />
[TLCLCommonCallback.Draw] OnPaint event ended<br />
</pre><br />
<br />
=== Implementing TLabel ===<br />
<br />
Implementing TLabel is particularly hard, despite it being such a basic component, because it requires that almost all painting be implemented. TLabel is not a windowed control, instead it depends on paint messages to be drawn directly into the form canvas.<br />
<br />
Before trying to get TLabel working it is recomended to test if drawing functions such as Rectangle work inside a form's OnPaint event.<br />
<br />
Several WinAPI methods need to be implemented, particularly:<br />
<br />
'''Device Context Methods'''<br />
<br />
BeginPaint, GetDC, EndPaint, ReleaseDC, CreateCompatibleDC<br />
<br />
see [[Device Contexts and GDI objects in the LCL interfaces]]<br />
<br />
'''GDI Objects Methods'''<br />
<br />
SelectObject, DeleteObject, CreateFontIndirect, CreateFontIndirectEx<br />
<br />
'''Miscelaneous functions'''<br />
<br />
InvalidateRect, GetClientBounds, SetWindowOrgEx<br />
<br />
'''Text drawing Methods'''<br />
<br />
DrawText. Instead of implementing DrawText one can also use the default TWidgetSet.DrawText, like the Carbon and Cocoa widgetsets do. But in this case it is necessary that one implements at least GetTextMetrics, GetTextExtentPoint and ExtTextOut. Without GetTextMetrics a form with a label will crash because the autosize will not be able to calculate the appropriate size for the label.<br />
<br />
'''Region functions to determine if the control is behind another'''<br />
<br />
CombineRgn, CreateRectRgn, GetClipRGN, RectVisible<br />
<br />
<br />
Below is the order in which paint procedures are called on a form with only one TLabel, to better understand the painting sequence:<br />
<br />
1 - GetDC is called once on software startup with hWnd = 0<br />
<br />
2 - The form is shown<br />
<br />
3 - GetDC is called again (this wouldn't happen without the label). A<br />
few font related functions are called, as well as DrawText with<br />
CalcRect set to True to calculate the size of the label.<br />
<br />
4 - InvalidateRect is called on the form canvas<br />
<br />
5 - Control goes back to the operating system until a paint message comes from the widgetset<br />
<br />
6 - BeginPaint is called, and at this point code on OnPaint event of the form will be executed<br />
<br />
7 - DrawText is called again with CalcRect set to false<br />
<br />
8 - The Painting ends.<br />
<br />
=== Implementing visibility for forms and controls and window state===<br />
<br />
The code that controls visibility is split between visibility for forms, and for controls<br />
<br />
'''Visibility for forms and window state'''<br />
<br />
This part also controls the state of the window (minimized, maximized or normal). It is implemented as a copy of the Windows API function ShowWindow, so you must implemente the TMyWidgetset.ShowWindow on the file mywinapi.inc Don´t forget to also add a header to the file mywinapih.inc<br />
<br />
Below is code that implements this function on the Qt widgetset. It should be very easy to understand, copy and implement on your own widgetset. You can also take a look how Gtk implements this. On Windows, the Windows API is called directly, of course, so there is no code to look at.<br />
<br />
<syntaxhighlight>{------------------------------------------------------------------------------<br />
function ShowWindow(hWnd: HWND; nCmdShow: Integer): Boolean;<br />
<br />
nCmdShow:<br />
SW_SHOWNORMAL, SW_MINIMIZE, SW_SHOWMAXIMIZED<br />
------------------------------------------------------------------------------}<br />
function TQtWidgetSet.ShowWindow(hWnd: HWND; nCmdShow: Integer): Boolean;<br />
var<br />
Widget: QWidgetH;<br />
begin<br />
{$ifdef VerboseQtWinAPI}<br />
WriteLn('WinAPI ShowWindow');<br />
{$endif}<br />
<br />
Result := False;<br />
<br />
Widget := QWidgetH(hWnd);<br />
<br />
// if Widget = nil then RaiseException('TQtWidgetSet.ShowWindow hWnd is nil');<br />
<br />
case nCmdShow of<br />
<br />
SW_SHOW: QWidget_setVisible(Widget, True);<br />
<br />
SW_SHOWNORMAL: QWidget_showNormal(Widget);<br />
<br />
SW_MINIMIZE: QWidget_setWindowState(Widget, QtWindowMinimized);<br />
<br />
SW_SHOWMINIMIZED: QWidget_showMinimized(Widget);<br />
<br />
SW_SHOWMAXIMIZED: QWidget_showMaximized(Widget);<br />
<br />
SW_HIDE: QWidget_setVisible(Widget, False);<br />
<br />
end;<br />
<br />
Result := True;<br />
end;</syntaxhighlight><br />
<br />
'''Visibility for controls'''<br />
<br />
For controls inside a form you need to implement TMyWSWinControl.ShowHide class function that resides on the TMyWSWinControl class on the file mywscontrols.pp<br />
<br />
Remember that most controls are descendent from TWinControl, so implementing this function there will guarantee that the Visible property is implemented for all standard controls that have it. Below is a sample code for Qt widgetset.<br />
<br />
<syntaxhighlight>{------------------------------------------------------------------------------<br />
Method: TQtWSWinControl.ShowHide<br />
Params: AWinControl - the calling object<br />
<br />
Returns: Nothing<br />
<br />
Shows or hides a widget.<br />
------------------------------------------------------------------------------}<br />
class procedure TQtWSWinControl.ShowHide(const AWinControl: TWinControl);<br />
begin<br />
if AWinControl = nil then exit;<br />
<br />
if not AWinControl.HandleAllocated then exit;<br />
<br />
if AWinControl.HandleObjectShouldBeVisible then<br />
QWidget_setVisible(TQtWidget(AWinControl.Handle).Widget, True)<br />
else QWidget_setVisible(TQtWidget(AWinControl.Handle).Widget, False);<br />
end;</syntaxhighlight><br />
<br />
=== Implementing TStrings based Components===<br />
Some components use a TStrings to store the information they display, such as: TCustomMemo, TCustomListBox and TCustomComboBox.<br />
<br />
To implement those it is not enougth to only implement their functions on the TQtCustomMemo class for example. One of the functions to implement will be called GetStrings, which looks like this:<br />
<br />
<syntaxhighlight>class function TQtWSCustomListBox.GetStrings(const ACustomListBox: TCustomListBox): TStrings;<br />
var<br />
ListWidgetH: QListWidgetH;<br />
begin<br />
ListWidgetH := QListWidgetH((TQtWidget(ACustomListBox.Handle).Widget));<br />
Result := TQtListStrings.Create(ListWidgetH, ACustomListBox);<br />
end;</syntaxhighlight><br />
<br />
This function must return a TStrings descendent designed to detect when strings are added to or removed from the string list and to send this information to the widgetset to update the control. For example, the following declaration shows what TQtListStrings looks like:<br />
<br />
<syntaxhighlight> TQtListStrings = class(TStrings)<br />
private<br />
FListChanged: Boolean; // StringList and QtListWidget out of sync<br />
FStringList: TStringList; // Holds the items to show<br />
FQtListWidget: QListWidgetH; // Qt Widget<br />
FOwner: TWinControl; // Lazarus Control Owning ListStrings<br />
FUpdating: Boolean; // We're changing Qt Widget<br />
procedure InternalUpdate;<br />
procedure ExternalUpdate(var Astr: TStringList; Clear: Boolean = True);<br />
procedure IsChanged; // OnChange triggered by program action<br />
protected<br />
function GetTextStr: string; override;<br />
function GetCount: integer; override;<br />
function Get(Index : Integer) : string; override;<br />
//procedure SetSorted(Val : boolean); virtual;<br />
public<br />
constructor Create(ListWidgetH : QListWidgetH; TheOwner: TWinControl);<br />
destructor Destroy; override;<br />
procedure Assign(Source : TPersistent); override;<br />
procedure Clear; override;<br />
procedure Delete(Index : integer); override;<br />
procedure Insert(Index : integer; const S: string); override;<br />
procedure SetText(TheText: PChar); override;<br />
//procedure Sort; virtual;<br />
public<br />
//property Sorted: boolean read FSorted write SetSorted;<br />
property Owner: TWinControl read FOwner;<br />
function ListChangedHandler(Sender: QObjectH; Event: QEventH): Boolean; cdecl;<br />
end;</syntaxhighlight><br />
<br />
You can see its implementation in the qtobjects.pas unit of the qt interface<br />
<br />
===Implementing Menus===<br />
<br />
Menus are available on the LCL to create main menus or popup menus. A TMenu is the owner of a larger menu structure with many items. Items can have subitems, and don't need extra TMenus.<br />
<br />
Also remember that on LCL the handle is only created when needed and at that time all properties of the controls are already initialized. This helps a lot on widgetsets where depending on the properties of a menu item it can be of one class or another, like Qt.<br />
<br />
The following things need to be implemented in order for the menus to work:<br />
<br />
1) All methods on the QtWSMenus unit, which will implement menu creation and modification<br />
<br />
2) function TWinCEWidgetSet.SetMenu(AWindowHandle: HWND; AMenuHandle: HMENU): Boolean; from the wincewinapi.inc file, which will implement support for a main menu associated with a window.<br />
<br />
====Menu Creation Order====<br />
<br />
<br />
One important thing to understand when implementing menus, is in which order they are created. For example, we want to create the following menu structure:<br />
<br />
[[Image:Menu_creation_order.png]]<br />
<br />
And when our application is executed, there will be a 'Creating MenuItem' message with the caption of the menu each time TQtWSMenuItem.CreateHandle is called, and a 'Creating Menu' message with the name of the menu (TMenu descendents don't have a caption), each time TQtWSMenu.CreateHandle is called.<br />
<br />
Here is the resulting output of such software:<br />
<br />
<pre><br />
Creating Menu. Name: MainMenu1<br />
Creating MenuItem: Item1 Parent=Menu.Items : TMenuItem<br />
Creating MenuItem: SubItem11 Parent=Item1 : TMenuItem<br />
Creating MenuItem: SubItem12 Parent=Item1 : TMenuItem<br />
Creating MenuItem: SubItem13 Parent=Item1 : TMenuItem<br />
Creating MenuItem: SubItem14 Parent=Item1 : TMenuItem<br />
Creating MenuItem: SubSubItem141 Parent=SubItem14 : TMenuItem<br />
Creating MenuItem: SubSubItem142 Parent=SubItem14 : TMenuItem<br />
Creating MenuItem: SubSubItem143 Parent=SubItem14 : TMenuItem<br />
Creating MenuItem: SubSubItem144 Parent=SubItem14 : TMenuItem<br />
Creating MenuItem: Item2 Parent=Menu.Items : TMenuItem<br />
Creating MenuItem: SubItem21 Parent=Item2 : TMenuItem<br />
Creating MenuItem: SubItem22 Parent=Item2 : TMenuItem<br />
Creating MenuItem: SubItem23 Parent=Item2 : TMenuItem<br />
Creating MenuItem: Item3 Parent=Menu.Items : TMenuItem<br />
Creating MenuItem: Item4 Parent=Menu.Items : TMenuItem<br />
</pre><br />
<br />
For all MenuItems one can use GetParentMenu to get their parent owner: Menu (TMainMenu).<br />
<br />
===Control enabling/disabling===<br />
<br />
The current way to set control enabling/disabling is by implementing the winapi EnableWindow. This API should work generically on any control. It should enable/disable mouse and keyboard input for the specified window or control, but also mark it as uneditable by the user, by making it greyed for example.<br />
<br />
<syntaxhighlight>{------------------------------------------------------------------------------<br />
Method: EnableWindow<br />
Params: HWnd - handle to window<br />
BEnable - whether to enable the window<br />
Returns: If the window was previously disabled<br />
<br />
Enables or disables mouse and keyboard input to the specified window or<br />
control.<br />
------------------------------------------------------------------------------}<br />
function TWin32WidgetSet.EnableWindow(hWnd: HWND; bEnable: Boolean): Boolean;</syntaxhighlight><br />
<br />
===Shaped Windows===<br />
<br />
Windows can be shaped based on a TBitmap or on a TRegion. The region is the visible part.<br />
<br />
To implement shaped windows based on a TBitmap, implement TWSWinControl.setShape<br />
<br />
To implement shaped windows based on a TRegion implement LCLIntf.SetWindowRgn<br />
<br />
See also: [[LCL Tips#Creating a non-rectangular window or control]]<br />
<br />
===System colors===<br />
<br />
Some color constants are actually system colors, like clBtnFace, clForm, clWindow, etc, etc.<br />
<br />
To implement support for system colors the WinAPI routine GetSysColor should be implemented:<br />
<br />
function GetSysColor(nIndex: Integer): DWORD; override;<br />
<br />
And here is a snip of the color constants which should be supported. Check LCLType for the latest values:<br />
<br />
<syntaxhighlight><br />
//==============================================<br />
// API system Color constants pbd<br />
// note these are usually shown ORed with<br />
// $80000000 as these would have interfered with<br />
// other MS color enumerations<br />
// GetSysColor and SetSysColor expects the values<br />
// below<br />
//==============================================<br />
<br />
type<br />
COLORREF = LongInt;<br />
TColorRef = COLORREF;<br />
<br />
const<br />
CLR_INVALID = TColorRef($FFFFFFFF);<br />
<br />
COLOR_SCROLLBAR = 0;<br />
COLOR_BACKGROUND = 1;<br />
COLOR_ACTIVECAPTION = 2;<br />
COLOR_INACTIVECAPTION = 3;<br />
COLOR_MENU = 4;<br />
COLOR_WINDOW = 5;<br />
COLOR_WINDOWFRAME = 6;<br />
COLOR_MENUTEXT = 7;<br />
COLOR_WINDOWTEXT = 8;<br />
COLOR_CAPTIONTEXT = 9;<br />
COLOR_ACTIVEBORDER = 10;<br />
COLOR_INACTIVEBORDER = 11;<br />
COLOR_APPWORKSPACE = 12;<br />
COLOR_HIGHLIGHT = 13;<br />
COLOR_HIGHLIGHTTEXT = 14;<br />
COLOR_BTNFACE = 15;<br />
COLOR_BTNSHADOW = 16;<br />
COLOR_GRAYTEXT = 17;<br />
COLOR_BTNTEXT = 18;<br />
COLOR_INACTIVECAPTIONTEXT = 19;<br />
COLOR_BTNHIGHLIGHT = 20;<br />
COLOR_3DDKSHADOW = 21;<br />
COLOR_3DLIGHT = 22;<br />
COLOR_INFOTEXT = 23;<br />
COLOR_INFOBK = 24;<br />
// PBD: 25 is unassigned in all the docs I can find<br />
// if someone finds what this is supposed to be then fill it in<br />
// note defaults below, and cl[ColorConst] in graphics<br />
COLOR_HOTLIGHT = 26;<br />
COLOR_GRADIENTACTIVECAPTION = 27;<br />
COLOR_GRADIENTINACTIVECAPTION = 28;<br />
COLOR_MENUHILIGHT = 29;<br />
COLOR_MENUBAR = 30;<br />
<br />
COLOR_FORM = 31;<br />
<br />
COLOR_ENDCOLORS = COLOR_FORM;<br />
<br />
COLOR_DESKTOP = COLOR_BACKGROUND;<br />
COLOR_3DFACE = COLOR_BTNFACE;<br />
COLOR_3DSHADOW = COLOR_BTNSHADOW;<br />
COLOR_3DHIGHLIGHT = COLOR_BTNHIGHLIGHT;<br />
COLOR_3DHILIGHT = COLOR_BTNHIGHLIGHT;<br />
COLOR_BTNHILIGHT = COLOR_BTNHIGHLIGHT;<br />
<br />
MAX_SYS_COLORS = COLOR_ENDCOLORS;<br />
SYS_COLOR_BASE = TColorRef($80000000);</syntaxhighlight><br />
<br />
===ShowMessage===<br />
<br />
These standard dialogs are implemented purely in the LCL in the following places:<br />
<br />
* Class TPromptDialog file lcl/include/promptdialog.inc<br />
<br />
===SpinEdit===<br />
<br />
Both TFloatSpinEdit and TSpinEdit are implemented in the class TWSFloatSpinEdit.<br />
<br />
===Clipboard===<br />
<br />
Clipboard support is implemented in lclintf by implementing Windows API routines. The routines are:<br />
<br />
<syntaxhighlight>function ClipboardFormatToMimeType(FormatID: TClipboardFormat): string; {$IFDEF IF_BASE_MEMBER}virtual;{$ENDIF}<br />
function ClipboardGetData(ClipboardType: TClipboardType;<br />
FormatID: TClipboardFormat; Stream: TStream): boolean; {$IFDEF IF_BASE_MEMBER}virtual;{$ENDIF}<br />
// ! ClipboardGetFormats: List will be created. You must free it yourself with FreeMem(List) !<br />
function ClipboardGetFormats(ClipboardType: TClipboardType;<br />
var Count: integer; var List: PClipboardFormat): boolean; {$IFDEF IF_BASE_MEMBER}virtual;{$ENDIF}<br />
function ClipboardGetOwnerShip(ClipboardType: TClipboardType;<br />
OnRequestProc: TClipboardRequestEvent; FormatCount: integer;<br />
Formats: PClipboardFormat): boolean; {$IFDEF IF_BASE_MEMBER}virtual;{$ENDIF}<br />
function ClipboardRegisterFormat(const AMimeType: string): TClipboardFormat; {$IFDEF IF_BASE_MEMBER}virtual;{$ENDIF}</syntaxhighlight><br />
<br />
===TSpeedButton===<br />
<br />
This control is a TGraphicControl descendent, so it has no handle and paints itself. To retain native look, it uses the function LCLIntf.DrawFrameControl to paint itself, so implement this function to have this control working. Naturally, lot's of other DC, WindowOrg, Text Drawing and Painting routines will have to be working, as explained for TLabel.<br />
<br />
===TRadioButton and TCheckButton===<br />
<br />
'''Messages:'''<br />
<br />
Basically the Widgetset must do:<br />
<br />
*Send LM_CHANGE when a radio button is unchecked/checked (LCL will take care if OnClick will be called or not)<br />
*Dont send LM_CHANGE when TWSCustomCheckBox.SetState is called (SetChecked)<br />
<br />
See also this bug report: http://bugs.freepascal.org/view.php?id=13939<br />
<br />
===FullScreen support===<br />
<br />
FullScreen is implemented as a Windows state wsFullScreen, and as such is implemented in LCLIntf.ShowWindow where the constant SW_SHOWFULLSCREEN should be handled.<br />
<br />
== An example of how the LCL interfaces work ==<br />
<br />
Below is a simple example. Suppose you have developed a trayicon component. How would you implement it in the LCL to work correctly on the various different supported platforms?<br />
<br />
You would need to generate the following files:<br />
<br />
\trayicon.pas<br />
<br />
\wstrayicon.pas<br />
<br />
\gtk\gtkwstrayicon.pas<br />
<br />
\gtk\trayintf.pas<br />
<br />
\win32\win32wstrayicon.pas<br />
<br />
\win32\trayintf.pas<br />
<br />
<br />
Providing separate wsXXX.pas and \$(LCLWidgetType)\XXXintf.pas files avoids the need for ifdefs altogether. You will need to add as a unit path $(LCLWidgetType) to the XXXintf.pas file in order initialize the correct trayintf.pas file, which in turn initializes the correct WS Tray class.<br />
<br />
Inside trayicon.pas you include wstrayicon. Derive your main class from an LCL class, and only use wstrayicon in its implementation. All LCL classes that communicate with a widgetset, must be derived from [[doc:/lcl/lclclasses/tlclcomponent.html|TLCLComponent]] declared in the [[doc:/lcl/lclclasses|LCLClasses]] unit.<br />
<br />
<syntaxhighlight>unit TrayIcon;<br />
<br />
interface<br />
<br />
type<br />
TTrayIcon = class(TLCLComponent)<br />
public<br />
procedure DoTray;<br />
end;<br />
<br />
implementation<br />
<br />
uses wstrayicon;<br />
<br />
procedure TTrayIcon.DoTray;<br />
begin<br />
// Call wstrayicon<br />
end;<br />
<br />
end.</syntaxhighlight><br />
<br />
in trayintf you use gtkwstrayicon or win32trayicon depending on which<br />
trayintf file it is.<br />
<br />
in wstrayicon you create a class like so:<br />
<br />
<syntaxhighlight>unit WSTrayIcon;<br />
<br />
uses WSLCLClasses, Controls, TrayIcon; // and other things as well<br />
<br />
TWSTrayIconClass = class of TWSTrayIcon;<br />
TWSTrayIcon = class(TWSWinControl);<br />
public<br />
class procedure EmbedTrayIcon(const ATrayIcon: TCustomTrayIcon);<br />
virtual; // these must all be virtual and class procedures!!<br />
class procedure RemoveTrayIcon(const ATrayIcon: TCustomTrayIcon); virtual;<br />
....<br />
end;<br />
...<br />
<br />
implementation<br />
<br />
procedure TWSTrayIcon.EmbedTrayIcon(const ATrayIcon: TCustomTrayIcon);<br />
begin<br />
//do nothing<br />
end;<br />
<br />
procedure TWSTrayIcon.RemoveTrayIcon(const ATrayIcon: TCustomTrayIcon);<br />
begin<br />
//do nothing<br />
end;</syntaxhighlight><br />
<br />
now in gtkwstrayicon.pas do this:<br />
<br />
<syntaxhighlight>uses WSTrayIcon, WSLCLClasses, Controls, TrayIcon, gtk, gdk;<br />
<br />
<br />
TGtkWSTrayIcon = class(TWSTrayIcon);<br />
private<br />
class function FindSystemTray(const ATrayIcon: TCustomTrayIcon):<br />
TWindow; virtual;<br />
public<br />
class procedure EmbedTrayIcon(const ATrayIcon: TCustomTrayIcon); override;<br />
class procedure RemoveTrayIcon(const ATrayIcon: TCustomTrayIcon);<br />
override;<br />
class function CreateHandle(const AWinControl: TWinControl; const<br />
AParams: TCreateParams): HWND; override;<br />
....<br />
end;<br />
...<br />
<br />
implementation<br />
<br />
procedure TGtkWSTrayIcon.CreateHandle(const AWinControl: TWinControl;<br />
const AParams: TCreateParams): HWND;<br />
var<br />
WidgetInfo: PWidgetInfo;<br />
begin<br />
<br />
Result := gtk_plug_new;<br />
WidgetInfo := CreateWidgetInfo(AWinControl, Result); // it's something<br />
like this anyway<br />
TGtkWSWincontrolClass(WidgetSetClass).SetCallbacks(AWinControl);<br />
// and more stuff<br />
end;<br />
<br />
function TGtkWSTrayIcon.FindSystemTray(const ATrayIcon:<br />
TCustomTrayIcon): TWindow;<br />
begin<br />
// do something<br />
end;<br />
<br />
<br />
procedure TGtkWSTrayIcon.EmbedTrayIcon(const ATrayIcon: TCustomTrayIcon);<br />
var<br />
SystemTray: TWindow;<br />
begin<br />
SystemTray := FindSystemTray(ATrayIcon);<br />
//do something<br />
end;<br />
<br />
procedure TGtkWSTrayIcon.RemoveTrayIcon(const ATrayIcon: TCustomTrayIcon);<br />
begin<br />
//do something<br />
end;<br />
<br />
......<br />
<br />
initialization<br />
<br />
RegisterWSComponent(TCustomTrayIcon, TGtkWSTrayIcon); //this is very<br />
important!!!<br />
<br />
end.</syntaxhighlight><br />
<br />
then finally in trayicon.pas you go as normal<br />
<br />
<syntaxhighlight>uses WSTrayIcon; //etc. you DON'T include GtkWSTrayIcon here!<br />
<br />
TCustomTrayIcon = class(TWinControl)<br />
public<br />
procedure EmbedControl;<br />
....<br />
end;<br />
<br />
...<br />
procedure TTrayIcon.EmbedControl;<br />
begin<br />
TWSTrayIconClass(WidgetSetClass).EmbedControl(Self);<br />
<br />
end;</syntaxhighlight><br />
<br />
----<br />
This document is work in progress. You can help by writing sections of this document. If you cannot find the information you are looking for in this document, please add your question to the [[Talk:LCL Internals|discussion page]]. This will help us to write documentation at a level that is neither too simple nor too complicated, and fully cover the areas that people want to know about.<br />
<br />
[[Category:LCL]]<br />
[[Category:Lazarus internals]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=fcl-web&diff=84674fcl-web2014-11-28T11:01:27Z<p>Sekelsenmat: /* Reading POST data */</p>
<hr />
<div>{{Web and Networking Programming}}<br />
<br />
== What is fpWeb ==<br />
fpWeb can be used to build cgi applications. '''We need more details here: what other functionality does it have, how does it compare to other frameworks/tools, e.g. Brook'''<br />
<br />
== Using fpWeb together with Lazarus ==<br />
<br />
===Installing the weblaz fpWeb Lazarus Package===<br />
<br />
The first step to do is installing the package which comes in the path lazarus/components/fpweb/weblaz.lpk. As usual with design-time packages, you'll have to rebuild Lazarus.<br />
<br />
===Creating a CGI application===<br />
<br />
After the weblaz package is installed, a very simple CGI web application which displays an HTML page can be created by going to the Lazarus menu "File->New...". From the list of possible applications select "CGI Application" as in the image below, which will create a main CGI project file and a fpweb web module.<br />
<br />
[[Image:New_cgi.PNG]]<br />
<br />
The TFPWebModule allows you to manipulate properties and events using the Object Inspector.<br />
<br />
To add code to show the page, a request handler should be added. To do this, double click the OnRequest property in the object inspector, as in the image below:<br />
<br />
[[Image:Webmodule.PNG]]<br />
<br />
In the event handler one should write the HTML code which will be displayed by the browser. To avoid mixing Pascal and HTML, this page can be loaded from the directory the CGI executable is in by using AResponse.Contents.LoadFromFile(). <br />
<br />
The type of the response should be set in AResponse.ContentType. For HTML pages this should have the value 'text/html;charset=utf-8'. <br />
<br />
Finally, Handled should be set to True to indicate that the request was successfully handled (and return a 200 OK status code to the browser). After adding this code, the web module should look like this:<br />
<br />
<syntaxhighlight>unit mainpage;<br />
<br />
{$mode objfpc}{$H+}<br />
<br />
interface<br />
<br />
uses<br />
Classes, SysUtils, FileUtil, HTTPDefs, websession, fpHTTP, fpWeb; <br />
<br />
type<br />
<br />
{ TFPWebModule1 }<br />
<br />
TFPWebModule1 = class(TFPWebModule)<br />
procedure DataModuleRequest(Sender: TObject; ARequest: TRequest;<br />
AResponse: TResponse; var Handled: Boolean);<br />
private<br />
{ private declarations }<br />
public<br />
{ public declarations }<br />
end; <br />
<br />
var<br />
FPWebModule1: TFPWebModule1; <br />
<br />
implementation<br />
<br />
{$R *.lfm}<br />
<br />
{ TFPWebModule1 }<br />
<br />
procedure TFPWebModule1.DataModuleRequest(Sender: TObject; ARequest: TRequest;<br />
AResponse: TResponse; var Handled: Boolean);<br />
begin<br />
AResponse.ContentType := 'text/html;charset=utf-8';<br />
AResponse.Contents.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'mainpage.html');<br />
Handled := True;<br />
end;<br />
<br />
begin<br />
RegisterHTTPModule('TFPWebModule1', TFPWebModule1);<br />
end.</syntaxhighlight><br />
<br />
=== Deploying the CGI application ===<br />
<br />
This section assumes the Apache web server is used. Of course, other web servers that support CGI (nginx, cherokee) can be used, too.<br />
<br />
Apache can be downloaded here: http://httpd.apache.org/download.cgi or installed using your distribution's package manager.<br />
<br />
The default installation of Apache will treat all files located in its cgi-bin directory as CGI programs, so the user won't be able to access plain HTML files placed there. This directory can be set in the file httpd.conf in the following section:<br />
<br />
<pre><br />
#<br />
# ScriptAlias: This controls which directories contain server scripts.<br />
# ScriptAliases are essentially the same as Aliases, except that<br />
# documents in the target directory are treated as applications and<br />
# run by the server when requested rather than as documents sent to the<br />
# client. The same rules about trailing "/" apply to ScriptAlias<br />
# directives as to Alias.<br />
#<br />
ScriptAlias /cgi-bin/ "C:/Program Files/Apache Software Foundation/Apache2.2/cgi-bin/"<br />
</pre><br />
<br />
If you place an executable called "mywebpage.cgi" in this directory, then the page can be accessed as http://localhost/cgi-bin/mywebpage.cgi (or remotely with the corresponding IP address or domain name).<br />
<br />
fcl-web with Lazarus on Windows produces .exe files. For Apache to serve these files you have to add this:<br />
<pre><br />
AddHandler cgi-script .exe<br />
</pre><br />
<br />
And to serve your executables from another directory, you add this:<br />
<pre><br />
ScriptAlias /bin/ "C:/lazarus_projects/test-fclweb/bin/"<br />
<Directory "C:/lazarus_projects/test-fclweb/bin/"><br />
AllowOverride None<br />
Options None<br />
Order allow,deny<br />
Allow from all<br />
</Directory><br />
</pre><br />
<br />
===Formatting the HTML and Reading Query fields===<br />
<br />
The previous example just showed a plain HTML page. One might wish to e.g.<br />
* dynamically change the HTML page output, and<br />
* as read the variables the browser passed to the webpage in Query fields (in e.g. HTTP GET and HTTP POST actions). <br />
<br />
A simple solution for the first problem is simply using the standard Pascal routine Format and adding %s or %d in the HTML file in the appropriate places which will receive a custom value.<br />
<br />
===Reading GET data===<br />
To read the GET variables one can use ARequest.QueryFields, which is a TStrings descendent. Each variable will be in a separate line in the TStrings in the format variablename=value, similarly to how they are shown in the browser page address. To search for a specific variable one can use ARequest.QueryFields.Values[], passing the variable name in the brackets to receive its value back, instead of parsing the string manually. <br />
<br />
The resulting code:<br />
<br />
<syntaxhighlight>procedure TFPWebModule1.DataModuleRequest(Sender: TObject; ARequest: TRequest;<br />
AResponse: TResponse; var Handled: Boolean);<br />
var<br />
HexText, AsciiText: string;<br />
begin<br />
HexText := ARequest.QueryFields.Values['hex'];<br />
AsciiText := HexToAnsii(HexText);<br />
<br />
AResponse.ContentType := 'text/html;charset=utf-8';<br />
AResponse.Contents.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'mainpage.html');<br />
AResponse.Contents.Text := Format(AResponse.Contents.Text,<br />
[HexText, AsciiText]);<br />
Handled := True;<br />
end;</syntaxhighlight><br />
<br />
===Reading POST data===<br />
<br />
Data submitted by POST requests can be obtained from <code>TRequest.Content</code>. It will come without the request headers - in other words it contains the body of the request.<br />
<br />
Submitted form data can also be accessed using <code>TRequest.ContentFields</code> which is the content parsed as fields separated by & and decoded. For example, the following set of form values:<br />
<br />
login: dfg 345&&<br />
login_senha: ====<br />
email: dfg<br />
<br />
Will be encoded in 'APPLICATION/X-WWW-FORM-URLENCODED' like this (see [http://en.wikipedia.org/wiki/POST_%28HTTP%29 wikipedia POST (HTTP)]):<br />
<br />
login=dfg+345%26%26&login_senha=%3D%3D%3D%3D&email=dfg<br />
<br />
And will be available in TRequest.ContentFields via the line index or using the Values property, which is more convenient:<br />
<br />
TRequest.ContentFields[0]: login=dfg 345&&<br />
TRequest.ContentFields[1]: login_senha=====<br />
TRequest.ContentFields[2]: email=dfg<br />
TRequest.ContentFields.Values['email']: dfg<br />
<br />
If using other mime-types than 'MULTIPART/FORM-DATA' and 'APPLICATION/X-WWW-FORM-URLENCODED' (the types supported by HTML forms):<br />
* content is only available in TRequest.Content, not TRequest.ContentFields<br />
* use of these mime-types raises an exception for FPC 2.4.2 (fixed in FPC 2.5+).<br />
<br />
Note that HTTP POST can also send Query fields (in the URL), e.g. http://server/bla?question=how, and those are accessed by TRequest.QueryFields as explained in the previous section.<br />
<br />
<syntaxhighlight>procedure TFPWebModule1.DataModuleRequest(Sender: TObject; ARequest: TRequest;<br />
AResponse: TResponse; var Handled: Boolean);<br />
var<br />
lData: String;<br />
begin<br />
lData := ARequest.Content;<br />
</syntaxhighlight><br />
<br />
=== Reading POST binary data ===<br />
To receive data on the server that has been POSTed e.g. as multipart/form-data, use something like this:<br />
<syntaxhighlight><br />
procedure TMainWebModule.TFPWebActions2Request(Sender: TObject;<br />
ARequest: TRequest; AResponse: TResponse; var Handled: Boolean);<br />
var<br />
i: Integer;<br />
begin <br />
// Process all received files<br />
for i := 0 to ARequest.Files.Count - 1 do<br />
begin<br />
// Doing something else than writeln is highly recommended ;)<br />
writeln ('Received Filename: '+ARequest.Files[i].LocalFileName);<br />
end;<br />
<br />
Handled := true;<br />
end;<br />
</syntaxhighlight><br />
<br />
The client can send data using e.g. FileFormPost.<br />
<br />
== Using multiple modules ==<br />
If there is only one module in the web application, all requests will be directed to this module. <br />
<br />
As your web application grows, multiple modules can be used. A new module can be added by choosing 'File - New' and then one of 'Web module' or 'HTML Web Module'. <br />
<br />
FCL-web uses the URL to determine how a HTTP request should be handled. It must therefore know which web-modules exist in the application. To achieve this, each module must be registered.<br />
<br />
Each module is registered with fcl-web in the initialization section of the unit it is defined in:<br />
<br />
<syntaxhighlight>RegisterHTTPModule('location', TMyModule);</syntaxhighlight><br />
<br />
The module will then be invoked if an URL of the form <br />
<nowiki>http://www.mysite.org/mycgi.cgi/location</nowiki><br />
or<br />
<nowiki>http://www.mysite.org/mycgi.cgi?module=location</nowiki><br />
is used.<br />
<br />
If multiple modules are present, the name of the module must appear in the URL, or an error will be raised.<br />
<br />
This behaviour can also be forced for applications that have only a single module by setting the Application's property AllowDefaultModule to false:<br />
<br />
<syntaxhighlight>Application.AllowDefaultModule := False;</syntaxhighlight><br />
<br />
In that case, the fcl-web application will always require the name of the module in the URL.<br />
<br />
The name of the request variable that determines the module name (by default, this is 'module') can be set in the Application.ModuleVariable property. The following code<br />
<br />
<syntaxhighlight>Application.ModuleVariable := 'm';</syntaxhighlight><br />
<br />
ensures that the following URL is directed to TMyModule:<br />
<nowiki>http://www.mysite.org/mycgi.cgi?m=location</nowiki><br />
<br />
If all this is not enough to determine the module to which the request should be passed, the Application.OnGetModule event can be used. It is of type TGetModuleEvent:<br />
<br />
<syntaxhighlight>type<br />
TGetModuleEvent = Procedure (Sender : TObject; ARequest : TRequest;<br />
Var ModuleClass : TCustomHTTPModuleClass) of object;<br />
</syntaxhighlight><br />
<br />
Creating an event handler for this event allows fine control over the module that is created to handle the request: the request (passed in ARequest) can be examined, and the 'ModuleClass' variable must be set to the class of the module that should handle the request.<br />
<br />
If 'ModuleClass' is 'Nil' on return, an error will be sent to the browser.<br />
<br />
== Using Actions ==<br />
<br />
A module can be used to group certain kinds of actions that logically belong together. Imagine a module TUserModule that is used to handle user management in the webpages. There can be multiple actions associated with a user:<br />
* Creating<br />
* Deleting<br />
* Editing<br />
* Displaying<br />
These different actions can be handled by the same module. One can determine the action from the URL manually, as in:<br />
<nowiki>http://mysite/mycgi.cgi/user?action=delete&id=12</nowiki><br />
This can be automated.<br />
<br />
In order to make it easier to distinguish between various actions, the module has a property actions: this is a collection, in which each item is associated with a different response to the request. The actions have various properties:<br />
; Name : The name of the action. The URL will be examined to determine the name of the action.<br />
; Content : A string. If set, this is sent to the browser.<br />
; Contents :A stringlist. If set, this is sent to the browser.<br />
; ContentProducer :If set, the contentproducer will handle the request.<br />
; Default: if set to 'True', then this action is the default action. That means that if FCL-Web cannot determine the action name, this action will be executed.<br />
; Template : If set, this template will be processed, and the results sent to the browser.<br />
There are also some events:<br />
; BeforeRequest : executed before the request is processed. Can be used to set the 'Content' or other properties.<br />
; AfterRequest : executed after the request is processed.<br />
; OnRequest : an event handler to handle the request. If set, the handler is used to handle the request.<br />
<br />
Again, as in the case of multiple modules, the URL is used to determine which action to execute. The part right after the module part ("user" in this example) is used:<br />
<nowiki>http://mysite/mycgi.cgi/user/delete&id=12</nowiki><br />
would execute the action named 'delete'. This is equivalent to the URL<br />
<nowiki>http://mysite/mycgi.cgi/user?action=delete&id=12</nowiki><br />
<br />
The 'ActionVar' property of the module can be used to set the name of the request variable to use. Setting<br />
<br />
<syntaxhighlight>UserModule.ActionVar := 'a';</syntaxhighlight><br />
<br />
reduces the above URL to<br />
<nowiki>http://mysite/mycgi.cgi/user?a=delete&id=12</nowiki><br />
<br />
If there is only one module in the application, the URL can be shortened to<br />
<nowiki>http://mysite/mycgi.cgi/delete&id=12</nowiki><br />
<br />
== Using HTML Templates ==<br />
For information about using templates, template tags and template tag parameters to generate response pages, please refer to the fptemplate.txt file under your FPC directory in /packages/fcl-base/texts/.<br />
<br />
Example projects that demonstrate using templates can be found under your FPC directory in /packages/fcl-web/examples/fptemplate/ (see the README.txt in there for more).<br />
(In earlier versions, these examples were in the Lazarus directory in /components/fpweb/demo/fptemplate/)<br />
<br />
== Tips & troubleshooting==<br />
<br />
=== Sending result codes ===<br />
To send a different HTTP response than 200 OK, use '''AResponse.Code''' and '''AResponse.CodeText''', e.g.<br />
<syntaxhighlight><br />
AResponse.Code:=404;<br />
AResponse.CodeText:='Document not found';<br />
</syntaxhighlight><br />
<br />
=== Sending binary data ===<br />
An approach that seems to work to send e.g. a tiff file from the web server to the client - adapted from $(fpcdirectory)\packages\fcl-web\examples\jsonrpc\demo1\wmdemo.pp - something like:<br />
<syntaxhighlight><br />
var<br />
<br />
AResponse.ContentStream := TMemoryStream.Create;<br />
try<br />
AResponse.ContentStream.LoadFromFile('/tmp/sample.tiff');<br />
AResponse.ContentType := 'image/tiff'; //or whatever MIME type you want to send<br />
// to do: there is an fpweb example that gets the mime type from the file extension...<br />
AResponse.ContentLength:=AResponse.ContentStream.Size; //apparently doesn't happen automatically?<br />
AResponse.SendContent;<br />
finally<br />
AResponse.ContentStream.Free;<br />
end;<br />
Handled := true; <br />
</syntaxhighlight><br />
<br />
<br />
=== Error: Could not determine HTTP module for request ===<br />
You may have multiple modules and multiple actions. If you specify an URL with only 1 item, like:<br />
<syntaxhighlight lang="html4strict">http://localhost/cgi-bin/somemodule</syntaxhighlight><br />
then fpweb assumes you're specifying an action. If you don't have a default module set, you will get a 500 internal server error (Could not determine HTTP module for request)<br />
<br />
You can modify this behaviour to let fpweb map to a module name instead by setting the application's '''PreferModuleName''' property to true.<br />
<br />
=== Error: response code 500 Internal Server error when trying to handle DELETE method ===<br />
In FPC 2.6.2 and lower, fcl-web does not accept the DELETE method and generates an error.<br />
<br />
== Notes ==<br />
<br />
* The cgiapp unit is deprecated, please use fpcgi as much as possible.<br />
<br />
* The fastcgi, custfcgi, and fpfcgi units are not supported on Darwin at this time, because it uses a different mechanism than the MSG_NOSIGNAL option for recv() to indicate that no SIGPIPE should be raised in case the connection breaks. See http://lists.apple.com/archives/macnetworkprog/2002/Dec/msg00091.html for how this should be fixed.<br />
<br />
* If you deploy your CGI application and get errors like "Error: No action name and no default action", you should make sure there's an action assigned to the URL, or catch non-supported actions with an action marked Default. In both cases, an OnRequest event handler for the action that sets Handled:=true should be used.<br />
<br />
== See also ==<br />
* [[fphttpclient]] Part of fcl-web that can be used stand-alone in client applications<br />
* ''write me!''fphttpserver Small stand alone Object Pascal web server. Can be used to serve fcl-web CGI applications.<br />
* [[CGI_Web_Programming#Debugging_CGI]] Information about debugging CGI applications<br />
* [https://github.com/leonardorame/Ext4-MVC-Tutorial/wiki/Lazarus-Server Part of a tutorial by Leonardo Ramé that shows how to program an fcl-web CGI application; includes example of generating JSON content]<br />
<br />
[[Category:Free Component Library]]<br />
[[Category:Networking]]<br />
[[Category:Lazarus]]<br />
[[Category:FPC]]<br />
[[Category:Components]]<br />
[[Category:Packages]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=fcl-web&diff=84673fcl-web2014-11-28T10:26:15Z<p>Sekelsenmat: /* Reading POST data */</p>
<hr />
<div>{{Web and Networking Programming}}<br />
<br />
== What is fpWeb ==<br />
fpWeb can be used to build cgi applications. '''We need more details here: what other functionality does it have, how does it compare to other frameworks/tools, e.g. Brook'''<br />
<br />
== Using fpWeb together with Lazarus ==<br />
<br />
===Installing the weblaz fpWeb Lazarus Package===<br />
<br />
The first step to do is installing the package which comes in the path lazarus/components/fpweb/weblaz.lpk. As usual with design-time packages, you'll have to rebuild Lazarus.<br />
<br />
===Creating a CGI application===<br />
<br />
After the weblaz package is installed, a very simple CGI web application which displays an HTML page can be created by going to the Lazarus menu "File->New...". From the list of possible applications select "CGI Application" as in the image below, which will create a main CGI project file and a fpweb web module.<br />
<br />
[[Image:New_cgi.PNG]]<br />
<br />
The TFPWebModule allows you to manipulate properties and events using the Object Inspector.<br />
<br />
To add code to show the page, a request handler should be added. To do this, double click the OnRequest property in the object inspector, as in the image below:<br />
<br />
[[Image:Webmodule.PNG]]<br />
<br />
In the event handler one should write the HTML code which will be displayed by the browser. To avoid mixing Pascal and HTML, this page can be loaded from the directory the CGI executable is in by using AResponse.Contents.LoadFromFile(). <br />
<br />
The type of the response should be set in AResponse.ContentType. For HTML pages this should have the value 'text/html;charset=utf-8'. <br />
<br />
Finally, Handled should be set to True to indicate that the request was successfully handled (and return a 200 OK status code to the browser). After adding this code, the web module should look like this:<br />
<br />
<syntaxhighlight>unit mainpage;<br />
<br />
{$mode objfpc}{$H+}<br />
<br />
interface<br />
<br />
uses<br />
Classes, SysUtils, FileUtil, HTTPDefs, websession, fpHTTP, fpWeb; <br />
<br />
type<br />
<br />
{ TFPWebModule1 }<br />
<br />
TFPWebModule1 = class(TFPWebModule)<br />
procedure DataModuleRequest(Sender: TObject; ARequest: TRequest;<br />
AResponse: TResponse; var Handled: Boolean);<br />
private<br />
{ private declarations }<br />
public<br />
{ public declarations }<br />
end; <br />
<br />
var<br />
FPWebModule1: TFPWebModule1; <br />
<br />
implementation<br />
<br />
{$R *.lfm}<br />
<br />
{ TFPWebModule1 }<br />
<br />
procedure TFPWebModule1.DataModuleRequest(Sender: TObject; ARequest: TRequest;<br />
AResponse: TResponse; var Handled: Boolean);<br />
begin<br />
AResponse.ContentType := 'text/html;charset=utf-8';<br />
AResponse.Contents.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'mainpage.html');<br />
Handled := True;<br />
end;<br />
<br />
begin<br />
RegisterHTTPModule('TFPWebModule1', TFPWebModule1);<br />
end.</syntaxhighlight><br />
<br />
=== Deploying the CGI application ===<br />
<br />
This section assumes the Apache web server is used. Of course, other web servers that support CGI (nginx, cherokee) can be used, too.<br />
<br />
Apache can be downloaded here: http://httpd.apache.org/download.cgi or installed using your distribution's package manager.<br />
<br />
The default installation of Apache will treat all files located in its cgi-bin directory as CGI programs, so the user won't be able to access plain HTML files placed there. This directory can be set in the file httpd.conf in the following section:<br />
<br />
<pre><br />
#<br />
# ScriptAlias: This controls which directories contain server scripts.<br />
# ScriptAliases are essentially the same as Aliases, except that<br />
# documents in the target directory are treated as applications and<br />
# run by the server when requested rather than as documents sent to the<br />
# client. The same rules about trailing "/" apply to ScriptAlias<br />
# directives as to Alias.<br />
#<br />
ScriptAlias /cgi-bin/ "C:/Program Files/Apache Software Foundation/Apache2.2/cgi-bin/"<br />
</pre><br />
<br />
If you place an executable called "mywebpage.cgi" in this directory, then the page can be accessed as http://localhost/cgi-bin/mywebpage.cgi (or remotely with the corresponding IP address or domain name).<br />
<br />
fcl-web with Lazarus on Windows produces .exe files. For Apache to serve these files you have to add this:<br />
<pre><br />
AddHandler cgi-script .exe<br />
</pre><br />
<br />
And to serve your executables from another directory, you add this:<br />
<pre><br />
ScriptAlias /bin/ "C:/lazarus_projects/test-fclweb/bin/"<br />
<Directory "C:/lazarus_projects/test-fclweb/bin/"><br />
AllowOverride None<br />
Options None<br />
Order allow,deny<br />
Allow from all<br />
</Directory><br />
</pre><br />
<br />
===Formatting the HTML and Reading Query fields===<br />
<br />
The previous example just showed a plain HTML page. One might wish to e.g.<br />
* dynamically change the HTML page output, and<br />
* as read the variables the browser passed to the webpage in Query fields (in e.g. HTTP GET and HTTP POST actions). <br />
<br />
A simple solution for the first problem is simply using the standard Pascal routine Format and adding %s or %d in the HTML file in the appropriate places which will receive a custom value.<br />
<br />
===Reading GET data===<br />
To read the GET variables one can use ARequest.QueryFields, which is a TStrings descendent. Each variable will be in a separate line in the TStrings in the format variablename=value, similarly to how they are shown in the browser page address. To search for a specific variable one can use ARequest.QueryFields.Values[], passing the variable name in the brackets to receive its value back, instead of parsing the string manually. <br />
<br />
The resulting code:<br />
<br />
<syntaxhighlight>procedure TFPWebModule1.DataModuleRequest(Sender: TObject; ARequest: TRequest;<br />
AResponse: TResponse; var Handled: Boolean);<br />
var<br />
HexText, AsciiText: string;<br />
begin<br />
HexText := ARequest.QueryFields.Values['hex'];<br />
AsciiText := HexToAnsii(HexText);<br />
<br />
AResponse.ContentType := 'text/html;charset=utf-8';<br />
AResponse.Contents.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'mainpage.html');<br />
AResponse.Contents.Text := Format(AResponse.Contents.Text,<br />
[HexText, AsciiText]);<br />
Handled := True;<br />
end;</syntaxhighlight><br />
<br />
===Reading POST data===<br />
<br />
Data submitted by POST requests can be obtained from <code>TRequest.Content</code>. It will come without the request headers - in other words it contains the body of the request.<br />
<br />
Submitted form data can also be accessed using <code>TRequest.ContentFields</code> which is the content parsed as fields separated by & and decoded. For example, the following set of form values:<br />
<br />
login: dfg 345&&<br />
login_senha: ====<br />
email: dfg<br />
<br />
Will be encoded in 'APPLICATION/X-WWW-FORM-URLENCODED' like this:<br />
<br />
login=dfg+345%26%26&login_senha=%3D%3D%3D%3D&email=dfg<br />
<br />
And will be available in TRequest.ContentFields via the line index or using the Values property, which is more convenient:<br />
<br />
TRequest.ContentFields[0]: login=dfg 345&&<br />
TRequest.ContentFields[1]: login_senha=====<br />
TRequest.ContentFields[2]: email=dfg<br />
TRequest.ContentFields.Values['email']: dfg<br />
<br />
If using other mime-types than 'MULTIPART/FORM-DATA' and 'APPLICATION/X-WWW-FORM-URLENCODED' (the types supported by HTML forms):<br />
* content is only available in TRequest.Content, not TRequest.ContentFields<br />
* use of these mime-types raises an exception for FPC 2.4.2 (fixed in FPC 2.5+).<br />
<br />
Note that HTTP POST can also send Query fields (in the URL), e.g. http://server/bla?question=how, and those are accessed by TRequest.QueryFields as explained in the previous section.<br />
<br />
<syntaxhighlight>procedure TFPWebModule1.DataModuleRequest(Sender: TObject; ARequest: TRequest;<br />
AResponse: TResponse; var Handled: Boolean);<br />
var<br />
lData: String;<br />
begin<br />
lData := ARequest.Content;<br />
</syntaxhighlight><br />
<br />
=== Reading POST binary data ===<br />
To receive data on the server that has been POSTed e.g. as multipart/form-data, use something like this:<br />
<syntaxhighlight><br />
procedure TMainWebModule.TFPWebActions2Request(Sender: TObject;<br />
ARequest: TRequest; AResponse: TResponse; var Handled: Boolean);<br />
var<br />
i: Integer;<br />
begin <br />
// Process all received files<br />
for i := 0 to ARequest.Files.Count - 1 do<br />
begin<br />
// Doing something else than writeln is highly recommended ;)<br />
writeln ('Received Filename: '+ARequest.Files[i].LocalFileName);<br />
end;<br />
<br />
Handled := true;<br />
end;<br />
</syntaxhighlight><br />
<br />
The client can send data using e.g. FileFormPost.<br />
<br />
== Using multiple modules ==<br />
If there is only one module in the web application, all requests will be directed to this module. <br />
<br />
As your web application grows, multiple modules can be used. A new module can be added by choosing 'File - New' and then one of 'Web module' or 'HTML Web Module'. <br />
<br />
FCL-web uses the URL to determine how a HTTP request should be handled. It must therefore know which web-modules exist in the application. To achieve this, each module must be registered.<br />
<br />
Each module is registered with fcl-web in the initialization section of the unit it is defined in:<br />
<br />
<syntaxhighlight>RegisterHTTPModule('location', TMyModule);</syntaxhighlight><br />
<br />
The module will then be invoked if an URL of the form <br />
<nowiki>http://www.mysite.org/mycgi.cgi/location</nowiki><br />
or<br />
<nowiki>http://www.mysite.org/mycgi.cgi?module=location</nowiki><br />
is used.<br />
<br />
If multiple modules are present, the name of the module must appear in the URL, or an error will be raised.<br />
<br />
This behaviour can also be forced for applications that have only a single module by setting the Application's property AllowDefaultModule to false:<br />
<br />
<syntaxhighlight>Application.AllowDefaultModule := False;</syntaxhighlight><br />
<br />
In that case, the fcl-web application will always require the name of the module in the URL.<br />
<br />
The name of the request variable that determines the module name (by default, this is 'module') can be set in the Application.ModuleVariable property. The following code<br />
<br />
<syntaxhighlight>Application.ModuleVariable := 'm';</syntaxhighlight><br />
<br />
ensures that the following URL is directed to TMyModule:<br />
<nowiki>http://www.mysite.org/mycgi.cgi?m=location</nowiki><br />
<br />
If all this is not enough to determine the module to which the request should be passed, the Application.OnGetModule event can be used. It is of type TGetModuleEvent:<br />
<br />
<syntaxhighlight>type<br />
TGetModuleEvent = Procedure (Sender : TObject; ARequest : TRequest;<br />
Var ModuleClass : TCustomHTTPModuleClass) of object;<br />
</syntaxhighlight><br />
<br />
Creating an event handler for this event allows fine control over the module that is created to handle the request: the request (passed in ARequest) can be examined, and the 'ModuleClass' variable must be set to the class of the module that should handle the request.<br />
<br />
If 'ModuleClass' is 'Nil' on return, an error will be sent to the browser.<br />
<br />
== Using Actions ==<br />
<br />
A module can be used to group certain kinds of actions that logically belong together. Imagine a module TUserModule that is used to handle user management in the webpages. There can be multiple actions associated with a user:<br />
* Creating<br />
* Deleting<br />
* Editing<br />
* Displaying<br />
These different actions can be handled by the same module. One can determine the action from the URL manually, as in:<br />
<nowiki>http://mysite/mycgi.cgi/user?action=delete&id=12</nowiki><br />
This can be automated.<br />
<br />
In order to make it easier to distinguish between various actions, the module has a property actions: this is a collection, in which each item is associated with a different response to the request. The actions have various properties:<br />
; Name : The name of the action. The URL will be examined to determine the name of the action.<br />
; Content : A string. If set, this is sent to the browser.<br />
; Contents :A stringlist. If set, this is sent to the browser.<br />
; ContentProducer :If set, the contentproducer will handle the request.<br />
; Default: if set to 'True', then this action is the default action. That means that if FCL-Web cannot determine the action name, this action will be executed.<br />
; Template : If set, this template will be processed, and the results sent to the browser.<br />
There are also some events:<br />
; BeforeRequest : executed before the request is processed. Can be used to set the 'Content' or other properties.<br />
; AfterRequest : executed after the request is processed.<br />
; OnRequest : an event handler to handle the request. If set, the handler is used to handle the request.<br />
<br />
Again, as in the case of multiple modules, the URL is used to determine which action to execute. The part right after the module part ("user" in this example) is used:<br />
<nowiki>http://mysite/mycgi.cgi/user/delete&id=12</nowiki><br />
would execute the action named 'delete'. This is equivalent to the URL<br />
<nowiki>http://mysite/mycgi.cgi/user?action=delete&id=12</nowiki><br />
<br />
The 'ActionVar' property of the module can be used to set the name of the request variable to use. Setting<br />
<br />
<syntaxhighlight>UserModule.ActionVar := 'a';</syntaxhighlight><br />
<br />
reduces the above URL to<br />
<nowiki>http://mysite/mycgi.cgi/user?a=delete&id=12</nowiki><br />
<br />
If there is only one module in the application, the URL can be shortened to<br />
<nowiki>http://mysite/mycgi.cgi/delete&id=12</nowiki><br />
<br />
== Using HTML Templates ==<br />
For information about using templates, template tags and template tag parameters to generate response pages, please refer to the fptemplate.txt file under your FPC directory in /packages/fcl-base/texts/.<br />
<br />
Example projects that demonstrate using templates can be found under your FPC directory in /packages/fcl-web/examples/fptemplate/ (see the README.txt in there for more).<br />
(In earlier versions, these examples were in the Lazarus directory in /components/fpweb/demo/fptemplate/)<br />
<br />
== Tips & troubleshooting==<br />
<br />
=== Sending result codes ===<br />
To send a different HTTP response than 200 OK, use '''AResponse.Code''' and '''AResponse.CodeText''', e.g.<br />
<syntaxhighlight><br />
AResponse.Code:=404;<br />
AResponse.CodeText:='Document not found';<br />
</syntaxhighlight><br />
<br />
=== Sending binary data ===<br />
An approach that seems to work to send e.g. a tiff file from the web server to the client - adapted from $(fpcdirectory)\packages\fcl-web\examples\jsonrpc\demo1\wmdemo.pp - something like:<br />
<syntaxhighlight><br />
var<br />
<br />
AResponse.ContentStream := TMemoryStream.Create;<br />
try<br />
AResponse.ContentStream.LoadFromFile('/tmp/sample.tiff');<br />
AResponse.ContentType := 'image/tiff'; //or whatever MIME type you want to send<br />
// to do: there is an fpweb example that gets the mime type from the file extension...<br />
AResponse.ContentLength:=AResponse.ContentStream.Size; //apparently doesn't happen automatically?<br />
AResponse.SendContent;<br />
finally<br />
AResponse.ContentStream.Free;<br />
end;<br />
Handled := true; <br />
</syntaxhighlight><br />
<br />
<br />
=== Error: Could not determine HTTP module for request ===<br />
You may have multiple modules and multiple actions. If you specify an URL with only 1 item, like:<br />
<syntaxhighlight lang="html4strict">http://localhost/cgi-bin/somemodule</syntaxhighlight><br />
then fpweb assumes you're specifying an action. If you don't have a default module set, you will get a 500 internal server error (Could not determine HTTP module for request)<br />
<br />
You can modify this behaviour to let fpweb map to a module name instead by setting the application's '''PreferModuleName''' property to true.<br />
<br />
=== Error: response code 500 Internal Server error when trying to handle DELETE method ===<br />
In FPC 2.6.2 and lower, fcl-web does not accept the DELETE method and generates an error.<br />
<br />
== Notes ==<br />
<br />
* The cgiapp unit is deprecated, please use fpcgi as much as possible.<br />
<br />
* The fastcgi, custfcgi, and fpfcgi units are not supported on Darwin at this time, because it uses a different mechanism than the MSG_NOSIGNAL option for recv() to indicate that no SIGPIPE should be raised in case the connection breaks. See http://lists.apple.com/archives/macnetworkprog/2002/Dec/msg00091.html for how this should be fixed.<br />
<br />
* If you deploy your CGI application and get errors like "Error: No action name and no default action", you should make sure there's an action assigned to the URL, or catch non-supported actions with an action marked Default. In both cases, an OnRequest event handler for the action that sets Handled:=true should be used.<br />
<br />
== See also ==<br />
* [[fphttpclient]] Part of fcl-web that can be used stand-alone in client applications<br />
* ''write me!''fphttpserver Small stand alone Object Pascal web server. Can be used to serve fcl-web CGI applications.<br />
* [[CGI_Web_Programming#Debugging_CGI]] Information about debugging CGI applications<br />
* [https://github.com/leonardorame/Ext4-MVC-Tutorial/wiki/Lazarus-Server Part of a tutorial by Leonardo Ramé that shows how to program an fcl-web CGI application; includes example of generating JSON content]<br />
<br />
[[Category:Free Component Library]]<br />
[[Category:Networking]]<br />
[[Category:Lazarus]]<br />
[[Category:FPC]]<br />
[[Category:Components]]<br />
[[Category:Packages]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=fcl-web&diff=84672fcl-web2014-11-28T10:22:26Z<p>Sekelsenmat: /* Reading POST data */</p>
<hr />
<div>{{Web and Networking Programming}}<br />
<br />
== What is fpWeb ==<br />
fpWeb can be used to build cgi applications. '''We need more details here: what other functionality does it have, how does it compare to other frameworks/tools, e.g. Brook'''<br />
<br />
== Using fpWeb together with Lazarus ==<br />
<br />
===Installing the weblaz fpWeb Lazarus Package===<br />
<br />
The first step to do is installing the package which comes in the path lazarus/components/fpweb/weblaz.lpk. As usual with design-time packages, you'll have to rebuild Lazarus.<br />
<br />
===Creating a CGI application===<br />
<br />
After the weblaz package is installed, a very simple CGI web application which displays an HTML page can be created by going to the Lazarus menu "File->New...". From the list of possible applications select "CGI Application" as in the image below, which will create a main CGI project file and a fpweb web module.<br />
<br />
[[Image:New_cgi.PNG]]<br />
<br />
The TFPWebModule allows you to manipulate properties and events using the Object Inspector.<br />
<br />
To add code to show the page, a request handler should be added. To do this, double click the OnRequest property in the object inspector, as in the image below:<br />
<br />
[[Image:Webmodule.PNG]]<br />
<br />
In the event handler one should write the HTML code which will be displayed by the browser. To avoid mixing Pascal and HTML, this page can be loaded from the directory the CGI executable is in by using AResponse.Contents.LoadFromFile(). <br />
<br />
The type of the response should be set in AResponse.ContentType. For HTML pages this should have the value 'text/html;charset=utf-8'. <br />
<br />
Finally, Handled should be set to True to indicate that the request was successfully handled (and return a 200 OK status code to the browser). After adding this code, the web module should look like this:<br />
<br />
<syntaxhighlight>unit mainpage;<br />
<br />
{$mode objfpc}{$H+}<br />
<br />
interface<br />
<br />
uses<br />
Classes, SysUtils, FileUtil, HTTPDefs, websession, fpHTTP, fpWeb; <br />
<br />
type<br />
<br />
{ TFPWebModule1 }<br />
<br />
TFPWebModule1 = class(TFPWebModule)<br />
procedure DataModuleRequest(Sender: TObject; ARequest: TRequest;<br />
AResponse: TResponse; var Handled: Boolean);<br />
private<br />
{ private declarations }<br />
public<br />
{ public declarations }<br />
end; <br />
<br />
var<br />
FPWebModule1: TFPWebModule1; <br />
<br />
implementation<br />
<br />
{$R *.lfm}<br />
<br />
{ TFPWebModule1 }<br />
<br />
procedure TFPWebModule1.DataModuleRequest(Sender: TObject; ARequest: TRequest;<br />
AResponse: TResponse; var Handled: Boolean);<br />
begin<br />
AResponse.ContentType := 'text/html;charset=utf-8';<br />
AResponse.Contents.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'mainpage.html');<br />
Handled := True;<br />
end;<br />
<br />
begin<br />
RegisterHTTPModule('TFPWebModule1', TFPWebModule1);<br />
end.</syntaxhighlight><br />
<br />
=== Deploying the CGI application ===<br />
<br />
This section assumes the Apache web server is used. Of course, other web servers that support CGI (nginx, cherokee) can be used, too.<br />
<br />
Apache can be downloaded here: http://httpd.apache.org/download.cgi or installed using your distribution's package manager.<br />
<br />
The default installation of Apache will treat all files located in its cgi-bin directory as CGI programs, so the user won't be able to access plain HTML files placed there. This directory can be set in the file httpd.conf in the following section:<br />
<br />
<pre><br />
#<br />
# ScriptAlias: This controls which directories contain server scripts.<br />
# ScriptAliases are essentially the same as Aliases, except that<br />
# documents in the target directory are treated as applications and<br />
# run by the server when requested rather than as documents sent to the<br />
# client. The same rules about trailing "/" apply to ScriptAlias<br />
# directives as to Alias.<br />
#<br />
ScriptAlias /cgi-bin/ "C:/Program Files/Apache Software Foundation/Apache2.2/cgi-bin/"<br />
</pre><br />
<br />
If you place an executable called "mywebpage.cgi" in this directory, then the page can be accessed as http://localhost/cgi-bin/mywebpage.cgi (or remotely with the corresponding IP address or domain name).<br />
<br />
fcl-web with Lazarus on Windows produces .exe files. For Apache to serve these files you have to add this:<br />
<pre><br />
AddHandler cgi-script .exe<br />
</pre><br />
<br />
And to serve your executables from another directory, you add this:<br />
<pre><br />
ScriptAlias /bin/ "C:/lazarus_projects/test-fclweb/bin/"<br />
<Directory "C:/lazarus_projects/test-fclweb/bin/"><br />
AllowOverride None<br />
Options None<br />
Order allow,deny<br />
Allow from all<br />
</Directory><br />
</pre><br />
<br />
===Formatting the HTML and Reading Query fields===<br />
<br />
The previous example just showed a plain HTML page. One might wish to e.g.<br />
* dynamically change the HTML page output, and<br />
* as read the variables the browser passed to the webpage in Query fields (in e.g. HTTP GET and HTTP POST actions). <br />
<br />
A simple solution for the first problem is simply using the standard Pascal routine Format and adding %s or %d in the HTML file in the appropriate places which will receive a custom value.<br />
<br />
===Reading GET data===<br />
To read the GET variables one can use ARequest.QueryFields, which is a TStrings descendent. Each variable will be in a separate line in the TStrings in the format variablename=value, similarly to how they are shown in the browser page address. To search for a specific variable one can use ARequest.QueryFields.Values[], passing the variable name in the brackets to receive its value back, instead of parsing the string manually. <br />
<br />
The resulting code:<br />
<br />
<syntaxhighlight>procedure TFPWebModule1.DataModuleRequest(Sender: TObject; ARequest: TRequest;<br />
AResponse: TResponse; var Handled: Boolean);<br />
var<br />
HexText, AsciiText: string;<br />
begin<br />
HexText := ARequest.QueryFields.Values['hex'];<br />
AsciiText := HexToAnsii(HexText);<br />
<br />
AResponse.ContentType := 'text/html;charset=utf-8';<br />
AResponse.Contents.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'mainpage.html');<br />
AResponse.Contents.Text := Format(AResponse.Contents.Text,<br />
[HexText, AsciiText]);<br />
Handled := True;<br />
end;</syntaxhighlight><br />
<br />
===Reading POST data===<br />
<br />
Data submitted by POST requests can be obtained from <code>TRequest.Content</code>. It will come without the request headers - in other words it contains the body of the request.<br />
<br />
Submitted form data can also be accessed using <code>TRequest.ContentFields</code> which is the content parsed as fields separated by & and decoded. For example, the following set of form values:<br />
<br />
login: dfg 345&&<br />
login_senha: ====<br />
email: dfg<br />
<br />
Will be encoded in 'APPLICATION/X-WWW-FORM-URLENCODED' like this:<br />
<br />
login=dfg+345%26%26&login_senha=%3D%3D%3D%3D&email=dfg<br />
<br />
And will be available in TRequest.ContentFields like this:<br />
<br />
TRequest.ContentFields[0]: login=dfg 345&&<br />
TRequest.ContentFields[1]: login_senha=====<br />
TRequest.ContentFields[2]: email=dfg<br />
<br />
If using other mime-types than 'MULTIPART/FORM-DATA' and 'APPLICATION/X-WWW-FORM-URLENCODED' (the types supported by HTML forms):<br />
* content is only available in TRequest.Content, not TRequest.ContentFields<br />
* use of these mime-types raises an exception for FPC 2.4.2 (fixed in FPC 2.5+).<br />
<br />
Note that HTTP POST can also send Query fields (in the URL), e.g. http://server/bla?question=how, and those are accessed by TRequest.QueryFields as explained in the previous section.<br />
<br />
<syntaxhighlight>procedure TFPWebModule1.DataModuleRequest(Sender: TObject; ARequest: TRequest;<br />
AResponse: TResponse; var Handled: Boolean);<br />
var<br />
lData: String;<br />
begin<br />
lData := ARequest.Content;<br />
</syntaxhighlight><br />
<br />
=== Reading POST binary data ===<br />
To receive data on the server that has been POSTed e.g. as multipart/form-data, use something like this:<br />
<syntaxhighlight><br />
procedure TMainWebModule.TFPWebActions2Request(Sender: TObject;<br />
ARequest: TRequest; AResponse: TResponse; var Handled: Boolean);<br />
var<br />
i: Integer;<br />
begin <br />
// Process all received files<br />
for i := 0 to ARequest.Files.Count - 1 do<br />
begin<br />
// Doing something else than writeln is highly recommended ;)<br />
writeln ('Received Filename: '+ARequest.Files[i].LocalFileName);<br />
end;<br />
<br />
Handled := true;<br />
end;<br />
</syntaxhighlight><br />
<br />
The client can send data using e.g. FileFormPost.<br />
<br />
== Using multiple modules ==<br />
If there is only one module in the web application, all requests will be directed to this module. <br />
<br />
As your web application grows, multiple modules can be used. A new module can be added by choosing 'File - New' and then one of 'Web module' or 'HTML Web Module'. <br />
<br />
FCL-web uses the URL to determine how a HTTP request should be handled. It must therefore know which web-modules exist in the application. To achieve this, each module must be registered.<br />
<br />
Each module is registered with fcl-web in the initialization section of the unit it is defined in:<br />
<br />
<syntaxhighlight>RegisterHTTPModule('location', TMyModule);</syntaxhighlight><br />
<br />
The module will then be invoked if an URL of the form <br />
<nowiki>http://www.mysite.org/mycgi.cgi/location</nowiki><br />
or<br />
<nowiki>http://www.mysite.org/mycgi.cgi?module=location</nowiki><br />
is used.<br />
<br />
If multiple modules are present, the name of the module must appear in the URL, or an error will be raised.<br />
<br />
This behaviour can also be forced for applications that have only a single module by setting the Application's property AllowDefaultModule to false:<br />
<br />
<syntaxhighlight>Application.AllowDefaultModule := False;</syntaxhighlight><br />
<br />
In that case, the fcl-web application will always require the name of the module in the URL.<br />
<br />
The name of the request variable that determines the module name (by default, this is 'module') can be set in the Application.ModuleVariable property. The following code<br />
<br />
<syntaxhighlight>Application.ModuleVariable := 'm';</syntaxhighlight><br />
<br />
ensures that the following URL is directed to TMyModule:<br />
<nowiki>http://www.mysite.org/mycgi.cgi?m=location</nowiki><br />
<br />
If all this is not enough to determine the module to which the request should be passed, the Application.OnGetModule event can be used. It is of type TGetModuleEvent:<br />
<br />
<syntaxhighlight>type<br />
TGetModuleEvent = Procedure (Sender : TObject; ARequest : TRequest;<br />
Var ModuleClass : TCustomHTTPModuleClass) of object;<br />
</syntaxhighlight><br />
<br />
Creating an event handler for this event allows fine control over the module that is created to handle the request: the request (passed in ARequest) can be examined, and the 'ModuleClass' variable must be set to the class of the module that should handle the request.<br />
<br />
If 'ModuleClass' is 'Nil' on return, an error will be sent to the browser.<br />
<br />
== Using Actions ==<br />
<br />
A module can be used to group certain kinds of actions that logically belong together. Imagine a module TUserModule that is used to handle user management in the webpages. There can be multiple actions associated with a user:<br />
* Creating<br />
* Deleting<br />
* Editing<br />
* Displaying<br />
These different actions can be handled by the same module. One can determine the action from the URL manually, as in:<br />
<nowiki>http://mysite/mycgi.cgi/user?action=delete&id=12</nowiki><br />
This can be automated.<br />
<br />
In order to make it easier to distinguish between various actions, the module has a property actions: this is a collection, in which each item is associated with a different response to the request. The actions have various properties:<br />
; Name : The name of the action. The URL will be examined to determine the name of the action.<br />
; Content : A string. If set, this is sent to the browser.<br />
; Contents :A stringlist. If set, this is sent to the browser.<br />
; ContentProducer :If set, the contentproducer will handle the request.<br />
; Default: if set to 'True', then this action is the default action. That means that if FCL-Web cannot determine the action name, this action will be executed.<br />
; Template : If set, this template will be processed, and the results sent to the browser.<br />
There are also some events:<br />
; BeforeRequest : executed before the request is processed. Can be used to set the 'Content' or other properties.<br />
; AfterRequest : executed after the request is processed.<br />
; OnRequest : an event handler to handle the request. If set, the handler is used to handle the request.<br />
<br />
Again, as in the case of multiple modules, the URL is used to determine which action to execute. The part right after the module part ("user" in this example) is used:<br />
<nowiki>http://mysite/mycgi.cgi/user/delete&id=12</nowiki><br />
would execute the action named 'delete'. This is equivalent to the URL<br />
<nowiki>http://mysite/mycgi.cgi/user?action=delete&id=12</nowiki><br />
<br />
The 'ActionVar' property of the module can be used to set the name of the request variable to use. Setting<br />
<br />
<syntaxhighlight>UserModule.ActionVar := 'a';</syntaxhighlight><br />
<br />
reduces the above URL to<br />
<nowiki>http://mysite/mycgi.cgi/user?a=delete&id=12</nowiki><br />
<br />
If there is only one module in the application, the URL can be shortened to<br />
<nowiki>http://mysite/mycgi.cgi/delete&id=12</nowiki><br />
<br />
== Using HTML Templates ==<br />
For information about using templates, template tags and template tag parameters to generate response pages, please refer to the fptemplate.txt file under your FPC directory in /packages/fcl-base/texts/.<br />
<br />
Example projects that demonstrate using templates can be found under your FPC directory in /packages/fcl-web/examples/fptemplate/ (see the README.txt in there for more).<br />
(In earlier versions, these examples were in the Lazarus directory in /components/fpweb/demo/fptemplate/)<br />
<br />
== Tips & troubleshooting==<br />
<br />
=== Sending result codes ===<br />
To send a different HTTP response than 200 OK, use '''AResponse.Code''' and '''AResponse.CodeText''', e.g.<br />
<syntaxhighlight><br />
AResponse.Code:=404;<br />
AResponse.CodeText:='Document not found';<br />
</syntaxhighlight><br />
<br />
=== Sending binary data ===<br />
An approach that seems to work to send e.g. a tiff file from the web server to the client - adapted from $(fpcdirectory)\packages\fcl-web\examples\jsonrpc\demo1\wmdemo.pp - something like:<br />
<syntaxhighlight><br />
var<br />
<br />
AResponse.ContentStream := TMemoryStream.Create;<br />
try<br />
AResponse.ContentStream.LoadFromFile('/tmp/sample.tiff');<br />
AResponse.ContentType := 'image/tiff'; //or whatever MIME type you want to send<br />
// to do: there is an fpweb example that gets the mime type from the file extension...<br />
AResponse.ContentLength:=AResponse.ContentStream.Size; //apparently doesn't happen automatically?<br />
AResponse.SendContent;<br />
finally<br />
AResponse.ContentStream.Free;<br />
end;<br />
Handled := true; <br />
</syntaxhighlight><br />
<br />
<br />
=== Error: Could not determine HTTP module for request ===<br />
You may have multiple modules and multiple actions. If you specify an URL with only 1 item, like:<br />
<syntaxhighlight lang="html4strict">http://localhost/cgi-bin/somemodule</syntaxhighlight><br />
then fpweb assumes you're specifying an action. If you don't have a default module set, you will get a 500 internal server error (Could not determine HTTP module for request)<br />
<br />
You can modify this behaviour to let fpweb map to a module name instead by setting the application's '''PreferModuleName''' property to true.<br />
<br />
=== Error: response code 500 Internal Server error when trying to handle DELETE method ===<br />
In FPC 2.6.2 and lower, fcl-web does not accept the DELETE method and generates an error.<br />
<br />
== Notes ==<br />
<br />
* The cgiapp unit is deprecated, please use fpcgi as much as possible.<br />
<br />
* The fastcgi, custfcgi, and fpfcgi units are not supported on Darwin at this time, because it uses a different mechanism than the MSG_NOSIGNAL option for recv() to indicate that no SIGPIPE should be raised in case the connection breaks. See http://lists.apple.com/archives/macnetworkprog/2002/Dec/msg00091.html for how this should be fixed.<br />
<br />
* If you deploy your CGI application and get errors like "Error: No action name and no default action", you should make sure there's an action assigned to the URL, or catch non-supported actions with an action marked Default. In both cases, an OnRequest event handler for the action that sets Handled:=true should be used.<br />
<br />
== See also ==<br />
* [[fphttpclient]] Part of fcl-web that can be used stand-alone in client applications<br />
* ''write me!''fphttpserver Small stand alone Object Pascal web server. Can be used to serve fcl-web CGI applications.<br />
* [[CGI_Web_Programming#Debugging_CGI]] Information about debugging CGI applications<br />
* [https://github.com/leonardorame/Ext4-MVC-Tutorial/wiki/Lazarus-Server Part of a tutorial by Leonardo Ramé that shows how to program an fcl-web CGI application; includes example of generating JSON content]<br />
<br />
[[Category:Free Component Library]]<br />
[[Category:Networking]]<br />
[[Category:Lazarus]]<br />
[[Category:FPC]]<br />
[[Category:Components]]<br />
[[Category:Packages]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=fcl-web&diff=84671fcl-web2014-11-28T10:21:41Z<p>Sekelsenmat: /* Reading POST data */</p>
<hr />
<div>{{Web and Networking Programming}}<br />
<br />
== What is fpWeb ==<br />
fpWeb can be used to build cgi applications. '''We need more details here: what other functionality does it have, how does it compare to other frameworks/tools, e.g. Brook'''<br />
<br />
== Using fpWeb together with Lazarus ==<br />
<br />
===Installing the weblaz fpWeb Lazarus Package===<br />
<br />
The first step to do is installing the package which comes in the path lazarus/components/fpweb/weblaz.lpk. As usual with design-time packages, you'll have to rebuild Lazarus.<br />
<br />
===Creating a CGI application===<br />
<br />
After the weblaz package is installed, a very simple CGI web application which displays an HTML page can be created by going to the Lazarus menu "File->New...". From the list of possible applications select "CGI Application" as in the image below, which will create a main CGI project file and a fpweb web module.<br />
<br />
[[Image:New_cgi.PNG]]<br />
<br />
The TFPWebModule allows you to manipulate properties and events using the Object Inspector.<br />
<br />
To add code to show the page, a request handler should be added. To do this, double click the OnRequest property in the object inspector, as in the image below:<br />
<br />
[[Image:Webmodule.PNG]]<br />
<br />
In the event handler one should write the HTML code which will be displayed by the browser. To avoid mixing Pascal and HTML, this page can be loaded from the directory the CGI executable is in by using AResponse.Contents.LoadFromFile(). <br />
<br />
The type of the response should be set in AResponse.ContentType. For HTML pages this should have the value 'text/html;charset=utf-8'. <br />
<br />
Finally, Handled should be set to True to indicate that the request was successfully handled (and return a 200 OK status code to the browser). After adding this code, the web module should look like this:<br />
<br />
<syntaxhighlight>unit mainpage;<br />
<br />
{$mode objfpc}{$H+}<br />
<br />
interface<br />
<br />
uses<br />
Classes, SysUtils, FileUtil, HTTPDefs, websession, fpHTTP, fpWeb; <br />
<br />
type<br />
<br />
{ TFPWebModule1 }<br />
<br />
TFPWebModule1 = class(TFPWebModule)<br />
procedure DataModuleRequest(Sender: TObject; ARequest: TRequest;<br />
AResponse: TResponse; var Handled: Boolean);<br />
private<br />
{ private declarations }<br />
public<br />
{ public declarations }<br />
end; <br />
<br />
var<br />
FPWebModule1: TFPWebModule1; <br />
<br />
implementation<br />
<br />
{$R *.lfm}<br />
<br />
{ TFPWebModule1 }<br />
<br />
procedure TFPWebModule1.DataModuleRequest(Sender: TObject; ARequest: TRequest;<br />
AResponse: TResponse; var Handled: Boolean);<br />
begin<br />
AResponse.ContentType := 'text/html;charset=utf-8';<br />
AResponse.Contents.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'mainpage.html');<br />
Handled := True;<br />
end;<br />
<br />
begin<br />
RegisterHTTPModule('TFPWebModule1', TFPWebModule1);<br />
end.</syntaxhighlight><br />
<br />
=== Deploying the CGI application ===<br />
<br />
This section assumes the Apache web server is used. Of course, other web servers that support CGI (nginx, cherokee) can be used, too.<br />
<br />
Apache can be downloaded here: http://httpd.apache.org/download.cgi or installed using your distribution's package manager.<br />
<br />
The default installation of Apache will treat all files located in its cgi-bin directory as CGI programs, so the user won't be able to access plain HTML files placed there. This directory can be set in the file httpd.conf in the following section:<br />
<br />
<pre><br />
#<br />
# ScriptAlias: This controls which directories contain server scripts.<br />
# ScriptAliases are essentially the same as Aliases, except that<br />
# documents in the target directory are treated as applications and<br />
# run by the server when requested rather than as documents sent to the<br />
# client. The same rules about trailing "/" apply to ScriptAlias<br />
# directives as to Alias.<br />
#<br />
ScriptAlias /cgi-bin/ "C:/Program Files/Apache Software Foundation/Apache2.2/cgi-bin/"<br />
</pre><br />
<br />
If you place an executable called "mywebpage.cgi" in this directory, then the page can be accessed as http://localhost/cgi-bin/mywebpage.cgi (or remotely with the corresponding IP address or domain name).<br />
<br />
fcl-web with Lazarus on Windows produces .exe files. For Apache to serve these files you have to add this:<br />
<pre><br />
AddHandler cgi-script .exe<br />
</pre><br />
<br />
And to serve your executables from another directory, you add this:<br />
<pre><br />
ScriptAlias /bin/ "C:/lazarus_projects/test-fclweb/bin/"<br />
<Directory "C:/lazarus_projects/test-fclweb/bin/"><br />
AllowOverride None<br />
Options None<br />
Order allow,deny<br />
Allow from all<br />
</Directory><br />
</pre><br />
<br />
===Formatting the HTML and Reading Query fields===<br />
<br />
The previous example just showed a plain HTML page. One might wish to e.g.<br />
* dynamically change the HTML page output, and<br />
* as read the variables the browser passed to the webpage in Query fields (in e.g. HTTP GET and HTTP POST actions). <br />
<br />
A simple solution for the first problem is simply using the standard Pascal routine Format and adding %s or %d in the HTML file in the appropriate places which will receive a custom value.<br />
<br />
===Reading GET data===<br />
To read the GET variables one can use ARequest.QueryFields, which is a TStrings descendent. Each variable will be in a separate line in the TStrings in the format variablename=value, similarly to how they are shown in the browser page address. To search for a specific variable one can use ARequest.QueryFields.Values[], passing the variable name in the brackets to receive its value back, instead of parsing the string manually. <br />
<br />
The resulting code:<br />
<br />
<syntaxhighlight>procedure TFPWebModule1.DataModuleRequest(Sender: TObject; ARequest: TRequest;<br />
AResponse: TResponse; var Handled: Boolean);<br />
var<br />
HexText, AsciiText: string;<br />
begin<br />
HexText := ARequest.QueryFields.Values['hex'];<br />
AsciiText := HexToAnsii(HexText);<br />
<br />
AResponse.ContentType := 'text/html;charset=utf-8';<br />
AResponse.Contents.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'mainpage.html');<br />
AResponse.Contents.Text := Format(AResponse.Contents.Text,<br />
[HexText, AsciiText]);<br />
Handled := True;<br />
end;</syntaxhighlight><br />
<br />
===Reading POST data===<br />
<br />
Data submitted by POST requests can be obtained from <code>TRequest.Content</code>. It will come without the request headers - in other words it contains the body of the request.<br />
<br />
Submitted form data can also be accessed using <code>TRequest.ContentFields</code> which is the content parsed as fields separated by & and decoded. For example, the following set of form values:<br />
<br />
login: dfg 345&&<br />
login_senha: ====<br />
email: dfg<br />
<br />
Will be encoded in 'APPLICATION/X-WWW-FORM-URLENCODED' like this:<br />
<br />
login=dfg+345%26%26&login_senha=%3D%3D%3D%3D&email=dfg<br />
<br />
And will be available in TRequest.ContentFields like this:<br />
<br />
TRequest.ContentFields[0]: login=dfg 345&&<br />
TRequest.ContentFields[0]: login_senha=====<br />
TRequest.ContentFields[0]: email=dfg<br />
<br />
If using other mime-types than 'MULTIPART/FORM-DATA' and 'APPLICATION/X-WWW-FORM-URLENCODED' (the types supported by HTML forms):<br />
* content is only available in TRequest.Content, not TRequest.ContentFields<br />
* use of these mime-types raises an exception for FPC 2.4.2 (fixed in FPC 2.5+).<br />
<br />
Note that HTTP POST can also send Query fields (in the URL), e.g. http://server/bla?question=how, and those are accessed by TRequest.QueryFields as explained in the previous section.<br />
<br />
<syntaxhighlight>procedure TFPWebModule1.DataModuleRequest(Sender: TObject; ARequest: TRequest;<br />
AResponse: TResponse; var Handled: Boolean);<br />
var<br />
lData: String;<br />
begin<br />
lData := ARequest.Content;<br />
</syntaxhighlight><br />
<br />
=== Reading POST binary data ===<br />
To receive data on the server that has been POSTed e.g. as multipart/form-data, use something like this:<br />
<syntaxhighlight><br />
procedure TMainWebModule.TFPWebActions2Request(Sender: TObject;<br />
ARequest: TRequest; AResponse: TResponse; var Handled: Boolean);<br />
var<br />
i: Integer;<br />
begin <br />
// Process all received files<br />
for i := 0 to ARequest.Files.Count - 1 do<br />
begin<br />
// Doing something else than writeln is highly recommended ;)<br />
writeln ('Received Filename: '+ARequest.Files[i].LocalFileName);<br />
end;<br />
<br />
Handled := true;<br />
end;<br />
</syntaxhighlight><br />
<br />
The client can send data using e.g. FileFormPost.<br />
<br />
== Using multiple modules ==<br />
If there is only one module in the web application, all requests will be directed to this module. <br />
<br />
As your web application grows, multiple modules can be used. A new module can be added by choosing 'File - New' and then one of 'Web module' or 'HTML Web Module'. <br />
<br />
FCL-web uses the URL to determine how a HTTP request should be handled. It must therefore know which web-modules exist in the application. To achieve this, each module must be registered.<br />
<br />
Each module is registered with fcl-web in the initialization section of the unit it is defined in:<br />
<br />
<syntaxhighlight>RegisterHTTPModule('location', TMyModule);</syntaxhighlight><br />
<br />
The module will then be invoked if an URL of the form <br />
<nowiki>http://www.mysite.org/mycgi.cgi/location</nowiki><br />
or<br />
<nowiki>http://www.mysite.org/mycgi.cgi?module=location</nowiki><br />
is used.<br />
<br />
If multiple modules are present, the name of the module must appear in the URL, or an error will be raised.<br />
<br />
This behaviour can also be forced for applications that have only a single module by setting the Application's property AllowDefaultModule to false:<br />
<br />
<syntaxhighlight>Application.AllowDefaultModule := False;</syntaxhighlight><br />
<br />
In that case, the fcl-web application will always require the name of the module in the URL.<br />
<br />
The name of the request variable that determines the module name (by default, this is 'module') can be set in the Application.ModuleVariable property. The following code<br />
<br />
<syntaxhighlight>Application.ModuleVariable := 'm';</syntaxhighlight><br />
<br />
ensures that the following URL is directed to TMyModule:<br />
<nowiki>http://www.mysite.org/mycgi.cgi?m=location</nowiki><br />
<br />
If all this is not enough to determine the module to which the request should be passed, the Application.OnGetModule event can be used. It is of type TGetModuleEvent:<br />
<br />
<syntaxhighlight>type<br />
TGetModuleEvent = Procedure (Sender : TObject; ARequest : TRequest;<br />
Var ModuleClass : TCustomHTTPModuleClass) of object;<br />
</syntaxhighlight><br />
<br />
Creating an event handler for this event allows fine control over the module that is created to handle the request: the request (passed in ARequest) can be examined, and the 'ModuleClass' variable must be set to the class of the module that should handle the request.<br />
<br />
If 'ModuleClass' is 'Nil' on return, an error will be sent to the browser.<br />
<br />
== Using Actions ==<br />
<br />
A module can be used to group certain kinds of actions that logically belong together. Imagine a module TUserModule that is used to handle user management in the webpages. There can be multiple actions associated with a user:<br />
* Creating<br />
* Deleting<br />
* Editing<br />
* Displaying<br />
These different actions can be handled by the same module. One can determine the action from the URL manually, as in:<br />
<nowiki>http://mysite/mycgi.cgi/user?action=delete&id=12</nowiki><br />
This can be automated.<br />
<br />
In order to make it easier to distinguish between various actions, the module has a property actions: this is a collection, in which each item is associated with a different response to the request. The actions have various properties:<br />
; Name : The name of the action. The URL will be examined to determine the name of the action.<br />
; Content : A string. If set, this is sent to the browser.<br />
; Contents :A stringlist. If set, this is sent to the browser.<br />
; ContentProducer :If set, the contentproducer will handle the request.<br />
; Default: if set to 'True', then this action is the default action. That means that if FCL-Web cannot determine the action name, this action will be executed.<br />
; Template : If set, this template will be processed, and the results sent to the browser.<br />
There are also some events:<br />
; BeforeRequest : executed before the request is processed. Can be used to set the 'Content' or other properties.<br />
; AfterRequest : executed after the request is processed.<br />
; OnRequest : an event handler to handle the request. If set, the handler is used to handle the request.<br />
<br />
Again, as in the case of multiple modules, the URL is used to determine which action to execute. The part right after the module part ("user" in this example) is used:<br />
<nowiki>http://mysite/mycgi.cgi/user/delete&id=12</nowiki><br />
would execute the action named 'delete'. This is equivalent to the URL<br />
<nowiki>http://mysite/mycgi.cgi/user?action=delete&id=12</nowiki><br />
<br />
The 'ActionVar' property of the module can be used to set the name of the request variable to use. Setting<br />
<br />
<syntaxhighlight>UserModule.ActionVar := 'a';</syntaxhighlight><br />
<br />
reduces the above URL to<br />
<nowiki>http://mysite/mycgi.cgi/user?a=delete&id=12</nowiki><br />
<br />
If there is only one module in the application, the URL can be shortened to<br />
<nowiki>http://mysite/mycgi.cgi/delete&id=12</nowiki><br />
<br />
== Using HTML Templates ==<br />
For information about using templates, template tags and template tag parameters to generate response pages, please refer to the fptemplate.txt file under your FPC directory in /packages/fcl-base/texts/.<br />
<br />
Example projects that demonstrate using templates can be found under your FPC directory in /packages/fcl-web/examples/fptemplate/ (see the README.txt in there for more).<br />
(In earlier versions, these examples were in the Lazarus directory in /components/fpweb/demo/fptemplate/)<br />
<br />
== Tips & troubleshooting==<br />
<br />
=== Sending result codes ===<br />
To send a different HTTP response than 200 OK, use '''AResponse.Code''' and '''AResponse.CodeText''', e.g.<br />
<syntaxhighlight><br />
AResponse.Code:=404;<br />
AResponse.CodeText:='Document not found';<br />
</syntaxhighlight><br />
<br />
=== Sending binary data ===<br />
An approach that seems to work to send e.g. a tiff file from the web server to the client - adapted from $(fpcdirectory)\packages\fcl-web\examples\jsonrpc\demo1\wmdemo.pp - something like:<br />
<syntaxhighlight><br />
var<br />
<br />
AResponse.ContentStream := TMemoryStream.Create;<br />
try<br />
AResponse.ContentStream.LoadFromFile('/tmp/sample.tiff');<br />
AResponse.ContentType := 'image/tiff'; //or whatever MIME type you want to send<br />
// to do: there is an fpweb example that gets the mime type from the file extension...<br />
AResponse.ContentLength:=AResponse.ContentStream.Size; //apparently doesn't happen automatically?<br />
AResponse.SendContent;<br />
finally<br />
AResponse.ContentStream.Free;<br />
end;<br />
Handled := true; <br />
</syntaxhighlight><br />
<br />
<br />
=== Error: Could not determine HTTP module for request ===<br />
You may have multiple modules and multiple actions. If you specify an URL with only 1 item, like:<br />
<syntaxhighlight lang="html4strict">http://localhost/cgi-bin/somemodule</syntaxhighlight><br />
then fpweb assumes you're specifying an action. If you don't have a default module set, you will get a 500 internal server error (Could not determine HTTP module for request)<br />
<br />
You can modify this behaviour to let fpweb map to a module name instead by setting the application's '''PreferModuleName''' property to true.<br />
<br />
=== Error: response code 500 Internal Server error when trying to handle DELETE method ===<br />
In FPC 2.6.2 and lower, fcl-web does not accept the DELETE method and generates an error.<br />
<br />
== Notes ==<br />
<br />
* The cgiapp unit is deprecated, please use fpcgi as much as possible.<br />
<br />
* The fastcgi, custfcgi, and fpfcgi units are not supported on Darwin at this time, because it uses a different mechanism than the MSG_NOSIGNAL option for recv() to indicate that no SIGPIPE should be raised in case the connection breaks. See http://lists.apple.com/archives/macnetworkprog/2002/Dec/msg00091.html for how this should be fixed.<br />
<br />
* If you deploy your CGI application and get errors like "Error: No action name and no default action", you should make sure there's an action assigned to the URL, or catch non-supported actions with an action marked Default. In both cases, an OnRequest event handler for the action that sets Handled:=true should be used.<br />
<br />
== See also ==<br />
* [[fphttpclient]] Part of fcl-web that can be used stand-alone in client applications<br />
* ''write me!''fphttpserver Small stand alone Object Pascal web server. Can be used to serve fcl-web CGI applications.<br />
* [[CGI_Web_Programming#Debugging_CGI]] Information about debugging CGI applications<br />
* [https://github.com/leonardorame/Ext4-MVC-Tutorial/wiki/Lazarus-Server Part of a tutorial by Leonardo Ramé that shows how to program an fcl-web CGI application; includes example of generating JSON content]<br />
<br />
[[Category:Free Component Library]]<br />
[[Category:Networking]]<br />
[[Category:Lazarus]]<br />
[[Category:FPC]]<br />
[[Category:Components]]<br />
[[Category:Packages]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=SQLite&diff=84597SQLite2014-11-25T21:30:47Z<p>Sekelsenmat: /* TSQLite3Dataset and TSQLiteDataset */</p>
<hr />
<div>{{SQLite}}<br />
<br />
== SQLite and FPC/Lazarus support ==<br />
SQLite is an embedded (non-server) single-user database that can be used in FPC and Lazarus applications. Various drivers can be used to access SQLite from FPC/Lazarus programs.<br />
All drivers do need the SQLite library/dll in the executable directory (which can be your project directory or e.g. (projectdir)/lib/architecture/ depending on your Lazarus project settings) (and distributed with your executable) in order to work.<br />
<br />
Win64: please see warning [[Windows Programming Tips#FPC 2.6.x/Lazarus warning|here]] on not using certain FPC/Lazarus Win64 versions.<br />
<br />
=== Built-in SQLDB ===<br />
FPC/Lazarus offers the built-in SQLDB components that include support for SQLite databases (''TSQLite3Connection''), which allow you to e.g. create GUIs with database components such as dbgrids. The advantage of using SQLDB is that it is fairly easy to change to a different database such as Firebird or PostgreSQL without changing your program too much.<br />
See below for details.<br />
<br />
[[Image:sqldbcomponents.png]]<br />
<br />
==== Spatialite support ====<br />
Spatialite are GIS extensions to SQLite which you can use from within SQLDB. See [[Spatialite]].<br />
<br />
==== Support for SQLite encryption ====<br />
In recent FPC versions (implemented March 2012), SQLDB included support for some extended versions of SQLite3 which encrypt the SQLite database file using the AES algorithm. Use the password property to set the encryption key. <br />
<br />
Examples: <br />
<br />
- [http://sqlcipher.net/ SQLCipher]: open source, e.g. Windows binaries not for free (you have to compile them yourself)<br />
<br />
- [http://system.data.sqlite.org/ System.Data.SQLite]: open source, Windows (32, 64, CE) binaries available, download e.g one of the Precompiled Binaries and rename SQLite.Interop.dll to sqlite3.dll (if you're using the Statically Linked ones, presumably you need to rename System.Data.SQLite.DLL to sqlite3.dll)<br />
<br />
- [http://wxcode.sourceforge.net/docs/wxsqlite3/ wxSQLite3]: open source, some binaries for Linux available (ex: https://launchpad.net/ubuntu/oneiric/+package/libwxsqlite3-2.8-0)<br />
<br />
==== sqlite3backup ====<br />
sqlite3backup is a unit provided with FPC (not in Lazarus but can be used programmatically) that provides backup/restore functionality for SQLite3. It uses SQLDB's sqlite3conn.<br />
<br />
=== Zeos ===<br />
[http://zeos.firmos.at/portal.php Zeos]<br />
<br />
=== SQLitePass ===<br />
[http://source.online.free.fr/ SqlitePass] components. Status: unknown.<br />
<br />
<br />
=== TSQLite3Dataset and TSQLiteDataset ===<br />
There are also separate TSQLiteDataset (unit sqliteds) and TSQLite3Dataset (unit sqlite3ds) packages; see below for a description on how to use them. Visit the [http://sqlite4fpc.yolasite.com/ sqlite4fpc homepage] to find the API reference and more tutorials.<br />
<br />
TSqliteDataset and TSqlite3Dataset are TDataset descendants that access, respectively, 2.8.x and 3.x.x sqlite databases. For new projects, you would presumably use TSQlite3Dataset as SQLite 3.x is the current version.<br />
<br />
Below is a list of the principal advantages and disadvantages compared to other FPC/Lazarus SQLite drivers/access methods:<br />
<br />
Advantages:<br />
<br />
* Flexible: programmers can choose to use or not to use the SQL language, allowing them to work with simple table layouts or any complex layout that SQL/sqlite allows<br />
<br />
Disadvantages:<br />
<br />
* Changing to other databases is more difficult than if you use the SQLDB or Zeos components<br />
<br />
{{Note|Given the above, many users will use SQLDB or Zeos due to the advantages unless they need lower-level access to the SQLite library}}<br />
<br />
== Using the SQLdb components with SQLite ==<br />
These instructions are focused on SQLDB (the TSQLite3Connection) specifics for SQLite. For a general overview, have a look at [[SqlDBHowto|SqlDBHowto]] which has some useful information about the SQLdb components. <br />
<br />
See [[SQLdb_Tutorial1]] for a tutorial on creating a GUI database-enabled program that is written for SQLite/SQLDB (as well as for Firebird/SQLDB, PostgreSQL/SQLDB, basically any RDBMS SQLDB supports).<br />
<br />
We will use a combination of three components from the Lazarus SQLdb tab: TSQLite3Connection, TSQLTransaction and TSQLQuery. The TSQLQuery acts as our TDataset; in the simplest case it just represents one of our tables. For the sake of simplicity: make sure you already have an existing SQLite database file and don't need to create a new one now. <br />
TSQLite3Connection can be found in the ''sqlite3conn'' unit, if you want to declare it yourself or are working in FreePascal.<br />
<br />
The three components are connected with each other as usual: In the TSQLQuery set the properties Database and Transaction, in the TSQLTransaction set the property Database. There is not much to do in the Transaction and Connection components, most of the interesting things will be done in the TSQLQuery. Configure the components as follows:<br />
<br />
TSQLite3Connection:<br />
* DatabaseName: Set this property to the file name (absolute path!) of your SQLite file. Unfortunately, you cannot simply use a relative path that works unchanged at designtime and at runtime ***is this still true? Can't you just copy the db file in a post-build shell script or symlink it?***. You should make sure that at application start the correct path to the file is always set programmatically, no matter what it contained at designtime.<br />
<br />
Note: To set the full library path (if you place your sqlite dll/so/dylib in a place where the OS won't find it, like the application directory on Linux/OSX), you can set the ''SQLiteLibraryName'' property (BEFORE any connection is established e.g. in the OnCreate event of the main form), like this:<br />
<syntaxhighlight><br />
SQLiteLibraryName:='./sqlite3.so';<br />
</syntaxhighlight><br />
<br />
TSQLQuery:<br />
* SQL: Set it to some simple select query on one of your tables. For example, if you have a table 'foo' and want this dataset to represent this table then just use the following: <syntaxhighlight lang="SQL">SELECT * FROM foo</syntaxhighlight><br />
<br />
* Active: Set this to True from within the IDE to test whether it is all set up correctly. This will also automatically activate the transaction and the connection objects. If you receive an error then either the DatabaseName of the connection is not correct or the SQL query is wrong. Later, when we are done adding the fields (see below) set them all to inactive again, we don't want the IDE to lock the SQLite database (single user!) when testing the application.<br />
<br />
* ''Probably not necessary for proper operation - will need to be checked (June 2012)'' Now we can add Fields to our TSQLQuery. While the components are still set to active do a right click and "edit fields...". Click the "+" button and add fields. It will list all fields your SQL query returned. Add every field you will need, you can also add lookup fields here; in this case just make sure you have already defined all needed fields in the other datasets before you start adding lookup fields that refer to them. If your table has many columns and you don't need them all you can just leave them out, you can also make your SQL a bit more specific. <br />
<br />
* In your code you need to call SQLQuery.ApplyUpdates and SQLTransaction.Commit, TSQLQuery.AfterPost and AfterInsert events are a good place for this when using it with data aware controls but of course you can also postpone these calls to a later time. If you don't call them, the database will not be updated.<br />
<br />
* "Database is locked": The IDE might still be locking the database (SQLite is a single user database), you probably forgot to set the components to inactive and disconnected again after you were done defining all the fields of your TSQLQuery objects. Use the Form's OnCreate event to set the path and activate the objects at runtime only. Most of the things you set in the TSQLQuery from within the IDE don't require (and some don't even allow) them to be active at design time, the only exception is defining the fields where it wants to read the table design, so inactive at design time should be the normal state.<br />
<br />
* Your tables should all have a primary key and you must make sure that the corresponding field has pfInKey and nothing else in its PoviderFlags (these flags control how and where the field is used when automatically constructing the update and delete queries).<br />
<br />
* If you are using lookup fields <br />
** make sure the ProviderFlags for the lookup field is completely empty so it won't attempt to use its name in an update query. The lookup field itself is not a data field, it only acts on the value of another field, the corresponding key field, and only this key field will later be used in the update queries. You can set the key field to hidden because usually you don't want to see it in your DBGrid but it needs to be defined.<br />
** LookupCache must be set to True. At the time of this writing for some reason the lookup field will not display anything otherwise (but still work) and strangely the exact opposite is the case when working with the TSQLite3Dataset or other TXXXDataset components, here it must be set to False. I'm not yet sure whether this is intended behavior or a bug.<br />
<br />
* Usually with simple tables you won't need to set any of the InsertSQL, UpdateSQL and DeleteSQL properties, just leave them empty. If you have the ProviderFlags of all your fields set correctly it should be able to create the needed SQL on the fly. For more details on InsertSQL, UpdateSQL and DeleteSQL, see [[Working_With_TSQLQuery#TSQLQuery.InsertSQL.2C_TSQLQuery.UpdateSQL_and_TSQLQuery.DeleteSQL:_Basic_Use_of_Parameters]].<br />
<br />
After the above is all set up correctly, you should now be able to use the TSQLQuery like any other TDataset, either by manipulating its data programmatically or by placing a TDatasouce on the Form, connecting it to the TSQLQuery and then using data contols like TDBGrid etc.<br />
<br />
=====Creating a Database=====<br />
The [http://www.freepascal.org/docs-html/fcl/sqldb/tsqlconnection.createdb.html TSQLite3Connection.CreateDB] method inherited from the parent class actually does nothing; to create a database if no file exists yet, you simply have to write table data as in the following example:<br />
<br />
(Code extracted from sqlite_encryption_pragma example that ships with Lazarus 1.3 onwards)<br />
<syntaxhighlight><br />
var<br />
newFile : Boolean;<br />
begin<br />
<br />
SQLite3Connection1.Close; // Ensure the connection is closed when we start<br />
<br />
try<br />
// Since we're making this database for the first time,<br />
// check whether the file already exists<br />
newFile := not FileExists(SQLite3Connection1.DatabaseName);<br />
<br />
if newFile then<br />
begin<br />
// Create the database and the tables<br />
try<br />
SQLite3Connection1.Open;<br />
SQLTransaction1.Active := true;<br />
<br />
// Here we're setting up a table named "DATA" in the new database<br />
SQLite3Connection1.ExecuteDirect('CREATE TABLE "DATA"('+<br />
' "id" Integer NOT NULL PRIMARY KEY AUTOINCREMENT,'+<br />
' "Current_Time" DateTime NOT NULL,'+<br />
' "User_Name" Char(128) NOT NULL,'+<br />
' "Info" Char(128) NOT NULL);');<br />
<br />
// Creating an index based upon id in the DATA Table<br />
SQLite3Connection1.ExecuteDirect('CREATE UNIQUE INDEX "Data_id_idx" ON "DATA"( "id" );');<br />
<br />
SQLTransaction1.Commit;<br />
<br />
ShowMessage('Succesfully created database.');<br />
except<br />
ShowMessage('Unable to Create new Database');<br />
end;<br />
end;<br />
except<br />
ShowMessage('Unable to check if database file exists');<br />
end;<br />
end;<br />
</syntaxhighlight><br />
<br />
=== SQLite3 and Dates ===<br />
* SQLite 3 doesn't store dates as a special DateTime value. It can stores them as strings, doubles or integers - see http://www.sqlite.org/datatype3.html#datetime. <br />
* In strings, the date separator is '-' as per SQL standard/ISO 8601. Thus, if you do an INSERT using the built-in DATE function, it will store it as something like 'YYYY-MM-DD'.<br />
* Reading a DateTime value can cause problems for DataSets if they are stored as strings: the .AsDateTime qualifier can stall on an SQLite 'string date' but this can be overcome by using something like <tt>strftime(''%d/%m/%Y'',recdate) AS sqlite3recdate</tt> in your SQL SELECT statement, which forces SQLite3 to return the date record in a specified format. (the format string %d/%m/%d corresponds to your locale date format which .AsDateTime will understand) '''==> Please open a bug report with an example application demonstrating the problemif this is the case'''<br />
* When comparing dates stored as strings (using for example the BETWEEN function) remember that the comparison will always be a <b>string</b> comparison, and will therefore depend on how you have stored the date value.<br />
<br />
== Using TSQLite3Dataset ==<br />
<br />
This section details how to use the TSQLite2Dataset and TSQLite3Dataset components to access SQlite databases.<br />
by Luiz Américo<br />
luizmed(at)oi(dot)com(dot)br<br />
<br />
<br />
====Requirements====<br />
<br />
* For sqlite2 databases (legacy):<br />
** FPC 2.0.0 or higher<br />
** Lazarus 0.9.10 or higher<br />
** SQLite runtime library 2.8.15 or above*<br />
<br />
* Sqlite2 is not maintained anymore and the binary file cannot be found in the sqlite site<br />
<br />
* For sqlite3 databases:<br />
** FPC 2.0.2 or higher<br />
** Lazarus 0.9.11 (svn revision 8443) or higher<br />
** sqlite runtime library 3.2.1 or higer (get it from [http://www.sqlite.org www.sqlite.org])<br />
<br />
'''Before initiating a lazarus project, ensure that:'''<br />
* the sqlite library is either <br />
** in the system PATH or<br />
** in the executable output directory and Lazarus (or current project) directories - this option might work on Windows only<br />
* under Linux, put cmem as the first unit in uses clause of the main program<br />
** In Debian, Ubuntu and other Debian-like distros, in order to build Lazarus IDE you must install the packages libsqlite-dev/libsqlite3-dev, not only sqlite/sqlite3 (Also applies to OpenSuSe)<br />
<br />
====How To Use (Basic Usage)====<br />
<br />
Install the package found at /components/sqlite directory (see instructions [[Install_Packages|here]])<br />
<br />
At design time, set the following properties:<br />
<br />
* FileName: path of the sqlite file [required] <br />
* TableName: name of the table used in the sql statement [required] <br />
* SQL: a SQL select statement [optional] <br />
* SaveOnClose: The default value is false, which means that changes are not saved. One can change it to true. [optional]<br />
* Active: Needs to be set at design time or at program startup. [required]<br />
<br />
'''Creating a Table (Dataset)'''<br />
<br />
Double-click the component icon or use the 'Create Table' item of the popup menu that appears when clicking the right mouse button.<br />
A simple self-explaining table editor will be shown.<br />
<br />
Here are all field types supported by TSqliteDataset and TSqlite3Dataset: <br />
<br />
* Integer<br />
* AutoInc<br />
* String<br />
* Memo<br />
* Bool <br />
* Float<br />
* Word<br />
* DateTime<br />
* Date<br />
* Time<br />
* LargeInt<br />
* Currency<br />
<br />
'''Retrieving the data'''<br />
<br />
After creating the table or with a previously created Table, open the dataset with the Open method.<br />
If the SQL property was not set then all records from all fields will be retrieved, the same if you set the SQL to:<br />
<br />
<syntaxhighlight>SQL := 'Select * from TABLENAME';</syntaxhighlight><br />
<br />
'''Applying changes to the underlying datafile'''<br />
<br />
To use the ApplyUpdates function, the dataset must contain at least one field that fulfills the requirements for a Primary Key (values must be UNIQUE and not NULL)<br />
<br />
It's possible to do that in two ways:<br />
<br />
* Set PrimaryKey property to the name of a Primary Key field<br />
* Add an AutoInc field (This is easier since the TSqliteDataSet automatically handles it as a Primary Key)<br />
<br />
If one of the two conditions is set, just call<br />
<br />
<syntaxhighlight>ApplyUpdates;</syntaxhighlight><br />
<br />
{{Note|If both conditions are set, the field corresponding to PrimaryKey is used to apply the updates.}}<br />
<br />
{{Note|Setting PrimaryKey to a field that is not a Primary Key will lead to loss of data if ApplyUpdates is called, so ensure that the chosen field contains not Null and Unique values before using it.}}<br />
<br />
=====Master/detail example=====<br />
Various examples of master/detail relations (e.g. the relation between customer and orders):<br />
* the generic SQLDB way of doing this using the <code>DataSource</code> property: [[MasterDetail]]<br />
* TSQLite3 specific example using locate: [[TSqlite3 Master Detail Example]].<br />
<br />
====Remarks====<br />
<br />
* Although it has been tested with 10,000 records and worked fine, TSqliteDataset keeps all the data in memory, so remember to retrieve only the necessary data (especially with Memo Fields).<br />
* The same datafile (Filename property) can host several tables/datasets<br />
* Several datasets (different combinations of fields) can be created using the same table simultaneously <br />
* It's possible to filter the data using WHERE statements in the sql, closing and reopening the dataset (or calling RefetchData method). But in this case, the order and number of fields must remain the same <br />
* It's also possible to use complex SQL statements using aliases, joins, views in multiple tables (remember that they must reside in the same datafile), but in this case ApplyUpdates won't work. If someone wants to use complex queries and to apply the updates to the datafile, mail me and i will give some hints how to do that<br />
* Setting filename to a sqlite datafile not created by TSqliteDataset and opening it is allowed but some fields won't have the correct field type detected. These will be treated as string fields.<br />
<br />
Generic examples can be found at fpc/fcl-db/src/sqlite SVN directory<br />
<br />
==See also==<br />
* [[SQLdb_Tutorial1]] Tutorial for Sqlite<br />
* [[SqlDBHowto]] General information on SQLDB<br />
* [[Working_With_TSQLQuery]] Information on SQLDB's TSQLQuery<br />
* [http://www.sqlite.org SQLite site]<br />
<br />
{{LCL Components Footer |TMySQL56Connection|TIBConnection}}<br />
{{LCL Components}}<br />
<br />
[[Category:Databases]]<br />
[[Category:Components]]<br />
[[Category:FPC]]<br />
[[Category:LCL]]<br />
[[Category:SQLite]]<br />
[[Category:Tutorials]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=Roadmap&diff=83139Roadmap2014-09-20T20:18:39Z<p>Sekelsenmat: /* Status of TGraphicControl based controls on each widgetset */</p>
<hr />
<div>This document gives an idea of the current status of the various parts of Lazarus and also helps new contributors to find a suitable place where they can help. It also shows the people implementing the various parts and the targets.<br />
<br />
__TOC__<br />
<br />
{{Template:Development Status}}<br />
<br />
==General status of widgetsets==<br />
<br />
{{Template:Widgetset Roadmap}}<br />
<br />
==Current status of the various parts of Lazarus==<br />
<br />
<br />
{| class="wikitable sortable"<br />
! Unit !! Item !! State !! Target !! Skills !! Responsible !! Comments<br />
|---- class="working"<br />
|IDE||TCollection Editor||working||0.9.x||FCL, RTTI, IDE||-||A generic TCollection editor for the various TCollections in the LCL/FCL.<br />
|---- class="working"<br />
|IDE||TActionList||working||0.9.x||-||-||-<br />
|---- class="working"<br />
|IDE||Doc Editor||working||-||fpdoc||-||The doc editor will be an integrated fpDoc editor similar to fpde. It will be a process of its own, so that it can show help for dialogs as well. It should also be able to write help for packages.<br />
|---- class="working"<br />
|IDE||Export LFM as xml||working||-||-||-||Load and save LFM files to XML.<br />
|---- class="partial"<br />
|IDE||[[Icon Editor Roadmap]]||in progress||post 1.0||-||-||A simple icon editor with the ability to create lrs files. It will be a good example and can help newbies to create icons for their components.<br />
|---- class="working"<br />
|LCL||Borderspacing||working||0.9.x||-||-||for aligned controls<br />
|---- class="working"<br />
|LCL||Drag&Drop||working||||-||-||<br />
|---- class="working"<br />
|LCL||Port to Darwin Power PC, Mac OS X||working||0.9.x||-||-||depends on FPC 1.9.5<br />
|---- class="working"<br />
|LCL||Port to Mac OS X x86||working||-||-||-||depends on FPC 2.1.1<br />
|---- class="working"<br />
|LCL||TSplitter||working||0.9.x||easy||-||-<br />
|---- class="working"<br />
|LCL||TFindDialog||working||-||-||-||Implemented in 0.9.16<br />
|---- class="working"<br />
|LCL||TReplaceDialog||working||-||-||-||Implemented in 0.9.16<br />
|---- class="working"<br />
|LCL||TControl.Font||in progress||0.9.x||-||-||-<br />
|---- class="working"<br />
|LCL||TTabControl||in progress||0.9.x||-||-||-<br />
|---- class="partial"<br />
|LCL||Docking (= the combination of forms)||partially working, in progress||post 1.0||deep LCL and interfaces||Mattias||-<br />
|---- class="working"<br />
|LCL||Frames (= forms as children)||working||0.9.28||deep knowledge of LCL||Mattias, Paul||-<br />
|---- class="working"<br />
|IDE||Visual Form Inheritence||working||post 1.0||IDE||Mattias||Properties are not yet propagated to open descendants<br />
|---- class="partial"<br />
|LCL||MDI - Multiple Documents Interfaces Putting fo ...||in progress||1.2||deep LCL and interfaces||[[User:Zeljan|Zeljan]]||An MDI LCL emulator for widgetsets which does not support MDI, also native implementation of MDI for qt and win32/64. Currently only qt has full MDI support, others are in progress.<br />
|---- class="not"<br />
|LCL||Palette support||not implemented||-||-||-||Required to correctly show colors on a 256 colors display<br />
|---- class="partial"<br />
|LCL||TCoolBar||partially working, in progress||post 1.0||LCL and anchoring||[[User:JuhaManninen|Juha]]||-<br />
|---- class="partial"<br />
|LCL||TControlBar||skeleton implementation to prevent errors in Delphi conversion, in progress||post 1.0||LCL and anchoring||[[User:JuhaManninen|Juha]]||-<br />
|---- class="working"<br />
|LCL||TMaskEdit||working||-||-||[[User:Bart|Bart]]||-<br />
|---- class="not"<br />
|LCL||TDirectoryTreeView||not implemented||-||-||-||-<br />
|---- class="not"<br />
|LCL||Constrain maximization to specific area||not implemented||-||winapi, gtk||-||When maximizing a window, the left, top, width and height can all be constrained to a specific rectangular area on the screen/desktop. After this is done, constrain the source editor and maybe other windows<br />
|---- class="working"<br />
|Components||TIcon||working||0.9.26||-||Marc||-<br />
|---- class="working"<br />
|Components||CUPS Package||working||0.9.x||easy||-||<br />
|---- class="working"<br />
|}<br />
<br />
==Status of features on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|Accelerator Keys<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Caret<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Clipboard<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Implemented in Android<br />
|----<br />
|Cursors<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Drag & Drop<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|[[Drop files event]]<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|MDI Support<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Printing<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Regions<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TCustomControl descendents<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|Unicode Support<br />
|class="working"|Working||class="not"|Impossible to Implement||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|[[BidiMode]]<br />
|class="working"|Working||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Application||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="working"|Working<br />
|----<br />
|TTimer||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TApplication.QueueAsyncCall||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|TThread.Synchronize||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class="unknown"|Unknown<br />
|class="working"|Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|PostMessage||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class=""unknown"|Unknown<br />
|class="not"|Not Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|PostThreadMessage||class="working"|Working||class="unknown"|Unknown||class="unknown"|Unknown<br />
|class="unknown"|Unknown||class="unknown"|Unknown||class="unknown"|Unknown<br />
|class="unknown"|Unknown||class="unknown"|Unknown||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of Graphics on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBitmap/TPixmap/TIcon/etc||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TBrush||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TFont||class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TPen||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|ExtTextOut||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="unknown"|Unknown||class="working"|Working<br />
|}<br />
<br />
==Status of native controls on each widgetset==<br />
Native controls are TWinControl descendants which do not descend from TCustomControl.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBitBtn||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TCalendar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TCheckBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TCheckGroup||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TCheckListBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TComboBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TEdit||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TForm||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TGroupBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TIdleTimer||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TImageList||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working|| class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TListBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TListView||class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TMainMenu||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TMemo||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TMenuItem||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TPageControl and TTabSheet||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TPairSplitter||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TPanel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TPopupMenu||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TProgressBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TRadioButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TRadioGroup||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TScrollBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TScrollBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TSpinEdit||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TSplitter||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TStaticText||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TStatusBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TToggleBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TTrackbar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TTrayIcon||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of dialogs on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|LCLIntf.MessageBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="working"|Working<br />
|class="working"|Working||class="unknown"|Unknown||class="partial"|Implemented for Android<br />
|----<br />
|Application.MessageBox, MessageDlg, LCLIntf.PromptUser||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="unknown"|Unknown||class="partial"|Implemented for Android<br />
|----<br />
|LCLIntf.AskUser||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|TColorDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TFontDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TOpenDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TPrinterSetupDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TSaveDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="not"|Not Implemented||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of TCustomControl based controls on each widgetset==<br />
Note that being a TCustomControl descendant does not guarantee that a control has no widgetset implementation. TArrow has it, although it has a good default implementation. TNotebook is fully implemented in the LCL.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TArrow ||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TNoteBook||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TUpDown||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TStringGrid||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TDrawGrid||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TToolBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TTreeView||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TValueListEditor||class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of TGraphicControl based controls on each widgetset==<br />
'''Note:''' These are for LCL wrapped components only, '''not''' for the specific GUI toolkit features itself.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBevel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TLabel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="partial"|Implemented for Android<br />
|----<br />
|TShape||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TSpeedButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TPaintBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TImage||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|}<br />
<br />
==Status of LazDeviceAPIs on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! customdrawn-android<br />
|----<br />
|Accelerometer||class="working"|Working<br />
|----<br />
|Messaging (SMS, MMS and E-Mail)||class="partial"|SMS Implemented<br />
|----<br />
|PositionInfo||class="working"|Working<br />
|}<br />
<br />
==See Also==<br />
<br />
*[[LCL Internals]]<br />
*[[TAChart Roadmap]]<br />
<br />
[[Category:Lazarus]]<br />
[[Category:Roadmaps]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=Roadmap&diff=83138Roadmap2014-09-20T20:18:17Z<p>Sekelsenmat: /* Status of native controls on each widgetset */</p>
<hr />
<div>This document gives an idea of the current status of the various parts of Lazarus and also helps new contributors to find a suitable place where they can help. It also shows the people implementing the various parts and the targets.<br />
<br />
__TOC__<br />
<br />
{{Template:Development Status}}<br />
<br />
==General status of widgetsets==<br />
<br />
{{Template:Widgetset Roadmap}}<br />
<br />
==Current status of the various parts of Lazarus==<br />
<br />
<br />
{| class="wikitable sortable"<br />
! Unit !! Item !! State !! Target !! Skills !! Responsible !! Comments<br />
|---- class="working"<br />
|IDE||TCollection Editor||working||0.9.x||FCL, RTTI, IDE||-||A generic TCollection editor for the various TCollections in the LCL/FCL.<br />
|---- class="working"<br />
|IDE||TActionList||working||0.9.x||-||-||-<br />
|---- class="working"<br />
|IDE||Doc Editor||working||-||fpdoc||-||The doc editor will be an integrated fpDoc editor similar to fpde. It will be a process of its own, so that it can show help for dialogs as well. It should also be able to write help for packages.<br />
|---- class="working"<br />
|IDE||Export LFM as xml||working||-||-||-||Load and save LFM files to XML.<br />
|---- class="partial"<br />
|IDE||[[Icon Editor Roadmap]]||in progress||post 1.0||-||-||A simple icon editor with the ability to create lrs files. It will be a good example and can help newbies to create icons for their components.<br />
|---- class="working"<br />
|LCL||Borderspacing||working||0.9.x||-||-||for aligned controls<br />
|---- class="working"<br />
|LCL||Drag&Drop||working||||-||-||<br />
|---- class="working"<br />
|LCL||Port to Darwin Power PC, Mac OS X||working||0.9.x||-||-||depends on FPC 1.9.5<br />
|---- class="working"<br />
|LCL||Port to Mac OS X x86||working||-||-||-||depends on FPC 2.1.1<br />
|---- class="working"<br />
|LCL||TSplitter||working||0.9.x||easy||-||-<br />
|---- class="working"<br />
|LCL||TFindDialog||working||-||-||-||Implemented in 0.9.16<br />
|---- class="working"<br />
|LCL||TReplaceDialog||working||-||-||-||Implemented in 0.9.16<br />
|---- class="working"<br />
|LCL||TControl.Font||in progress||0.9.x||-||-||-<br />
|---- class="working"<br />
|LCL||TTabControl||in progress||0.9.x||-||-||-<br />
|---- class="partial"<br />
|LCL||Docking (= the combination of forms)||partially working, in progress||post 1.0||deep LCL and interfaces||Mattias||-<br />
|---- class="working"<br />
|LCL||Frames (= forms as children)||working||0.9.28||deep knowledge of LCL||Mattias, Paul||-<br />
|---- class="working"<br />
|IDE||Visual Form Inheritence||working||post 1.0||IDE||Mattias||Properties are not yet propagated to open descendants<br />
|---- class="partial"<br />
|LCL||MDI - Multiple Documents Interfaces Putting fo ...||in progress||1.2||deep LCL and interfaces||[[User:Zeljan|Zeljan]]||An MDI LCL emulator for widgetsets which does not support MDI, also native implementation of MDI for qt and win32/64. Currently only qt has full MDI support, others are in progress.<br />
|---- class="not"<br />
|LCL||Palette support||not implemented||-||-||-||Required to correctly show colors on a 256 colors display<br />
|---- class="partial"<br />
|LCL||TCoolBar||partially working, in progress||post 1.0||LCL and anchoring||[[User:JuhaManninen|Juha]]||-<br />
|---- class="partial"<br />
|LCL||TControlBar||skeleton implementation to prevent errors in Delphi conversion, in progress||post 1.0||LCL and anchoring||[[User:JuhaManninen|Juha]]||-<br />
|---- class="working"<br />
|LCL||TMaskEdit||working||-||-||[[User:Bart|Bart]]||-<br />
|---- class="not"<br />
|LCL||TDirectoryTreeView||not implemented||-||-||-||-<br />
|---- class="not"<br />
|LCL||Constrain maximization to specific area||not implemented||-||winapi, gtk||-||When maximizing a window, the left, top, width and height can all be constrained to a specific rectangular area on the screen/desktop. After this is done, constrain the source editor and maybe other windows<br />
|---- class="working"<br />
|Components||TIcon||working||0.9.26||-||Marc||-<br />
|---- class="working"<br />
|Components||CUPS Package||working||0.9.x||easy||-||<br />
|---- class="working"<br />
|}<br />
<br />
==Status of features on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|Accelerator Keys<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Caret<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Clipboard<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Implemented in Android<br />
|----<br />
|Cursors<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Drag & Drop<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|[[Drop files event]]<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Applicable<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|MDI Support<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Printing<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Regions<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TCustomControl descendents<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|Unicode Support<br />
|class="working"|Working||class="not"|Impossible to Implement||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|[[BidiMode]]<br />
|class="working"|Working||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|Application||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="working"|Working<br />
|----<br />
|TTimer||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TApplication.QueueAsyncCall||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|TThread.Synchronize||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class="unknown"|Unknown<br />
|class="working"|Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|PostMessage||class="working"|Working||class="unknown"|Unknown||class="working"|Working<br />
|class="unknown"|Unknown||class="working"|Working||class=""unknown"|Unknown<br />
|class="not"|Not Working||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|PostThreadMessage||class="working"|Working||class="unknown"|Unknown||class="unknown"|Unknown<br />
|class="unknown"|Unknown||class="unknown"|Unknown||class="unknown"|Unknown<br />
|class="unknown"|Unknown||class="unknown"|Unknown||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of Graphics on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBitmap/TPixmap/TIcon/etc||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TBrush||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TFont||class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TPen||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|ExtTextOut||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="unknown"|Unknown||class="working"|Working<br />
|}<br />
<br />
==Status of native controls on each widgetset==<br />
Native controls are TWinControl descendants which do not descend from TCustomControl.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBitBtn||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TCalendar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TCheckBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TCheckGroup||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TCheckListBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TComboBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TEdit||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TForm||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TGroupBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TIdleTimer||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TImageList||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working|| class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TListBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TListView||class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TMainMenu||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TMemo||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TMenuItem||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Implemented in Android<br />
|----<br />
|TPageControl and TTabSheet||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|----<br />
|TPairSplitter||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TPanel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TPopupMenu||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TProgressBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|----<br />
|TRadioButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TRadioGroup||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TScrollBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TScrollBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TSpinEdit||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TSplitter||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TStaticText||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TStatusBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TToggleBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TTrackbar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="working"|Working<br />
|----<br />
|TTrayIcon||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of dialogs on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|LCLIntf.MessageBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="partial"|Partially Implemented||class="working"|Working<br />
|class="working"|Working||class="unknown"|Unknown||class="partial"|Implemented for Android<br />
|----<br />
|Application.MessageBox, MessageDlg, LCLIntf.PromptUser||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="unknown"|Unknown||class="partial"|Implemented for Android<br />
|----<br />
|LCLIntf.AskUser||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="unknown"|Unknown||class="not"|Not Implemented<br />
|----<br />
|TColorDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TFontDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TOpenDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TPrinterSetupDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="not"|Not Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TSaveDialog||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="not"|Not Implemented||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of TCustomControl based controls on each widgetset==<br />
Note that being a TCustomControl descendant does not guarantee that a control has no widgetset implementation. TArrow has it, although it has a good default implementation. TNotebook is fully implemented in the LCL.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TArrow ||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TNoteBook||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TUpDown||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TStringGrid||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TDrawGrid||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="partial"|Partially Implemented<br />
|----<br />
|TToolBar||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TTreeView||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TValueListEditor||class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|class="partial"|Partially Implemented||class="partial"|Partially Implemented||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|}<br />
<br />
==Status of TGraphicControl based controls on each widgetset==<br />
'''Note:''' These are for LCL wrapped components only, '''not''' for the specific GUI toolkit features itself.<br />
<br />
{| class="wikitable sortable"<br />
! Component !! win32 !! gtk !! gtk2 !! carbon !! qt !! wince !! fpgui !! cocoa !! customdrawn<br />
|----<br />
|TBevel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="not"|Not Implemented<br />
|----<br />
|TLabel||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="not"|Not Implemented||class="working"|Working||class="partial"|Implemented for Android<br />
|----<br />
|TShape||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="partial"|Partially Implemented||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TSpeedButton||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TPaintBox||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="unknown"|Unknown<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|----<br />
|TImage||class="working"|Working||class="working"|Working||class="working"|Working<br />
|class="working"|Working||class="working"|Working||class="partial"|Partially Implemented<br />
|class="not"|Not Implemented||class="not"|Not Implemented||class="working"|Working<br />
|}<br />
<br />
==Status of LazDeviceAPIs on each widgetset==<br />
<br />
{| class="wikitable sortable"<br />
! Component !! customdrawn-android<br />
|----<br />
|Accelerometer||class="working"|Working<br />
|----<br />
|Messaging (SMS, MMS and E-Mail)||class="partial"|SMS Implemented<br />
|----<br />
|PositionInfo||class="working"|Working<br />
|}<br />
<br />
==See Also==<br />
<br />
*[[LCL Internals]]<br />
*[[TAChart Roadmap]]<br />
<br />
[[Category:Lazarus]]<br />
[[Category:Roadmaps]]</div>Sekelsenmathttps://wiki.freepascal.org/index.php?title=User:Sekelsenmat&diff=82971User:Sekelsenmat2014-09-10T14:40:16Z<p>Sekelsenmat: /* Finished projects */</p>
<hr />
<div>Hi, my real name is Felipe and I am an electric engineer graduated at the University of São Paulo.<br />
<br />
==Current projects==<br />
<br />
*[[Lazarus Season of Code]]<br />
*[[Free Pascal Application Suite]]<br />
*[[Free Pascal Window Manager]]<br />
*[[Lazarus 0.99.0 release notes]]<br />
*[[Lazarus Custom Drawn Controls]]<br />
*[[Android Interface]]<br />
<br />
==Finished projects==<br />
<br />
* 2006 - [http://www.braillevirtual.fe.usp.br online Braille Course] based on motion graphics<br />
<br />
* 2008 - Develop a digital osciloscope with two coleagues of mine. The osciloscope is connected to the computer via a ISA Card. The interface software is written in Lazarus and is a Multi-platform, graphical application that can access the ISA Card on both Windows and Linux. You can download the final report and also the source code for the software here: http://eletronicalivre.incubadora.fapesp.br/portal/english/oscilloscope/<br />
<br />
* 2008 - [http://www.auxiliosopticos.fcm.unicamp.br Auxílios Ópticos] website.<br />
<br />
* 2010 - [http://magnifier.sourceforge.net/ Virtual Magnifying Glass].<br />
<br />
* 2013 - [https://play.google.com/store/apps/details?id=com.felipe.truedemocracy True Democracy for Android].<br />
<br />
==ToDo List for Lazarus==<br />
<br />
* <strike>Improve Qt widgetset until it can compile many examples. Only hello example is currently fully functional.</strike><br />
* <strike>Implement basic parts of Windows CE interface, notabily TApplication, TCustomForm and TButton.</strike><br />
* Things to check for Windows Unicode Support:<br />
** <strike>StatusBar</strike><br />
** <strike>File Open dialog</strike><br />
** <strike>TMemo</strike><br />
** <strike>win32proc.MeasureText for button size on Lazarus About box</strike><br />
** <strike>ListView</strike><br />
<br />
==Qt Contest 2008==<br />
<br />
Moved here: [[Qt Contest 2008]]<br />
<br />
==Orphaned links==<br />
<br />
[[Image:Capture 2.jpg]]<br />
[[Image:Wince.PNG]]<br />
<br />
==Dock images for comparison==<br />
<br />
[[New Lazarus Icon Proposals]]<br />
<br />
==Smartphone Marketshares==<br />
<br />
Moved here: [[Smartphone Development]]<br />
<br />
==Lazarus and Free Pascal usage statistics from Source Forge==<br />
<br />
Lazarus Measures in 11/8/2010, being that the Last release was 0.9.28 in 2009-10-26<br />
<br />
{| border=2 width="100%"<br />
|-<br />
! Platform<br />
! Downloads in Source Forge<br />
! Downloads %<br />
|-<br />
! win32 - x86<br />
| 128558<br />
| 67,66%<br />
|-<br />
! Linux - All platforms<br />
| 33000<br />
| 17,37%<br />
|-<br />
! win64<br />
| 11459<br />
| 6,03%<br />
|-<br />
! wince - arm<br />
| ~9000<br />
| 4,74%<br />
|-<br />
! Mac - PowerPC & x86<br />
| ~8000<br />
| 4,21%<br />
|-<br />
! Total<br />
| 190017<br />
| <br />
|}<br />
<br />
Free Pascal Measures in 11/8/2010, being that the Last release was 2.4 in 2009-12-31<br />
<br />
{| border=2 width="100%"<br />
|-<br />
! Platform<br />
! Downloads in Source Forge<br />
! Downloads %<br />
|-<br />
! win32 - x86<br />
| 85641<br />
| 55,31%<br />
|-<br />
! Linux - All platforms<br />
| ~14000 <br />
| 9,04%<br />
|-<br />
! win64<br />
| 2387<br />
| 1,54%<br />
|-<br />
! wince - arm<br />
| ~800<br />
| 0,52%<br />
|-<br />
! Mac - PowerPC 64, PowerPC, x86 and iPhone<br />
| ~5000<br />
| 3,23%<br />
|-<br />
! DOS<br />
| ~2600<br />
| 1,68%<br />
|-<br />
! FreeBSD<br />
| ~200<br />
| 0,13%<br />
|-<br />
! OS/2<br />
| ~200<br />
| 0,13%<br />
|-<br />
! NintendoDS (counting 2.2.4)<br />
| ~40000<br />
| 25,84%<br />
|-<br />
! GameBoy Advanced (counting 2.2.4)<br />
| ~4000<br />
| 2,58%<br />
|-<br />
! Total<br />
| 154828<br />
| <br />
|}<br />
<br />
Summed figures of Lazarus + Free Pascal with the following adjustments: All FPC stats x2 because of it's own server, except Linux which is x3 because it can be easily found in distributions:<br />
<br />
{| border=2 width="100%"<br />
|-<br />
! Platform<br />
! Downloads in Source Forge<br />
! Downloads %<br />
|-<br />
! win32 - x86<br />
| 280000<br />
| 56,68%<br />
|-<br />
! Linux - All platforms<br />
| 75000<br />
| 15,18%<br />
|-<br />
! win64<br />
| 16000<br />
| 3,24%<br />
|-<br />
! wince - arm<br />
| 11000<br />
| 2,23%<br />
|-<br />
! Mac - PowerPC 64, PowerPC, x86 and iPhone<br />
| 18000<br />
| 3,64%<br />
|-<br />
! DOS<br />
| 5200<br />
| 1,05%<br />
|-<br />
! FreeBSD<br />
| 400<br />
| 0,08%<br />
|-<br />
! OS/2<br />
| 400<br />
| 0,08%<br />
|-<br />
! NintendoDS (counting 2.2.4)<br />
| 80000<br />
| 16,19%<br />
|-<br />
! GameBoy Advanced (counting 2.2.4)<br />
| 8000<br />
| 1,62%<br />
|-<br />
! Total<br />
| 494000<br />
| <br />
|}<br />
<br />
== Building FPC ===<br />
<br />
In Mac OS X, with FPC 2.4.0 installed and building Trunk:<br />
<br />
cd ~/Programas/fpctrunk/<br />
make clean all install INSTALL_PREFIX=~/Programas/fpctrunk/install<br />
<br />
==Links==<br />
<br />
*http://wiki.lazarus.freepascal.org/Image:Lazarus_gtk1_unicode.png<br />
<br />
Temporario, como usar ListView no Android:<br />
*http://dustinbreese.blogspot.com/2009/12/creating-listview-with-alternating.html<br />
<br />
<br />
[[Summer of Code]]<br />
<br />
[[FPC Advantages]]</div>Sekelsenmat