Iterating children of a TVertScrollBox - c++builder

I have a single TForm with a single TVertScrollBox. I have added 6 TPanels as children of this TVertScrollBox.
I would like to iterate over each of these panels and check the Tag property of each, but I can't find the correct method to do so.
For testing, I've added an OnClick event handler for one of the panels that contains the following code:
void __fastcall TForm1::Panel1Click(TObject *Sender)
{
int i;
for (i = 0; i < this->VertScrollBox1->ChildrenCount; ++i)
{
ShowMessage("Child: " + this->VertScrollBox1->Children[i]->Name);
}
for (i = 0; i < this->VertScrollBox1->ComponentCount; ++i)
{
ShowMessage("Component: " + this->VertScrollBox1->Components[i]->Name);
}
}
It seems the ChildrenCount property always returns 2, and the Name displayed by ShowMessage for each of these children is an empty string, even though each panel has a unique Name property.
The ComponentCount property always returns 1, and again- the displayed Name is always an empty string.
Can someone tell me which properties or methods to use to iterate over these children?

Children & ChildrenCount are the correct properties to use but it sounds like your panels are being stored in a container stored within the scrollbox. (I've seen this in other components and I'm not at my dev machine to research).
Check the Classnames of the two children, and what their children are. When you've astablished which child (identified by ClassName) is the container, you'll know how to drill down to your panels.

Related

How to make TListView display order the same as the items were added?

I am adding a list of comet names and numbers into the VCL TListView and TListBox in C++Builder. I need the display order to be the order in which the names were added. This happens with the TListBox but not the TListView.
I am loading a .CSV file into a TStringList and then looping through the TStringList to load the contents into the TListBox and TListView. The TListBox displays the names in the order they are added. The TListView displays the names and numbers in two columns in an order I can't understand. With the TListView, I tried using the function Add() and Insert().
Below is my code. The picture shows the different results I get. How can I make the TListView display the names and numbers in the order they are added the same as the TListBox?
TListItem *ListItem;
std::auto_ptr<TStringList> MyCSVFile(new TStringList);
MyCSVFile->Delimiter = ',';
MyCSVFile->StrictDelimiter = true;
MyCSVFile->CommaText = "";
MyCSVFile->Clear();
MyCSVFile->LoadFromFile(GetFileName);
for(Row_Num=1; Row_Num < MyCSVFile->Count; Row_Num++){
Row_string = MyCSVFile->Strings[Row_Num];
Row_tokens->CommaText = Row_string;
Name_string = Row_tokens->Strings[Name_Cell_Num];
Num_string = Row_tokens->Strings[Num_Cell_Num];
ListBox1->Items->Add(Name_string);
//ListView - Add()
ListItem = ListView->Items->Add();
ListItem->Caption = Cell_string;
ListItem->SubItems->Add( Num_string );
//Alternate method ListView - Insert()
//ListItem = ListView->Items->Insert(0);
//ListItem->Caption = Cell_string;
//ListItem->SubItems->Insert(0, Num_string);
}
ListBox and ListView
I have tried using the Add() and Insert() functions with TListView but the display order is not the order items are added. I don't know any other way to get items into the TListView.
By default, the TListView sorts the items based on their captions or subitems, but setting the SortType to stNone will disable the sorting.
So, you can add the following line before the loop:
ListView->SortType = stNone;

jetpack compose lazy custom layout

I tried to develop a simple custom layout just like the documentation
#Composable
fun MyBasicColumn(
modifier: Modifier = Modifier,
content: #Composable () -> Unit
) {
Layout(
modifier = modifier,
content = content
) { measurables, constraints ->
// Don't constrain child views further, measure them with given constraints
// List of measured children
val placeables = measurables.map { measurable ->
// Measure each children
measurable.measure(constraints)
}
// Set the size of the layout as big as it can
layout(constraints.maxWidth, constraints.maxHeight) {
// Track the y co-ord we have placed children up to
var yPosition = 0
// Place children in the parent layout
placeables.forEach { placeable ->
// Position item on the screen
placeable.placeRelative(x = 0, y = yPosition)
// Record the y co-ord placed up to
yPosition += placeable.height
}
}
}
}
it works fine when I know exact number of items
but what about lazy items?
there is nothing in documentation about how can I develop a LazyCustomLayout
You don't exactly have to know how many items are in the Layout, since even for dynamic lists, there's always a 'current number of items' which can be computed. Let's say you download a list of texts from a server, and then intend to use this Layout to render those. Even in that case, while the server may vary the length of the list, i.e., the list is dynamic in size, you would presumably have a LiveData object keeping track of the list items. From there, you can easily use the collectAsState() method inside a Composable, or the observeAsState() method tied to a LifecycleOwner to convert it into the Compose-compatible MutableState<T> variable. Hence, whenever the LiveData notifies a new value (addition, or deletion), the MutableState<T> variable will also be updated to reflect those values. This, you can use inside the said Layout, which is also a Composable and hence, will update along-side the server-values, in real-time.
The thing is, no matter how you get your list, in order to show it on-screen, or use it anywhere in your app, you would always have a list object, which can be exploited using Compose's declarative and reactive nature.

