So I want to add a lot of buttons with a script. I want to style them, but I can't find a method to do so.
I want to do something like
Button current = new Button();
current.addStyle("button-style");
Is this possible?
UNITY UI TOOLKIT
When a button is clicked I run a function
public void displayChildrenIcons(GameObject parent, string type)
{
var root = GetComponent<UIDocument>().rootVisualElement;
var displayArea = root.Q<VisualElement>("options");
displayArea.Clear();
for (int i = 0; i < parent.transform.childCount; i++)
{
Button current = new Button();
//How do I style this button before adding it?
displayArea.Add(current);
}
}
Check out the class IStyle. You can create one of these variables and change it so you can customimze style. Then assign it with Button.style = IStle;
public IStyle iStyle = new();
Button current = new();
curent.style = bStyle;
displayArea.Add(current);
Related
Basically how you would create a public void MethodToDoStuff(), attach a monobehaviour script and link the method on a button, so that when its clicked, said method "MethodToDoStuff" is called.
Now I want to do that via an editor script.
Add an event trigger component
On the event trigger component, add a PointerDown and PointerUp event
On the PointerUp and PointerDown, link a public method on another script to be run (doesHandler.HidePanel()) "see code below"
I could do this manually but having an editor script is super effiecient.
Here is what I have so far:
All help is appreciated, Thanks!
EDITOR SCRIPT:
void OnWizardCreate()
{
doesHandler = GameObject.FindWithTag("WhatItDoes").GetComponent<WhatThisDoes>();
GameObject selection = Selection.activeGameObject;
EventTrigger trig=(EventTrigger)selection.AddComponent(typeof(EventTrigger));
EventTrigger.Entry onPointerDown = new EventTrigger.Entry();
onPointerDown.eventID = EventTriggerType.PointerDown;
EventTrigger.Entry onPointerUp = new EventTrigger.Entry();
onPointerUp.eventID = EventTriggerType.PointerUp;
trig.triggers.Add(onPointerDown);
trig.triggers.Add(onPointerUp);
}
OTHER SCRIPT:
public void HidePanel()
{
whatItDoesPanel.SetActive(false);
}
On runtime you would usually call e.g.
onPointerDown.AddListener(doesHandler.HidePanel);
however this would only add the listener temporarily.
Adding a persistent listener is a bit more complex but luckily there now is a tool for this: UnityEventTools.AddPersistentListener so afaik you would only have to add
UnityEventTools.AddPersistentListener(onPointerDown, doesHandler.HidePanel);
UnityEventTools.AddPersistentListener(onPointerUp, doesHandler.HidePanel);
Additional afaik you should before use Undo.RecordObject in order to mark the changed object and the scene as dirty and add a Undo/Redo entry like
Undo.RecordObject(selection, "Added event triggers");
So probably something like
void OnWizardCreate()
{
doesHandler = Object.FindObjectOfType<WhatThisDoes>();
if(!doesHandler)
{
Debug.LogWarning("No WhatThisDoes found in the scene -> Ignored");
return;
}
var selection = Selection.activeGameObject;
if(!selection)
{
Debug.LogWarning("Nothing selected -> Ignored")
return;
}
if(selection.GetComponent<EventTrigger>())
{
Debug.LogWarning($"The selected object {selection} already has an EventTrigger attached! -> Ignored");
return;
}
// log the undo before making changes
Undo.RecordObject(selection, "Added event triggers");
var onPointerDown = new EventTrigger.Entry();
onPointerDown.eventID = EventTriggerType.PointerDown;
UnityEventTools.AddPersistentListener(onPointerDown, doesHandler.HidePanel);
var onPointerUp = new EventTrigger.Entry();
onPointerUp.eventID = EventTriggerType.PointerUp;
UnityEventTools.AddPersistentListener(onPointerUp, doesHandler.HidePanel);
var trig = selection.AddComponent<EventTrigger>();
trig.triggers.Add(onPointerDown);
trig.triggers.Add(onPointerUp);
}
Ok, so I have a pretty specific and to me quite complicated issue, as I'm a GWT newbie.
I have a GWT flex table, which I use to dynamically add rows, whose cells contain GWT widgets. The row number changes, but the number of columns in static, always 6. Each row contains a cell with a remove button and five cells each with their own textbox.
What I need to do is somehow code a kind of relationship between the textbox in cell 6 of one row and the textbox in cell 5 in the next row (and vice versa).
To illustrate: when something changes in the textbox at [1,6] the content of textbox at [2,5] needs to be overwritten with the same value. If the textbox at [2,5] changes the textbox at [1,6] needs to change as well. I cannot use a button to commit the changes, it needs to happen via onValueChange or Blur or something similar, which doesn't require the user to perform a specific action.
My problem stems mostly from trying to figure out how to address specific cells in the flex table and their content. For the remove button the solution was easy enough with a click event handler, but for this issue I just can't seem to be able to come up with a solution.
Sadly I also cannot provide any of the code which I have up until now, since it's a business secret. I can only give a broad description of the problem like the one above.
EDIT:
Actually, it's probably more a problem of not having much code in terms of this specific problem.
What I have is a flex table, which has initially only the header row. Upon clicking a button below this table the addNewField() method is called, which just contains the creation, setting of default values and adding of the text fields into a new row.
addNewField() {
int rows = flextable.getRowCount();
Button removeBtn = new Button("x");
removeBtn.getElement().setId(Integer.toString(rows));
//then the button's event handler
TextBox name = new TextBox();
name.setText("something");
flextable.setWidget(rows, 0, "name");
//repeat 4 more times with incrementing columns for the other widgets
}
This way I add entire rows of editable TextBoxes. What I need is a way to influence the values of the 6th column TextBox of a chosen row and the 5th column TextBox of chosen row + 1.
EDIT2: I've tried the dirty option just to see how it would go and somehow the compare inside the if breaks the app. The compiler detects a nullpointerexception and I can't even debug it with breakpoints because it fails to compile and won't start. I can't figure out why though. I threw the code directly into the event for testing purposes, so pardon the ugliness.
TextBox bis = new TextBox();
bis.setText(rows + ":10:00");
subs.setWidget(rows, 5, bis);
bis.addValueChangeHandler(new ValueChangeHandler<String>()
{
#Override
public void onValueChange(ValueChangeEvent<String> event)
{
allRows: for (int i = 0; i < subs.getRowCount(); i++)
{
for (int j = 0; j < subs.getCellCount(i); j++)
{
if ( subs.getWidget(i, j) == bis )
{
TextBox widgetAtColumnSix = ((TextBox) subs.getWidget(i, 5));
String text = widgetAtColumnSix.getText();
TextBox widgetAtColumnFiveRowPlusOne = ((TextBox) subs.getWidget(i + 1, 4));
widgetAtColumnFiveRowPlusOne.setText(text);
break allRows;
}
}
}
}
});
EDIT: Since you edited your question and you dont want to use EventBus you could iterate over your FlexTable and set your TextBox value depending on your current rowIndex and cellIndex... Its not nice but it should work:
public class CellWidget extends Composite {
private TextBox nameBox;
public CellWidget() {
FlowPanel flowPanel = new FlowPanel();
Button deleteButton = new Button("x");
nameBox = new TextBox();
nameBox.addValueChangeHandler(new ValueChangeHandler<String>() {
#Override
public void onValueChange(ValueChangeEvent<String> event) {
notifiyTextBox(CellWidget.this, event.getValue());
}
});
flowPanel.add(nameBox);
flowPanel.add(deleteButton);
initWidget(flowPanel);
}
public void setText(String text) {
nameBox.setText(text);
}
}
public void notifiyTextBox(CellWidget source, String string) {
rows: for (int i = 0; i < flextable.getRowCount(); i++) {
columns: for (int j = 0; j < flextable.getCellCount(i); j++) {
if (flextable.getWidget(i, j) == source) {
CellWidget widgetAtColumnSix = ((CellWidget) flextable.getWidget(i, 5));
widgetAtColumnSix.setText(string);
CellWidget widgetAtColumnFiveRowPlusOne = ((CellWidget) flextable.getWidget(i + 1, 4));
widgetAtColumnFiveRowPlusOne.setText(string);
break rows;
}
}
}
}
I still would recommend using an eventbus. To make it even more convenient there is the GWT Event Binder lib, which makes using events a breeze.
So when you change a value in your textbox[2,5] it also fires your CustomEvent. All Widgets, that need to change their textbox value just need to catch...
I have dropdown options where options populate dynamically, I have a multifield,checkbox,dropdown. When i click on the checkbox[event on selectionchanged] its fetch the items count from multifield and display options.
var select2opts = [];
var dialog = this.findParentByType('dialog');
var panel1 = this.findParentByType('panel');
var dropdown = panel1.getComponent("dropdown1");
var button = panel1.getComponent("button1");
var customfield = panel1.getComponent("customfield");
for (var i = 1; i <= customfield.items.getCount()-1 ; i++) {
select2opts.push({value: i, text:"Tab "+i});
}
dropdown.setOptions(select2opts);
dropdown.show();
But Rather than checkbox, i want some image to be place there like refresh & on click this function will get call. Which type of widget and event i can use for that.
Thanks
You can use the button xtype. It has a icon property that takes url of the image to be used. Set your function as the value of handler property. The handler function gets called every time the button is clicked. button and event objects are passed to the handler function. The button object can be used to get reference to the dialog object.
Reference : http://dev.day.com/docs/en/cq/current/widgets-api/output/CQ.Ext.Button.html
I am developing an RCP application, I wanted to set the status line. I figured out that I can extend the ActionBarAdvisor class and by overriding the method fillStatusLine() method I can set the status.
private StatusLineContributionItem statusItem;
#Override
protected void fillStatusLine(IStatusLineManager statusLine) {
statusItem = new StatusLineContributionItem("LoggedInStatus");
statusItem.setText("Logged in");
statusLine.add(statusItem);
}
Now, I wish to set image along with it. Is is possible to add image to status line?
You need to override fill(Composite parent) method in your StatusLineContributionItem. There you can add custom components (images, buttons etc. to a status line). For example: http://book.javanb.com/eclipse-rich-client-platform-designing-coding-and-packaging-java-applications-oct-2005/ch17lev1sec7.html
org.eclipsercp.hyperbola/StatusLineContribution
public void fill(Composite parent) {
Label separator = new Label(parent, SWT.SEPARATOR);
label = new CLabel(parent, SWT.SHADOW_NONE);
GC gc = new GC(parent);
gc.setFont(parent.getFont());
FontMetrics fm = gc.getFontMetrics();
Point extent = gc.textExtent(text);
if (widthHint > 0)
widthHint = fm.getAverageCharWidth() * widthHint;
else
widthHint = extent.x;
heightHint = fm.getHeight();
gc.dispose();
StatusLineLayoutData statusLineLayoutData = new StatusLineLayoutData();
statusLineLayoutData.widthHint = widthHint;
statusLineLayoutData.heightHint = heightHint;
label.setLayoutData(statusLineLayoutData);
label.setText(text);
label.setImage(image);
...
}
You chould use the following class: org.eclipse.ui.texteditor.StatusLineContributionItem.class this contains the method setImage(Image image).
It is found in: plugins/org.eclipse.ui.workbench.texteditor_(version).jar of your eclipse installation.
This is class extends: org.eclipse.jface.action.StatusLineContributionItem.class.
Note there are 2 classes named: StatusLineContributionItem.class the other resides in: plugins/org.eclipse.jface_(version).jar and is named: org.eclipse.jface.action.StatusLineContributionItem.class.
This one however does not contain the setImage(Image image) method.
You can then call:
StatusLineManager statusLine = new StatusLineManager();
StatusLineContributionItem i = new StatusLineContributionItem("myid");
i.setText("myText");
i.setImage(SWTResourceManager.getImage(MyClass.class, "config.gif");
...
statusLine.add(i);
...
return statusLine;
If you want complete customization you can use the solution above overriding the fill(Composite composite) method.
Reference:
http://help.eclipse.org/luna/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Freference%2Fapi%2Forg%2Feclipse%2Fui%2Ftexteditor%2FStatusLineContributionItem.html
When I create a custom dialog in GTK (both, GTK2 or GTK3) and set it to be modal, all input to other windows of my application is ignored. This works nearly always, but it fails under certain conditions.
When I add a ScrolledWindow containing a TreeView to my dialog, it still works as supposed. But if I fill the TreeView with entries until the ScrolledWindow starts to display its scroll bars --- the modality is suddenly lost and I can click on my other windows!
Here is the most basic example I was able to set up. It's written in Vala, but you'll get the idea:
class MyDialog: Gtk.Dialog {
public MyDialog() {
this.modal = true;
var data = new Gtk.ListStore(1, typeof(string));
// increase this number -- the dialog is not modal anymore!
for (int i=0; i<2; ++i) {
Gtk.TreeIter current;
data.append(out current);
data.set(current, 0, "Lorem Ipsum");
}
var render = new Gtk.CellRendererText();
var column = new Gtk.TreeViewColumn();
column.pack_start(render, true);
column.add_attribute(render, "text", 0);
var treeview = new Gtk.TreeView.with_model(data);
treeview.append_column(column);
treeview.show();
var scroll = new Gtk.ScrolledWindow(null, null);
scroll.set_size_request(100, 100);
scroll.add(treeview);
scroll.show();
(this.get_content_area() as Gtk.Box).add(scroll);
}
}
int main (string[] args) {
Gtk.init (ref args);
var window = new Gtk.Window();
window.set_default_size(350, 170);
window.destroy.connect(Gtk.main_quit);
var button = new Gtk.Button.with_label("Click me!");
button.clicked.connect(() => {
var dialog = new MyDialog();
dialog.set_transient_for(window);
dialog.run();
dialog.destroy();
});
window.add(button);
window.show_all();
Gtk.main();
return 0;
}
Compile it with:
valac --pkg gtk+-3.0 main.vala
Am I missing something? Is this behaviour wanted? Or is it a bug? If so, is there a workaround?
EDIT: I investigated a bit further: The problem disappears when the overlay-scrollbars from Ubuntu are uninstalled. So It's not solved yet, but I know where I have to report this...
Definitely a bug. Post a bug report and/or upgrade your GTK+ lib.