What design alternatives are there for nested page controls? - delphi

In our primary application, we have a form that will allow us to do cross tab analysis of data in four different ways. Presently, each analysis appears in its own page of a PageControl on the screen. Now, upper management would like us to add in a historical aspect to the form, which in other areas we would use a PageControl to do, but nesting two of them seems like a bad idea to display the periods and analyses tabs stacked on top of each other. Does anyone have any suggestions as to how we could re-work this to look decent and work well? Thanks.

What about using the TTabset control along the bottom of the form to allow switching between the historical periods and the current data? I would also make sure that there was a visual difference in how the data is presented for historical vs current data. Like use an off grey cell background for historical data.

Use an small (horizontal) TTabSet with a vertical one.
See here (you can click on the picture to zoom). The TTabSet is shipped OOTB with Delphi. The vertical one can be written very easily if your requirements are low. If you want, I can share the code. But if you want a better vertical tab set then you can spend more time on writing or get one which is ready made from Torry or somewhere else.
HTH.

IMHO, you can use frames for each analysis result page, then you can use either PageControl or TabSet or any other visual control for loading and showing the appropriate frame.
Since frames are totally independent from the visual control you use to select proper period and analysis, you won't be restricted to tab-based controls; for example you can have a tabset for analysis selection, and a treeview for period selection.
Frames have some additional benefits here too:
First of all, their code is kept in
separate units and this will increase
code readability.
Second, you can design a base frame
and put all the controls and codes
which all these 4 analysis share into
that base frame, and in this way have
a better code reuse.
Third, you can either drop each frame
on your main form and make them load
just like before, or you can define a
container control (e.g a panel), and
based on user's selection load one of
the frames into the container control
dynamically, so reduce initial load
time of your application, and
probably reduce the overall system
resource consumption.

Related

hide UI components at RUN TIME , design issue

on a form I need a first set of UI controls at process start, later I only need a second set of components. I put the set for process set #1 on a first panel , after finish process step #1 I start to hide panel #1, is ther any better way from UI design guide lines ?
I would use Frames instead of Panels. You can design Frames at design-time just like Forms, and then create instances of your Frames at run-time as needed. So create your first Frame (you can even place it on the Form at design-time) and then at run-time, when ready you can destroy the first Frame instance and create an instance of the second Frame.
Using panels like you describe is a very common and very respectable way to proceed. Nothing wrong with doing it that way.
Another often used idiom is a page control with hidden tabs. So, make a page control. Add two tab sheets. Set TabVisible to False for both tab sheets. Then at run time set the ActivePage property of the page control to specify which page is shown to the user.
The page control approach is really rather similar to using panels. It's perhaps marginally easier to work with at design time, but much comes down to personal preference.

Is there a text editor with columns instead of scrolling?