CBuilder TMenu showing in wrong place

I have a Form that needs to be embedded in another Form. I'm placing on TCard:
EmbeddedForm->Parent = ACard;
EmbeddedForm->BorderStyle = bsNone;
EmbeddedForm->Align = alClient;
EmbeddedForm->Show();
All is working well, except that menus on the EmbeddedForm are offset to where they would be if the form were located in top left of the screen. To be clear, the menu shows up in the proper place on the EmbeddedForm, but when clicked, the sub-menu is in the wrong place.
I've tried modifying the DrawItem event, but so far I can't call the base class DrawItem() as it's protected:
void __fastcall TEmbeddedForm::File1DrawItem(TObject *Sender, TCanvas *ACanvas, TRect &ARect, bool Selected)
{
ARect.Left = MainMenu1.Left; // or some other calculation, not important yet
ARect.Top = MainMenu1.Top;
// ??? how to do normal drawItem from here?
}
I'm thinking, either I have to draw it myself (I don't want to) or somehow explain to TMainMenu where it's actually located (preferred solution).

Add a combobox in to listview control in c++ builder

I want to create a listview with 2 columns. in the first column it must be the row number and in the second number it should contains a combobox. I write the following code, but second column just show "combo" string. it does not show any combo box. what is the wrong?
for (int i = 0; i < 10; i++) {
TListItem *items;
items= this->ListView1->Items->Add();
items->Caption=IntToStr(i);
items->SubItems->AddObject("combo"+IntToStr(i),(TObject *)this->ComboBox1);
}
It does not show a TComboBox because you have not actually set the TComboBox to be a child control of the TListView. All you have done is store the TComboBox pointer as a user-defined value associated with the TListItem. That has no effect on the UI, so get rid of it:
for (int i = 0; i < 10; i++)
{
TListItem *items = ListView1->Items->Add();
items->Caption = IntToStr(i);
items->SubItems->Add("combo"+IntToStr(i));
}
To actually show a TComboBox inside of the TListView, you have to assign the TListView as the Parent of the TComboBox, and then use the SetBounds() method to position and size the TComboBox whenever you need to show it:
ComboBox1->Parent = ListView1;
...
RECT rect = {0};
ListView_GetSubItemRect(ListView1->Handle, SomeListItem->Index, 1, LVIR_BOUNDS, &rect);
ComboBox1->SetBounds(rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top);
// update ComboBox1->Items as needed...
ComboBox1->Visible = true;
...
ComboBox1->Visible = false;
With that said, what you are attempting to do is better handled using the TValueListEditor component instead. Add items to it as needed, then use its ItemProps property to set each item's TItemProp.EditStyle property to esPickList, and then use the TValueListEditor.OnGetPickList event or the TItemProp.PickList property to manage the ComboBox strings as needed.

Vaadin Listbox Option Tooltip

Is it possible to add the title(tooltip) attribute to a listbox ot twincolselect in Vaadin?
I've tried to use setItemCaptionPropertyId() along with setItemCaptionMode() but in vain.
At the end when Vaadin renders the page, the resultant html has only the value attribute to the select component and no title attribute is present.
Update - my question should have been re-phrased to say - I need tooltip on each individual item (individual row) within a listbox or twinselect.
Here is an example for Nativeselect component
// Create the selection component
final NativeSelect mynativeselect= new NativeSelect("myLabel");
// Add some items
for (int i = 0; i < 25; ++i) {
mynativeselect.addItem(i);
}
//set tooltip
mynativeselect.setDescription("My tooltip");

Resources