GTK# - Changing propeties of widgets - .net-core

I'm trying to make a program that works like Total Commander (I have to do it for school). I use dotnet for the program and Glade for designing the window. I got the window to load properly, however I am not able to access the ui elements and change it's properties. I gave the element's id and widget name but it still says it cannot find it and that it's missing propety. Here's code of MainWindow.cs:
using System;
using Gtk;
using UI = Gtk.Builder.ObjectAttribute;
namespace GtkNamespace
{
class MainWindow : Window
{
[UI] private MainWindow window = null;
[UI] private Button _button2 = null;
public MainWindow() : this(new Builder("MainWindow.glade")) { }
private MainWindow(Builder builder) : base(builder.GetObject("MainWindow").Handle)
{
builder.Autoconnect(this);
DeleteEvent += Window_DeleteEvent;
}
private void Window_DeleteEvent(object sender, DeleteEventArgs a)
{
Application.Quit();
}
}
}
The [UI] part works for buttons, but not for widgets and other ui elements. If you'd like, I can get it on github.

Let's say you have a Button with id buttonClickme in your glade file,
if you want to access it, you can do
Button buttonClickme = (Gtk.Button)builder.GetObject("buttonClickme");
Later you can use this object to change/read any property of this widget.
buttonClickme.Name = "newName";
Console.WriteLine("Changed button name :" + buttonClickme.Name);
buttonClickme.Label = "New Label";
Similarly, you can access any object mentioned in your .glade file.
example of my glade file
<object class="GtkButton" id="buttonClickme">
<property name="label" translatable="yes">button</property>
<property name="name">buttonClickme</property>
<signal name="clicked" handler="on_buttonClickme_clicked" swapped="no"/>
</object>

Related

Dynamically add Icons to titlebar Maui

Im creating an App where I want have multiple icons in my titlebar (they should be clickable). One Icon should be on the Left of the title text like so (this icon is static and will not change):
The other Icons should be on the right (these icons should be dynamic, as they will be used to alert the user if anything important happens):
I'm using a simple shell, so no Navigationpage, thus I don't think <NavigationPage.Titleview> can be used in this case. Is there any way to achieve something like this in Maui?
You can use the shell title view as stated in this answer, it is pointing to Xamarin documentation but it is also valid for MAUI.
In your case you will have something like this inside your AppShell.xaml :
<Shell.TitleView>
<Grid ColumnDefinitions="auto,*,auto">
<Label Text="Title" BackgroundColor="Red"></Label>
<HorizontalStackLayout Grid.Column="2">
<Label Text="Icon" BackgroundColor="Red"></Label>
</HorizontalStackLayout>
</Grid>
</Shell.TitleView>
Which look like this (very trendy design) :
How to update the icons can be done by data binding or creating directly the object from C# :
<HorizontalStackLayout Grid.Column="2" x:Name="IconsContainer">
<Label Text="Icon" BackgroundColor="Red" IsVisible="{Binding Icon1Visible}"></Label>
</HorizontalStackLayout>
And in the C# :
public partial class AppShell : Shell
{
public bool Icon1Visible { get; set; } = false;
public AppShell()
{
InitializeComponent();
// An object containing the binding data
BindingContext = this;
// Directly create a new icon
AddIcon();
// Show an icon through binding
ShowIcon();
}
public void ShowIcon()
{
Icon1Visible = true;
}
public void AddIcon()
{
var icon = new Label();
icon.Text = "And another one";
IconsContainer.Children.Add(icon);
}
}
To get whenever you want to update the icons I would go with dependency injection and either pass directly a view model to bind the icons on or using events.

Manually Open custom inspector for serializable object

