Xamarin.Forms.CarouselPage title color - textcolor

I have a code in my mobile application written with Xamarin.Forms :
public CarouselPage CreateMenuPage() {
var menuPage = new CarouselPage();
menuPage.Title = "Application name";
menuPage.BackgroundColor = Color.White;
return menuPage;
}
As a result, the page title is invisible, because it has the same color (white) as the background.
How to set custom font color for title of CarouselPage?

The page title is not invisible, it wont be displayed as Pages that are opened modally or are at the root of your app don't display a title.
In Xamarin Forms you set the Title on each Page and these values are used by containers (like NavigationPage, TabbedPage, etc) when they need to describe their children. Any Page that are intending to add to a container should have the Title set (at least).
As an example the below Test Title can be seen but not the Carousel Content Page Titles.
public static Page GetMainPage()
{
var MainPage = new MasterDetailPage();
MainPage.Master = new ContentPage();
MainPage.Detail = new NavigationPage(new CarouselPage
{
Children =
{
new ContentPage {Content = new BoxView {Color = new Color (1, 0, 0)}, Title = "Page 1"},
new ContentPage {Content = new BoxView {Color = new Color (0, 1, 0)}, Title = "Page 2"},
new ContentPage {Content = new BoxView {Color = new Color (0, 0, 1)}, Title = "Page 3"}
},
Title = "test",
});
return MainPage;
}

Related

Text doesn't show up on GtkLabel

I have this code:
using Gtk;
class ConquerLauncher : Gtk.Application {
protected override void activate() {
var window = new ApplicationWindow(this);
window.add(new InputList());
window.show_all();
}
}
public int main(string[] args) {
return new ConquerLauncher().run(args);
}
class InputList : Box {
public InputList() {
this.set_orientation(Orientation.VERTICAL);
var listStore = new Gtk.ListStore(1,typeof(Label));
var treeView = new TreeView.with_model(listStore);
this.pack_start(treeView);
this.pack_start(new InputBox(this,listStore));
var column = new TreeViewColumn();
column.set_title("Foo bar's");
treeView.append_column(column);
treeView.set_model(listStore);
}
}
class InputBox : Box {
public InputBox(InputList list,Gtk.ListStore store) {
this.set_orientation(Orientation.HORIZONTAL);
var entry = new Entry();
this.pack_start(entry);
var button = new Button.with_label("Add foo bar");
this.pack_start(button);
button.clicked.connect(() => {
var text = entry.text;
entry.text = "";
TreeIter tp;
store.append(out tp);
store.set(tp, 0, new Label(text), -1);
this.show_all();
list.show_all();
});
}
}
What I want to do:
I want to create some sort of input form consisting of three elements:
In an Entry the user should write some text. If the presses the button, it should be added to the TreeView with a ListStore as a model.
Expectation:
The user enters a text, presses the button, the contents of the Entry are added to the TreeView and the text input field is cleared.
Reality:
Everything works, except the label that is added to the TreeView is blank.
Before:
Here an example input:
After pressing the button:

Gtk.Stack won't change visible child inside an event callback function

