Delphi control that could mimic "Add-ons|Extension list" of Firefox? - delphi

My aim is to update the look of the GUI in my app. Currently my GUI contains a lot of listboxes which are used to edit some objects in an old fashioned way, that is, user double-clicks an item and a dialog is shown to modify the corresponding object.
I think a good modern approach is how Firefox displays the extensions installed (a snapshot below).
My question is about how to build such a GUI in Delphi(win32) easily? Are there any components you use mimicing such behaviour or will I just need to code this from stratch using panels? (IMO a very cumbersome job I'd like to avoid - the selection logic, resizings, etc...)

You can do something similar (not exactly) with standard components; TDBCtrlGrid, TSpeedButton,...
alt text http://img8.imageshack.us/img8/9585/imagen29ox3.png

If you're using Delphi 2007 or Delphi 2009, you might be able to do something similar using TCategoryButtons (from the 'Additional' component palette page). Drop it on a form and right click to display the popup menu, and then click "Categories Editor...". Add a category with the resulting dialog, set it's caption, and optionally set up Items it contains. Not exactly the same, but it might do what you need.
You could also use a dialog with a TTreeView (if you have categories of objects) or TListView to emulate the Delphi 2007 Projects->Options dialog. Clicking an item in the TreeView or ListView displays the proper page of a TPageControl to configure the object.

I mostly agree with Lars, but I would use a frame for each item instead of a panel. That would separate into its own file, and you would get easy designtime support for it.

Using a TFrame for each list item and put them all Aligned Top on a TScrollBox might work. Also see TDBCtrlGrid which does something like that in combination with datasets.

It can be done with existing Delphi controls.
For instance in the TCustomListBox control you can create your own OnDrawItem event to draw your own list item. You also need to create your own OnMeasureItem to change the item height.
In some cases it is very limited, so if you want more freedom you will need to do it from scratch.

Related

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 ?

Firemonkey: Styling the tGrid or alternative Grid/List components (Virtual)

I'm trying to create my first app based on FireMonkey, and I hit a wall.
The only virtual list control I can find is tGrid.
This component is pretty good, but I can not figure out how to extend or customize it.
I get that there is tCheckbox column, tImage column etc, but what if I need a ButtonColumn or something like this?
Also I would like to style a row, based on the state of the data it represents.
An Example: if the data that is represented in the row has "Error=True" it should be displayed in red.
Has anyone got a similar problem? Or found alternate virtual list/grid components? Or even just some tips on use of the tGrid component.
These components are pretty essential in all database apps so it should be a pretty common request.
Also just as a note, I don't think the TGrid supports Drag & Drop of rows?
I have looked at
Firemonkey version of VirtualTreeView
and
Firemonkey and large amounts of data
If you look at the sources, TCheckColumn is only 15 code lines. If you need to create your own column descendant class it's quite straightforward.
This is one solution, otherwise you can dynamically create some components in your cells and then cast the children when checking the props (TColumn.CellControlByRow() return a TControl and the children would be what you have put in there).
As you want to 'style' your row I would suggest you to write your own TColumn class, even if you can do painting in the OnPaint Event.

How make a control that look like the "download" dialog of firefox

I have a application that like firefox, can be enhanced from plugins available from internet.
Now, I want to provide in Delphi (2010) a dialog similar to the download from firefox. I have no skills in build graphical controls.
Using the standard controls of Delphi, what could be the best way... using a TListView/TStringGrid with custom draw or...
The idea is show a icon in the left, a title with subtitle with 1-3 lines on the middle and date/version on the right. That row must be selectable and that is all.
For the UI part,
The easiest way: Use TNextGrid in "Slide view" from bergsoft. It's one of my favorite VCL controls. Check this screenshot:
http://www.bergsoft.net/res/screenshots/next-grid/slides-style.gif
The most flexible way: Use TVirtualStreeTree with custom draw, but it'll take some time to get use to that most powerful tree view control and apply a custom draw.
The Most promising way: Use TMS software's advanced poly list (in beta stage currently), check the Screenshots in the following page and it's very nice looking!:
http://www.tmssoftware.com/site/advpolylist.asp
use VirtualStringTree from SoftGems.
Use TFrame to create a custom control for one download, and then reuse it.
Use a TDataSet descendant (eg. TClientDataSet, JVCL's TjvMemoryData or any other dataset you like) to have a table with all the fields needed to describe your download. For example:
Plugin_Name - Char(255)
Plugin_Icon - Blob
Downloaded_Size - Int64
Total_Size - Int64
//etc.
(Of course the above fields are provided just as an example - the actual fields are up to you).
After this, connect a TDataSource to your table and use an TDBCtrlGrid to show your data as you wish. For the above example, you can put on your record a TDBLabel, TDBImage, TjvDBProgressBar (unfortunately we don't have a data-aware gauge shipped with Delphi) etc. all these connected to the appropriate fields.
In this way you can simulate a list (if you set TDBCtrlGrid's Column property to 1) with a custom layout in which you can do select, add, delete etc.
HTH

how to set the tabwidth of the listbox portion of a TComboBox in Delphi

You can easily achieve a multicolumn effect in a listbox by setting the TabWidth property of TListbox. For example, http://delphi.about.com/cs/adptips2000/a/bltip1200_3.htm
I need to do the same in the drop down list of a ComboBox, but comboboxes don't publish any TabWidth property.
Any ideas?
In a comment to this answer advising you to owner-draw the list box items you say:
I'm wondering why I must do that when the required functionality already exists on a listbox
A combo box is actually composed of three native child windows - the combo box itself, an embedded edit, and a list box. You can use the GetComboBoxInfo() function to fill a COMBOBOXINFO structure (i.e. a TComboBoxInfo record) with information about the control, and it will return the 3 HWND elements in it. With that you are able to alter the appearance and behaviour of the list box. In principle.
For the list box to use the tab stops it needs to have the LBS_USETABSTOPS style flag set. Unfortunately this can't be turned on later, the list box has to be created with it. So you could use the functionality only if you were able to turn the style flag on for the list box, which is created during the CreateWindowEx() call for the combo box. AFAICS this can only be done by hooking the CreateWindowEx() call itself, identifying the internal call that creates the list box, and altering the passed style. This means runtime modification of code, and not in your executable but in a Windows DLL.
Owner-drawing the list items looks like it would be much easier.
From what I know there is not so simple way as TabWidth here but you can override Paint method and draw it yourself. Looking at listbox and combobox sources may help.

Design-time drag and drop in Delphi?

Before Delphi 2006 (I think) introduced the TFlowPanel and TGridPanel, I did a control that was similar in concept. It still does a couple of things those controls do not do, and when upgrading my code to Delphi 2009, I decided to add a couple of enhancements to that as well.
Right now, the order of the child controls is determined by their creation order. The FlowPanel and GridPanel show a better way with ControlIndex and other filtered properties, but I was wondering if there is a way to handle drag and drop reordering in design-time? As far as I can tell, dragging an edit control and dropping it onto my panel doesn't call anything that I can access at design-time.
I was half-fantasising about a way to either detect the drop operation directly, or to perhaps detect when a control is moved so I can determine where it should go.
Any ideas?
Update:
OK, got it working. The container control was already overriding AlignControls to manage the placement of the controls. When you drag the nested control and drop it, AlignControls is again called. I then compared the new coordinates of the control with the other controls in the list and moved it to the appropriate position.
There were a couple of problems that I had to work through (mostly related to the many calls to AlignControls) but the basic concept is simple enough. Thanks to all the commenters for all the help.
You can't drag a control that's already on the form and drop it onto your panel. Dragging is only for moving a control, not for changing its parent. To change the parent, cut and paste.
If the control is already on your panel, and you want to move it to another position on your panel, then the panel can control the layout by overriding the TWinControl.AlignControls method. When a control is moved, its SetBounds method is called, and among the things tha happens is that it calls AlignControl(Self) on its parent window. That calls AlignControls. Look in Controls.pas, and you'll see that that's a complicated method, but it's what is responsible for the layout of the children on a control, and that's exactly what you're planning to change.
Perhaps some of these suggestions might help.
You can re-parent a control in the designer without having to do cut-and-paste. View the structure pane, and simply drag the visual control to the node of another parent in the structure pane. If you have things in a flowpanel, drag everything out of the flow panel and drag them back in the order that you want them to be.
(You can re-parent ANY visual control this way, without changing anything other than its parent. I highly recommend doing it this way.)
You can view the form as text, and move the declaration order around in there -- but obviously you'll need to be careful when editing the "resource" file directly.
You can set tab order in the designer, so you could make a different control based on tab order that works as you want. You can right click on the form and change the creation order of the non-visual controls, but that doesn't work with visual controls.
Have you tried to write an "OnDragDrop" event for your grid component, where you check if your component is in design mode?
I haven't written such a component yet, but I don't see why the event shouldn't trigger.

Resources