In this specific case I am targeting a Raspi, but should be a common thing for GTK based UIs:
I can create controls from scratch using declares. Some where I am adding features to those that the IDE created, some that do not have a visible control representation, like alerts.
But I fail when I try to insert a visible control I created into the view hierarchy. I tried with a Canvas as a container, adding the fully instantiated declared control as a child, or directly addressing the windows’ widget, but nothing. Parent of the declared widget will still be nil.
Are there any examples on how to do this? Would any of the 3rd party developers share his knowledge?
Thanks a lot!
I cannot Add on Plugin control for example because their panel type is in such way that I cannot embed on it, might be something like that your battling.
This has been longstanding issue for years and has held back things.
- You cannot embed on plugin control.
- If you let the control return its own GDK handle then that works but your still screwed since you cannot create Graphics then to expose to Xojo.
So its a no win cycle no matter which way one goes.
Now back to your issue…I would start trying to just embed on the Window that should work sort of…you might need to poke around a bit and grab the Windows first container as in might have some sort of Box container.
For canvas it might not actually embed the controls as in it might be just embedded on the Window. Or the Canvas might contain some sort of box which you would need to poke around to find, like VBox.
You can save your some work while testing and poking around by using the Linux Bridge Plugin (its free). Then you dont have to worry about getting the declares right at least while your poking around.
A first test in poking around:
It shows that the Canvas is GtkContainer of some sort…but not GtkBox, I did not have other containers currently in the Linux bridge to test others but I could add the other types to aid the poking around more.
using EinhugurLinuxBridgeGtk
Var ctrl as GtkWidget = GtkWidget.FromIntegerPtr(Integer(me.Handle))
if ctrl <> nil then
MessageBox "Got GtkWidget" // I Get this
var container as GtkContainer = GtkContainer.Cast(ctrl)
if container <> nil then
MessageBox "Got container" // And this
var box as GtkBox = GtkBox.Cast(container)
if box <> nil then
MessageBox "Got Box" // Not this
end if
end if
end if
Same test on plugin control shows its just GtkWidget and not even GtkContainer. Which is why plugin ListBox cannot even embed a scrollbar or anything on Linux.
Thanks a lot, Björn. So, doesn’t look good right now, if I understood you correctly? Shouldn’t one be able to add a declared widget to the container of a window?
Somehow Xojo must be doing all this too … Would be too good to have a ViewControl that just opens an embeddable rectangle you can feed with your declare controls. A feature request somewhere down in past.
I tried this with window and Canvas where this was the open event. But nothing visible:
Sub Open() Handles Open
Me.Bar = New GTKLevelBar
bar.realize
var parent As New GTKWidget(Self)
bar.SetSizeRequest Self.Width, Self.Height
bar.AllocateSize(0, 10, Self.Width, Self.Height)
GTKContainer(window1.ApplicationWindow).AddChild bar
End Sub
I think it would depend on what kind of container it is.
Like if its GtkFixed then you add it with gtk_fixed_put
but I added a bit more to the plugin to test more after last post.
But it does not respond to Fixed either… so hmmmm guess I need to add something more maybe I just dont know what.
using EinhugurLinuxBridgeGtk
Var ctrl as GtkWidget = GtkWidget.FromIntegerPtr(Integer(Canvas1.Handle))
if ctrl <> nil then
MessageBox "Got GtkWidget"
var container as GtkContainer = GtkContainer.Cast(ctrl)
if container <> nil then
MessageBox "Got container"
var box as GtkBox = GtkBox.Cast(container)
if box <> nil then
MessageBox "Got Box"
end if
end if
var fixed as GtkFixed = GtkFixed.Cast(container)
if fixed <> nil then
MessageBox "Got fixed"
end if
end if
More testing shows its not GtkLayout either
but…as for your code then I think your missing gtk_widget_showfor your widget.
Some more info for you.
Canvas
Is of type XojoEventBox (custom GtkWidget container)
If you grab the first child from the XojoEventBox then you get GtkFixed which is probably where you should embed to.
Window
First child of the Window is GtkFixed. Which is probably what you should embed to, and not to the Window it self.
Remember to use gtk_widget_show which was missing from your code.
Thank you again, Björn. I had widget.show implemented at some stage too, will re-add it fur further tests.
Sadly gtk.org is currently down for me so I cannot find the docs to add missing parts (I took an old library I once started and started adding things).-
I still cannot get it to work though even if knowing where to get to the GtkFixed.
Maybe I am missing somehing
No it works !!!
It was just my reference counter that was making the button always go out of scope and get disposed.
The “Test” button is the one I embedded, and its embedded on Canvas.
using EinhugurLinuxBridgeGtk
Var ctrl as GtkWidget = GtkWidget.FromIntegerPtr(Integer(Canvas1.Handle))
MessageBox ctrl.Name
if ctrl <> nil then
MessageBox "Got GtkWidget"
var container as GtkContainer = GtkContainer.Cast(ctrl)
if container <> nil then
MessageBox "Got container"
var fixed as GtkFixed = GtkFixed.Cast(container.FirstChild())
if fixed = nil then
MessageBox "Fixed is bad"
end if
var button as GtkButton = new GtkButton("Test")
btn = button
button.SizeAllocate(10,10, 80, 30) // Not sure if I needed this one, probably not
button.SetSizeRequest(80,30) // Not sure if I needed this one, probably not
fixed.Put(button, 10, 10)
button.Show()
end if
end if
Thanks a lot once again, Björn!
Are GTKFixed and Container.FirstChild extensions not yet published?
I tried with my own resurrected library (inside Opening event of a Canvas):
var container As GTKContainer = GTKContainer.FromPtr(Ptr(Me.Handle))
If container = Nil Then Break
var fixed As GTKFixed = GTKFixed(container.FirstChild)
If fixed = Nil Then Break
This is how far I get because fixed will always be nil. What I do in FirstChild is
#If TargetLinux
Var initialList As GList = gtk_container_get_children(Mid)
Var result As GTKContainer = GTKContainer.FromPtr(initialList.FirstItem)
initialList.Free
Return result
#EndIf
But InitialList, a 0 aligned structure of 3 ptrs, will always be zero.
Any ideas where my fault is?
FirstChild was because I am lazy bastard, i did not want to have to deal with figuring out how to return collection to get this test done.
But the implementation of it is:
static REALobject FirstChild(REALobject instance)
{
#if X_WINDOW
ClassData(GObjectXojoClass, instance, GObjectData, me);
GList* children = gtk_container_get_children(GTK_CONTAINER(me->Object));
if(children == NULL)
{
return NULL;
}
REALobject widgetInstance = REALnewInstanceOfClass(&GtkWidgetXojoClass);
ClassData(GObjectXojoClass, widgetInstance, GObjectData, widgetData);
widgetData->Object = G_OBJECT(children->data);
g_object_ref(widgetData->Object);
return widgetInstance;
#else
return NULL;
#endif
}
I will compile 2 missing Linux targets also in the Plugin and Post it even if all the new routines have not been documented yet, so you have something you can test.
(will post again in few min)
Here is Linux Bridge 2.2 Pre-Release so you can test:
https://1drv.ms/u/s!AmeKIsBCQHA5gdRC2X2E-d0AZX731w?e=ORDt6t
The new additions have not been documented but I had the tool auto generate the documentation so you see syntax for everything. (Tool gives me 53 warnings on things where documentation needs revisiting)
Posted Official version now that has documentation and some fixes, so better for you to grab that one if you want to test.
1 Like
Excellent, Björn, thanks a lot!
I have to switch a bit between classes because my library is currently not based on yours, which I guess I will change – no reason to build everything from scratch if your foundation is also free –, but it’s working. Second control is a GTKLevelBar declared from my library, brought onto screen with your Linux Bridge.
No problem at all my friend.
This plugin is not a lot used so I mostly add to it when I know there is some need so by all means if you are missing something then let me know.
1 Like
Thank you, Björn. Think I’ll update my repository soon so we can have a Linux declare library to share. I was surprised to see such a thing does not exist. It was built in Xojo Core API times, so I still find quite some things to change.
I ran into a different question but will rather open a new thread on it.