So I am currently working on an app for elementary os and encountered a problem.
I have a window which has a Granite.Sourcelistview on the left and a stack holding the different views on the right. My problem is that when pressing a button on one of the screens (the project settings screen i created), the stack should change the current view to a different one but it doesn't. The current view stays and is not changed.
This is the window:
public class MainWindow : Gtk.Window {
private SourceListStackView srcl_view {get; set;}
construct {
var header = new Gtk.HeaderBar ();
header.show_close_button = true;
//this is the source list view
srcl_view = new SourceListStackView ();
var paned = new Gtk.Paned (Gtk.Orientation.HORIZONTAL);
paned.position = 130;
paned.pack1 (srcl_view, false, false);
paned.add2 (srcl_view.stack);
add(paned);
set_titlebar (header);
}
public static int main(string[] args) {
Gtk.init (ref args);
MainWindow app = new MainWindow ();
app.show_all ();
Gtk.main ();
return 0;
}
}
This is the sourcelistview class that i created:
public class SourceListStackView : Granite.Widgets.SourceList {
public Gtk.Stack stack {get; set;}
public SourceListStackView () {
var project_page = new ProjectSettings ();
stack = new Gtk.Stack ();
var project = new Granite.Widgets.SourceList.ExpandableItem("Root");
this.root.add(project);
stack.add_named(project_page, "hello");
//here depending on what item of the sourcelist is created,
//the view with the same name as the item
//should be displayed (not the best mechanism but works)
this.item_selected.connect ((item) => {
if(item != null){
stack.visible_child_name = item.name;
}
});
//problematic part is here: This won't change the current view..why?
//The button should add another item to the
// source list view and change the current view
// to the newly created Welcome Screen but it doesn't do that..
project_page.button.clicked.connect(() => {
project.add(new Granite.Widgets.SourceList.Item ("Welcome"));
stack.add_named(new Granite.Widgets.Welcome("bla bli blu", "bla"), "Welcome");
stack.set_visible_child_name("Welcome");
});
}
}
This is the view with the button that should trigger the change of the view:
public class ProjectSettings : Granite.SimpleSettingsPage {
public Gtk.Button button {get; set;}
public ProjectSettings () {
Object (
activatable: false,
description: "This is a screen",
header: "",
icon_name: "preferences-system",
title: "Screen"
);
}
construct {
var project_name_label = new Gtk.Label ("Name");
project_name_label.xalign = 1;
var project_name_entry = new Gtk.Entry ();
project_name_entry.hexpand = true;
project_name_entry.placeholder_text = "Peter";
content_area.attach (project_name_label, 0, 0, 1, 1);
content_area.attach (project_name_entry, 1, 0, 1, 1);
button = new Gtk.Button.with_label ("Save Settings");
action_area.add (button);
}
}
The part that does not work is this one:
//problematic part is here: This won't change the current view.. why?
project_page.button.clicked.connect(() => {
project.add(new Granite.Widgets.SourceList.Item ("Welcome"));
stack.add_named(new Granite.Widgets.Welcome("bla bli blu", "bla"), "Welcome");
stack.set_visible_child_name("Welcome");
});
I do not know why it wont change the view. I specifically tell it to set the visible child to "Welcome" (and that is exactly how i named it one line above), but it just won't appear. Can someone explain to me why?
I can easily change the stack's visible child outside of the signal/event but inside of it won't do the trick..
Thanks a lot
Update: The issue was solved through José Fonte's comment down below: I instantiated the view, called the show_all () method on it and then added it to the stack and set the visible child to it.

SWT - How to change the size of Text box dynamically

