Difference between revisions of "MSEide+MSEgui"

From Free Pascal wiki
(TTextEdit)
(Fixed heading levels; added See also for orphaned tutorial pages)
 
(70 intermediate revisions by 7 users not shown)
Line 1: Line 1:
= Introduction =
+
{{MSEide+MSEgui(pg)}}
The MSE IDE is a Cross Platform GUI Development System for Pascal programmers, completely written in Pascal. The MSE GUI does not feature VCL compatibility. The graphics library provides an interface to win32 and X11. Despite being a single person (Martin Schreiber) effort for the moment, the IDE and GUI has already an amazing feature list:  
+
 
 +
'''WARNING''': MSE project is part now of '''mse-org''': https://github.com/mse-org
 +
 
 +
MSEide & MSEgui sources are here:
 +
https://github.com/mse-org/mseide-msegui
 +
 
 +
Biography of Martin:
 +
https://sites.google.com/view/martin-schreiber-biography/
 +
 
 +
== Introduction ==
 +
 
 +
The MSEide is a Cross Platform GUI Development System for Pascal programmers, completely written in Pascal. The MSEgui does not feature VCL compatibility. The graphics library provides an interface to win32 and X11. Despite being a single person (Martin Schreiber) effort for the moment, the IDE and GUI has already an amazing feature list:  
  
 
* Internal character encoding is UCS2.
 
* Internal character encoding is UCS2.
Line 14: Line 25:
 
* and more...
 
* and more...
  
== But what about Lazarus? ==
+
=== But what about Lazarus? ===
 +
 
 
