Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GooCanvasItemModel no error but item view never draw #257

Open
jerome-diver opened this issue Jan 17, 2021 · 16 comments
Open

GooCanvasItemModel no error but item view never draw #257

jerome-diver opened this issue Jan 17, 2021 · 16 comments
Assignees

Comments

@jerome-diver
Copy link

jerome-diver commented Jan 17, 2021

When i try to use model/view method with GooCanvas, i can not get it working fine to show items.
look at this code:

local lgi = require 'lgi'
local Goo = lgi.GooCanvas
local Gtk = lgi.Gtk

local win = Gtk.Window { width = 640, height = 500, anchor = Gtk.GTK_WINDOW_TOPLEVEL }
local frame = Gtk.Frame { width = 400, height = 400 }
local canvas = Goo.Canvas { parent = frame, id = 'canvas', width = 300, height = 300 }

win.on_key_press_event = nil
win.on_map_event = function() win.on_map_event = nil end
win.on_destroy = Gtk.main_quit
tool_bar = Gtk.Toolbar { height = 48 }
tool_bar:insert(Gtk.ToolButton { stock_id = 'gtk-quit', on_clicked = function() win:destroy() end }, -1)

local root_model = Goo.CanvasGroupModel:new(nil, nil)
local item_model = Goo.CanvasGroupModel:new(nil, nil)
local rectangle_model = Goo.CanvasRectModel { x = 0, y = 0, line_width = 2, width = 200, height = 150,
                                              stroke_color = 'yellow', fill_color = 'black', radius_x = 10, radius_y = 10 }
local text_model = Goo.CanvasTextModel { text = 'Voila !', x = 20, y = 20, anchor = Goo.GOO_CANVAS_ANCHOR_CENTER,
                                         font = 'source-code bold 12', fill_color = 'red' }
item_model:set_parent(root_model)
rectangle_model:set_parent(item_model)
text_model:set_parent(item_model)
canvas:set_root_item_model(root_model)
local item = canvas:create_item(item_model)

item:ensure_updated()
item:raise()
canvas:update()
local is_visible = item:is_visible() and "yes" or "no"              --? print "yes", but never show on canvas
print("item is visible ? "..is_visible)

local vbox = Gtk.VBox:new(6)
vbox:add(tool_bar)
vbox:add(frame)
Gtk.Container.add(win, vbox)

win:show_all()
Gtk.main()

I excpected it to show a rectangle with a content text, but it show nothing (try it) and no error.
define a model with a perent show an error about to not be possible for parent to be writable (but it should be in the goo_canvas API doc...), i read an other one issue there who indicates to use set_parent method (so i do it).
What i do wrong ?

@psychon
Copy link
Collaborator

psychon commented Jan 18, 2021

(try it)

Sorry, I pass. No GooCanvas here.

What i do wrong ?

No idea, I never used GooCanvas. Perhaps it is easier if you start with an example from that GooCanvas docs and translate that to Lua: https://developer.gnome.org/goocanvas/stable/goocanvas-simple-canvas.html

You might have more look asking the GooCanvas developers or on stack overflow.

@jerome-diver
Copy link
Author

Ok, i did try from goo_canvas gnome official example code translated to Lua, but it failed to show item and i read something (here) about missing writable parent to pass at creation time.
I also asked on goocanvas mail list but no answer at this time in the past two days.
Let me see if someone other know something around with this and i will be back if i find something in relation or if i fix this.
thank you

@psychon
Copy link
Collaborator

psychon commented Jan 18, 2021

I tried translating https://developer.gnome.org/goocanvas/stable/goocanvas-simple-canvas.html to Lua, but could not figure out how to call goo_canvas_rect_new. Yay for varargs. :-(

local lgi = require("lgi")
local Gtk = lgi.Gtk
local GooCanvas = lgi.GooCanvas

Gtk.init()

local window = Gtk.Window.new(Gtk.WindowType.TOPLEVEL)
window:set_default_size(640, 600)
window:show()
window.on_delete_event = function() os.exit(0) end

local scrolled_win = Gtk.ScrolledWindow.new(nil, nil)
scrolled_win:set_shadow_type(Gtk.ShadowType.IN)
scrolled_win:show()
window:add(scrolled_win)