I am trying to create a Simple UI which contains a combo, a text box and a browse button. The combo will be containing two values: Execution Times and Execute with File.
When the Execution Times option is selected, the combo box followed by a text box should be displayed.
when the Execute with File option is selected, the combo box, a text box, and a browse button should be displayed.
When I am switching between these options, the widgets are not getting aligned properly. Refer to the below image. The text box size is not getting expanded to the available space.
public class TestUI {
public static void main(String[] args)
{
Display display = new Display();
final Shell shell = new Shell(display);
shell.setText("StackOverflow");
shell.setLayout(new GridLayout(1, true));
Composite composite = new Composite(shell, SWT.NONE);
composite.setLayout(new GridLayout(3, false));
composite.setLayoutData(new GridData(GridData.FILL_BOTH));
Combo combo = new Combo(composite, SWT.READ_ONLY);
String[] input = { "Execution Times", "Execute with File" };
combo.setItems(input);
Text loopText = new Text(composite, SWT.SINGLE | SWT.BORDER);
GridData gridData = new GridData(SWT.BEGINNING | GridData.FILL_HORIZONTAL);
gridData.horizontalSpan = 2;
loopText.setLayoutData(gridData);
loopText.setEnabled(false);
Button browseButton = new Button(composite, SWT.PUSH);
browseButton.setText("Browse...");
browseButton.setVisible(false);
combo.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
String text2 = combo.getText();
System.out.println(text2);
if (text2.equals("Execution Times")) {
loopText.setEnabled(true);
loopText.setText("1");//$NON-NLS-1$
GridData gridData1 = new GridData(SWT.BEGINNING, SWT.TOP, false, false);
gridData1.grabExcessHorizontalSpace = true;
gridData1.horizontalSpan = 2;
loopText.setLayoutData(gridData1);
browseButton.setVisible(false);
loopText.getParent().layout();
}
if (text2.equals("Execute with File")) {
GridData gridData1 = new GridData(SWT.BEGINNING, SWT.TOP, false, false);
gridData1.grabExcessHorizontalSpace = true;
loopText.setLayoutData(gridData1);
gridData.exclude= false;
browseButton.setVisible(true);
browseButton.setFocus();
loopText.setText("");
loopText.setEnabled(false);
loopText.getParent().layout();
}
}
});
shell.pack();
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
}
Can any one help me on this?
From what I understand, depending on the combo selection, the text field and text field plus button serve different purposes:
when Execution Times is selected, the number of times is to be entered
otherwise Execute with File requires a file name to be entered or browsed for
Therefore, I would use a Composite next to the combo widget to hold either a text field to enter a number (or even a Spinner) or a text field and button to enter/select a file name.
Composite composite = new Composite( parent, SWT.NONE );
Text executionTimesText = new Text( composite, SWT.BORDER );
composite.setLayout( new StackLayout() );
Composite executionFileComposite = new Composite( composite, SWT.NONE );
// use a GridLayout to position the file name text field and button within the executionFileComposite
combo.addListener( SWT.Selection, event -> {
StackLayout layout = ( StackLayout )composite.getLayout();
if( combo.getSelectionIndex() == 0 ) {
layout.topControl = executionTimesText;
} else if( combo.getSelectionIndex() == 1 ) {
layout.topControl = executionFileComposite;
}
composite.layout();
}
The StackLayout allows you to stack the different input fields and switch betwen them as needed (i.e. according to the combo's selection).
For starters, you don't need to recreate the GridData for the Text widget every time. Instead, just modify the original via gridData.horizontalSpan, or if in practice you don't have access to the GridData instance, you can get at it via ((GridData) gridData.getLayoutData()).horizontalSpan, etc.
The reason you're seeing the blank space at the bottom of the Shell is because you've created a layout with 3 columns, and then added the following:
The Combo
The Text (with horizontalSpan set to 2, so this uses 2 columns)
The Button
The Combo and the Text take up all 3 columns, so a new row is added for the Button. Then you call pack(), and the preferred size is calculated, which will be for 2 rows, and the first row only sized for 2 widgets.
Instead of calling pack() and shrinking the size of the Shell down to the preferred size, we can just set a size on the Shell via Shell.setSize(...). In general you don't want to mix setSize(...) and layouts, but you've tagged your post with "RCP", so your Shell will already have a size and you won't be manually calling pack() and open().
Full example:
public static void main(String[] args) {
Display display = new Display();
final Shell shell = new Shell(display);
shell.setSize(300, 80);
shell.setText("StackOverflow");
shell.setLayout(new GridLayout(1, true));
Composite composite = new Composite(shell, SWT.NONE);
composite.setLayout(new GridLayout(3, false));
composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
final Combo combo = new Combo(composite, SWT.READ_ONLY);
String[] input = {"Execution Times", "Execute with File"};
combo.setItems(input);
final Text loopText = new Text(composite, SWT.SINGLE | SWT.BORDER);
final GridData textGridData = new GridData(SWT.FILL, SWT.FILL, true, false);
textGridData.horizontalSpan = 2;
loopText.setLayoutData(textGridData);
loopText.setEnabled(false);
final Button browseButton = new Button(composite, SWT.PUSH);
browseButton.setText("Browse...");
browseButton.setVisible(false);
combo.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
String text2 = combo.getText();
System.out.println(text2);
if (text2.equals("Execution Times")) {
loopText.setEnabled(true);
loopText.setText("1");
// Can also do ((GridData) textGridData.getLayoutData())...
textGridData.grabExcessHorizontalSpace = true;
textGridData.horizontalSpan = 2;
browseButton.setVisible(false);
loopText.getParent().layout();
}
if (text2.equals("Execute with File")) {
loopText.setEnabled(false);
loopText.setText("");
textGridData.grabExcessHorizontalSpace = true;
textGridData.horizontalSpan = 1;
browseButton.setVisible(true);
browseButton.setFocus();
loopText.getParent().layout();
}
}
});
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
Alternatively, if you are actually creating and opening a new Shell, then call pack() (to get the preferred size) prior to making the Text widget take up two columns:
shell.pack();
// Move these two lines down to the end
textGridData.horizontalSpan = 2;
browseButton.setVisible(false);
shell.layout(true, true);
shell.open();
What we've done is add all 3 widgets without adjusting the horizontalSpan. Then, call pack() to set the size of the Shell assuming that all 3 widgets appear in a single row. After calling pack(), set the horizontalSpan to 2, and hide the Button. When the Shell is opened, you will see:

GXT ToolBar is scrolled