Is there a text editor which offers horizontal, rather than vertical, scrolling (showing two pages side by side)?
I currently use TextMate, but would switch to any editor which offers this layout. I'm getting really bored of scrolling up and down, over and over.
I've attached a screenshot of MS Word, which has a side-by-side horizontal scroll view for documents longer than a page.
I want something like that, Any recommendations?
Emacs offers a follow-mode which you might find helpful ( see for instance here http://www.emacswiki.org/emacs/FollowMode).
A short description of how it is used and what it does:
You need to open a buffer in two windows and enter follow-mode using M-x follow-mode. This is actually a bit of a drawback, because you need to learn how to use emacs, if you don't know it already (imho learning how to use emacs is worth spending some time).
After entering follow-mode the second buffer will skip to the place where the first buffer ends, similar to the page-by-page view offered by Microsoft Word. Now if you move the cursor down one line at a time and you leave the first buffer window at the bottom, the cursor will appear at the top of the second. If you move further down and you are at the bottom of the second window, both buffers will scroll simultaneously, the same holds for page-wise scrolling using C-v and M-v.
If your monitor screen is wide enough, you can open a third window to further increase number of lines being displayed.
I have made a screenshot, which shows a text file opened in this mode: Screenshot auf Follow mode
Hmmm, it seems you are looking for layout features which you aren't likely to find in a text editor. Text editors are generally line based and don't understand the concept of pages. Text editors do things like code folding and allow lines to be wrapped or not. That is why text editors scroll in the vertical direction. These factors would affect pagination.
The concept of a page (and being able to lay them out side by side) doesn't really exist unless you are using a presentation manager such as a word processor or a desktop publishing package.
In vim: <Esc>:vsplit will open a second column for the file.
In all fairness, I should warn you that Vim has a steep learning curve, and will force you to wrap your head around new concepts like command mode / edit mode / visual mode. The results are definitely worth it, if you have the time to learn it.
I'm not sure if I know exactly what you want. Does Sublime Text 2's two-column layout with File > New View Into File do what you want?
A change on one side is reflected instantly in the other side, and you can scroll them independently. You can have up to four columns per window.
In LibreOffice Writer, go to View -> Zoom... and set Zoom factor to Fit width and height, and set View layout to Automatic. You can also set the number of columns manually, and if you choose two columns, you can use Book Mode.
With scroll-binding in vim, you can edit two files side by side: scroll-binding in Vim.
Show a text file with two columns in vim: http://vim.wikia.com/wiki/View_text_file_in_two_columns

Icon in header row for column setup

I would like to add an icon to the header of my data grid as it is done in Thunderbird.
There is an icon that is above the vertical scrollbar, no matter the position of the horizontal scrollbar. This icon allows the setup of the columns.
In Delphi there a lot of different grid components, that allow customizations and adding icons to there cells / header cells. But I could not find any component that has an area above the vertical scrollbar that is fixed, which when clicked allows some action. I could even use the VirtualTreeView component to emulate the grid, if it turns out to be easier to customize that component.
I am looking for some guidance on what need to be done to get that functionality.
Thanks,
Thomas
VirtualTreeView in Listbox mode would be nice, because of it's speed, great documentation and ease use in MVC-like patterns. Delphi tempts to store data in the visual components themselves, which letter causes troubles. While VTW allwos the same, it also allows to acutally separate data from GUI, and i like it.
But i am surprised by your claim "which when clicked allows some action.".
Even most basic components allow it:
http://docwiki.embarcadero.com/Libraries/XE2/en/Vcl.Grids.TCustomGrid.OnFixedCellClick
So could you make more detaiils, why you cannot use standard components ? with screenshot and editors, how u want it rendered, where you want to click and what kind of action should happen ?

Fluid Form Layout in Delphi

We have developed a software. In this software we are show and hiding a few controls on various input screens depending on various situations.
When we hid a control what happens is that the space occupied by that control is left as it is and layout looks very bad at times esp. in screens that have larger numbers of controls. Our client does not like this and has asked us to do something about this.
My question:
Is there some way by which we can create Fluid Layouts so that when a control is hidden the rest of the controls automatically adjusts themselves to fill the empty space left by the control hidden and when the control is show they should automatically make way for the control and adjust themselves accordingly.
I know we can achieve this by coding but that will require a lot of code in each screen for adjusting the layout. I am looking something which will reduce coding in each screen as there are 80+ screens.
Please suggest some way which is less error pron and can get rid of unnecessary coding in each input screen.
I think your best option is to use a component that handles the layout of your vcl controls on your form in runtime (depending on the conditions that you define). I recommend you try the Devexpress ExpressLayout Control
you can find two great demo videos here
ExpressLayout Control - How to Customize Layout Views
ExpressLayout Control - Create and Customize a Simple Layout
(source: devexpress.com)
You can check these features
Auto-Management - Control groups and individual control elements are automatically managed by the Layout Control. You never worry about pixel-by-pixel positioning.
Form auto-sizing - The form can be automatically resized to fit its contents best.
Bye.
Now, I'm not sure how complex layout you have, but I guess you can use TFlowPanel and/or TGridPanel for this. Flowpanel has a nice handling of components that change visiblity. I'm not sure how well gridpanel handles the same...
What kind of controls are you dynamically hiding, and what do you mean with auto fill space?
I do not know if it is as this simple: place controls on panels, and use align alTop/alClient/alBottom. When you hide a panel, all other panels will move automatically up.
One problem though: if you want to show a panel again, the order of panels can sometimes be screwed up... Can be fixed by manually setting .Top property, or "hide" by setting .Height := 1;
What I would do with a complex layout is actually split it up into several tabs. This has two advantages. It simplifies the form layout, and allows you to show and hide whole tabs depending on choices made in other tabs.
Raize Components have a TRzFlowPanel UI component. Does exactly what you're after.
Use TRzFlowPanel to put an empty flow panel on a form. The major difference between a traditional panel and a flow panel is the way in which controls are placed. With a traditional panel, you place a control (such as a button) in a specific location. You can freely move that control to any location within the panel using the mouse. In a flow panel, each control is placed in a specific location, regardless of where you place it with the mouse. The automatic location is controlled by the FlowStyle property. For example, using the default FlowStyle property of LeftRightTopBottom, the first control you add to the flow panel snaps to the top left corner. The second control that you add snaps next to the first control, and so on.

Delphi, frames vs forms. What for multi-document interface?

yesterday I've started discussion on "MDI vs tabbed interface". I've asked whether should I continue developing my app as MDI-based, or should I embed the child forms into tab sheets.
Someone pointed that I should use TFrames instead... My question is: why?
What are pros of using TFrames when embedding the form over TFrame? So far I don't know any, switching would only require me to rewrite some parts of code...
(I'm not going to use embedding at design time anyway!)
Thanks in advance
Answering the comment to provide a reason why to use frames:
I would consider frames to be building blocks of the GUI, with design time combination of existing components to more advanced components. Before Delphi 5 one would have used a TCustomPanel descendant with child controls and registered this as the new component, ready to be dropped onto a form. Frames allow for the same thing with less hassle.
They allow you to concentrate on developing exactly the functionality you need, and nothing more. Done right you can then embed them into tab control sheets, into modal or modeless dialogs, into MDI child frames and into standard frames. You can even add several of them into one form - something one would probably not do with embedded forms. The point is that for maximum reusability a layered approach is often necessary, and frames help with that.
A frame is fit for embedding from the go. A form has to be adapted to not show a caption bar and border, normally one would override the CreateParams() and adjust the window style accordingly. There are a lot more form properties in the inspector that just don't make sense for an embedded form. IMHO one should use the most basic and generic entity that suffices. A form just is much more than a control container for embedding.
OTOH I don't know of any disadvantage of embedding a frame that embedding a form wouldn't have.
Edit:
There's a comment regarding events like OnCreate or OnShow that frames don't have. Actually, I'd consider that another advantage of frames, as event handlers don't have parameters, so a lot of stuff gets hard-coded in forms, necessarily.
Consider the case of per-user settings: in OnCreate there's not much information available, so one invariably ends up using a constant or the name of the form for the INI file section, making it very hard or even impossible to reuse the form or to create several instances of it. With frames on the other hand a method LoadSettings is the obvious way to do it, and it can carry the necessary parameters. That way control is returned to where it belongs, to the container of the embedded frame / form. Reusability is only possible if the behaviour can be adjusted from the outside.
For contained objects that are not components and need to be lifetime-managed, there are for example AfterConstruction and BeforeDestruction.
Maybe you will find some answers in this thread: gui-design-multiple-forms-vs-simulated-mdi-tabs-vs-pagecontrol
Frame use the fastest load and without delay when creating the frame.
But the frame should be has a parent to embedded it. Disadvantage with no onCreate or onShow event has been triggered. but you can call with message for trigger onShow event like this one :
put on private section of frame:
procedure CMShowingChanged(var M: TMessage); message CM_SHOWINGCHANGED;
and then create the code like this :
procedure TFrame1.CMShowingChanged(var M: TMessage);
begin
inherited;
if Showing then
begin
// .... put your code for onShowing is triggered
end
else
begin
// .... put your code for onHiding is triggered
end;
end;
Hope can helping you to consider embedded frame for GUI.
You may consider combined with PageControl to control your frame opening.
Manz
I had same decision few years ago for one of our applications, we wanted to make it looks embedded forms, first I used the Frames and I wrote a class to manage it.
Later I found TLMDDisplayForm component from LMDTools, which making embedding forms inside it very easy task, it reduced the code used and we have more features.
one of main goals that we changed from frames to Forms was missing some events of TForm like: OnCreate, OnShow, OnActive which we use for some tasks in our applications, beside missing some properties such as: ActiveControl and other things I don't remember.
If you would like to go with Forms, I suggest you to use LMDTools which make the task easier for you, beside the basic version is free :-)
For dynamically inserted forms/frames I personally prefer to use embedded forms over frames. Several versions back when one would edit a frame which was set to alClient, the frame would resize between edits and any controls which were aligned specific to the right of the frame would change position. When using embedded forms this didn't happen so I made the switch. I believe this issue is now fixed with later versions of Delphi.
I strongly agree with the points Mghie made earlier regarding the inability to pass information to the embedded form through notification events. To solve this I generally implement a series of interfaces in each embedded form for communication. This really simplifies the code, and allows for more generic implementations where you have a single "container" that will be dealing with many different types of embedded forms/frames. A few examples of this are available on my blog as part of the wizard framework I designed.
I think both should be used. For example, I have a "standard" frame that has a dbnavigator, dbgrid and datasource components which is very handy for the typical data browsing. Instead of inserting such components every time, I insert a frame that also has the ability to export its data (with JVCL :D) to several formats...but I know what I want to display at design time, so I suggest a very easy rule: if it is known at design time, use frames, otherwise use embedded forms.
However, keep in mind that forms were not designed to be embedded. Using them like so, its unnatural (as a vampire states when she buries her 80 old year daughter and she looked like 30 :D). The embedded form knows little about the one that owns it and can also (logically) assume that is not embedded.
Complementing that, a frame is a component, and so, when embedded (owned by) in a form, the form knows about it and the frame knows about the form (can use its methods and properties. An embedded one can also do that but requires extra coding)
Perhaps Embarcadero could give us a hand by creating a TEmbeddableForm or an interface for such purposes
Regards,
Alvaro Castiello
Frames are good when you want to repeat a "sub-form" multiple times in a form. I'd not use them for tabbed interfacing, as the embedded form is a better solution for MDI/Tabbed interface use.

Resources