local canvas = GooCanvas.Canvas.new()
canvas:set_size_request(600, 450)
canvas:set_bounds(0, 0, 1000, 1000)
canvas:show()
scrolled_win:add(canvas)

local root = canvas:get_root_item()

local rect_item = GooCanvas.CanvasRect.new(root, 100, 100, 400, 400)

@jerome-diver
Copy link
Author

jerome-diver commented Jan 18, 2021

when you want to call a method from a fake Lua object, the first argument is kind of "self".
When you call a method with ":" instead of "." you pass the caller to first argument (self). It is Lua basic knowledge.

So for use this "new" method, you have to call it like this:

local window = Gtk.Window:new( Gtk.GTK_WINDOW_TOPLEVEL )

But you can also use an other one easy way:

local win = Gtk.Window { width = 640, height = 500, anchor = Gtk.GTK_WINDOW_TOPLEVEL }

The same rectangle and text included without model used is this part of code:

local item = Goo.CanvasGroup { parent = canvas.root_item,
                               x = 0, y = 0,
                               width = 200, height = 150 }
local rect = Goo.CanvasRect { parent = item,
                              x = 0, y = 0,
                              width = 200, height = 150,
                              line_width = 2,
                              stroke_color = 'yellow',
                              fill_color = 'black',
                              radius_x = 10, radius_y = 10 }
local txt = Goo.CanvasText { parent  = item_grp,
                             text = 'Voila !',
                             x = 20, y = 20, width = -1,
                             anchor = Goo.GOO_CANVAS_ANCHOR_CENTER,
                             font = 'source-code bold 12',
                             fill_color = 'red' }

Anyway, my code is not wrong, almost on the very first steps, just copy and past it to see the result.
You have to use Lua-5.3 version with it.