I have a window editor that holds nodes. I would like to open a custom inspector when one of these nodes is selected. The node class is a custom serializable class. Is this possible?.
It seems that custom inspectors can be created manually through the Editor.CreateEditor method but can't see how to let it appear docked like an usual inspector in the unity inspector window.
I would like to achieve the same behaviour that we have when we select a gameobject in sceneview that inmediately show properties for the object (Components, etc...) in the unity inspector.
Cheers
As I'm not sure what you're asking, here are multiple different solutions;
Selection
If you just want your nodes to become the focus of the hierarchy, then in your custom window's OnGUI method, use the code below;
[CustomEditor(typeof(NodeManager))]
public class NodeManager : EditorWindow
{
private static NodeManager window;
private Node[] m_nodes;
[MenuItem("Custom Windows/Node Inspector")]
public static void Init()
{
if(window == null)
window = GetWindow<NodeManager>("Node Manager", true, typeof(SceneView));
}
public void OnGUI()
{
m_nodes = GameObject.FindObjectsOfType<Node>();
foreach(Node node in m_nodes)
{
GUILayout.BeginHorizontal();
{
GUILayout.Label(node.name);
if (GUILayout.Button("Select"))
Selection.objects = new Object[] { node.gameObject };
}
GUILayout.EndHorizontal();
}
}
}
This adds a Button for each object in your custom window view, that will then select that object in the hierarchy.
Auto-Docking
I originally found the second response to this question, which goes into the details of parameters of the GetWindow method, and with this you can clearly see how to dock the window (I've converted it from JS to C# below).
(I looked fairly extensively in UnityEditor and UnityEditorInternal namespaces but couldn't find the Hierarchy or the Inspector).
GetWindow<T>(string title, bool focus, params System.Type[] desiredDockNextTo)
Which we can write for this example as;
EditorWindow.GetWindow<NodeInspector>("Node Test", true, typeof(SceneView));
This example docks the windows next to the SceneView window. This functionality can be combined with a custom inspector's OnInspectorGUI method, to automatically launch the custom node window, if it's not already open.
[CustomEditor(typeof(Node))]
public class NodeInspector : Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
NodeManager.Init();
}
}
Sorry if this isn't what you are looking for, if it's not then please give more details and I will amend my answer to better suit the question.
Hope this helped.
Has a possibility, you can make a custom ScriptableObject and Custom Editor for It, and when open the node inspector, just find a instance of the scriptable object and use Selection.selectedObject = scriptableObject, and in the custom editor, make a static field called 'editor' to draw inside.
It will work.

How to extend the context menu inside the rehosted workflow designer?

We are using a rehosted designer (currently WF 4.0) with a lot of custom activities, all of them have custom designers. For a bunch of them, I would like to add entries to the context menu of the designer when in design mode. I'm talking about this menu:
E.g. for a XAML coded activity I would like to have an "Open source..." entry which will load the XAML source of that specific activity into a new designer. To do that I must add the entry to the menu, and when clicked figure out on which activity it was clicked. Both parts are unclear to me. How can I achieve that?
In WF 3 there was the ActivityDesignerVerb class to do that. In WF 4 there seems to be workflowDesigner.Context.Services.Publish<ICommandService>(...), but I can't figure out how to use that to add a custom action to the context menu. How can I do that?
This SO entry shows something for internal debugger commands, but I want to add a completely new command.
Solving it in the host
If you want to solve this on the workflow designer host, and not in the individual activities, it's quite simple and straightforward to do this.
When you host the workflow designer and create the workflow designer, you can simply access its ContextMenu property and modify its Items collection.
var wfd = new WorkflowDesigner();
wfd.ContextMenu.Items.Add(new MenuItem() { Header = "Hello", Command = yourCommand, });
If you want different menu items for each activity, you can subscribe to the SelectionChanged event:
wfd.Context.Items.Subscribe<Selection>(SelectionChanged);
And then implement your own logic:
private void SelectionChanged(Selection selection)
{
// Remove old menu item
if (oldMenuItem != null)
{
wfd.ContextMenu.Items.Remove(oldMenuItem);
oldMenuItem = null;
}
var modelItem = selection.PrimarySelection;
if (selection.SelectionCount == 1 && modelItem != null)
{
// Get activity type
var activityType = modelItem.ItemType;
var menuItem = new MenuItem() { /* ... */ };
wfd.ContextMenu.Items.Add(menuItem);
oldMenuItem = menuItem;
}
}
Solving it in the activity designer
If you want to always show a specific context menu item regardless of where your workflow designer UI is hosted, you can create a custom item in your activity designer XAML:
<sap:ActivityDesigner.ContextMenu>
<ContextMenu>
<MenuItem Header="Show" Command="{Binding YourCommand}"/>
</ContextMenu>
</sap:ActivityDesigner.ContextMenu>
OK so all you need to do is implement the ICommand interface on your custom activity.
So, for example - expose a custom command property from the customer activity class, then in the constructor apply a delegate event to the command handler -
/// <summary>
/// Custom activity
/// </summary>
public partial class CustomActivityDesigner
{
/// <summary>
/// Command used to display a dialog at design time
/// </summary>
public ICommand ShowCustomDialog{ get; set; }
public CustomSchedulerDesigner()
{
InitializeComponent();
ShowCustomDialog= new DelegateCommand(x =>
//Do some stuff here that will display your dialog
//you may want to consider passing the `this.ModelItem`
//to your dialog so it can then interact with the ModelTrees etc
//for example
var dialog = new MyDialog(this.ModelItem);
dialog.ShowDialog();
);
}
}
Finally,
hook the new command up to the UI via the activity designer xaml.
<sap:ActivityDesigner.ContextMenu>
<ContextMenu>
<MenuItem Header="Show" Command="{Binding ShowCustomDialog}"/>
</ContextMenu>
</sap:ActivityDesigner.ContextMenu>