I'm developing a simple GXT widget - it's a TreePanel with a ToolBar added using setTopComponent.
The problem is that as soon as the tree is large enough so that it can be scrolled, the scroll-bar doesn't scroll the tree only, but scrolls the ToolBar as well.
What should be change so that ToolBar remains on the top of page, and only the tree is scrolled.
public class TreePanelExample extends LayoutContainer {
#Override
protected void onRender(Element parent, int index) {
super.onRender(parent, index);
Folder model = getTreeModel();
TreeStore<ModelData> store = new TreeStore<ModelData>();
store.add(model.getChildren(), true);
final TreePanel<ModelData> tree = new TreePanel<ModelData>(store);
tree.setDisplayProperty("name");
tree.setAutoLoad(true);
ToolBar toolBar = new ToolBar();
toolBar.setBorders(true);
toolBar.add(new Button("Dummy button", new SelectionListener<ButtonEvent>() {
public void componentSelected(ButtonEvent ce) {
Info.display("Dummy button", "I'm so dumb!");
}
}));
ContentPanel panel = new ContentPanel();
panel.setHeaderVisible(false);
panel.setCollapsible(false);
panel.setFrame(false);
panel.setAutoWidth(true);
panel.setAutoHeight(true);
// setting fixed size doesn't make any difference
// panel.setHeight(100);
panel.setTopComponent(toolBar);
panel.add(tree);
add(panel);
}
The problem is that
TreePanelExample extends LayoutContainer
while instead it should extend Viewport.
Additionally I shouldn't have used
panel.setAutoWidth(true);
panel.setAutoHeight(true);
Plus it is necessary to add the main panel using
new BorderLayoutData(LayoutRegion.CENTER);
Here is the complete solution:
public class TreePanelExample extends Viewport {
public TreePanelExample() {
super();
setLayout(new BorderLayout());
Folder model = getTreeModel();
TreeStore<ModelData> store = new TreeStore<ModelData>();
store.add(model.getChildren(), true);
final TreePanel<ModelData> treePanel = new TreePanel<ModelData>(store);
treePanel.setDisplayProperty("name");
treePanel.setAutoLoad(true);
ToolBar toolBar = new ToolBar();
toolBar.setBorders(true);
toolBar.add(new Button("Dummy button", new SelectionListener<ButtonEvent>() {
public void componentSelected(ButtonEvent ce) {
Info.display("Dummy button", "I'm so dumb!");
}
}));
ContentPanel panel = new ContentPanel();
panel.setBodyBorder(false);
panel.setHeaderVisible(false);
panel.setTopComponent(toolBar);
panel.setLayout(new FitLayout());
panel.add(treePanel);
BorderLayoutData centerData = new BorderLayoutData(LayoutRegion.CENTER);
centerData.setMargins(new Margins(5, 5, 5, 5));
centerData.setCollapsible(true);
panel.syncSize();
add(panel, centerData);
}

SWT: show popup menu below toolbar button after clicking on it

I want to show a popup menu below a toolbar button when the user clicks this button. I've read about the SWT.DROP_DOWN style for a ToolItem but this seems very much limited to a simple list of items according to this sample. Instead, I want to show a popup menu with, e.g., checkbox and radio button menu items.
You can make MenuItem with styles SWT.CHECK, SWT.CASCADE, SWT.PUSH, SWT.RADIO, SWT.SEPARATOR
see javadoc..
So you can "hang" swt menu to selection of dropdown on toolbar item like this
public class Test {
private Shell shell;
public Test() {
Display display = new Display();
shell = new Shell(display, SWT.SHELL_TRIM);
shell.setLayout(new FillLayout(SWT.VERTICAL));
shell.setSize(50, 100);
ToolBar toolbar = new ToolBar(shell, SWT.FLAT);
ToolItem itemDrop = new ToolItem(toolbar, SWT.DROP_DOWN);
itemDrop.setText("drop menu");
itemDrop.addSelectionListener(new SelectionAdapter() {
Menu dropMenu = null;
#Override
public void widgetSelected(SelectionEvent e) {
if(dropMenu == null) {
dropMenu = new Menu(shell, SWT.POP_UP);
shell.setMenu(dropMenu);
MenuItem itemCheck = new MenuItem(dropMenu, SWT.CHECK);
itemCheck.setText("checkbox");
MenuItem itemRadio = new MenuItem(dropMenu, SWT.RADIO);
itemRadio.setText("radio1");
MenuItem itemRadio2 = new MenuItem(dropMenu, SWT.RADIO);
itemRadio2.setText("radio2");
}
if (e.detail == SWT.ARROW) {
// Position the menu below and vertically aligned with the the drop down tool button.
final ToolItem toolItem = (ToolItem) e.widget;
final ToolBar toolBar = toolItem.getParent();
Point point = toolBar.toDisplay(new Point(e.x, e.y));
dropMenu.setLocation(point.x, point.y);
dropMenu.setVisible(true);
}
}
});
shell.open();
while(!shell.isDisposed()) {
if(!display.readAndDispatch()) display.sleep();
}
display.dispose();
}
public static void main(String[] args) {
new Test();
}
}