In your example code, you try to use view item without models. I know to do this without any problem.
My problem is to just use models of GooCanvas items (and i use the goo_canvas official example in C about models/views.
you can find it there: goocanvas2 model/view explain with example

@psychon
Copy link
Collaborator

psychon commented Jan 18, 2021

My problem is that the example from https://developer.gnome.org/goocanvas/stable/goocanvas-simple-canvas.html contains this code:

  rect_item = goo_canvas_rect_new (root, 100, 100, 400, 400,
                                   "line-width", 10.0,
                                   "radius-x", 20.0,
                                   "radius-y", 10.0,
                                   "stroke-color", "yellow",
                                   "fill-color", "red",
                                   NULL);

However, there does not seem to be such a function in the GObjectIntrospection data / I cannot call GooCanvas.CanvasRect.new.

@jerome-diver
Copy link
Author

jerome-diver commented Jan 18, 2021

Yes you can with ":", but not with ".".

local rect_item = GooCanvas.CanvasRect:new(root,  100, 100, 400, 400,
                                   "line-width", 10.0,
                                   "radius-x", 20.0,
                                   "radius-y", 10.0,
                                   "stroke-color", "yellow",
                                   "fill-color", "red",
                                   NULL)

do you see the syntax difference ? (the char between "CanvasRect" and "new" is ":", not ".")
it is equivalent than:

local rect_item = GooCanvas.CanvasRect.new(GooCanvas, root,  100, 100, 400, 400,
                                   "line-width", 10.0,
                                   "radius-x", 20.0,
                                   "radius-y", 10.0,
                                   "stroke-color", "yellow",
                                   "fill-color", "red",
                                   NULL)

just use ":" instead of "." to pass the caller object as"self".
read this
But also, read again the other one solution i gave you before. You don't need method "new" directly to create a new (fake) object instance.
Do you get it ?

@psychon
Copy link
Collaborator

psychon commented Jan 19, 2021

Okay, I officially do not understand GooCanvas. Sorry.

@jerome-diver
Copy link
Author

@psychon ok but it is not about GooCanvas that you do not (officialy) understand, it is about Lua there.

But my question was around lgi library and the use of models with GooCanvas with it.

@psychon
Copy link
Collaborator

psychon commented Jan 21, 2021

ok but it is not about GooCanvas that you do not (officialy) understand, it is about Lua there.

Well... then what is your Lua question? Sorry, but I basically see "when calling the GooCanvas and GTK APIs like this, I only get a blank window", which to me points at GooCanvas/GTK.

@jerome-diver
Copy link
Author

jerome-diver commented Jan 21, 2021

We are, there, in a github repo about Lua AND Gtk / GObject / GooCanvas and some around wrapper (that's what lgi is all about). And my question is not specific to only Lua or Gtk or GooCanvas, but specific to lgi, as expected on a lgi github repo issue page/post (call it as you prefer, but look at the target widely).

Read back my first post on this issue post and the question should be clear:
Is there a problem with lgi with GooCanvas models/views items use ?

I follow the GooCanvas example page about to use models and did translate it to Lua code with lgi way to implement GooCanvas to print an item and i see probably two problems (maybe... i'm asking about that too).

  1. i can not call "parent" at GooCanvas.CanvasGroupModel (i define parent through "set_parent" method after to create the model, but i think it is maybe normal or not, because parent is not a property, but it should be call at create model time... someone whop know what Lua is and what lgi is about and how to use it the best way will tell me...)

  2. item is never draw even after to create_item from a model as expected

look at this:

@psychon
Copy link
Collaborator

psychon commented Jan 21, 2021

Is there a problem with lgi with GooCanvas models/views items use ?

I don't know. Apparently there is since you seem to be having problems. Besides that, I do not know much about GooCanvas.

i can not call "parent" at GooCanvas.CanvasGroupModel

According to https://developer.gnome.org/goocanvas2/stable/GooCanvasGroupModel.html, the only "parent" in GooCanvasGroupModel is the parameter name of the first parameter of goo_canvas_group_model_new. Besides that, the docs do not mention any parent and definitely no goo_canvas_group_model_set_parent method. Thus, there is no :set_parent() in Lua.

item is never draw even after to create_item from a model as expected

Sorry, but that still sounds like a GooCanvas question to me and not a LGI one. At least I have no idea what to do about this.

@jerome-diver
Copy link
Author

jerome-diver commented Jan 21, 2021

I think you can not help me with your present skill about GooCanvas or Lua or lgi.

  1. set_parent is a GooCanvasItemModel method that you can see in any official Gnome API
    if you know about OOP and heritage and know to read an API, you can see that a child can get method from a parent, you should go deeper and find this easy: GooCanvas::Item_Model class reference . I find it with "search" entry with keywords: "goo_canvas set_parent".
  2. sure i do signal a (maybe) problem, but you can not help with that if you have not enough skills as i can see.
  3. You can not understand that this question is not about GooCanvas because you can not make the link between a wrapper and its original API (you failed to read and understand) to wrap. The question is not about GooCanvas, because the GooCanvas code is working, but not the lgi wrapper with that.
  4. and :set_parent() is not a Lua method, but a GooCanvas method call from lgi wrapper (in Lua code)... what can't you understand there ?

If you failed to use colon with Lua and failed to understand the problem and an OOP API, please feel free to let someone other try to help me without saturate the thread there with more confusion to share. It is not personal, so don't be hurt but you can not help me, an other one with a little more skills around will.
Thank you to tryed anyway.

@psychon
Copy link
Collaborator

psychon commented Jan 22, 2021

GooCanvas::Item_Model class reference .

That link goes to the docs for goocanvasmm. In goocanvas, GooCanvasGroupModel inherits from GooCanvasItemModelSimple, which inherits from GObject. None of them have a set_parent method. However, GooCanvasGroupModel implements the GooCanvasItemModel interface. This one actually has a set_parent method. The documentation for it says:

This function cannot be used to add a model to a group or to change the parent of a model.

Thus, it seems like we actually found your problem: You should not call :set_parent() / it does not do what you think it does.

(Well... the goocanvasmm docs that you found basically say the same thing.)

please feel free to let someone other try to help me

Okay, I will unsubscribe from this issues. However, I think I am "the last man/woman standing". The last commit from @pavouk to LGI has been in January 2019 and I feel like they stopped reacting to GH issues at the same time. There are some other people that sometimes help here, but I doubt they can help much here.

Good luck.

@jerome-diver
Copy link
Author

jerome-diver commented Jan 22, 2021

ho yes, correct, i didn't see this part. That is true, and set_parent() method exist but should not be used as i think it should be. And that is why there is no error at run time. I was expecting "set_parent" method to set a parent (much more when i can not set it at create time as a property can be).
i also see that not much people use (or maybe just help) with model, maybe because model is something that will be removed on next (major ?) versions.
Looks like close to no one is using MVC with GooCanvas (or goo_canvas at least), and i should consider to find something other or go with qt Gui and find the wrapper to use with Lua.

i feel myself lucky anyway, thank you for try to support with that, you tried really and finally you helped a bit with that, it is enough to be notified as a good intention. I do appreciate.

I think you will gain quickly some more skills around with this good spirit too, i hope also myself to gain some more skills too (i'm pretty new to Lua about 1 month, and new with Gtk and GooCanvas about two weeks).

@jerome-diver
Copy link
Author

jerome-diver commented Jan 23, 2021

Ok @psychon, i find the solution !
this is my gist code with comments explaining what can be done or not

so here is a simple code showing how can be used GooCanvas Items models with LGI.
I think it is specific to LGI because of the way that LGI can not create a new model with its parent first but goo_canvas it wraps from can do it.
Parent property there seems to be writable only, there should maybe have a bug to target there or something missing in the LGI wrapper... i don't know.

#! /usr/bin/lua5.3

local lgi = require 'lgi'
local Goo = lgi.GooCanvas
local Gtk = lgi.Gtk

local win = Gtk.Window { width = 640, height = 500, anchor = Gtk.GTK_WINDOW_TOPLEVEL }
local frame = Gtk.Frame { width = 400, height = 400 }

local canvas = Goo.Canvas { parent = frame, id = 'canvas', width = 300, height = 300 }

win.on_key_press_event = nil
win.on_map_event = function() win.on_map_event = nil end
win.on_destroy = Gtk.main_quit

tool_bar = Gtk.Toolbar { height = 48 }
tool_bar:insert(Gtk.ToolButton { stock_id = 'gtk-quit', on_clicked = function() win:destroy() end }, -1)
status_bar = Gtk.Statusbar { }

function canvas:on_item_created(self)
  print("has been created and width is "..self.model.width)  -- yes, it has been created and i get the model
end

-- Let's create models (i find no way possible to define parent at this process time, this is strange to me and something to look around there):
local root_model = Goo.CanvasGroupModel { y = 0, x = 0, width = 500, height = 400 }
local item_model = Goo.CanvasGroupModel { y = 0, x = 0, width = 400, height = 400 }
local rect_model = Goo.CanvasRectModel { x = 0, y = 0, line_width = 2, width = 200, height = 150,
                                         stroke_color = 'yellow', fill_color = 'black', radius_x = 10, radius_y = 10 }
local text_model = Goo.CanvasTextModel { text = 'Voila !', x = 20, y = 20, anchor = Goo.GOO_CANVAS_ANCHOR_CENTER,
                                         font = 'source-code bold 12', fill_color = 'red', width = 100 }
-- instead to update parent, we should add child... (this is the solution i find, if you feel concerned, tell me if there is other one)
root_model:add_child(item_model, -1)
item_model:add_child(rect_model, -1)
item_model:add_child(text_model, -1)
canvas:set_root_item_model(root_model) -- and define the root item model as root_model to be the CanvasGroupModel

local vbox = Gtk.VBox:new(6)
vbox:add(tool_bar)
vbox:add(frame)
vbox:add(status_bar)

Gtk.Container.add(win, vbox)

win:show_all()
Gtk.main()

@ntd
Copy link
Contributor

ntd commented Aug 18, 2022

just use ":" instead of "." to pass the caller object as"self".

No idea about the issue itself, but the above declaration (and the provided examples) stands out as wrong.

You always need to pass the "caller object" (AKA instance) when using methods, but the constructors (i.e. all the new functions and friends) are not methods. More than that: you still don't have an instance to pass and if your code works it is just by accident.

For example, in your last snippet you create a GtkVBox:

local vbox = Gtk.VBox:new(6)

This is equivalent to Gtk.VBox.new(Gtk.VBox, 6), so you are basically passing true to the homogegeneous argument. The proper code should be:

local vbox = Gtk.VBox.new(true, 6)

See the static methods documentation for more details.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants