MPart is not user after switch perspective - eclipse-rcp

I have an issue related to switching perspectives in E4. The two perspectives shares the same MPart. After switching to a new perspective the new MPart will be used. After swithing back to the original perspective the second MPart will still be used instead of the first one.
In the image you can find the application structure and both of the Perspectives has Outline screen on it.
When opening perspective one, the Outline works for that perspective. Then if we switch to perspective two (that has different other screen) the second Outline will be activated and works correct. When switching back to the first perspective the second Outline will be still active and the first Outline will not respond to any requests.
After switching to perspective I active all the MPart back with:
List<MPart> part = service.findElements(perspective, null, MPart.class, null);
List<MPartStack> mainPartStack = service.findElements(perspective, "partstack.shared", MPartStack.class, null);
if (!mainPartStack.isEmpty()) {
for (int i = part.size() - 1; i >= 0; i--) {
List<MPart> children = service.findElements(mainPartStack.get(0), part.get(i).getElementId(), MPart.class,
null);
if (!children.contains(part.get(i))) {
this.partService.activate(part.get(i));
}
}
}
How can I activate the first Outline back so that it will respond to new request from the first perspective?

Created a shared Outline part and use a placeholder to reuse the Outline. With this solution I changed the perspective switch implementation. So that if a user go back to the first perspective that the data of the outline is the same when he was switching to the second.

Related

e4 RCP: programmatically open part in new window

I would like to programmatically open an MPart in a new MWindow.
Similar to as if I would create the part in a partstack somewhere in the existing window and then manually drag it away with the mouse.
So, one way would be to create a non-rendered window which contains this part. And once it should be shown, we can set it to being rendered. But: once we close this window, we cannot bring it back?!
This approach worked for me:
Define an empty window in the e4xmi which is set to not be rendered
Once we want to display the part, we create it (if it is not open already) and add it to the window
MUIElement window = modelService.find(myWindowId, app);
MPart part = (MPart) modelService.find(myPartId, application);
if (part == null) {
part = MBasicFactory.INSTANCE.createPart();
part.setLabel(ProcedureFlowChartPart.PART_TITLE);
part.setContributionURI("bundleclass://MyPartPath");
part.setElementId(myPartId);
((MWindow) window).getChildren().add(part);
}
partService.showPart(part, PartState.ACTIVATE);
window.setToBeRendered(true);
modelService.bringToTop(window);

Unity UI : How to reenable a dropdown after its panel was deactivated and then reactivated?

I am new to Unity, so this is probably a dumb question but here goes:
I have a Unity app; it has several scenes. One of those scenes has a Canvas upon which there are several overlapping Panels. On one of the Panels (PanelA), there is a Dropdown. When the app first runs PanelA is active and on top by default and the dropdown works fine. But after I deactivate PanelA with a C# call to
panelA.SetActive(false);// hides the panel
and then later reactivate it like so:
panelA.SetActive(true); // redisplays the panel
The dropdown no longer displays its list of option when clicked on. The dropdown is still there and still shows its first option "None" and when clicked on the drop-down changes color to indicate that it was touched, but the dropdown does not drop down its list of options.
What am I missing? Why doesn't the dropdown show the list of options?
Thanks
Windows 10 Pro v1709, unity 2017.1.1f1 Personal
My hierarchy is like so, PanelB is the panel that gets set active after PanelA is inactivated:
The script called when the dropdowns option is selected is called like so in Start():
PickDropDown.onValueChanged.AddListener(delegate {
myDropdownValueChangedHandler(PickDropDown);
});
and the called function is:
private void myDropdownValueChangedHandler(Dropdown target) {
Debug.Log("selected: "+target.value);
stage = 0;
currentval = PickDropDown.options [PickDropDown.value].text;
advice.text = "";
title.text = currentval;
if (currentval != NONE) {
advice.text = "You chose to do "+currentval;
nextVal();
}
}
void newVal(){
Debug.Log("newVal " );
PanelA.SetActive (true);
PanelB.SetActive (false);
Debug.Log("options count="+ PickDropDown.options.Count );
}
void nextVal(){
Debug.Log("nextSet " );
PanelB.SetActive (true);
/*** next line shows the answer to my problem - from killer_mech **/
Destroy(PickDropDown.transform.Find("Dropdown List").gameObject);
/***************************************************************/
PanelA.SetActive (false);
}
Yes, this is a bug in unity. I can reproduce this now. This is happening because Unity is creating a game Object called "Dropdown List" inside dropdown which should get destroyed after the closing. But I have noticed a slight delay is happening while destroying(I used editor debug mode for this). When you set the game object active flag as false, it somehow stops the destroy object and results in object Dropdown List staying there so next time when you try to interact with it the object will still present. You will also notice a white box below the Dropdown list after this which indicates the dropdown list still is present.
For the solution what I did was just before I was about to turn my gameobject off I used
Destroy(PickDropDown.transform.Find("Dropdown List").gameObject);
Destroying this object solves the problem. I know this is not a good way to do it, but I checked whether any references to options are destroyed while destroying this which resulted in no error for me. And Dropdown creates new "Dropdown List" gameobject. So it is safe to assume that destroying is OK. Well not sure if any other good solution for this is out there but for now you can use this.
Note: I have tested this bug with Panel, Empty Gameobject as parent and finally with Dropdown
This shows what is happening inside the drop-down. 1) During No popup 2) During Open 3)After setactive off before the child is destroyed.

How can I switch between two menu bars occupying the same space below the window title in GTK3?

