2

How can I add a context menu to a gframe in gWidgets2? I tried the following construct, but it seems that I cannot attach a addPopupMenu to a gframe:

 require(gWidgets2)
 w <- gwindow("gformlayout", visible=T)
 f <- gframe("frame", horizontal=FALSE, container=w)
 l <- glabel("Lorem ipsum dolor sit amet, \nconsectetur adipiscing elit.", container=f)
 b <- gbutton("change name", container=f, handler=function(h,...) {
     names(f) <- "new name"
 })
 lst <- list(gaction('world', handler=function(h,...) svalue(world) <- "world"), 
             gaction('continent', handler=function(h,...) svalue(world) <- "continent"), 
             gaction('country', handler=function(h,...) svalue(world) <- "country"), 
             gaction('state', handler=function(h,...) svalue(world) <- "state"))
 add3rdmousePopupMenu(f, lst)
 #addPopupMenu(f, lst)
 add3rdmousePopupMenu(b, lst)

The context-menu is attached fine to the button, but NOT to the gframe. So how can I add a context menu that would pop-up when right-clicking the gframe label?


UPDATE
As per the answers, I tried the code below:

require(gWidgets2)
f <- gframe("", cont=gwindow())
l <- glabel("label")                    # no cont argument
add3rdmousePopupMenu(l, list(a=gaction("Hi"))) 
f$block$setLabelWidget(l$block)         # the voodoo

But when I right-click on the label, I only get the standard Gtk context menu for selecting text:

enter image description here

Using Ubuntu 14.04 with Gtk+ 2.24.23. My sessionInfo():

> sessionInfo()
R version 3.0.2 (2013-09-25)
Platform: x86_64-pc-linux-gnu (64-bit)

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C               LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
 [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8    LC_PAPER=en_US.UTF-8       LC_NAME=C                 
 [9] LC_ADDRESS=C               LC_TELEPHONE=C             LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] splines   grid      stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] reshape2_1.4         gWidgets2RGtk2_1.0-3 memoise_0.2.1        Hmisc_3.14-4         Formula_1.1-1       
 [6] survival_2.37-7      lattice_0.20-29      RGtk2_2.20.29        gWidgets2_1.0-6      digest_0.6.4        

loaded via a namespace (and not attached):
[1] cluster_1.14.4      latticeExtra_0.6-26 plyr_1.8.1          RColorBrewer_1.0-5  Rcpp_0.11.2        
[6] stringr_0.6.2       tools_3.0.2 
landroni
  • 2,902
  • 1
  • 32
  • 39
  • It has something to do with `add3rdmousePopupMenu`, which I say based on glancing at the source code. I'll try to make a proper solution for you if I have time. – Hack-R Aug 26 '14 at 20:50
  • added it as a solution. HTH. – Hack-R Aug 26 '14 at 21:12

2 Answers2

1

