Eclipse RCP: Set Image in the status line - eclipse-rcp

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

Related

Add style when creating button with script Unity ui toolkit

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);

Binding Image URIs via Image.SetBinding() not working properly

I'm using the following code snippet to bind a image url to a image object (used as one element in a ViewCell object).
...
Image Picture = new Image()
{
Aspect = Aspect.AspectFit,
HorizontalOptions = LayoutOptions.StartAndExpand
}; // ImageSource.FromUri(new Uri("sImageUrl")))
Picture.SetBinding(Image.SourceProperty, "sImageUrl");
...
The images in the list, for which I'm using that cell view, are not loading always. I was not able to identify the exact reason for the problem, but I think the problem is the load-process (for loading the images from the url/internet)..
Maybe the problem could be solved by setting the url via new Uri(...) as described in the documentation
var webImage = new Image { Aspect = Aspect.AspectFit };
webImage.Source = ImageSource.FromUri(new Uri("https://xamarin.com/content/images/pages/forms/example-app.png"));
Now my question: is there a workaround for binding a uri object? e.g.
...
Image Picture = new Image()
{
Aspect = Aspect.AspectFit,
HorizontalOptions = LayoutOptions.StartAndExpand
}; // ImageSource.FromUri(new Uri("sImageUrl")))
Picture.SetBinding(Image.SourceProperty, ImageSource.FromUri(new Uri("sImageUrl")));
...
I'm working with xamarin studio (version 6.1.2, build 44, update channel "beta", os x).
Would be great if someone got a tipp.
Thanks a lot,
Alex
after some more trying I found a solution.. I'm not sure if it's a secure / professional way.. But for now, it seems to work.
What I did: I implemented my own class "AsyncSrcImage", derived it from Image and added another bindable property:
public class AsyncSrcImage : Image
{
private static String sDefaultURL = "";
public static readonly BindableProperty AsyncImgUrlProperty = BindableProperty.Create(nameof(AsyncImgUrl), typeof(String), typeof(AsyncSrcImage), sDefaultURL);
public String AsyncImgUrl
{
get { return (String)GetValue(AsyncImgUrlProperty); }
set { SetValue(AsyncImgUrlProperty, value); }
}
}
Additionally I adjusted the rendering process with a custom renderer. There I'm loading the image source via new Uri(...) as described in the documentation:
using Xamarin.Forms.Platform.Android;
using Xamarin.Forms;
using System;
[assembly: ExportRenderer(typeof(AsyncSrcImage), typeof(AsyncSrcImageRenderer))]
public class AsyncSrcImageRenderer : ImageRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Image> e)
{
base.OnElementChanged(e);
AsyncSrcImage oImage = (AsyncSrcImage)Element;
if (oImage != null && oImage.AsyncImgUrl != "")
{
oImage.Source = ImageSource.FromUri(new Uri(oImage.AsyncImgUrl));
}
}
}
Maybe that helps other folks ;)

JavaFX 8 is there way to get the FXML reference from a Node?