OpenLaszlo kills some mouse events of a loaded Flex application

This is a question about OpenLaszlo (or rather Flex?) internals:
I was able to load a full Flex application swf into a OpenLaszlo (trunk release, older releases failed). It works in Flash 10 as well as in 11. But OpenLaszlo seems to capture or
block certain mouse events. When I add the SWF into
YFilesSWF.content.sprite (YFilesSWF is extending the window class)
then most mouse actions work (e.g. Flex buttons), but some don't (some clickable items on a kindo f canvas). I observed further that when I add the SWF to
YFilesSWF.sprite (YFilesSWF is extending the view)
, then the SWF does not react to ANY mouse events anymore. That means window is somewhat better, but not good enough.
I'm using the
flash.display.Loader
class for loading the SWF in a normal way. This is the AS3 Loader class implementation which I use for loading the swf and which I include inside the OpenLaszlo app :
public class LoadSwf extends Sprite
{
public var externalSwfLoader:Loader = new Loader();
public var swfDisplayObject:DisplayObject;
public var swfComObject:Object;
public function LoadSwf(url:String,p:Sprite):void
{
// externalSwfLoader.mouseChildren = false;
// this.mouseChildren = false;
// p.mouseChildren = false;
// externalSwfLoader.mouseEnabled = false;
// this.mouseEnabled = false;
// p.mouseEnabled = false;
p.addChild(this);
externalSwfLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, createSwfObjects);
externalSwfLoader.load(new URLRequest(url));
}
public function createSwfObjects(evt:Event):void
{
var loaderInfo:LoaderInfo = evt.target as LoaderInfo;
swfDisplayObject = evt.target.content;
swfComObject = loaderInfo.content;
addChild(swfDisplayObject);
}
}
This is the OpenLaszlo code of how the class is used:
<class name="YFilesSWF" extends="window">
<passthrough>
import LoadSwf;
</passthrough>
<attribute name="loadSwf" />
<handler name="oninit"><![CDATA[
this.loadSwf = new LoadSwf("SimpleGraphEditor.swf", this.content.sprite);
]]></handler>
</class>
Does anybody know what and where OpenLaszlo is destroying some
of the Flex mouse events and how to prevent it?
Is there a yet better component than window that will
preserve the Flex mouse events?
What would be required to modify in the OL components source code?
Thanks!

How to create "Browse for folder" dialog in Adobe FLEX?

Know someone, how to create "Browse for folder" dialog in Adobe FLEX? And it is possible?
Thanx.
If it's an Air app you can do :
var f : File = new File;
f.addEventListener(Event.SELECT, onFolderSelected);
f.browseForDirectory("Choose a directory");
If it's a pure As3 app, you cannot Browse for folder, you can just browse for file via FileReference class.
in Web, for multiple file upload, (for single file upload, use FileRefernce)
private var _refAddFiles:FileReferenceList;
private function browse():void
{
_refAddFiles = new FileReferenceList();
var fileFilter:FileFilter=new FileFilter("*.jpg","*.jpg;*.jpeg;");
_refAddFiles.addEventListener(Event.SELECT, onSelectFile);
_refAddFiles.browse([fileFilter]);
}
<mx:Button click="browse"/>
This will work, and what you want to do after selection,
private function onSelectFile(event:Event):void
{
_arrUploadFiles = [ ];
if (_refAddFiles.fileList.length >= 1)
{
for (var k:Number = 0; k < _refAddFiles.fileList.length; k++)
{
_arrUploadFiles.push({ name: _refAddFiles.fileList[k].name,
file: _refAddFiles.fileList[k]});
}
}
}
This is a quick function set to create a nice folder browser in Flex:
private var file:File = new File();
private function pickFile(event:MouseEvent):void {
file.addEventListener(Event.SELECT, openFile);
file.browseForDirectory("Select folder...");
}
private function openFile(event:Event):void{
folderPath.text = file.nativePath;
}
The first function deals with the folder browser, the second one populates a text input with the full folder path.
Howto:
On the stage, create a simple mx:button and add a call to the pickFile() function for the click event:
<mx:Button click="{pickFile(event);}" />
Then, put also on the stage an mx:TextInput component, to show the folder path after selection:
<mx:TextInput id="folderPath" editable="false" />
This way you have a button to click in order to show the system folder browser, and a text input to show the full folder path after selection.
To improve the button look, you can embed a nice folder icon :-)
Just my 2c. :-)

Resources