A popup menu “pops” up a menu after a mouse click, typically a right mouse click. Implemented in gWidgets are the functions 1add3rdmousepopupmenu(the one you want) andaddpopupmenu` for a popup on any click. The menu is specified using the syntax for gmenu.

A simple example would be something like:

> w <- gwindow("Click on button to change")
> g <- ggroup(cont = w) # abbreviate container
> glabel("Hello ", cont=g)
guiWidget of type: gLabelRGtk for toolkit: guiWidgetsToolkitRGtk2
> world <- gbutton("world", cont=g)
> lst <- list()
> lst$world$handler <- function(h,...) svalue(world) <- "world"
> lst$continent$handler <- function(h,...) svalue(world) <- "continent"
> lst$country$handler <- function(h,...) svalue(world) <- "country"
> lst$state$handler <- function(h,...) svalue(world) <- "state"
> add3rdmousepopupmenu(world, lst)

I had a chance to test this and it works for me with gWidgets, gWidgets2, and gWidgetsRGtk2 using 64-bit R 3.1.1 on Windows. You can find documentation for the add3rdmousepopupmenu handler

  1. in the gWidgets2 manual here or
  2. by typing ??add3rdmousepopupmenu with gWidgets2 loaded,
  3. in the recently updated document by the author John Verzani giving examples for the gWidgets API, which applies not only to gWdigets2, but also his gWidgets, gWidgetsQt, gWidgetsRGtk2, and gWidgetsrJava packages which call the gWdigets API
  4. and in the gWidgets2 vignette on CRAN
Hack-R
  • 22,422
  • 14
  • 75
  • 131
  • I tried this but both `add3rdmousePopupMenu(world, lst)` and ` addPopupMenu(world, lst)` result in `Error in UseMethod("getBlock") : no applicable method for 'getBlock' applied to an object of class "function"` when using `gWidgets2`. Not sure what is wrong.. – landroni Aug 27 '14 at 09:03
  • @landroni I will try to help you with that. You should add it to the question though or break them into two different questions. I will update my solution as soon as I think I know what's causing your error. Please include the exact code that leads to that error. – Hack-R Aug 27 '14 at 12:30
  • I can't replicate the error and I don't see any search results related to it... can you give a replicable example? – Hack-R Aug 27 '14 at 12:48
  • I simply ran `require(gWidgets2)`, then the code you posted, and instead of the last line: `add3rdmousePopupMenu(world, lst)`. – landroni Aug 27 '14 at 17:46
  • @landroni I see. I'm still not able to replicate that error, however I tried it again and noticed that `add3rdmousepopupmenu` should not have the "P" in "Popup" capitalized. Sorry about that, in my defensive that is a copy and paste from authoritative documentation; apparently they had a typo since the "P" in `addPopupmenu` is in fact capitalized. It works for me. Does that fix it for you too? – Hack-R Aug 27 '14 at 18:04
  • No, not really, I tried with the capitalized, too. BTW, that document must have been for the old version: `gWidgets`, and some changes have taken place. – landroni Aug 27 '14 at 18:19
  • @landroni the documentation was published July 14, 2014... can you paste your code, output and the output of `R.Version`? – Hack-R Aug 27 '14 at 18:23
  • Could you link to the documentation you're referring to? Thanks. – landroni Aug 27 '14 at 18:29
  • @landroni Sure, done. If you have any more/continued errors please consider pasting your code and version information and/or continuing this in chat. StackOverflow is officially warnings us that there are too many comments LOL – Hack-R Aug 27 '14 at 18:47
  • 1
    Thanks @NerdLife. The documentation is not always correct, but I'm happy to try and update. I need to be more clear about the difference between `gWidgets` and `gWidgets2`. Most things are similar, but there were enough changes to make the additional `2` warranted. Any docs for `gWidgets` are old, even if the package was updated recently. – jverzani Aug 27 '14 at 21:27
  • @jverzani Yes it would be nice to have a short list of fundamental differences between `gWidgets` and `gWidgets2`. It would come in handy if one wanted to port a `gWidgets` package (e.g. `latticist`) to `gWidgets2`. – landroni Aug 28 '14 at 07:14
  • Could you please recheck the question, @jverzani? The code works fine to add a context-menu to a `gbutton`, but NOT to a `gframe`. Maybe a bug.. – landroni Aug 29 '14 at 19:43
  • The code that you posted was taken from the `gWidgets` vignette, but it does NOT work with `gWidgets2` (they're not perfectly compatible). In the latter, `addPopupMenu` expects a `list` of `gaction` objects, NOT `function` objs. – landroni Aug 29 '14 at 19:45
1

@landroni I didn't check, but would be surprised if popup menus could be added to gframe labels directly. But with Gtk things can be worked around. Here is how you can put a popup menu in the label position:

f <- gframe("", cont=gwindow())
l <- glabel("label")                    # no cont argument
add3rdmousePopupMenu(l, list(a=gaction("Hi"))) 
f$block$setLabelWidget(l$block)         # the voodoo
l$widget$setSelectable(FALSE)           # may not be needed

As for whether this is intuitive to the users, I'll let you decide....

jverzani
  • 5,600
  • 2
  • 21
  • 17
  • Good point on the usability, and this gave me an idea for a different GUI approach. However, the code above doesn't seem to work: I still get the GTK standard menu for a text widget. Perhaps the `glabel` should first be made non-selectable? – landroni Aug 29 '14 at 20:30
  • For an example of this, if you do `l2 <- glabel("label", cont=gwindow()); add3rdmousePopupMenu(l2, list(a=gaction("Hi")))`, the c-menu on the `glabel` won't work.. – landroni Aug 29 '14 at 20:57
  • @landroni Oops, it should be `add3rdmousePopupMenu`. (I need to make an alias to `add3rdMousePopupMenu`, as that camel-casing seems more natural.) That works on linux. If it doesn't work with this change let me know. – jverzani Aug 29 '14 at 22:00
  • Strange. Here on Linux, too, I don't get a c-menu with the code posted (even when fixing the typo and using the correct `add3rdmousePopupMenu`). – landroni Aug 30 '14 at 09:24
  • @landroni I just double checked with a new unbuntu install and it is working. Do you get any errors, or just no response> – jverzani Aug 30 '14 at 13:17
  • I updated the Question with the exact code that I'm running and a screenshot of the issue I'm seeing. – landroni Aug 30 '14 at 13:59
  • Okay, I'm stumped. It works for my Ubuntu (14.04). Not sure where to go as I don't see any error messages. Seems like the default menu is being called instead of the new one, so the popup bit works, but not the adding of a menu. Sorry. – jverzani Aug 30 '14 at 15:08
  • I suspect that the issue comes from the `glabel` being *selectable*. For instance, when you use `gframe` the label text can NOT be selected by the user. How could I make `l <- glabel("label")` NOT selectable at all? – landroni Aug 30 '14 at 15:11
  • 1
    `l$widget$setSelectable(FALSE)` should do that. – jverzani Aug 30 '14 at 15:48
  • Nice. Glad to hear it. – jverzani Aug 30 '14 at 22:13
  • But what if I wanted to put such a customized `gframe` into a `glayout` grid slot? I tried the following: `gl <- glayout(cont=gwindow()); gl[1,1] <- gframe("", cont=gl); l <- glabel("label")`, but no luck. How can you put such a construct into a `glayout`? – landroni Aug 31 '14 at 20:15
  • Should work just as before. Maybe you need to save the `gframe` object into a variable for convenience? – jverzani Sep 01 '14 at 02:41
  • Hmm, it does seem to work. Not sure what was wrong before. If I still hit trouble, I'll post a separate question. – landroni Sep 01 '14 at 12:17