I am trying to figure out if there is a way to get a reference to the FXML for a given node.
For example I am dynamically loading views - assume I have a Pane referenced in the current Controller:
private void openView() {
FXMLLoader loader = new FXMLLoader();
Parent node = loader.load(this.getClass().getResource("MyView.fxml").openStream());
pane.getChildren().add(node);
node.requestFocus();
}
I would like to save which views were open so that I can relaunch them next time the window is open. Something like this:
private void saveOpenViews() {
pane.getChildren().forEach(child -> {
String fxmlLocation = child.getFXML();
etc....
}
}
I can't seem to find a way to get that back to persist what was open... Was hoping there was a way, other than manually tracking in another place.
Thanks.
Store the related fxml information in the node userData when you load the node from fxml, then lookup the userdata when you need to know what fxml the node is related to.
private void openView() {
FXMLLoader loader = new FXMLLoader();
URL fxmlLocation = this.getClass().getResource("MyView.fxml");
Parent node = loader.load(fxmlLocation.openStream());
node.setUserData(fxmlLocation);
pane.getChildren().add(node);
node.requestFocus();
}
private void saveOpenViews() {
pane.getChildren().forEach(child -> {
URL fxmlLocation = (URL) child.getUserData();
etc....
}
}

Add and bind UIView on External Monitor using MvvmCross

I'm attempting to Display an UIView on an external monitor in iOS if one is detected. I am able to detected and display a simple UIView using the following code...
public void CheckForExternalDisplay()
{
if (UIScreen.Screens.Length > 1)
{
Mvx.Trace(MvxTraceLevel.Diagnostic, "Multiple screens found");
var externalScreen = UIScreen.Screens[1];
var rect = new RectangleF(new PointF(0, 0), externalScreen.AvailableModes.Max(m => m).Size);
var window = new UIWindow(rect)
{
Screen = UIScreen.Screens[1],
ClipsToBounds = true,
Hidden = false
};
var presenterView = new PresenterView(rect);
window.AddSubview(presenterView);
}
}
This UIView is Very Simple. It contains a UILabel and a RadialProgress View. Most of the heavy lifting to determine what the values should be are already being done on another viewmodel that is updating a view attached to a screen on the phone. I have tried several techniques to try and get the UIView on the external display to update.
Using MvxMessenger. - I tried passing a message to both a new ViewModel and to the View itself. The new ViewModel received the message only after I created a new instance from the publishing viewmodel. However, I could never intercept messages directly from the view...
Delay binding and regular fluent binding where the bound viewmodel properties are simply updated from another viewmodel.
Attempted to bind this View with a viewmodel already associated with another view.
Wishing in one hand, and crapping in the other... Guess which one filled up first ;)
It's almost as if the UIview (below), isn't being registered/associated with a viewmodel. I'm sure I'm missing something somewhere. As always, I appreciate the help!
public sealed class PresenterView
: MvxView
{
private readonly RadialProgressView _progressView;
private readonly MvxSubscriptionToken _token;
private IMvxMessenger _messenger;
private UILabel _displayLabel;
public PresenterView(RectangleF frame)
: base(frame)
{
Frame = frame;
_messenger = Mvx.Resolve<IMvxMessenger>();
_token = _messenger.Subscribe<DisplayMessage>(OnDisplayMessageReceived);
_displayLabel = new UILabel
{
AdjustsFontSizeToFitWidth = true,
Lines = 1,
LineBreakMode = UILineBreakMode.TailTruncation,
Text = "This is a workout",
Font = UIFont.FromName("rayando", 96f),
BackgroundColor = UIColor.Clear,
PreferredMaxLayoutWidth = Frame.Width - 10,
Frame = new RectangleF(0, 0, Frame.Width - 10, frame.Height / 7),
TextColor = UIColor.White,
TextAlignment = UITextAlignment.Center,
AutoresizingMask = UIViewAutoresizing.All
};
AddSubview(_displayLabel);
_progressView = new RadialProgressView
{
Center = new PointF(Center.X, Center.Y),
MinValue = 0f,
};
AddSubview(_progressView);
this.DelayBind(() =>
{
MvxFluentBindingDescriptionSet<PresenterView, PresenterViewModel> set =
this.CreateBindingSet<PresenterView, PresenterViewModel>();
set.Bind(_progressView).For(pv => pv.Value).To(vm => vm.ClockValue);
set.Bind(_progressView).For(pv => pv.MaxValue).To(vm => vm.MaxProgress);
set.Bind(_workoutLabel).To(vm => vm.DisplayText);
set.Apply();
});
}
private void OnDisplayMessageReceived(DisplayMessage obj)
{
_workoutLabel.Text = obj.Message;
}
}
I do realize that I have included both solutions here. I did try each of them independently.
From the code you've posted, I can't see anywhere you are actually setting the data context for your view.
In 'normal mvvmcross' either:
an MvxViewController creates its own DataContext (ViewModel) using its show request in viewDidLoad
some other app code sets an MvxView's DataContext based on app- specific logic - see n=32 in http://mvvmcross.wordpress.com as an example
In your code, i can't currently see where you set this - so try setting view.DataContext somewhere.

Reload data in GXT grid freezes

Based on the GXT showcase example 'Paging BeanModel Grid' I try to reload the grid when I have done a modifiaction to my data source. I defined the loader like that:
final BasePagingLoader<PagingLoadResult<ModelData>> loader =
new BasePagingLoader<PagingLoadResult<ModelData>>(proxy, new BeanModelReader());
loader.setRemoteSort(true);
The data loads correctly.
When I do:
loader.load();
My paging toolbar just freezes and goes disabled, the grid freezes too and displays what appears to be a loading mask.
I tried to add some events to force a double reload without luck:
grid.addListener(Events.Attach, new Listener<GridEvent<ModelData>>() {
public void handleEvent(GridEvent<ModelData> be) {
loader.load();
}
});
I tried to use the reconfigure(store,cm) option as well and same result.
Any help?
Thanks,
Jordi.
The loading bar grays out so you can see it is working, and the grid may also have a loading message. The code that is working is the server, probably preparing the items.
Set logging messages in your server code (RPC servlet probably), at the beginning and at the end of the call, to see how long they take to run. That is likely where the actual 'freeze' is actually happening, based on the info in your question.
There could be a pause in the browser after that time as well, but in that case the loading circle would stop moving.
To me there is a bug on the grid controller:
Code details:
private final BasePagingLoader<PagingLoadResult<ModelData>> loader;
private Grid<ModelData> grid;
[...]
public ListUsersView(RpcProxy<PagingLoadResult<UserTableEntryBean>> proxy) {
// Create loader
loader = new BasePagingLoader<PagingLoadResult<ModelData>>(proxy, new BeanModelReader());
loader.setRemoteSort(true);
// Create store
store = new ListStore<ModelData>(loader);
FlowLayout layout = new FlowLayout();
layout.setMargins(new Margins(3, 0, 0, 0));
this.setLayout(layout);
final PagingToolBar toolBar = new PagingToolBar(50);
toolBar.bind(loader);
List<ColumnConfig> columns = new ArrayList<ColumnConfig>();
columns.add(new ColumnConfig(UserTableEntryBean.Fields.username.name(), "Username", 100));
columns.add(new ColumnConfig(UserTableEntryBean.Fields.email.name(), "E-mail", 200));
ColumnConfig date = new ColumnConfig(UserTableEntryBean.Fields.creationDate.name(), "Creation date", 100);
date.setDateTimeFormat(DateTimeFormat.getFormat("dd/MM/y"));
columns.add(date);
ColumnModel cm = new ColumnModel(columns);
grid = new Grid<ModelData>(store, cm);
grid.setLoadMask(true);
grid.setBorders(true);
grid.setAutoExpandColumn(UserTableEntryBean.Fields.creationDate.name());
[...]
}
public boolean refreshTable() {
return loader.load();
}