[http://www.lazarus.freepascal.org Lazarus] is an IDE that aims to provide a high degree of compatibility with VCL code, while providing a native look on many platforms. The native look is very important for many developers, but combined with the VCL compatibility necessitates many complex interfaces to the different native widget sets (Gtk,Win32,Carbon,Qt). The continuous evolution of these native widget sets (gtk1->gtk2, win32->?, qt) provokes endless catching up.  
 
[http://www.lazarus.freepascal.org Lazarus] is an IDE that aims to provide a high degree of compatibility with VCL code, while providing a native look on many platforms. The native look is very important for many developers, but combined with the VCL compatibility necessitates many complex interfaces to the different native widget sets (Gtk,Win32,Carbon,Qt). The continuous evolution of these native widget sets (gtk1->gtk2, win32->?, qt) provokes endless catching up.  
  
[http://homepage.bluewin.ch/msegui/ MSEide+MSEgui] neither features (or suffers :-) VCL compatibility, nor provides a real native look on target platforms. The graphics library provides an interface to win32 and X11. The advantage of the X11 layer is the immediate availability of a large and stable (in time) target platform.  
+
[http://sourceforge.net/projects/mseide-msegui/ MSEide+MSEgui] neither features (or suffers :-) VCL compatibility, nor provides a real native look on target platforms. The graphics library provides an interface to win32 and X11. The advantage of the X11 layer is the immediate availability of a large and stable (in time) target platform.  
  
 
These different goals of both projects make them both fulfill different needs.
 
These different goals of both projects make them both fulfill different needs.
  
== Why this wiki ==
+
=== Why this wiki ===
 +
 
 
The design of the MSE GUI is a fresh approach to GUI design patterns. It features many innovative solutions for typical GUI tasks. Being innovative, the MSE GUI library differs substantially from VCL/LCL/CLX. Switching from VCL to MSE may be more challenging than switching [[Code Conversion Guide|from VCL to LCL]]. These wiki pages aim to ease the first steps with this promising alternative IDE and GUI library.
 
The design of the MSE GUI is a fresh approach to GUI design patterns. It features many innovative solutions for typical GUI tasks. Being innovative, the MSE GUI library differs substantially from VCL/LCL/CLX. Switching from VCL to MSE may be more challenging than switching [[Code Conversion Guide|from VCL to LCL]]. These wiki pages aim to ease the first steps with this promising alternative IDE and GUI library.
  
 +
== Installation ==
  
= Installation =
+
* Current version: 5.0 (2020-04-02)
 +
* Authoritative reference: [http://mseide-msegui.sourceforge.net/ MSEide+MSEgui homepage] with installation instructions
 +
* Cooperative homepage: [http://www.msegui.com/MSEide+MSEgui]
 +
* Download: [https://github.com/mse-org/mseide-msegui/releases/]
 +
* Work in progress: [https://github.com/mse-org/mseide-msegui]
  
* Current version: 2.0beta2, 2008-12-21
+
== Quick start ==
* Authoritative reference: [http://homepage.bluewin.ch/msegui/ MSEide+MSEgui homepage]
 
* Download: [http://sourceforge.net/project/showfiles.php?group_id=165409 Sourceforge]
 
* Work in progress: [http://sourceforge.net/svn/?group_id=165409 Subversion]
 
  
== On Linux ==
+
=== Open Project ===
#Download [http://www.freepascal.org/download.var FPC 2.2.2] and install
 
#Download [http://sourceforge.net/project/showfiles.php?group_id=165409 MSEide & MSEgui] - you will need two zip files: mseide_bin_*.zip and mseide_msegui_src_*.zip
 
##Extract them both under a directory of your choice ('yourdirectory')
 
#Run 'yourdirectory/bin/i386-linux/mseide'
 
## Click to 'Settings'-'Configure MSEide' and set '${MSEDIR}' to 'yourdirectory/msegui'
 
## Click to 'Project'-'Open' and select 'yourdirectory/msegui/apps/demo/demo.prj'
 
## Click to 'Target'-'Continue', to build and run in debugger
 
  
== On Windows ==
+
Launch the IDE and use Project->Open to open the provided demo msegui/apps/demo/demo.prj. The title of the IDE reflects the opened project. Hit F9 and (if you followed the installation instructions :-), be amazed by the speed of FPC+MSE.
#Download [http://www.freepascal.org/download.var FPC 2.2.2] and install
 
#Download a GDB Debugger, for instance [http://sourceforge.net/project/showfiles.php?group_id=2435&package_id=20507 MinGW] - file gdb-6.8-mingw-3.tar.bz2 - and install
 
#Download [http://sourceforge.net/project/showfiles.php?group_id=165409 MSEide & MSEgui] - you will need two zip files: mseide_bin_*.zip and mseide_msegui_src_*.zip
 
##Extract them both under a directory of your choice (='yourdirectory', for instance C:\Programme\mse\)
 
#Run 'yourdirectory\bin\i386-win32\mseide.exe', for instance C:\Programme\mse\bin\i386-win32\mseide.exe
 
## Click to 'Settings'-'Configure MSEide' and set '${MSEDIR}' to 'yourdirectory\msegui', for instance C:\Programme\mse\msegui\
 
## In the same dialog, set '${COMPILER}' to point to the FPC exe file, for instance to C:\Programme\fpc\2.2.3\bin\i386-win32\ppc386.exe
 
## In the same dialog, set '${DEBUGGER}' to point to the GDB exe file, for instance to C:\Programme\gdb-6.8\bin\gdb.exe
 
## Click to 'Project'-'Open' and select a demo project 'yourdirectory/msegui/apps/demo/demo.prj', for instance C:\Programme\mse\msegui\apps\demo\demo.prj
 
## Click to 'Target'-'Continue', to build demo.exe and run it in a debugger.
 
 
 
= Quick start =
 
  
== Open Project ==
+
=== First RAD steps ===
Launch the IDE and use Project->Open to open the provided demo msegui/apps/demo/demo.prj. The title of the IDE reflects the opened project. Hit F9 and (if you followed the installation instructions :-), be amazed by the speed of FPC+MSE.
 
  
== First RAD steps ==
 
 
Close the running project. Use Project->Source to open the project source demo.pas. Ctrl-click on the parameter mainfo in the line  
 
Close the running project. Use Project->Source to open the project source demo.pas. Ctrl-click on the parameter mainfo in the line  
 
  application.createform(tmainfo,mainfo);
 
  application.createform(tmainfo,mainfo);
to navigate to main.pas. Click on F12 to toggle between unit and form. Not everything will feel that familiar, because of that, these pages are written. Click on the button, this will auto raise the property editor (unusual but usefull). Let us add another button. Make the component palette visible if necessary (View->Toolbar->Component Palette). Select the tbutton on the widget page. Click on the form to create the button. Give it a caption in the usual way. Creating an event handler does not work with the usual double clicking on the onexecute property. Instead, you must select the onexecute property in the property editor, type the name of an event handler and press enter. The MSE RAD will create the handler and position the pointer on the definition. Use ctrl-shift-down arrow (or up) to navigate between implementation and definition. Just add some code like writeln('Hello world'); Hit F9. The writeln will end up in the target console window of MSE (not the console in which you started MSE).
+
to navigate to main.pas. Click on F12 to toggle between unit and form. Not everything will feel that familiar, because of that, these pages are written. Click on the button, this will auto raise the property editor (unusual but useful). Let us add another button. Make the component palette visible if necessary (View->Toolbar->Component Palette). Select the tbutton on the widget page. Click on the form to create the button. Give it a caption in the usual way. Creating an event handler does not work with the usual double clicking on the onexecute property. Instead, you must select the onexecute property in the property editor, type the name of an event handler and press enter. The MSE RAD will create the handler and position the pointer on the definition. Use ctrl-shift-down arrow (or up) to navigate between implementation and definition. Just add some code like writeln('Hello world'); Hit F9. The writeln will end up in the target console window of MSE (not the console in which you started MSE).
 +
 
 +
=== Adding a Main Menu ===
 +
 
 +
==== Add Main Menu ====
 +
 
 +
Add a tmainmenu component from the Gui component tab to your main form. Click on your mainform (mainfo), so that Object Inspector shows the properties of the mainform. Use the arrow next to the mainmenu property of the mainform, to select tmainmenu1 as the mainmenu of mainfo.
 +
 
 +
==== Add Menu Items ====
 +
 
 +
In the Object Inspector, expand the mainmenu branch. In this branch, open the menu property of mainmenu. Change the submenu.count of menu to 1 (or higher). Now expand the submenu.count property, which will show "Item 0". Expand "Item 0" and set the caption, for instance to "&File". Now you can repeat the same procedure one level deeper... Change the submenu.count property of "Item 0" to 1. Expand this last submenu.count property and set the caption of the new "Item 0", for instance to "E&xit". Hit F9 and your program should have a menu ''F''ile with the entry E''x''it in it.
  
== Adding a Main Menu ==
+
Alternatively, in Object Inspector you may right click a submenu.count property, or an "Item n" property, which will reveal a context sensitive pop up menu. Use this pop up menu to insert, append or delete menu items.
=== Add Main Menu ===
 
Add a tmainmenu component from the Widget Component tab to your main form. Click on your mainform (mainfo) so that the Object Inspector show the properties of the mainform. Use the arrow next to the mainmenu property of the mainform, to select tmainmenu1 as the mainmenu of mainfo.
 
=== Add Menu Items ===
 
In the object inspector click on the cross to open the mainmenu treeview branch. Open the menu property of mainmenu. Change the submenu.count of menu to 1 (or higher). Now open the submenu.count property, it will show "Item 0". Open "Item 0" and set the caption to "File". Change the submenu.count property of "Item 0" to 1. Open this last submenu.count property and set the caption of the new "Item 0" to Quit. Hit F9 and your program should have a menu File with the entry Quit in it.
 
  
Once there is one submenu, you can add more by right clicking on a "Item X". This will reveal a context sensitive menu with "Insert, Append, Delete".  
+
Once you have more than one submenu, you can use drag and drop to move the menu items ("Item n"). Start the drag mouse move on the "Item n" line.
  
Once you have more than one submenu, you can use drag and drop to move the "Item X"s. Start the drag mouse move on the "Item X" line.
+
=== Create New Project ===
  
== Create New Project ==
 
 
In order to create a new project based on a template, use Project->New->From Template.
 
In order to create a new project based on a template, use Project->New->From Template.
 
For a GUI project select "default.prj", for a console project select "console.prj"
 
For a GUI project select "default.prj", for a console project select "console.prj"
  
= The concept =
+
== The concept ==
  
 
MSEgui is a Pascal program library, which provides the building blocks for developing programs with graphical user interface.<sup>1</sup>
 
MSEgui is a Pascal program library, which provides the building blocks for developing programs with graphical user interface.<sup>1</sup>
Line 83: Line 82:
 
MSEide is the corresponding integrated development environment for effective software production with Free Pascal and MSEgui. MSEide is also suitable for the development of gcc and microcontroller applications.  
 
MSEide is the corresponding integrated development environment for effective software production with Free Pascal and MSEgui. MSEide is also suitable for the development of gcc and microcontroller applications.  
  
Currently MSEide+MSEgui run under i386-linux and i386-win32, while supported microprocessors are CPU32, ARM and AVR32. MSEgui is predominantly platform independent. Additional platforms may be added by implementing the system-dependent software elements. The system-dependent MSEgui modules are located in subdirectories of lib/common/kernel.  
+
Currently MSEide+MSEgui run under i386-linux, x86-64-linux, arm-linux, x86-64-freebsd, i386-win32 and x86-64-win64 while supported microprocessors are CPU32, ARM and AVR32. MSEgui is predominantly platform independent. Additional platforms may be added by implementing the system-dependent software elements. The system-dependent MSEgui modules are located in subdirectories of lib/common/kernel.  
 +
 
 +
=== Main development goals ===
  
== Main development goals ==
 
 
* Relevant increase in productivity, compared with other development systems.  
 
* Relevant increase in productivity, compared with other development systems.  
 
* Identical appearance and functionality on all platforms, without additional measures in the user code.  
 
* Identical appearance and functionality on all platforms, without additional measures in the user code.  
 
* Dependence on additional libraries kept as little as possible.
 
* Dependence on additional libraries kept as little as possible.
 
* Orthogonality - there should be as little as possible interference between different program elements and as few as possible exceptions and special cases.  
 
* Orthogonality - there should be as little as possible interference between different program elements and as few as possible exceptions and special cases.  
* Highly parameterized GUI elements.  
+
* Highly parametrised GUI elements.  
 
* Working with MSEide+MSEgui should be fun.
 
* Working with MSEide+MSEgui should be fun.
  
== Architecture overview ==
+
=== Architecture overview ===
 +
 
 
MSEgui requires <u>no external component libraries</u> - it communicates directly with the graphical interface of the operating system, X11 via Xlib on Linux and gdi32 under Windows.  
 
MSEgui requires <u>no external component libraries</u> - it communicates directly with the graphical interface of the operating system, X11 via Xlib on Linux and gdi32 under Windows.  
  
Line 136: Line 137:
 
<sup>1</sup>) This chapter is based on a translation of a German text provided by Martin Schreiber.
 
<sup>1</sup>) This chapter is based on a translation of a German text provided by Martin Schreiber.
  
= Tips: MSEide =
+
== Tips: MSEide ==
 +
 
 +
=== Larger fonts ===
  
== Larger fonts ==
+
Some may find the standard menu font a bit small. The standard font for the main menu of an MSEgui application is the font defined by the stf_menu stock font. You can change a stock font value with a startup parameter, <fontheight> is given in pixels.
Some may find the standard menu font a bit small. The standard font for the main menu of an msegui application is the font defined by the stf_menu stock font. You can change a stock font value with a startup parameter.
 
 
  --FONTALIAS=<alias>,<fontname>[,<fontheight>[,<fontwidth>[,<options>]]]
 
  --FONTALIAS=<alias>,<fontname>[,<fontheight>[,<fontwidth>[,<options>]]]
So if you start the mseide like this, you can get a larger font:
+
So if you start the mseide like this, you can get a larger menu font:
 
   mseide --FONTALIAS=stf_menu,sans,16
 
   mseide --FONTALIAS=stf_menu,sans,16
 +
In order to increase the base font size for all stock fonts use
 +
  mseide --FONTALIAS=stf_default,,16
 +
 +
=== Shortcuts ===
  
== Shortcuts ==
 
 
Common
 
Common
 
* '''Ctrl+F4''' - Close
 
* '''Ctrl+F4''' - Close
Line 179: Line 184:
 
* '''Ctrl+U''' - Unindent
 
* '''Ctrl+U''' - Unindent
  
== Print from IDE ==
+
=== Print from IDE ===
 +
 
 
You need the [http://ghostscript.com/awki ghostscript]
 
You need the [http://ghostscript.com/awki ghostscript]
  
== Recent opened files or projects ==
+
=== Recent opened files or projects ===
 +
 
 
The last opened projects are in the dropdown list of 'Project'-'Open'-'Name'.
 
The last opened projects are in the dropdown list of 'Project'-'Open'-'Name'.
 
The last opened files are in the dropdown list of 'File'-'Open'-'Name'.
 
The last opened files are in the dropdown list of 'File'-'Open'-'Name'.
  
== Menu Editing ==
+
=== Menu Editing ===
* Use submenu.count to add the first submenu entry.
+
 
* Right click on a menu item "Item X" to display a context-sensitive menu that allows to insert,append or delete a submenu entry
+
* Use submenu.count to set the wanted menu items count.
* Use drag and drop on a submenu entry to move the different submenu entries.
+
* Right click on submenu.count or on a menu item "Item X" to display a context-sensitive menu that allows to insert,append or delete a submenu entry
 +
* Use drag and drop on a submenu entry to move the the item in the array.
 +
 
 +
=== New Panels in the IDE ===
  
== New Panels in the IDE ==
 
 
Example, you want to have the watch, stack and cpu window in a window:
 
Example, you want to have the watch, stack and cpu window in a window:
 
* select the menu item '''View'''-'''Panels'''-'''New Panel'''.
 
* select the menu item '''View'''-'''Panels'''-'''New Panel'''.
Line 201: Line 210:
 
* to use tabs drag one of the grip of the inserted widgets to the centre of the panel.
 
* to use tabs drag one of the grip of the inserted widgets to the centre of the panel.
  
== Design Tab-Order ==
+
=== Design Tab-Order ===
 +
 
 
Main way in '''MSEide''' is set the tab order after all widgets are placed in the form with the popup menu function "Set Tab Order".
 
Main way in '''MSEide''' is set the tab order after all widgets are placed in the form with the popup menu function "Set Tab Order".
 
Select a widget in the container where you wish to set the tab oder, click right, click "Set Tab Order", click row 0, click "Start", click the widget in the container which should get tab order 0, click the widget which should get tab order 1..
 
Select a widget in the container where you wish to set the tab oder, click right, click "Set Tab Order", click row 0, click "Start", click the widget in the container which should get tab order 0, click the widget which should get tab order 1..
  
 
An alternative is to drag and drop the rows to the desired position. The first row corresponds to the tab order 0 the second to the 1 and so on.
 
An alternative is to drag and drop the rows to the desired position. The first row corresponds to the tab order 0 the second to the 1 and so on.
=== Creating a new event handler ===
+
 
 +
==== Creating a new event handler ====
 +
 
 
Select the event you want in the '''Object Inspector''', then type name of the new event handler. IDE create a new procedure(declaration and implementation) in the source code.
 
Select the event you want in the '''Object Inspector''', then type name of the new event handler. IDE create a new procedure(declaration and implementation) in the source code.
 
If you double-click the name of the event handler in the '''Object Inspector''', source editor opens with the cursor at begin of your handler implementation.
 
If you double-click the name of the event handler in the '''Object Inspector''', source editor opens with the cursor at begin of your handler implementation.
  
  
= Tips: MSEgui =
+
== Tips: MSEgui ==
 +
 
 +
=== Tabbed control ===
  
== Tabbed control ==
 
 
* Put '''ttabwidget''' control on the form. Now you have container (''ttabwidget1'') for pages.
 
* Put '''ttabwidget''' control on the form. Now you have container (''ttabwidget1'') for pages.
 
* Put as many '''ttabpage''' controls on the ''ttabwidget1'' as tabs you want.
 
* Put as many '''ttabpage''' controls on the ''ttabwidget1'' as tabs you want.
  
== Splitter ==
+
=== Splitter ===
 +
 
 
We have two widgets (widgetLeft, widgetRight) and we need horizontal splitter between them.
 
We have two widgets (widgetLeft, widgetRight) and we need horizontal splitter between them.
 
* Add TSplitter to form and resize it as you want.
 
* Add TSplitter to form and resize it as you want.
Line 225: Line 239:
 
* If you need the vertical splitter then use other properties '''linktop''', '''linkbottom''', '''spo_vmove''', '''spo_vprop'''.
 
* If you need the vertical splitter then use other properties '''linktop''', '''linkbottom''', '''spo_vmove''', '''spo_vprop'''.
  
== Switch-off auto-scrolling of the form(widget) ==
+
=== Switch-off auto-scrolling of the form(widget) ===
 +
 
 
Change the '''container - frame - sbhorz - options - sbo_showauto''' property of the form to '''False'''.
 
Change the '''container - frame - sbhorz - options - sbo_showauto''' property of the form to '''False'''.
  
== Read/write data in the twidgetgrid ==
+
=== Read/write data in the twidgetgrid ===
 +
 
 
* '''editwidget.value''' -> value of the actual row
 
* '''editwidget.value''' -> value of the actual row
 
* '''editwidget[rowindex]''' or '''editwidget.gridvalue[rowindex]''' -> value of the addressed row
 
* '''editwidget[rowindex]''' or '''editwidget.gridvalue[rowindex]''' -> value of the addressed row
 
* '''editwidget.gridvalues''' the whole column as a dynamic array.
 
* '''editwidget.gridvalues''' the whole column as a dynamic array.
  
== First events ==
+
=== First events ===
 +
 
 
'''OnCreate''' is called before loaded procedures of the components of the form
 
'''OnCreate''' is called before loaded procedures of the components of the form
 
are called, '''OnLoaded''' is called after loaded procedures of the components of
 
are called, '''OnLoaded''' is called after loaded procedures of the components of
Line 240: Line 257:
 
component is called.
 
component is called.
  
== MDI ==
+
=== MDI ===
 +
 
 
MDI - application can be created using TDockFormWidget or TDockPanel (as MDI-area) and TDockForm (as ancestor for you MDI-child window).
 
MDI - application can be created using TDockFormWidget or TDockPanel (as MDI-area) and TDockForm (as ancestor for you MDI-child window).
 
There are examples:
 
There are examples:
Line 246: Line 264:
 
* Simple MDI-controller (create, switch, ... the child windows) http://mihafpc.narod.ru/MDISample.tar.gz or in ''$MSESOURCES/contributed/miha''
 
* Simple MDI-controller (create, switch, ... the child windows) http://mihafpc.narod.ru/MDISample.tar.gz or in ''$MSESOURCES/contributed/miha''
  
== Drawing ==
+
=== Drawing ===
=== Redraw form the additional thread ===
+
 
 +
==== Redraw form the additional thread ====
 +
 
 
Use a '''tthreadcomp''' (tab '''Gui''') to do the long time procedure. If you need to
 
Use a '''tthreadcomp''' (tab '''Gui''') to do the long time procedure. If you need to
 
access widgets and other gui variables from the additional thread, call
 
access widgets and other gui variables from the additional thread, call
 
'''application.lock''' before and '''aplication.unlock''' after accessing the main
 
'''application.lock''' before and '''aplication.unlock''' after accessing the main
 
event thread elements.
 
event thread elements.
=== Force repaint ===
+
 
 +
==== Force repaint ====
 +
 
 
* '''twidget.invalidate''' to invalidate an individual widget
 
* '''twidget.invalidate''' to invalidate an individual widget
 
* '''twidget.rootwidget.invalidate''' to invalidate the window
 
* '''twidget.rootwidget.invalidate''' to invalidate the window
 
* '''application.invalidate''' to invalidate all windows (=forms) in the application
 
* '''application.invalidate''' to invalidate all windows (=forms) in the application
=== Draw text ===
+
 
 +
==== Draw text ====
 +
 
 
There are two methods to draw texts in MSEgui:
 
There are two methods to draw texts in MSEgui:
 
* Simple text positioning by baseline position of start of the first character with '''tcanvas.drawstring'''.
 
* Simple text positioning by baseline position of start of the first character with '''tcanvas.drawstring'''.
 
* With the drawtext procedures of '''msedrawstring.pas'''.
 
* With the drawtext procedures of '''msedrawstring.pas'''.
=== Widgets canvas ===
+
 
 +
==== Widgets canvas ====
 +
 
 
No twidget has a canvas. The canvas used for painting is normally one of the
 
No twidget has a canvas. The canvas used for painting is normally one of the
 
canvas of twindow, it can also be an canvas of a tbitmap or a tprinter
 
canvas of twindow, it can also be an canvas of a tbitmap or a tprinter
Line 267: Line 293:
 
''tcanvas.font'' is initialized by '''twidget.getfont''', ''canvas.color'' by
 
''tcanvas.font'' is initialized by '''twidget.getfont''', ''canvas.color'' by
 
'''twidget.actualcolor''' before calling '''twidget.dopaint''', see '''twidget.paint''' procedure in msegui.pas.
 
'''twidget.actualcolor''' before calling '''twidget.dopaint''', see '''twidget.paint''' procedure in msegui.pas.
=== Theming (Frames & Faces) ===
+
 
 +
==== Theming (Frames & Faces) ====
 +
 
 
Every twidget has a property '''frame''' and '''face'''. If they are deactivated  
 
Every twidget has a property '''frame''' and '''face'''. If they are deactivated  
 
(<disabled> in object inspector) they are only an nil pointer and need no  
 
(<disabled> in object inspector) they are only an nil pointer and need no  
Line 305: Line 333:
 
To centralise the frame look use an '''tframecomp''' (tab ''Gui'') and select the  
 
To centralise the frame look use an '''tframecomp''' (tab ''Gui'') and select the  
 
framecomp in ''template'' of the ''frame'' properties.
 
framecomp in ''template'' of the ''frame'' properties.
=== Desktop colors in the MSE application ===
+
 
 +
==== Desktop colors in the MSE application ====
 +
 
 
Default values of the mapped colors stored in the array '''msegraphics.defaultmapped'''.
 
Default values of the mapped colors stored in the array '''msegraphics.defaultmapped'''.
 
For change it's values you can use function '''msegraphics.setcolormapvalue'''
 
For change it's values you can use function '''msegraphics.setcolormapvalue'''
Line 311: Line 341:
  
  
= Application examples and screenshots =
+
== Application examples and screenshots ==
 +
 
 +
=== A Firebird application ===
  
== A Firebird application ==
 
 
The following screen shots are taken from an MSEgui Firebird database application.
 
The following screen shots are taken from an MSEgui Firebird database application.
 
The programmer writes he has customized the look and feel of his application in about 30 minutes with a tfacecomp and two tframecomp. He states that the look and feel is identical on Linux and Windows.
 
The programmer writes he has customized the look and feel of his application in about 30 minutes with a tfacecomp and two tframecomp. He states that the look and feel is identical on Linux and Windows.
Line 341: Line 372:
 
[[Image:mse_gripfade1.png]]
 
[[Image:mse_gripfade1.png]]
  
 +
=== An embedded system ===
  
== An embedded system ==
 
 
An embedded system for medical applications, in this case steam sterilizers,
 
An embedded system for medical applications, in this case steam sterilizers,
 
was realized with MSE-IDE & MSE-GUI for the control unit, nowadays also
 
was realized with MSE-IDE & MSE-GUI for the control unit, nowadays also
Line 358: Line 389:
 
The informational fields display the devices' operating values in real time using a
 
The informational fields display the devices' operating values in real time using a
 
MSE system timer to collect the information from the PLC.
 
MSE system timer to collect the information from the PLC.
<br><br>
+
 
  
 
[[Image:ProcessDisplay.png|Process Display]]
 
[[Image:ProcessDisplay.png|Process Display]]
 +
  
 
After processing has been started, the display is switched to a different format
 
After processing has been started, the display is switched to a different format
Line 368: Line 400:
 
border, the diagram would change to a scrolling mode, always showing the current state
 
border, the diagram would change to a scrolling mode, always showing the current state
 
at the extreme right.
 
at the extreme right.
<br><br>
+
 
  
 
[[Image:StateDisplay.png|State Display]]
 
[[Image:StateDisplay.png|State Display]]
 +
  
 
For diagnostic purposes, also a schematic state display is available. This shows a
 
For diagnostic purposes, also a schematic state display is available. This shows a
Line 379: Line 412:
 
The schematic field really is the output of a separate program, running in parallel
 
The schematic field really is the output of a separate program, running in parallel
 
to the process display which provides the upper and lower parts of the screen display.
 
to the process display which provides the upper and lower parts of the screen display.
<br><br>
+
 
  
 
[[Image:ControlScreen.png|Control Screen]]
 
[[Image:ControlScreen.png|Control Screen]]
 +
  
 
There is also a mode for setting several control and function parameters and to
 
There is also a mode for setting several control and function parameters and to
Line 388: Line 422:
 
Some of the pages allow access only after entering a pass code to prevent missuse of
 
Some of the pages allow access only after entering a pass code to prevent missuse of
 
critical functions.
 
critical functions.
<br><br>
+
 
  
 
[[Image:ProtocolReview.png|Protocol Review]]
 
[[Image:ProtocolReview.png|Protocol Review]]
 +
  
 
This is a screen displaying a graphical protocol of a previous process. The protocol
 
This is a screen displaying a graphical protocol of a previous process. The protocol
Line 397: Line 432:
 
print out and for the on screen display shown, which uses the png format for loading
 
print out and for the on screen display shown, which uses the png format for loading
 
into the display field.
 
into the display field.
<br><br>
+
 
  
 
[[Image:Attribution.png|Attribution]]
 
[[Image:Attribution.png|Attribution]]
 +
  
 
Of course, there is also an attribution display, showing program version, creator information
 
Of course, there is also an attribution display, showing program version, creator information
Line 407: Line 443:
 
Above all of that sits a transparent button to close the picture.
 
Above all of that sits a transparent button to close the picture.
  
 +
== Reference: MSEide ==
  
= Reference: MSEide =
 
 
*To move and resize components without gridsnap use shift+cursorkeys and ctrl+cursorkeys.
 
*To move and resize components without gridsnap use shift+cursorkeys and ctrl+cursorkeys.
 
*There are many possibilities with properties twidget.frame and twidget.face, for instance tiled semitransparent bitmaps and color fades (all twidget descendants have these properties!).  
 
*There are many possibilities with properties twidget.frame and twidget.face, for instance tiled semitransparent bitmaps and color fades (all twidget descendants have these properties!).  
For client area of forms use tmseform.container.frame and tmseform.container.face, tmseform has additionally onpaint to do custom drawing.  
+
 
You can write your own widgets and override procedure dopaint or use teventwidget with onpaint,onresize,onmouseevent,onkeydown,onkeyup...
+
For client area of forms use tmseform.container.frame and tmseform.container.face, tmseform has additionally onpaint to do custom drawing.  
 +
 
 +
You can write your own widgets and override procedure dopaint or use teventwidget with onpaint,onresize,onmouseevent,onkeydown,onkeyup...
  
 
  How to convert filenames to windows format?  
 
  How to convert filenames to windows format?  
Line 427: Line 465:
 
  Have a look at property dragdock.
 
  Have a look at property dragdock.
  
== MSEi18n ==
+
=== MSEi18n ===
 
 
= Reference: MSEgui =
 
== Widgets ==
 
=== TSimpleWidget ===
 
=== TMainMenuWidget ===
 
=== TSimpleWidget ===
 
=== TMseFormWidget ===
 
=== TDockFormWidget ===
 
=== TPaintbox ===
 
How to draw line (or circle) on tpaintbox?
 
In event onpaint:
 
procedure tmainfo.paintboxonpaint(const sender: twidget; const canvas: tcanvas);
 
begin
 
  with sender,canvas do begin
 
  drawline(nullpoint,pointty(size),cl_yellow); 
 
  //diagonal line across widget
 
  drawellipse(makerect(makepoint(bounds_cx div 2,bounds_cy div 2), size),cl_red);
 
  //circle (or ellipse) centered in widget                           
 
  end;
 
end;
 
Makepoint and makerect are in msegraphutils.
 
 
 
=== TEventWidget ===
 
=== TButton ===
 
* A rectangular clickable area that can show text/bitmap.
 
- Main properties:
 
Caption: read/write the text that appear on top of it.
 
onexecute: read/write the address of a procedure (event handler) to be executed when clicked.
 
 
 
=== TStockGlyphButton ===
 
=== TRichButton ===
 
=== TLabel ===
 
* Draws a piece of text on the given surface (canvas: screen/printer/bitmap).
 
- Main properties:
 
Caption: read/write the piece of text.
 
 
 
=== TGroupBox ===
 
=== TStepBox ===
 
=== TStringDisp ===
 
*A read only version of TStringEdit, difference from TLabel: has a frame around it.
 
-Main properties:
 
Value: read/write the text that are showed.
 
Caption: A label normally describing the purpose or meaning of the presented text, it can be positioned around the frame.
 
 
 
=== TByteStringDisp ===
 
=== TIntegerDisp ===
 
=== TRealDisp ===
 
=== TDateTimeDisp ===
 
=== TBooleanDisp ===
 
=== TToolBar ===
 
=== TDrawGrid ===
 
=== TStringGrid ===
 
=== TTabBar ===
 
=== TTabPage ===
 
=== TTabWidget ===
 
=== TDockHandle ===
 
=== TDockPanel ===
 
=== TSpliter ===
 
A widget very similar to "tspacer" but :
 
- designed to rearrange areas occupied by adjacent widgets
 
- a linked widget may only enlarge by "eating" the opposite one, so the summary area of both widgets don't change
 
- has GUI look ( hatched grip, color etc) switched on by default
 
- facilitates run-time repositioning oneself and linked widgets
 
- linked widgets may even be other splitters, spacers (with their linked widgets ),..
 
 
 
=== TSpacer ===
 
* a regular widget which creates a kind of positional link between surrounding widgets
 
* designed to maintain distances between widgets
 
* may have GUI look, caption etc switched off by default
 
* resizing a spacer repositions its linked widgets
 
 
 
=== TLayouter ===
 
* a tspacer descendant designed to (auto)resize or/and move its contained widgets acc to some size/positon dependencies
 
* may have GUI look, frame caption etc switched off by default
 
* layouters may be nested to achieve copmplex layouts
 
Each layout change/assignment is divided into performing 2 consequent stages :
 
Stage 1:
 
  Widgets may be auto resized in 5 consequent steps using the following options:
 
- if plo_syncmaxautosize in place_options :
 
  = all widgets are autosized then their client areas are syncronized to the clientareas of the highest and the widest of the widget
 
* calls "msegui.syncmaxautosize"
 
  - if plo_syncpaintwidth in place_options :
 
    = the paintwidths of all widgets are synchronized to the widget with the widest outer frame width ( ex. width of "frame.caption" )
 
* mainly makes sense if "lao_alignx" set and {align_glue = wam_start or wam_end} ( see below ) when the widgets will be adjusted in order to fit into the inner client width of tlayouter:
 
 
 
x-aligh level 
 
        V
 
      | Widget_1 the_widest_frame_caption|
 
      | Widget_2 frame_caption2          |
 
      | Widget_N wider_frame_captionN    |
 
 
 
  here, the effect is shown for "cp_right" frame captions
 
  // otherwise syncronizes to the outer ( of the frame except its caption ) width
 
// of the Z-top widget
 
* calls "msegui.syncpaintwidth"
 
* paintwidth is the outer width
 
- if plo_syncpaintheight in place_options :
 
    = the paintheights of all widgets are synchronized to the widget with the highest outer frame width ( ex. width of "frame.caption" ).
 
* mainly makes sense if lao_aligny set and {align_glue = wam_start or wam_end} ( see below ) the widgets will be adjusted in order to fit into the inner client height of tlayouter :
 
 
 
+------------------------------+
 
      | The_                        |
 
      | tallest_            taller_  |
 
      | frame_    frame_    frame_  |
 
      | caption  caption2  captionN | 
 
      |                              |
 
| Widget1  Widget_2  Widget_N |<== y-align level       
 
 
 
here, the effect is shown for "cp_topleft" frame captions
 
// otherwise syncronizes to the outer ( of the frame except its caption )
 
// height of the Z-top widget
 
* calls "msegui.syncpaintheight"
 
- plo_synccaptiondistx in place_options :
 
  = causes all widgets to have the widest common room for their cp_(left/right)* frame captions
 
* calls "msegui.synccaptiondistx"
 
- plo_synccaptiondisty in place_options :
 
  = causes all widgets to have the highest common room for their cp_(top/bottom)* frame captions
 
* calls "msegui.synccaptiondisty"
 
 
 
Stage 2: the widgets may be (re)arranged within the layouter
 
There're 2 modes of such (re)arrangement which can be partially ( orthogonally ) combined ( see later ):
 
  1) the place(ment) mode ( lao_place* in optionslayout ) :
 
- widgets are placed at some distances between each other, possibly with some margins, rooms of invisible widgets ( having visible=false) are also allocated  unless "plo_noinvisible in place_options"
 
* the widgets are placed in the order of decreasing their "widgetrect.x" coordinates before alignment
 
* the inter-widget distances and the side margins ( if apllied ) in both dimentions are identical and limited between "place_mindist" and "place_maxdist"
 
  = if {lao_placex in optionslayout} and {place_mode <> wam_none} then the following relevant settings aplly :
 
* non-limiting value of "place_maxdist" :
 
# |Widget_1------Widget_2------Widget_3|
 
        * non-limiting value of "place_maxdist" and
 
{plo_propmargin in place_options} :
 
# |---Widget_1---Widget_2---Widget_3---|
 
* limiting value of "place_maxdist" and {place_mode = wam_start} :
 
# |Widget_1----Widget_2----Widget_3????|
 
* limiting value of "place_maxdist" and {place_mode = wam_start} and {plo_propmargin in place_options} :
 
# |---Widget_1---Widget_2---Widget_3???|
 
* limiting value of "place_maxdist" and
 
        {place_mode = wam_end} :
 
# |??????Widget_1---Widget_2---Widget_3|
 
* limiting value of "place_maxdist" and {place_mode = wam_end} and {plo_propmargin in place_options} :
 
# |???Widget_1---Widget_2---Widget_3---|
 
* limiting value of "place_maxdist" and {place_mode = wam_center} :
 
# |???Widget_1---Widget_2---Widget_3???|
 
* limiting value of "place_maxdist" and {plo_endmargin in place_options} :
 
# |Widget_1----Widget_2----Widget_____3|, or
 
# |Widget_1----Widget_____2----Widget_3|, or
 
# |Widget_____1----Widget_2----Widget_3|, here, the most left amongst widgets having both [an_left,an_right] set is expanded otherwise the most right widget ( Widget_3 in the example )
 
* limiting value of "place_maxdist" and {place_mode = wam_end} and {plo_propmargin in place_options} and   {plo_endmargin in place_options} :
 
# |--Widget_1--Widget_____2--Widget_3--|,
 
The legend: limiting value of "place_maxdist" : such value which produce some visuall effect on the ayouter
 
"----" : distance ( = number of minuses, limited by place_maxdis )
 
"????" : some remaining space ( = number of questmarks )
 
"Widget_1" : widget of the original size
 
"Widget__..__1" : (auto)resized widget
 
= if {lao_placey in optionslayout} and {place_mode <> wam_none} then the things are handled in the same manner as with "lao_placex" but for the vertical "top2bottom" direction of placement instead of the horizontal "left2right" one
 
2) the align(ment) mode ( optionslayout.lao_align* ) :
 
- widgets are gathered into a visual group to a dedicated "leader" widget of the layout ( set by "align_leader" and defaults to the lowest in Z-Order = twidget.widgets[0] ) the leader stays in place while the others :
 
= if lao_alignx in optionslayout ( the hor alignment mode ):
 
* if align_mode = wam_start : snap their left borders to the left border of leader
 
* else if align_mode = wam_end : snap their right borders to the right border of leader
 
* else if align_mode = wam_center : snap their v-axes to the v-axis of leader after that,
 
= if lao_aligny in optionslayout ( the vert alignment mode ):
 
* if align_mode = wam_start : snap their top borders to the top border of leader
 
* else if align_mode = wam_end : snap their bottom borders to the bottom border of leader
 
* else if align_mode = wam_center : snap their h-axes to the h-axis of leader
 
        - after that, the whole widget group can be aligned within the layouter:
 
= if align_glue =  wam_start
 
* if lao_alignx in optionslayout: the left extent of group snaps to the left border of layouter
 
* if lao_aligny in optionslayout: the top extent of group snaps to the top border of layouter
 
= else if align_glue = wam_end
 
* if lao_alignx in optionslayout: the right extent of group snaps to the right border of layouter
 
* if lao_aligny in optionslayout: the bottom extent of group snaps to the bottom border of layouter
 
= else if align_glue =  wam_center
 
* if lao_alignx in optionslayout: the v-axis of group snaps to the v-axis of layouter
 
* if lao_aligny in optionslayout: the h-axis of group snaps to the h-axis of layouter
 
Mutually exclusive settings:
 
* only one of "align_mode" can be choosen
 
* only one of  "glue_mode" can be choosen
 
* "optionslayout.lao_alignx" & "optionslayout.lao_placex"
 
* "optionslayout.lao_aligny" & "optionslayout.lao_placey"
 
V-alignment ( optionslayout.lao_aligny ) may be combined with h-placement ( optionslayout.lao_placex ), and h-alignment ( optionslayout.lao_alignx ) may be combined with v-placement ( optionslayout.lao_placey )
 
!!! The effects of the above described { resizing / placement / alignment } are irreversible.
 
So, the only way to revert is to set "wan_none" then to revert manually !!!
 
 
 
=== TListView ===
 
=== TImage ===
 
=== TDial ===
 
=== TChart ===
 
=== TChartRecorder ===
 
=== TPolygon ===
 
=== TPickWidget ===
 
=== TOpenglWidget ===
 
  
== Edit ==
+
== [[Reference: MSEgui]] ==
=== TStringEdit ===
+
[[Reference: MSEgui|On this page you can find a working in progress for documenting MSEGUI.]]
=== TMemoEdit ===
 
=== THexStringEdit ===
 
=== TDropdownListEdit ===
 
A tstringedit with a dropdownlist to choose text values. Important dropdown.options members:
 
- deo_autodropdown dropdown on keypress
 
- deo_selectonly don't allow entering arbitrary text.
 
- deo_forceselect don't allow entering empty text.
 
  
=== THistoryEdit ===
 
A tstringedit which shows the previously entered values in a dropdownlist for selection.
 
  
=== TIntegerEdit ===
+
== See also ==
=== TKeyStringEdit ===
 
Maps string to string.
 
  
=== TEnumEdit ===
+
* [[MSEide MSEgui first step]] Tutorial for beginners showing to create first program.
Maps integer to string, zero based and sequencial (first item 0, next 1, ...).
+
* [[MSEide MSEgui Howto]] Windows example.
  
=== TEnumTypeEdit ===
+
== External links ==
A tenumedit which maps Pascal enums to their names. Use oninit to store the typeinfo pointer of the enum type into sender.typeinfopo.
 
  
=== TSelector ===
+
WARNING: MSE project is part now of mse-org: https://github.com/mse-org
TSelector  is the most specialized widget of the dropdown editwidget group, it is based on tenumedit (tenumedit maps an integer to a string) and uses for the dropdownlist a second map which must be created on the fly in ongetdropdowninfo. An example is tcommselector where the enumedit maps commnrty to commname and the dropdownlist shows the available RS232 ports
 
only.
 
  
=== TRealEdit ===
+
MSEide & MSEgui sources are here:
=== TRealSpinEdit ===
+
https://github.com/mse-org/mseide-msegui
=== TDateTimeEdit ===
 
=== TCalendarDateTimeEdit ===
 
=== TEdit ===
 
MSEgui counterpart of Delphi TEdit. You will never use it.
 
  
=== TWidgetGrid ===
 
=== TItemEdit ===
 
=== TDropDownItemEdit ===
 
A tstringedit with a dropdownlist to choose text values. Important dropdown.options members:
 
- deo_autodropdown dropdown on keypress
 
- deo_selectonly don't allow entering arbitrary text.
 
- deo_forceselect don't allow entering empty text.
 
  
=== TMBDropDownItemEdit ===
+
Website:
=== TTreeItemEdit ===
+
http://mseide-msegui.sourceforge.net/
=== TRecordFieldEdit ===
 
Used in twidgetgrid in order to edit fields of a ttreeitemedit. Example is MSEide projecttreeform.pas.
 
  
=== TDialogStringEdit ===
+
Community website:
=== TPointerEdit ===
+
http://www.msegui.com
=== TSlider ===
 
=== TProgressBar ===
 
=== TBooleanEdit ===
 
=== TBooleanEditRadio ===
 
=== TDataButton ===
 
A button with an integer value. Clicking increments the value until "max", then it restarts with "min". Can be inserted into a twidgetgrid. The current value selects the showed image and face by the items of "imagenums" and "valuefaces".
 
 
 
=== TStockGlyphDataButton ===
 
=== TDataIcon ===
 
Shows an imagelist item by lookup from "value" to "imagenums". Clicking increments value until "max" then it restarts with "min". Can be inserted into a twidgetgrid.
 
 
 
=== TTextEdit ===
 
Only useful if inserted into a twidgetgrid, builds a text editor, used in MSEide source editor.
 
 
 
=== TDataImage ===
 
A pixmap display widget which can be inserted into twidgetgrid.
 
 
 
=== TTerminal ===
 
 
 
== NoGui ==
 
=== TActivator ===
 
=== TThreadComp ===
 
=== TStatFile ===
 
- so that to be in effect, it should also be assigned to the form where the widget using the stafile is placed on
 
- in design, if "onstatwrite" is set and "filedir" is not yet created, deactivate exception "ECreateError" in project settings ( "Debugger" tab )
 
- "filedir" may contain "~/" indicating the user's home directory
 
- options "oe_savestate" & "oe_savevalue" of "client" widgets define what to store to the file
 
- position etc changes or/and value changes
 
- in case when a main form shares its stafile with non-main forms, on creating non-main ones, just edited not saved data of the main form ( bound to vars of the statfile) are reset to values read from the statfile upon creating the form; for "sfo_memory", this effect absents unless widgets on the concurring forms share same variable[s]; to avoid this behaviour, disable "fo_autoreadstat" & "fo_autowritestat" of the non-main forms
 
- each "tstafile" owns:
 
    = tstatwriter:
 
* provides methods of writing sections & statvars to a memory/file stream
 
- tstatreader:
 
* holds list of sections with statvars each
 
* provides search & check & reading interface to the statvars
 
* provides reading statvars from a memory/file stream
 
Positioning to a section speeds up accessing its statvars
 
- there also is "tstatfiler" ( exposed by some "tstatfile" events ) which:
 
  = may present or "tstatwriter" or "tstatreader" ( there's a check method )
 
  = provides directionless "update" methods with internal switch to needed direction of processing
 
- "reading" or "writing" statvars on per-section basis
 
 
 
=== TTimer ===
 
=== TNoGuiAction ===
 
=== TPipeReadercomp ===
 
=== TSysEnvManager ===
 
=== TProcessMonitor ===
 
=== TFilechangeNotifier ===
 
 
 
== Gui ==
 
=== TFaceList ===
 
=== TFrameComp ===
 
Terminilogy :
 
 
 
client area = area of the widget which interacts with a user
 
 
 
bevelling = additional facets rising/sinking frame & client area,
 
constists of two parts
 
- external: between frame and widget
 
- internal: between frame and client area
 
 
 
frame= flat space between external & internal facets, floats at the inner level of the external face
 
 
 
* Both frame & bevelling affect the client area ***
 
 
 
=== TFaceComp ===
 
- doesn't affect the widget frame but client area of the frame
 
 
 
=== TBitmapComp ===
 
=== TImageList ===
 
=== TPopupMenu ===
 
=== TMainMenu ===
 
=== TAction ===
 
Shortcut processing order :
 
 
 
- the smallest piece of processing is "doshortcut" procedure which
 
is called until processed:
 
= starting from the sender up to the toplevel widget
 
= then by all child widgets with non-set "ow_noparentshortcut"
 
= then, if "ow_nochildshortcut" isn't set, by the parent widget
 
= then by the widget oneself
 
 
- "doshortcut" is checked in the following order:
 
= starting from form's main menu
 
= then from the owning window ( the widget oneself )
 
= then from the application
 
 
 
* A shortcut is bound to a widget by :
 
- placing an action component on the widget ***
 
- direct assigning the shortcut to the widget (menus,..)
 
 
 
=== TShortCutController ===
 
=== TPostscriptPrinter ===
 
=== TGdiPrinter ===
 
=== TWmfPrinter ===
 
=== TSkinController ===
 
=== TGuiThreadComp ===
 
 
 
== Dialog ==
 
=== TFileListview ===
 
=== TFileDialog ===
 
=== TFaceComp ===
 
=== TFileNameEdit ===
 
=== TDirDropdownEdit ===
 
=== TColorEdit ===
 
=== TMemoDialogEdit ===
 
=== TPageSizeSelector ===
 
=== TPageOrientationSelector ===
 
 
 
=== DB ==
 
 
 
=== DBedit ==
 
 
 
=== DBfields ==
 
 
 
=== Report ==
 
=== TRepSpacer ===
 
=== TRecordBand ===
 
=== TrepValueDisp ===
 
=== TRepPageNumdisp ===
 
=== TRepPrintDateDisp ===
 
=== TBandGroup ===
 
=== TTileArea ===
 
 
 
=== Design ==
 
=== TGdbMi ===
 
=== TSyntaxEdit ===
 
=== TSyntaxPainter ===
 
 
 
=== Comm ===
 
=== TCommPort ===
 
=== TAsciiCommPort ===
 
=== TAsciiProtPort ===
 
=== TCommSelector ===
 
 
 
= External links =
 
  
 
Unofficial incomplete help pages started from Z505  
 
Unofficial incomplete help pages started from Z505  
Line 810: Line 494:
  
 
Read the beginner's tutorial (in Russian)
 
Read the beginner's tutorial (in Russian)
at: http://freepascal.ru/article//mse/20060108181639/
+
at: http://freepascal.ru/article/mse/20060108181639/
  
Also: "MSEide+MSEgui. Draw lesson." (in Russian) http://freepascal.ru/article//mse/20060205191314/
+
Also: "MSEide+MSEgui. Draw lesson." (in Russian) http://freepascal.ru/article/mse/20060205191314/
  
 
You can also find an English translation here:
 
You can also find an English translation here:
Line 820: Line 504:
 
http://freepascal.ru/wiki/index.php/MSEide%26MSEgui
 
http://freepascal.ru/wiki/index.php/MSEide%26MSEgui
  
 +
MSElang, the future compiler for the MSEide+MSEgui project
 +
https://gitlab.com/mseide-msegui/mselang/wikis/home
 
----
 
----
 +
 +
[[Category:MSEide+MSEgui]]

Latest revision as of 07:01, 1 September 2020

English (en) español (es) français (fr) Bahasa Indonesia (id)

WARNING: MSE project is part now of mse-org: https://github.com/mse-org

MSEide & MSEgui sources are here: https://github.com/mse-org/mseide-msegui

Biography of Martin: https://sites.google.com/view/martin-schreiber-biography/

Introduction

The MSEide is a Cross Platform GUI Development System for Pascal programmers, completely written in Pascal. The MSEgui does not feature VCL compatibility. The graphics library provides an interface to win32 and X11. Despite being a single person (Martin Schreiber) effort for the moment, the IDE and GUI has already an amazing feature list:

  • Internal character encoding is UCS2.
  • Internationalization tool included.
  • Docking forms.
  • Embedded forms (similar to TFrame).
  • Visual form inheritance.
  • Links to xlib and gdi32, no external widget library needed.
  • Database access components and data edit widgets.
  • Integrated debugging.
  • Integrated report designer.
  • Flexible and handy build system with switchable macros.
  • and more...

But what about Lazarus?

Lazarus is an IDE that aims to provide a high degree of compatibility with VCL code, while providing a native look on many platforms. The native look is very important for many developers, but combined with the VCL compatibility necessitates many complex interfaces to the different native widget sets (Gtk,Win32,Carbon,Qt). The continuous evolution of these native widget sets (gtk1->gtk2, win32->?, qt) provokes endless catching up.

MSEide+MSEgui neither features (or suffers :-) VCL compatibility, nor provides a real native look on target platforms. The graphics library provides an interface to win32 and X11. The advantage of the X11 layer is the immediate availability of a large and stable (in time) target platform.

These different goals of both projects make them both fulfill different needs.

Why this wiki

The design of the MSE GUI is a fresh approach to GUI design patterns. It features many innovative solutions for typical GUI tasks. Being innovative, the MSE GUI library differs substantially from VCL/LCL/CLX. Switching from VCL to MSE may be more challenging than switching from VCL to LCL. These wiki pages aim to ease the first steps with this promising alternative IDE and GUI library.

Installation

  • Current version: 5.0 (2020-04-02)
  • Authoritative reference: MSEide+MSEgui homepage with installation instructions
  • Cooperative homepage: [1]
  • Download: [2]
  • Work in progress: [3]

Quick start

Open Project

Launch the IDE and use Project->Open to open the provided demo msegui/apps/demo/demo.prj. The title of the IDE reflects the opened project. Hit F9 and (if you followed the installation instructions :-), be amazed by the speed of FPC+MSE.

First RAD steps

Close the running project. Use Project->Source to open the project source demo.pas. Ctrl-click on the parameter mainfo in the line

application.createform(tmainfo,mainfo);

to navigate to main.pas. Click on F12 to toggle between unit and form. Not everything will feel that familiar, because of that, these pages are written. Click on the button, this will auto raise the property editor (unusual but useful). Let us add another button. Make the component palette visible if necessary (View->Toolbar->Component Palette). Select the tbutton on the widget page. Click on the form to create the button. Give it a caption in the usual way. Creating an event handler does not work with the usual double clicking on the onexecute property. Instead, you must select the onexecute property in the property editor, type the name of an event handler and press enter. The MSE RAD will create the handler and position the pointer on the definition. Use ctrl-shift-down arrow (or up) to navigate between implementation and definition. Just add some code like writeln('Hello world'); Hit F9. The writeln will end up in the target console window of MSE (not the console in which you started MSE).

Adding a Main Menu

Add Main Menu

Add a tmainmenu component from the Gui component tab to your main form. Click on your mainform (mainfo), so that Object Inspector shows the properties of the mainform. Use the arrow next to the mainmenu property of the mainform, to select tmainmenu1 as the mainmenu of mainfo.

Add Menu Items

In the Object Inspector, expand the mainmenu branch. In this branch, open the menu property of mainmenu. Change the submenu.count of menu to 1 (or higher). Now expand the submenu.count property, which will show "Item 0". Expand "Item 0" and set the caption, for instance to "&File". Now you can repeat the same procedure one level deeper... Change the submenu.count property of "Item 0" to 1. Expand this last submenu.count property and set the caption of the new "Item 0", for instance to "E&xit". Hit F9 and your program should have a menu File with the entry Exit in it.

Alternatively, in Object Inspector you may right click a submenu.count property, or an "Item n" property, which will reveal a context sensitive pop up menu. Use this pop up menu to insert, append or delete menu items.

Once you have more than one submenu, you can use drag and drop to move the menu items ("Item n"). Start the drag mouse move on the "Item n" line.

Create New Project

In order to create a new project based on a template, use Project->New->From Template. For a GUI project select "default.prj", for a console project select "console.prj"

The concept

MSEgui is a Pascal program library, which provides the building blocks for developing programs with graphical user interface.1

MSEide is the corresponding integrated development environment for effective software production with Free Pascal and MSEgui. MSEide is also suitable for the development of gcc and microcontroller applications.

Currently MSEide+MSEgui run under i386-linux, x86-64-linux, arm-linux, x86-64-freebsd, i386-win32 and x86-64-win64 while supported microprocessors are CPU32, ARM and AVR32. MSEgui is predominantly platform independent. Additional platforms may be added by implementing the system-dependent software elements. The system-dependent MSEgui modules are located in subdirectories of lib/common/kernel.

Main development goals

  • Relevant increase in productivity, compared with other development systems.
  • Identical appearance and functionality on all platforms, without additional measures in the user code.
  • Dependence on additional libraries kept as little as possible.
  • Orthogonality - there should be as little as possible interference between different program elements and as few as possible exceptions and special cases.
  • Highly parametrised GUI elements.
  • Working with MSEide+MSEgui should be fun.

Architecture overview

MSEgui requires no external component libraries - it communicates directly with the graphical interface of the operating system, X11 via Xlib on Linux and gdi32 under Windows.

For the individual GUI elements no operating system resources are required - only the main windows are known to the operating system. The entire processing of external events (keyboard, mouse, focus control ...) happens within MSEgui on a Pascal level.

The base class for GUI elements is a twidget. There is no distinction between simple graphic elements and elements which can receive input focus, as is the case in Delphi. All MSEgui widgets have the full functionality of a twidget at their disposal.

Important features of twidget are twidget.frame and twidget.face. When frame or face are not used, they are represented by NIL pointer, in this way using almost no resources.

twidget.frame is responsible for the frame around the working area of the element. The appearance of the frame is higly adjustable - it can be a simple and quickly drawable 3D frame, as well as a complex and slower composite construct, based on images. There are also other frame elements, that can build scroll bars, buttons and labels.

twidget.face draws the background of the working area of a desktop GUI element - color gradients and images in various forms can be shown, while partial transparency is also possible.

Setting the properties of frame and face can be centralised by using tframecomp and tfacecomp, which can be selected into tframe and tface as templates.

The next level of centralization is tskincontroller, through which program-wide settings can be made. In order to achieve that, tskinkontroller assigns to the GUI elements the appropriate tframcomp and tfacecomp templates.

The control of the widget functions (focusin, focusout, ...) is done by virtual procedures and functions and not through messages. The MSEgui message function has other tasks. Also a Corba-style interface is used - for the safe connection between the various components and the automatic disconnection through destroy, a tobjectlinker is used.

The type msestring is used in MSEgui for storing text. At the moment, msestring equals WideString. However, the reference counted FPC WideString (UnicodeString) is planned to be used under Windows, as soon as it becomes available in one of the future FPC releases.

In text files the utf-8, ASCII or the local encoding is used - MSEide+MSEgui does not use utf-16 files.

The MSEgui database components provide the conversion from the local encoding or the utf-8 (adjustable) to WideString for the data buffering. For file operations, a set of MSEgui's own functions with WideString interface exists. An MSEgui application can therefore work consistently with WideStrings, which is a significant relief for some tasks.

Specialized data edit widgets for the basic data types (integer, real, tdatetime, ...) are available in MSEgui (tintegeredit, trealedit, tdatetimeedit, ...). The main event property of these widgets is onsetvalue, which can be used for reacting upon user input.

The t*edit widgets can be inserted into a twidgetgrid and in that way form a column of the appropriate data format.

For viewing and editing of data fields a tdbwidgetgrid togeather with a set of tdb*editwidgets can be used. Worth mentioning are also different lookup components and a tlookupbuffer, a fast associative data memory.

The basic component of the MSEgui's database environment is tmsebufdataset, from which tmsesqlquery is derived. MSEgui DB is a fork of the FPC SQLDB system, where TBufDataset and large parts of TSQLQuery and the connection components have been completely rewritten.

tmsebufdataset offers local indices, calculated and internalcalc-fields, a mode with an interrupted database connection, an in-memory mode where no database connectivity is necessary and can keep a local journal, in order to later reconect a previously disconnected database connection. tmsebufdataset stores texts as WideStrings of variable length.

Further, there are SQL script components and tsqlresult for quick queries without the TDataset overhead. Persistent TField instances are either kept within tmsesqlquery, where they can be edited in the object inspector via tmsesqlquery.controller.fields, or they can be inserted into forms or modules as as individual components from the 'DBf' component palette.

MSEide supports 'visual form inheritance', Submodule (Delphi TFrame equivalent) and allows the assignment of components of other forms or modules to component properties at design time.

Internationalization is done via resource modules that are loadable at runtime. The MSEi18n, a tool that supports the import and export of texts in spreadsheet programs is available for editing - therefore facilitating a translation by nonprogrammers.

1) This chapter is based on a translation of a German text provided by Martin Schreiber.

Tips: MSEide

Larger fonts

Some may find the standard menu font a bit small. The standard font for the main menu of an MSEgui application is the font defined by the stf_menu stock font. You can change a stock font value with a startup parameter, <fontheight> is given in pixels.

--FONTALIAS=<alias>,<fontname>[,<fontheight>[,<fontwidth>[,<options>]]]

So if you start the mseide like this, you can get a larger menu font:

 mseide --FONTALIAS=stf_menu,sans,16

In order to increase the base font size for all stock fonts use

 mseide --FONTALIAS=stf_default,,16

Shortcuts

Common

  • Ctrl+F4 - Close
  • Ctrl+S - Save
  • Ctrl+E - Select page
  • F11 - Toggle Form/Inspector
  • F12 - Toggle Form/Unit
  • Shift+Ctrl+[0..9] - Bookmark 0..9
  • Ctrl+[0..9] - Go to bookmark 0..9
  • Ctrl+LeftClick - Go to var(class, method, unit) declaration
  • Shift+Ctrl+Up - Go to method declaration
  • Shift+Ctrl+Down - Go to method implementation
  • Shift+Ctrl+Space - Show procedure header

Debug

  • F7 - Step
  • F8 - Next
  • F9 - Continue
  • Shift+F7 - Finish
  • Shift+Ctrl+F8 - Next instruction
  • Shift+Ctrl+F7 - Step instruction
  • F5 - Toggle breakpoint
  • Shift+F5 - Toggle breakpoint enabled/disabled
  • Ctrl+B - Breakpoints on/off
  • Ctrl+W - Watches on/off

Editor

  • Ctrl+Z - Undo
  • Ctrl+X - Cut
  • Ctrl+C - Copy
  • Ctrl+V - Paste
  • Ctrl+F - Find
  • F3 - Search again
  • Ctrl+L - Go to line.
  • Ctrl+I - Indent block
  • Ctrl+U - Unindent

Print from IDE

You need the ghostscript

Recent opened files or projects

The last opened projects are in the dropdown list of 'Project'-'Open'-'Name'. The last opened files are in the dropdown list of 'File'-'Open'-'Name'.

Menu Editing

  • Use submenu.count to set the wanted menu items count.
  • Right click on submenu.count or on a menu item "Item X" to display a context-sensitive menu that allows to insert,append or delete a submenu entry
  • Use drag and drop on a submenu entry to move the the item in the array.

New Panels in the IDE

Example, you want to have the watch, stack and cpu window in a window:

  • select the menu item View-Panels-New Panel.
  • select the menu item View-Watches.
  • drag the Watches window by the grip (not the window title!) in the new panel.
  • same with Stack and CPU window.
  • to split horizontal drag one of the grip of the inserted widgets to the left border of the panel.
  • to split vertical drag one of the grip of the inserted widgets to the bottom border of the panel.
  • to use tabs drag one of the grip of the inserted widgets to the centre of the panel.

Design Tab-Order

Main way in MSEide is set the tab order after all widgets are placed in the form with the popup menu function "Set Tab Order". Select a widget in the container where you wish to set the tab oder, click right, click "Set Tab Order", click row 0, click "Start", click the widget in the container which should get tab order 0, click the widget which should get tab order 1..

An alternative is to drag and drop the rows to the desired position. The first row corresponds to the tab order 0 the second to the 1 and so on.

Creating a new event handler

Select the event you want in the Object Inspector, then type name of the new event handler. IDE create a new procedure(declaration and implementation) in the source code. If you double-click the name of the event handler in the Object Inspector, source editor opens with the cursor at begin of your handler implementation.


Tips: MSEgui

Tabbed control

  • Put ttabwidget control on the form. Now you have container (ttabwidget1) for pages.
  • Put as many ttabpage controls on the ttabwidget1 as tabs you want.

Splitter

We have two widgets (widgetLeft, widgetRight) and we need horizontal splitter between them.

  • Add TSplitter to form and resize it as you want.
  • Change the linkleft of tsplitter1 to widgetLeft and linkright to widgetRight. At this step our widgets stick to splitter.
  • Change the spo_hmove to True. That's all.
  • If you want to save a proportion between width of widgetLeft and width of widgetRight when the main form is resized then change the so_hprop to True.
  • If you need the vertical splitter then use other properties linktop, linkbottom, spo_vmove, spo_vprop.

Switch-off auto-scrolling of the form(widget)

Change the container - frame - sbhorz - options - sbo_showauto property of the form to False.

Read/write data in the twidgetgrid

  • editwidget.value -> value of the actual row
  • editwidget[rowindex] or editwidget.gridvalue[rowindex] -> value of the addressed row
  • editwidget.gridvalues the whole column as a dynamic array.

First events

OnCreate is called before loaded procedures of the components of the form are called, OnLoaded is called after loaded procedures of the components of the form are called. Many components do initializations in loaded procedures, event properties are inactive before procedure loaded of the component is called.

MDI

MDI - application can be created using TDockFormWidget or TDockPanel (as MDI-area) and TDockForm (as ancestor for you MDI-child window). There are examples:

Drawing

Redraw form the additional thread

Use a tthreadcomp (tab Gui) to do the long time procedure. If you need to access widgets and other gui variables from the additional thread, call application.lock before and aplication.unlock after accessing the main event thread elements.

Force repaint

  • twidget.invalidate to invalidate an individual widget
  • twidget.rootwidget.invalidate to invalidate the window
  • application.invalidate to invalidate all windows (=forms) in the application

Draw text

There are two methods to draw texts in MSEgui:

  • Simple text positioning by baseline position of start of the first character with tcanvas.drawstring.
  • With the drawtext procedures of msedrawstring.pas.

Widgets canvas

No twidget has a canvas. The canvas used for painting is normally one of the canvas of twindow, it can also be an canvas of a tbitmap or a tprinter or... MSEgui uses one canvas to paint a whole window with all widgets. tcanvas.font is initialized by twidget.getfont, canvas.color by twidget.actualcolor before calling twidget.dopaint, see twidget.paint procedure in msegui.pas.

Theming (Frames & Faces)

Every twidget has a property frame and face. If they are deactivated (<disabled> in object inspector) they are only an nil pointer and need no more resources. Activate them by clicking on the ellipse button in the right object inspector column in the row face respective frame.

The face property defines the background of the client area of the widget.

It is a combination of a fade and a bitmap. Both of them can be semitransparent. The bitmap can be stretched and/or tiled. Example: you want to create a button with a fade as face.

  • place a tbutton on the form.
  • in object inspector activate property face.
  • set face.fade.color.count to 2.
  • click on the + at color.count.
  • in item 0 select cl_gray.
  • in item 1 select cl_ltgray, now you have a left to write fade from gray to light gray.
  • change face.fade.direction to gd_up or gd_down, you get a convex resp. concave fade.

If you want, you can blend an additional structure over the fade:

  • select the wanted pattern image in face.image.
  • activate face.image.alignment al_tiled.
  • adjust face.image.transparency to your needs, $000000 = opaque, $ffffff = fully transparent. The number defines the transparency of the three color channels ($RRGGBB).

To centralise the face look use an tfacecomp (tab Gui) and select the facecomp in template of the face properties.

The frame property defines the look of an additional frame around the component and shows a possible caption at the widget. Example: you want an lowered frame around and a caption right of the button.

  • activate property frame.
  • set frame.levelo to -1.
  • set frame.leveli to 1.
  • enter the caption text in frame.caption.
  • set frame.captionpos to cp_right.

To centralise the frame look use an tframecomp (tab Gui) and select the framecomp in template of the frame properties.

Desktop colors in the MSE application

Default values of the mapped colors stored in the array msegraphics.defaultmapped. For change it's values you can use function msegraphics.setcolormapvalue Win32 and KDE example ($MSESOURCES/contributed/miha/GuiStyle.pas)


Application examples and screenshots

A Firebird application

The following screen shots are taken from an MSEgui Firebird database application. The programmer writes he has customized the look and feel of his application in about 30 minutes with a tfacecomp and two tframecomp. He states that the look and feel is identical on Linux and Windows.

mse dbwidgetgrid1.jpg

mse dbwidgetgrid2.jpg

Linux version: mse form1.jpg

Windows version: mse form1w.jpg

Linux version: mse button1.jpg

Windows version: mse button1w.jpg

The report is designed and rendered with the built-in MSEide+MSEgui report designer and report generator.

mse report1.jpg

Two MDI forms with fade and flat frame.

mse gripfade1.png

An embedded system

An embedded system for medical applications, in this case steam sterilizers, was realized with MSE-IDE & MSE-GUI for the control unit, nowadays also commonly called the "human machine interface", HMI.

Main Screen

The control unit uses a touch panel a its display, therefore all active controls have to be made rather large to enable the personnel to handle them easily. The main screen consists of a few informational display fields and allows to select the implemented sterilizing processes by means of a menu consisting of several button components showing the process names along with a short description in a separate panel. The visibility of the buttons and their captions are defined during program loading by means of a configuration file. The informational fields display the devices' operating values in real time using a MSE system timer to collect the information from the PLC.


Process Display


After processing has been started, the display is switched to a different format showing the operating values in large digits on some numeric display field components on the left and a graphical representation of the process history on the right, again both as real time "live displays". If the diagram curves would reach the right panel border, the diagram would change to a scrolling mode, always showing the current state at the extreme right.


State Display


For diagnostic purposes, also a schematic state display is available. This shows a simplified schematic of the apparatus, along with real time animated symbols of the control elements, as there are valves and pumps, each displayed in a derived version of a timage component, created and placed dynamically on program load. Also shown are the most important process values as numerical displays, also dynamically placed. The schematic field really is the output of a separate program, running in parallel to the process display which provides the upper and lower parts of the screen display.


Control Screen


There is also a mode for setting several control and function parameters and to recall previous operational and diagnostic data. It is organised as a tabbed screen containing several run time parametrized menu pages and a couple of display field pages. Some of the pages allow access only after entering a pass code to prevent missuse of critical functions.


Protocol Review


This is a screen displaying a graphical protocol of a previous process. The protocol is usually printed out immediately after termination, as required by the regulations. The printer output is generated as a postscript file, processed by ghostscript both for print out and for the on screen display shown, which uses the png format for loading into the display field.


Attribution


Of course, there is also an attribution display, showing program version, creator information and the tools used for the creation of the system, Free Pascal and MSE-IDE & MSE-GUI. As background, it uses a photography of one such apparatus as it is used in clinics displayed in an image component carrying several label fields used for the text. Above all of that sits a transparent button to close the picture.

Reference: MSEide

  • To move and resize components without gridsnap use shift+cursorkeys and ctrl+cursorkeys.
  • There are many possibilities with properties twidget.frame and twidget.face, for instance tiled semitransparent bitmaps and color fades (all twidget descendants have these properties!).

For client area of forms use tmseform.container.frame and tmseform.container.face, tmseform has additionally onpaint to do custom drawing.

You can write your own widgets and override procedure dopaint or use teventwidget with onpaint,onresize,onmouseevent,onkeydown,onkeyup...

How to convert filenames to windows format? 
Unit msefileutils: 
function tosysfilepath(const path: filenamety): filenamety; 
procedure tosysfilepath1(var path: filenamety); 
Converts to filename format of actual OS. 
function tomsefilepath(const path: filenamety): filenamety; 
procedure tomsefilepath1(var path: filenamety); 
Converts from filename format of actual OS.
Where is the MDI ???   
In MSEgui we have tdockform and tdockpanel for that purpose. 
Have a look at property dragdock.

MSEi18n

Reference: MSEgui

On this page you can find a working in progress for documenting MSEGUI.


See also

External links

WARNING: MSE project is part now of mse-org: https://github.com/mse-org

MSEide & MSEgui sources are here: https://github.com/mse-org/mseide-msegui


Website: http://mseide-msegui.sourceforge.net/

Community website: http://www.msegui.com

Unofficial incomplete help pages started from Z505 at: http://z505.com/cgi-bin/mse/idx.cgi?file=generalindex

Read the beginner's tutorial (in Russian) at: http://freepascal.ru/article/mse/20060108181639/

Also: "MSEide+MSEgui. Draw lesson." (in Russian) http://freepascal.ru/article/mse/20060205191314/

You can also find an English translation here: http://www.geocities.com/yetanothergeek/mseide-tutorial-en/

This page in Russian: http://freepascal.ru/wiki/index.php/MSEide%26MSEgui

MSElang, the future compiler for the MSEide+MSEgui project https://gitlab.com/mseide-msegui/mselang/wikis/home