diff options
-rw-r--r-- | docs/fpGUI_tech_ref.tex | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/docs/fpGUI_tech_ref.tex b/docs/fpGUI_tech_ref.tex new file mode 100644 index 00000000..eb8105f8 --- /dev/null +++ b/docs/fpGUI_tech_ref.tex @@ -0,0 +1,156 @@ +\documentclass[a4paper,11pt]{report} + +% Define the title +\author{Graeme Geldenhuys} +\title{fpGUI - A technical reference} + +\setlength{\parindent}{0pt} +\setlength{\parskip}{1ex plus 0.5ex minus 0.2ex} + +\begin{document} + +% generates the title +\maketitle +\newpage + +% insert the table of contents +\tableofcontents +\newpage + +% ******************************************************************* +\chapter{Introduction} +After developing many cross platform applications with Kylix and Delphi +I started getting very frustrated with the differences between the look and +behaviour of the applications under Linux and Windows. The code was also +riddled with IFDEF statements. + +Then I stumbled across the Free Pascal and Lazarus projects. I thought this +is it, the answer to all my cross platform development problems. Unfortunately +after working with Lazarus for a few months I started finding more and more +issues with the widget sets, though the IDE was great. + +The Lazarus LCL is a wrapper for each platforms native widget set. This +brought with it the same issues I experienced with Kylix and Delphi. This got +me thinking about how I could resolve this issue. + +Then it hit me - implement the widget set myself using Free Pascal! Painting +the widgets myself to get a consistent look and implementing a consistent +behaviour. Instead of reinventing the wheel, I thought I would do some searching +to see if there is another project I can contribute to or help by giving me +a head start. + +The first version of my widget set was based around a heavily modified version +of the Light Pascal Toolkit\footnote{http://sourceforge.net/projects/lptk}. +I then discovered the discontinued fpGUI and fpGFX projects. I tried +to contact the original author to no avail. The fpGUI code hasn't been +touched in four years (since early 2002). After studying the code for a +few weeks, I came to the conclusion that fpGUI is much closer to what I strived +to accomplish with my modified LPTK. A lot was still missing from fpGUI though. + +After thinking long and hard, I decided to start my widget set again, but +this time based on the work done in fpGUI and fpGFX. I also added to the +mix some good ideas I saw in Qt 4.1. So far I have completed quite a few things +missing in fpGUI, but I still need to do a lot to get to the point where I +can test drive it in a commercial application. I set myself a list of +things outstanding which should get it to a usable level. I also added a +lot of documentation as I went as there was no documentation included with +the original fpGUI and fpGFX projects. Documentation is important +to attract other developers in using the widget set. + + + +% ******************************************************************* +\chapter{GUI and Events} +This chapter is currently a copy and paste of an email I wrote explaining +how the events work. The difference between the GFX events and the GUI events. +Soon I will rewrite this chapter and add a lot more detail. Here follows the email +text for now. + +The GFX part gets events from the windowing system, be that X11 or +GDI. That means that TFCustomWindow gets all the events from the +windowing system. + +Now the GUI part. Every widget is \emph{not} a TFCustomWindow, so every +widget doesn't have a Handle. The GUI is implemented with only one +handle per Form (TFForm). All widgets are just painted onto the canvas +of the TFForm. + +If you look at the TFCustomForm you will see it has a instance of +TFCustomWindow stored in FWnd. That instance gets all the events from +the windowing system. So to let the widgets also get events we have to +implement our own event system. The TFCustomForm will then send those +custom events (TEventObj descendants) by translating the windowing +events into our custom GUI events. + +For example:\\ +Lets say we have a Form with a Button on it. Now we want to handle a +OnMouseMove event on the Button. The flow of events will go as follows: + +\begin{itemize} + \item TFCustomForm.Wnd will receive the OnMouseMove from the windowing +system and process it in the WndMouseMoved() method. + + \item WndMouseMoved() will translate that windowing system event into +whatever GUI events are needed and start sending them. + + \item Any TWidget descendant handles events in the ProcessEvent() method. +TWidget being the big one. + + \item Because TFCustomForm is a TFContainerWidget descendant, it means it +can contain other widgets. So it starts distributing the GUI events to +the children. Distribution is done by the DistributeEvent() method. + + \item If TFCustomButton needed to do any special processing with the GUI +event, it would handle it in its ProcessEvent() method. +TWidget.ProcessEvent normally does most of the generic work. + + \item As an example of a widget that does custom processing, have a +look at the TFMenuItem.ProcessEvent(). In this case it handles the +TMouseEnterEventObj and TMouseLeaveEventObj events so it can changes +it's look when the mouse enters a menu item or leaves a menu item. +\end{itemize} + +So as a summary:\\ +TFCustomForm contains a instance of a GFX window. Translates all the +GFX events (underlying windowing events) to GUI events (TEventObj +descendants) and distributes them to the children of the Form. + + +% ******************************************************************* +\chapter{Layout Algorithm} + +\section{Initialisation of a window (form)} +If a window presents itself for the first time, and no standard size was + given, then it must compute these. + This is a recursive process, with which the event TCalcSizesEventObj is + set for all children of the window from top to bottom in the Widget tree + (beginning with the window). + TWidget reacts to the receipt of this event as follows (in TWidget.EvCalcSizes): + +\begin{itemize} + \item The event is passed on with TWidget.DistributeEvent to all children. + + \item The virtual protected method TWidget.DoCalcSizes is called. + Again derived Widgets overwrites this method, in order to compute its sizes + of (minimum, maximum, optimum). + + \item The results of DoCalcSizes are if necessary corrected, e.g. + the maximum size may not be smaller than the minimum size. + + \item If the code for the window finished the dispatch of this event, all Widgets + in the window has valid statements of size. + Now it can do its own, initials size sets (this is the before computed + optimum size of the window). + This is accomplished by TWidget.SetBounds. +\end{itemize} + +... to be continued ... + + +% ******************************************************************* +\chapter{Database Components} + +... to be continued ... + + +\end{document} |