Changing layout at runtime

Coming from Linux-land here, I suppose that the whole hpkg GUI can be reworked into three parts:

  • Package discovery (a la GNOME Software)
  • Package management (a la Synaptic or Pamac; for Haiku, this is SoftwareUpdater + Repo manager + An installed packages list)
  • A cute little GUI to be used when someone double-clicks a .hpkg
2 Likes

Also: I think the installer thingy is more of a training-wheels app that isnā€™t going to actually be used for installing stuff.

Another layout API trouble: BBox label is clipped.

Code:

BLayoutItem *CreateTextControlLayoutItem(BTextControl *view)
{
	BGroupLayout *layout;
		BLayoutBuilder::Group<>(B_VERTICAL, 0)
			.GetLayout(&layout)
			.AddGroup(B_HORIZONTAL, 0)
				.Add(view->CreateLabelLayoutItem())
				.AddGlue()
				.End()
			.Add(view->CreateTextViewLayoutItem())
			.End();
	return layout;
}

BBox *NewLabelBox(const char *name, const char *label)
{
	BBox *box = new BBox(name);
	if (label != NULL) {
		box->SetLabel(label);
	}
	return box;
}

TestView::TestView(): PageView("components", false, "Test", "Test page.")
{
	fTeam = new BTextControl("team", "Team:", "0", NULL); fTeam->SetEnabled(false);
	fPort = new BTextControl("port", "Port:", "0", NULL); fPort->SetEnabled(false);
	fToken = new BTextControl("token", "Token:", "0", NULL); fToken->SetEnabled(false);

	fLeftView = new BTextControl("left", "Left:", "0", NULL);
	fTopView = new BTextControl("top", "Top:", "0", NULL);
	fRightView = new BTextControl("right", "Right:", "255", NULL);
	fBottomView = new BTextControl("bottom", "Bottom:", "255", NULL);

	BLayoutBuilder::Group<>(this, B_VERTICAL, B_USE_SMALL_SPACING)
		.SetInsets(B_USE_SMALL_SPACING)
		.Add(
			BLayoutBuilder::Group<>(NewLabelBox("box1", NULL), B_HORIZONTAL, B_USE_SMALL_SPACING)
				.SetInsets(B_USE_SMALL_SPACING)
				.Add(CreateTextControlLayoutItem(fTeam))
				.Add(CreateTextControlLayoutItem(fPort))
				.Add(CreateTextControlLayoutItem(fToken))
				.View())
		.Add(
			BLayoutBuilder::Group<>(NewLabelBox("frame", "Frame"), B_HORIZONTAL, B_USE_SMALL_SPACING)
				.SetInsets(B_USE_SMALL_SPACING)
				.Add(CreateTextControlLayoutItem(fLeftView))
				.Add(CreateTextControlLayoutItem(fTopView))
				.Add(CreateTextControlLayoutItem(fRightView))
				.Add(CreateTextControlLayoutItem(fBottomView))
				.View())
		.AddGlue()
		.End();
}

Result:
layout

2 Likes

I know itā€™s all a matter of taste, but have to say I like HaikuDepot as single, one-stop package management. In (some?) Linux distros, I without fail pick the wrong app and end up with some tool showing every available software with not much information or screenshots or anything. And it takes an unreasonably long time to be up and responsiveā€¦

Nope, I prefer HaikuDepot as is, even though its ā€œFeatured packagesā€ has some capacity for improvement. Thereā€™s already a simple view mode when double clicking a HPKG. Get the ā€œOpenOriginPackageā€ Tracker add-on to get the same for any file of a package.

Sorry for the derail. If people want to discuss this further, I can split this into a new threadā€¦

1 Like

I explored FileTypes source code and found that it use following workaround:

.SetInsets(padding, 2*padding, padding, padding)

It is not working properly with big font size:

2 Likes

This looks like https://dev.haiku-os.org/ticket/13174.

1 Like

BMenuField vertical label layout is not working properly while BTextControl is fine:
layout2

Workaround:

BLayoutItem *CreateMenuFieldLayoutItem(BMenuField *view)
{
	BGroupLayout *layout;
		BLayoutBuilder::Group<>(B_VERTICAL, 0)
			.GetLayout(&layout)
			.AddGroup(B_HORIZONTAL, 0)
				.Add(view->CreateLabelLayoutItem())
				.AddGlue()
				.End()
			.AddStrut(16) // workaround
			.Add(view->CreateMenuBarLayoutItem())
			.End();
	return layout;
}
1 Like

I think there was another ticket but I canā€™t find it. @PulkoMandy do you remember?

I found solution:

BBox *NewLabelBox(const char *name, const char *label, BView *content)
{
	BBox *box = new BBox(name);
	if (label != NULL)
		box->SetLabel(label);
	if (content != NULL)
		box->AddChild(content);
	return box;
}

// ...

.Add(
	NewLabelBox("frame", "Frame", 
		BLayoutBuilder::Group<>(NewColorView("content", B_TRANSPARENT_COLOR), B_HORIZONTAL, B_USE_SMALL_SPACING)
			.SetInsets(B_USE_SMALL_SPACING, 0, B_USE_SMALL_SPACING, B_USE_SMALL_SPACING)
			.Add(CreateTextControlLayoutItem(fLeftView))
			.Add(CreateTextControlLayoutItem(fTopView))
			.Add(CreateTextControlLayoutItem(fRightView))
			.Add(CreateTextControlLayoutItem(fBottomView))
			.View()
	)
)

This code work fine with different font sizes. BBox donā€™t support inserting BLayoutItem inside it, it only supports AddChild with BView argument.

1 Like

BBox uses a custom layout to layout a single child inside the box (making sure the title and border remains visible). It handles another children as a replacement for the title (usually a BMenuField, occasionally a checkbox is put there). If you try to set a group layout or some other layout on it, this custom layout is removed. So, yes, you need a child view to set your layout on. This is annoying but behaving as expected given the current design.

Maybe the layout builder could get an AddBox() method to do that in a more natural way?

If this is an invalid usage of the Layout API, perhaps we can make the SetLayout() call in BBox private, or add a debugger() call in BBox to make sure it never happens?