I like to switch menu bars depending on a button or internal state (COM port used). How can I do that in GTK3+ (preferably using Glade and GtkBuilder)? GtkOverlay does not seem to be the correct approach.
Put both menubars in a gtk(v)box and just declare one of the menubars as invisible in Glade (Leave the one you want by default visible). Then you can later switch menubars by hiding/showing them.
Mind, if you are on Ubuntu, you might run into problems. Ubuntu's Unity moves the menu bar to the top of the workspace, and it might not be happy with two menu bars just existing. In a program I made a couple of years ago Ubuntu refused to show the second menu (but I wasn't hiding either of them, so you might be in luck).
Thanks jcoppens for your answer, but I am not sure how the solution would look over all with one of the positions in the vertical box invisible but still occupying space / the height of one menu bar. Wouldn't that create a gap between either the title and the menu bar (first menu bar visible) or the menu bar and the container below (second menu bar visible)?
I solved it by (before I saw your answer):
Using Glade, create a new file and put the two menu bars in there.
In the Glade file for the main window, create a vertical box with one
item right below the title. (In my case, my main frame contains a
vertical box with three items, the first position is kept empty and
will contain one of the two menu bars, the second one contains all
other items inside another container, and the third item contains a
status bar.)
In the C module using GtkBuilder, I switch the menu bars as shown
below:
/**
* This function adds or replaces the menu bar.
* #param id id string for menu bar
*/
void amci_tester_set_menubar(const gchar *id) {
GtkWidget *menu_bar = GTK_WIDGET(gtk_builder_get_object(builder, id));
GtkBox *box_menu = GTK_BOX(gtk_builder_get_object(builder, "boxMainMenu"));
GList *children = gtk_container_get_children(GTK_CONTAINER(box_menu));
if (children != NULL)
gtk_container_remove(GTK_CONTAINER(box_menu), (GtkWidget *) g_list_first(children)->data);
gtk_box_pack_start(box_menu, menu_bar, false, false, 0);
// Although the visible property is shown as being set in the Glade GUI, in
// the Glade file it is not set.
gtk_widget_set_visible(menu_bar, true);
g_list_free(children);
}
In the beginning of main, I put the usual GtkBuilder stuff, instantiating a GtkBuilder object and then adding the default / first to be shown menu bar object:
// Init GTK+.
gtk_init(&argc, &argv);
// Create new GtkBuilder object from file.
builder = gtk_builder_new_from_file(glade_filename_app);
if (builder == NULL) {
g_warning("Could not create builder from %s", glade_filename_app);
return 1;
}
// Add menu bar for PC menu bar (default) from file.
if (!gtk_builder_add_from_file(builder, glade_filename_menu_pc, &error)) {
g_warning("%s", error->message);
g_free(error);
return 1;
}

Redrawing control behind composite with SWT.NO_BACKGROUND

Original goal:
I have a TreeMenu that i use to display my Menu.
In this tree, a user can select different items.
I would like to disable the tree, so that a user cannot select a new item after choosing the first.
The catch is, we cannot use setEnabled, because we are not allowed to use the greyed out look. The look/colors may not change.
Our proposed solution
Our first idea was to use a Composite with SWT.NO_BACKGROUND on top of the menu, to prevent any user interaction with the TreeMenu.
Code:
final Composite cover = new Composite(getPage().shell, SWT.NO_BACKGROUND);
cover.setLocation(getMenu().getLocation());
cover.setSize(getMenu().getSize());
cover.moveAbove(getMenu());
This has a problem with redrawing.
If the screen is covered by another screen and then brought back to front, the Cover Composite is filled with fragments of the previous overlapping window.
Our idea was to manually redraw the menu:
cover.moveBelow(getMenu());
getMenu().update();
cover.moveAbove(getMenu());
We placed the code inside the paintEventListener.
But this caused an infinite loop and did not solve the problem.
Questions
Does anyone have an idea how we can achive our orignial goal?
Does anyone know how we can make our proposed solution work?
Look at SWT-Snippet80. It shows how to prevent selections. A solution to your problem would be adding a listener like this to your tree:
tree.addListener(SWT.Selection, new Listener() {
TreeItem[] oldSelection = null;
public void handleEvent( Event e ) {
Tree tree = (Tree)(e.widget);
TreeItem[] selection = tree.getSelection();
if ( oldSelection != null )
tree.setSelection(oldSelection);
else
oldSelection = selection;
}
});
I wouldn't recommend trying to implement your workaround. I believe that placing transparent controls on top of each other is unsupported in SWT - I think I read a comment from Steve Northover on this subject once. Even if you made it work for some OS, it probably won't work in another - it's too much of a hack.
A solution that is supported by SWT, is having transparent windows on top of each other. But that is also really hard to implement (resizing, moving, always on top, redraw artifacts) and probably as big a hack as the other workaround. Go for the listener.

Adding title to window border for Eclipse RCP detached view

I am working on an Eclipse RCP project which has detachable views. I would like to be able to put some text on the window border which surrounds the view once it is detached. Does anyone have any experience with this? Development environment is Eclipse 3.4 on Windows.
THANKS.
I am not sure it is possible through the conventional update triggering a updateTitle():
If you take a look at the code of org.eclipse.ui.internal.DetachedWindow, you will see a disturbing method updateTitle():
private void updateTitle() {
if (activePart != null) {
// Uncomment to set the shell title to match the title of the active part
// String text = activePart.getTitle();
//
// if (!text.equals(s.getText())) {
// s.setText(text);
// }
}
}
All commented!
You cannot. The detached one is a tool window rather than a main window, so it isn't good to have a title on it