diff --git a/DESCRIPTION b/DESCRIPTION new file mode 100644 index 0000000..3fe906d --- /dev/null +++ b/DESCRIPTION @@ -0,0 +1,44 @@ +Package: gWidgets2RGtk2 +Type: Package +Title: Implementation of gWidgets2 for RGtk2 package +Version: 1.0 +Date: 2011-09-18 +Author: John Verzani +Maintainer: jverzani@gmail.com +Description: Implements gWidgets2 API for RGtk2 +License: GPL-3 +Depends: + methods, + memoise, + RGtk2, + gWidgets2 +LazyLoad: yes +Collate: + 'misc.R' + 'gtk-misc.R' + 'GComponent.R' + 'GContainer.R' + 'GWidget.R' + 'gbutton.R' + 'gwindow.R' + 'ggroup.R' + 'gframe.R' + 'glabel.R' + 'gtimer.R' + 'gedit.R' + 'gcheckbox.R' + 'gcheckboxgroup.R' + 'icons.R' + 'gradio.R' + 'gnotebook.R' + 'gslider.R' + 'gspinbutton.R' + 'gexpandgroup.R' + 'gstackwidget.R' + 'glayout.R' + 'gpanedgroup.R' + 'gseparator.R' + 'gtext.R' + 'gcombobox.R' + 'gaction.R' + 'gcalendar.R' diff --git a/NAMESPACE b/NAMESPACE new file mode 100644 index 0000000..2da263a --- /dev/null +++ b/NAMESPACE @@ -0,0 +1,32 @@ +export("font<-.RGtkObject") +export(.addStockIcons.guiWidgetsToolkitRGtk2) +export(.gaction.guiWidgetsToolkitRGtk2) +export(.gbutton.guiWidgetsToolkitRGtk2) +export(.gcalendar.guiWidgetsToolkitRGtk2) +export(.gcheckbox.guiWidgetsToolkitRGtk2) +export(.gcheckboxgroup.guiWidgetsToolkitRGtk2) +export(.gcombobox.guiWidgetsToolkitRGtk2) +export(.gedit.guiWidgetsToolkitRGtk2) +export(.getStockIconByName.guiWidgetsToolkitRGtk2) +export(.getStockIcons.guiWidgetsToolkitRGtk2) +export(.gexpandgroup.guiWidgetsToolkitRGtk2) +export(.gframe.guiWidgetsToolkitRGtk2) +export(.ggroup.guiWidgetsToolkitRGtk2) +export(.glabel.guiWidgetsToolkitRGtk2) +export(.glayout.guiWidgetsToolkitRGtk2) +export(.gnotebook.guiWidgetsToolkitRGtk2) +export(.gpanedgroup.guiWidgetsToolkitRGtk2) +export(.gradio.guiWidgetsToolkitRGtk2) +export(.gseparator.guiWidgetsToolkitRGtk2) +export(.gslider.guiWidgetsToolkitRGtk2) +export(.gspinbutton.guiWidgetsToolkitRGtk2) +export(.gstackwidget.guiWidgetsToolkitRGtk2) +export(.gtext.guiWidgetsToolkitRGtk2) +export(.gtimer.guiWidgetsToolkitRGtk2) +export(.gwindow.guiWidgetsToolkitRGtk2) +export(addToGtkStockIcons) +export(getBlock.RGtkObject) +export(getWidget.RGtkObject) +exportClasses(guiWidgetsToolkitRGtk2) +importClassesFrom(gWidgets2,BasicToolkitInterface) +importClassesFrom(gWidgets2,guiWidgetsToolkit) diff --git a/R/GComponent.R b/R/GComponent.R new file mode 100644 index 0000000..6c382f6 --- /dev/null +++ b/R/GComponent.R @@ -0,0 +1,201 @@ +##' @include gtk-misc.R +NULL + + +## Base classes. These are *not* exported, rather each toolkit implementation needs +## to (mostly) provide these same basic classes: +## GComponent +## - GWidget +## - GButton +## - GLabel +## - Others matching the constructors +## -GContainer +## - GWindow +## - GGroup +## - GFrame +## - GExpandGroup +## - GLayout +## - GNotebook +## - GPanedGroup +## - GStacked + + +##' Base Class for widgets and containers +##' +##' GComponent as parent for GContainer and GWidget. +##' Here we place GtkWidget and GtkObject methods. Container methods in GContainer +##' @importClassesFrom gWidgets2 BasicToolkitInterface +GComponent <- setRefClass("GComponent", + contains="BasicToolkitInterface", + fields=list( + toolkit="ANY", + widget="ANY", + block="ANY", + parent="ANY", # NULL for gwindow, else parent container + handler_id="ANY", + .e="environment" + ), + methods=list( + initialize=function(toolkit=guiToolkit(), ...) { + initFields(toolkit=toolkit, + .e=new.env() + ) + if(is(handler_id, "unitializedField")) + handler_id <<- NULL + + callSuper(...) + }, + get_length = function(...) { + "Get length of object. Needed for sapply." + 1 + }, + get_visible = function() widget$getVisible(), + set_visible = function(value) widget$setVisible(as.logical(value)), + get_enabled = function() widget$getSensitive(), + set_enabled = function(value) widget$setSensitive(as.logical(value)), + get_tooltip = function(...) widget$getTooltipText(), + set_tooltip = function(value) widget$setTooltipText(paste(value, collapse="\n")), + ## font + set_font = function(obj, value) { + ## pass off to widget + tmp <- getWidget(obj) + font(tmp) <- value + }, + ## tag + get_attr = function(key) { + if(missing(key)) + ls(.e) + else + attr(.e, key) + }, + set_attr = function(key, value) { + tmp <- .e + attr(tmp, key) <- value + }, + is_extant = function() { + "Is widget still available?" + if(is(block, "")) + return(FALSE) + else + TRUE + }, + get_size=function(...) { + alloc <- block$getAllocation()$allocation + c(width=alloc$width, height=alloc$height) + }, + set_size=function(value, ...) { + ## Huh?? + }, + + ## Work with containers + set_parent = function(parent) parent <<- parent, + add_to_parent = function(parent, child, expand=NULL, fill=NULL, anchor=NULL, ...) { + "Add a child to parent if it is ia container and non null. Dispatches to add_child method of parent" + + if(missing(parent) || is.null(parent)) + return() + + ## return here. This is for tcltk compliance + if(is(parent, "GLayout")) + return() + + if(!is(parent, "GContainer") && is.logical(parent) && parent) { + tmp <- gwindow(toolkit=toolkit) + tmp$add_child(child, expand, fill, anchor, ...) + return() + } + if(!is(parent, "GContainer")) { + message("parent is not a container") + return() + } + + parent$add_child(child, expand, fill, anchor, ...) + }, + + + ## RGtk2 handler code + handler_widget = function() widget, # allow override for block (glabel) + add_handler = function(signal, handler, action=NULL, ...) { + if(missing(handler) || is.null(handler)) + return(NULL) + ## + gSignalConnect(handler_widget(), signal, handler, user.data.first=TRUE, data=list(obj=.self, action=action)) + }, + ## for RGtk2, distinction made here + add_event_handler = function(signal, handler, action=NULL, ...) { + if(missing(handler)) + return(NULL) + + FUN <- function(h, ...) { + handler(h, ...) + FALSE # need logical + } + gSignalConnect(handler_widget(), signal, FUN, user.data.first=TRUE, data=list(obj=.self, action=action)) }, + ## typical signal maps + add_handler_clicked = function(handler, action=NULL, ...) { + add_handler("clicked", handler, action, ...) + }, + add_handler_focus=function(handler, action=NULL, ...) { + add_event_handler("focus-in-event", handler, action, ...) + }, + add_handler_blur=function(handler, action=NULL, ...) { + add_event_handler("focus-out-event", handler, action, ...) + }, + keystroke_handler=function(handler, action=NULL, ...) { + f <- function(d, widget, event,...) { + h <- list(obj=d$obj,action=d$action) + h$key <- event$getString() # XXX This is bad -- no locale, ... + state <- event$getState() + if(state == 0) + h$modifier <- NULL + else + h$modifier <- gsub("-mask", "", names(which(state == GdkModifierType))) + handler(h,...) + return(FALSE) # propogate + } + f + }, + add_handler_keystroke=function(handler, action=NULL, ...) { + "Keystroke handler. Defined for all, but only gedit, gtext" + if(missing(handler) || is.null(handler)) + return() + add_event_handler("key-release-event", keystroke_handler, action, ...) + }, + ## + emit_signal=function(signal, ..., detail=NULL) { + "Emit signal, for svalue<- assignments, others" + gSignalEmit(widget, signal, ..., detail) + }, + ## + add_popup_menu = function(menulist, action=NULL, ...) { + XXX("Add popup menu code") + }, + + + ## Work with handlers (block, un, remove) + block_handler=function(ID) { + if(missing(ID)) + ID <- handler_id + lapply(ID, gSignalHandlerBlock, obj=widget) + }, + unblock_handler=function(ID) { + if(missing(ID)) + ID <- handler_id + lapply(ID, gSignalHandlerUnblock, obj=widget) + }, + remove_handler=function(ID) { + if(missing(ID)) + ID <- handler_id + lapply(ID, gSignalHandlerDisconnect, obj=widget) + if(identical(ID, handler_id)) + handler_id <<- NULL # zero out if this one + } + + ) + ) + +##' exported Subclass of GComponent for users to subclass +##' +##' @exportClasses GComponentRGtk2 +GComponentRGtk2 <- setRefClass("GComponentRGtk2", + contains="GComponent") diff --git a/R/GContainer.R b/R/GContainer.R new file mode 100644 index 0000000..f0e4af0 --- /dev/null +++ b/R/GContainer.R @@ -0,0 +1,11 @@ +##' @include GComponent.R +NULL + +##' Base class for container objects +GContainer <- setRefClass("GContainer", + contains="GComponent", + fields=list( + children="list" + )) + + diff --git a/R/GWidget.R b/R/GWidget.R new file mode 100644 index 0000000..6312664 --- /dev/null +++ b/R/GWidget.R @@ -0,0 +1,41 @@ +##' @include GComponent.R +NULL + +##' Base class for widget objects +GWidget <- setRefClass("GWidget", + contains="GComponent", + fields=list( + coerce_with="ANY" # function + ) + ) + +##' Class to hold widget with items where handlers apply to each item +##' +GWidgetWithItems <- setRefClass("GWidgetWithItems", + contains="GWidget", + fields=list( + widgets="list" + ), + methods=list( + add_handler=function(signal, handler, action=NULL) { + "Just adds observer, need to connect widget to call notify_observers" + if(!missing(handler) && is.function(handler)) { + o <- gWidgets2:::observer(.self, handler, action) + invisible(add_observer(o, signal)) + } + }, + block_handler=function(ID) { + "Block all handlers" + block_observer(ID) + }, + unblock_handler=function(ID) { + "unblock all handlers" + unblock_observer(ID) + }, + remove_handler=function(ID) { + "remove all handlers" + remove_observer(ID) + } + )) + + diff --git a/R/gaction.R b/R/gaction.R new file mode 100644 index 0000000..63dfc6f --- /dev/null +++ b/R/gaction.R @@ -0,0 +1,85 @@ +##' @include GWidget.R +NULL + +##' Toolkit constructor +##' +##' @export +##' @rdname gWidgets2RGtk2-undocumented +.gaction.guiWidgetsToolkitRGtk2 <- function(toolkit, + label, tooltip=NULL, icon = NULL, key.accel = NULL, + handler = NULL,action = NULL, parent = NULL, ... ) { + GAction$new(toolkit, + label, tooltip=tooltip, icon = icon, key.accel = key.accel, + handler = handler,action = action, parent = parent, ...) +} + + +## XXX +GAction <- setRefClass("GAction", + contains="GWidget", + fields=list( + accel_key="ANY" + ), + methods=list( + initialize=function(toolkit=NULL, + label="", tooltip=NULL, icon = NULL, key.accel = NULL, + handler, action=NULL, parent, ...) { + + widget <<- gtkAction(name=make.names(label), + label=label, + tooltip=tooltip, + stock.id=icon) + + initFields(block=widget, + accel_key=key.accel) + + if(!is.null(parent) && !is.null(handler)) + add_key_accel(parent, handler) + + handler_id <<- add_handler_changed(handler, action) + + callSuper(toolkit) + }, + add_key_accel=function(parent, handler) { + ## accel buttons + if(!is.null(accel_key) && !is.null(parent)) { + toplevel <- getBlock(parent)$toplevel + ## mask Shift-1, Control-4 alt-8 + ## key sprintf("GDK_%s",key) + ## flag GtkAccelFlags -- 1 + if(grepl("^Control", accel_key) || + grepl("^Alt", accel_key) || + grepl("^Shift", accel_key)) { + tmp <- strsplit(accel_key, "-")[[1]] + modifier <- c(Shift="shift-mask", "Control"="control-mask", Alt="mod1-mask")[tmp[1]] + key <- sprintf("GDK_%s", tmp[2]) + } else { + modifier <- "modifier-mask" + key <- sprintf("GDK_%s", accel_key) + } + a <- gtkAccelGroup() + toplevel$addAccelGroup(a) + a$connect(get(key), modifier, "visible", function(...) { + h <- list(action=action) + handler(h, ...) + TRUE + }) + } + }, + get_value=function( ...) { + widget$getLabel() + }, + set_value=function(value, ...) { + widget$setLabel(value) + }, + get_tooltip=function(...) { + widget['tooltip'] + }, + set_tooltip=function(value, ...) { + widget$setTooltip(paste(value, "\n")) + }, + add_handler_changed=function(handler, action=NULL, ...) { + add_handler("activate", handler, action=action, ...) + } + )) + diff --git a/R/gbutton.R b/R/gbutton.R new file mode 100644 index 0000000..665d783 --- /dev/null +++ b/R/gbutton.R @@ -0,0 +1,87 @@ +##' @include GWidget.R +NULL + +##' Toolkit button constructor +##' +##' @export +##' @rdname gWidgets2RGtk2-undocumented +.gbutton.guiWidgetsToolkitRGtk2 <- function(toolkit, text, handler, action, container, ...) { + GButton$new(toolkit, text, handler, action, container, ...) +} + +##' Button class +GButton <- setRefClass("GButton", + contains="GWidget", + fields=list( + other = "ANY" + ), + methods=list( + initialize=function(toolkit=NULL, text=NULL, handler, action, container, ...) { + widget <<- gtkButton() + toolkit <<- toolkit # otherwise next line fails to find toolkit for dispatch + if(!is_empty(text)) + set_value(text) + + + + initFields(block=widget) + add_to_parent(container, .self, ...) + + if(is(action, "GAction")) { + #make_action_proxy(action) + gtkaction <- action$widget + ## + widget$setRelatedAction(gtkaction) # connect + widget$setUseActionAppearance(TRUE) + ## + icon <- gtkaction['stock-id'] + if(!is.null(icon)) { + image <- gtkaction$createIcon(GtkIconSize[4]) # button size + widget$setImage(image) + } + ## tooltip + tip <- gtkaction['tooltip'] + if(!is.null(tip)) + tooltip(.self) <- tip + } else { + handler_id <<- add_handler_changed(handler, action) + } + callSuper(toolkit) + }, + set_value=function(value, index=TRUE, drop=TRUE, ...) { + icon <- getStockIconByName(value, toolkit=toolkit) + if(!is.null(icon)) { + image <- gtkImageNew() + image$SetFromStock(icon, size="button") + widget$setImage(image) + } + widget$setLabel(value) + }, + get_value=function(index=TRUE, drop=TRUE, ...) { + widget$getLabel() + }, + + ## font is a real hack + set_font = function(obj, value) { + object <- getWidget(obj)[[1]] # label is first child or something + if(is(object, "GtkAlignment")) + object <- object[[1]][[2]] # a real hacke + font(object) <- value + + }, + ## Handler: changed -> clicked + add_handler_changed=function(handler, action=NULL, ...) { + add_handler_clicked(handler, action=action, ...) + }, + remove_border=function() { + "Remove border by setting relief to none" + widget$SetRelief(GtkReliefStyle['none']) + } + )) + + +## ##' exported Subclass of GComponent for users to subclass +## ##' +## ##' @exportClasses GButtonRGtk2 +## GButtonRGtk2 <- setRefClass("GButtonRGtk2", +## contains="GButton") diff --git a/R/gcalendar.R b/R/gcalendar.R new file mode 100644 index 0000000..c4ef058 --- /dev/null +++ b/R/gcalendar.R @@ -0,0 +1,99 @@ +##' @include GWidget.R +NULL + +##' Toolkit constructor +##' +##' @export +##' @rdname gWidgets2RGtk2-undocumented +.gcalendar.guiWidgetsToolkitRGtk2 <- function(toolkit, + text="", + format="%Y-%m-%d", + handler = NULL,action = NULL, container = NULL, ... ) { + GCalendar$new(toolkit, + text=text, + format=format, + handler = handler,action = action, container = container, ...) +} + + + +## Calendar +GCalendar <- setRefClass("GCalendar", + contains="GWidget", + fields=list( + "format"="character" + ), + methods=list( + initialize=function(toolkit=NULL, + text="", + format="%Y-%m-%d", + handler, action, container, ...) { + + block <<- gtkHBox() + widget <<- gtkEntry() + widget$setText(text) + button <- gtkButton("Date...") + + initFields(format=format) + + block$packStart(widget, expand=TRUE, fill=TRUE) + block$packStart(button) + + calendar_callback <- function(h,...) { + ## called when button is clicked + ## pop up a calendar, when date selected, copy to entry + win <- gtkWindowNew(show=FALSE) + cal <- gtkCalendarNew() + if(nchar(cur_date <- widget$getText())) { + tmp <- strsplit(cur_date, "-")[[1]] + cal$selectDay(tmp[3]) + cal$selectMonth(tmp[2] - 1L, tmp[1]) + } + win$Add(cal) + cal$Show(); + win$Show() + + cal$AddCallback("day-selected-double-click", function(w,...) { + l <- cal$GetDate() + date_selected <- paste(l$year, l$month+1, l$day,sep="-",collapse="-") + date_selected <- format(as.Date(date_selected,format=format)) + set_value(date_selected) + win$Destroy() + }) + } + gSignalConnect(button, "clicked", f=calendar_callback) + + + add_to_parent(container, .self, ...) + + handler_id <<- add_handler_changed(handler, action) + + callSuper(toolkit) + }, + get_value=function( ...) { + val <- widget$getText() + cur_date <- try(as.Date(val, format=format)) + if(inherits(cur_date,"try-error")) + val <- NA + else + val <- as.character(cur_date) + }, + set_value=function(value, ...) { + widget$setText(value) + }, + add_handler_changed=function(handler, action=NULL, ...) { + if(missing(handler) || is.null(handler)) + return() + f <- function(h, widget, event, ...) { + keyval <- event$GetKeyval() + if(keyval == GDK_Return) { + handler(h, widget, event, ...) + return(TRUE) + } else { + return(FALSE) + } + } + add_handler("activate", f, action=action, ...) + } + )) + diff --git a/R/gcheckbox.R b/R/gcheckbox.R new file mode 100644 index 0000000..411af8a --- /dev/null +++ b/R/gcheckbox.R @@ -0,0 +1,97 @@ +##' @include GWidget.R +NULL + +##' Toolkit XXX constructor +##' +##' @export +##' @rdname gWidgets2RGtk2-undocumented +.gcheckbox.guiWidgetsToolkitRGtk2 <- function(toolkit, + text, checked = FALSE, use.togglebutton=FALSE, handler = NULL, action = NULL, + container = NULL, ... ) { + if(use.togglebutton) + GToggleButton$new(toolkit, + text, checked, handler, action, container, ...) + else + GCheckbox$new(toolkit, + text, checked, handler, action, container, ...) +} + +##' Basic check box +GCheckbox <- setRefClass("GCheckbox", + contains="GWidget", + fields=list( + XXX="ANY" + ), + methods=list( + initialize=function(toolkit=NULL, + text="", checked = FALSE, handler = NULL, action = NULL, + container = NULL, ... ) { + + widget <<- gtkCheckButtonNewWithLabel(text) + widget$setActive(checked) + + initFields(block=widget) + add_to_parent(container, .self, ...) + + handler_id <<- add_handler_changed(handler, action) + + callSuper(toolkit) + }, + set_value=function(value, index=TRUE, drop=TRUE, ...) { + widget$setActive(value) + }, + get_value=function(index=TRUE, drop=TRUE, ...) { + widget$getActive() + }, + get_items = function(i, j, ..., drop=TRUE) { + widget[[1]]$getLabel() + }, + set_items = function(i, j, ..., value) { + widget[[1]]$setLabel(value) + }, + add_handler_changed=function(handler, action=NULL, ...) { + add_handler("toggled", handler, action=action, ...) + } + )) + + +##' Basic toggle button +GToggleButton <- setRefClass("GToggleButton", + contains="GCheckbox", + fields=list( + XXX="ANY" + ), + methods=list( + initialize=function(toolkit=NULL, + text, checked = FALSE, handler = NULL, action = NULL, + container = NULL, ... ) { + + widget <<- gtkToggleButtonNewWithLabel(text) + set_value(checked) + set_items(value=text) + + initFields(toolkit=toolkit, + block=widget) + add_to_parent(container, .self, ...) + + handler_id <<- add_handler_changed(handler, action) + + .self + }, + get_items = function(i, j, ..., drop=TRUE) { + widget$getLabel() + }, + set_items = function(i, j, ..., value) { + ## use UseStock if in stock icon + widget$setLabel(value) + }, + add_handler_changed=function(handler, action=NULL, ...) { + add_handler("toggled", handler, action=action, ...) + } + )) + +## ##' exported Subclass of GComponent for users to subclass +## ##' +## ##' @exportClasses GCheckBoxRGtk2 +## GCheckboxRGtk2 <- setRefClass("GCheckboxRGtk2", +## contains="GCheckbox") diff --git a/R/gcheckboxgroup.R b/R/gcheckboxgroup.R new file mode 100644 index 0000000..b0bdaf6 --- /dev/null +++ b/R/gcheckboxgroup.R @@ -0,0 +1,244 @@ +##' @include GWidget.R +NULL + +##' Toolkit XXX constructor +##' +##' @export +##' @rdname gWidgets2RGtk2-undocumented +.gcheckboxgroup.guiWidgetsToolkitRGtk2 <- function(toolkit=NULL, + items, checked = FALSE, horizontal = FALSE, + use.table=FALSE, handler = NULL, + action = NULL, container = NULL, ... ) { + if(use.table) + GCheckboxGroupTable$new(toolkit, items, checked = checked, + handler = handler,action = action, container = container, ...) + else + GCheckboxGroup$new(toolkit, + items, checked = checked, horizontal = horizontal, + handler = handler, action = action, container = container, ...) +} + + +##' Single line edit class +GCheckboxGroup <- setRefClass("GCheckboxGroup", + contains="GWidgetWithItems", + methods=list( + initialize=function(toolkit, + items, checked = FALSE, horizontal = FALSE, + handler = NULL, + action = NULL, container = NULL, ... ) { + + if(horizontal) + block <<- gtkHBox() + else + block <<- gtkVBox() + widget <<- NULL + widgets <<- list() + + set_items(value=items) + + add_to_parent(container, .self, ...) + + handler_id <<- add_handler_changed(handler, action) + + callSuper(toolkit) + }, + get_value=function(index=TRUE, drop=TRUE, ...) { + items <- get_items() + items[get_index()] + }, + set_value=function(value, index=TRUE, drop=TRUE, ...) { + items <- get_items() + ind <- pmatch(value, items) + set_index(ind) + }, + get_index = function(...) { + sapply(widgets, function(i) i$getActive()) + }, + set_index=function(value, ...) { + if(is.numeric(value)) { + tmp <- rep(FALSE, length=get_length()) + tmp[value] <- TRUE + value <- tmp + } + mapply(gtkToggleButtonSetActive, widgets, value) + }, + get_items = function(i, ...) { + sapply(widgets, function(i) i[[1]]$getLabel()) + }, + set_items = function(value, i, ...) { + ## make widgets + widgets <<- sapply(value, gtkCheckButtonNewWithLabel) + ## layout widgets + sapply(block$getChildren(), gtkContainerRemove, object=block) # remove old + sapply(widgets, gtkBoxPackStart, object=block, expand=FALSE, padding=1) + ## connec widgets + sapply(widgets, gSignalConnect, signal="toggled", f=function(self, ...) { + self$notify_observers(signal="toggled", ...) + }, data=.self, user.data.first=TRUE) + invisible() + }, + get_length = function() { + length(widgets) + }, + ## Handler: changed -> clicked + add_handler_changed=function(handler, action=NULL, ...) { + add_handler("toggled", handler, action=action, ...) + } + )) + + +##' table with checkboxes +GCheckboxGroupTable <- setRefClass("GCheckboxGroupTable", + contains="GWidget", + methods=list( + initialize=function(toolkit, + items, checked = FALSE, + handler = NULL, + action = NULL, container = NULL, ... ) { + + widget <<- gtkTreeViewNew(TRUE) + widget$SetRulesHint(TRUE) # shade + + block <<- gtkScrolledWindowNew() + block$SetPolicy("GTK_POLICY_AUTOMATIC","GTK_POLICY_AUTOMATIC") + block$Add(widget) + + store <- rGtkDataFrame(make_items()) + widget$setModel(store) + widget$setHeadersVisible(FALSE) + + ## set up the view columns + vc <- gtkTreeViewColumnNew() + widget$insertColumn(vc, 0) + cr <- gtkCellRendererToggle() + vc$PackStart(cr, TRUE) + cr['activatable'] <- TRUE # needed + vc$addAttribute(cr, "active", 1) + item.toggled <- function(tbl, cell, path, data) { + store <- tbl$getModel() + row <- as.numeric(path) + 1 + store[row,2] <- !store[row, 2] + } + gSignalConnect(cr, "toggled", item.toggled, data=widget, user.data.first=TRUE) + + cr <- gtkCellRendererTextNew() + vc <- gtkTreeViewColumnNew() + vc$PackStart(cr, TRUE) + vc$addAttribute(cr, "text", 0) + widget$insertColumn(vc, 1) + + ## icons, tooltips??? + + + set_items(value=items) + set_index(checked) + + add_to_parent(container, .self, ...) + + handler_id <<- add_handler_changed(handler, action) + + callSuper(toolkit) + }, + ## helper function + make_items = function(items, icons, tooltips, checked=rep(FALSE, length(items))) { + if(missing(items) || + (is.data.frame(items) && nrow(items) == 0) || + (length(items) == 0) + ) { + out <- data.frame(items=character(0), + checked=logical(0), + icons=character(0), + tooltips=character(0), + stringsAsFactors=FALSE) + } else if(is.data.frame(items)) { + ## check + out <- items + if(ncol(out) == 1) + out$checked <- as.logical(rep(checked, length=nrow(items))) + if(ncol(out) == 2) + out$icons <- rep("", nrow(items)) + if(ncol(out) == 3) + out$tooltip <- rep("", nrow(items)) + } else { + ## piece together + items <- as.character(items) + + if(missing(icons)) + icons <- "" + icons <- rep(icons, length=length(items)) + + if(missing(tooltips)) + tooltips <- "" + icons <- rep(tooltips, length=length(items)) + + checked <- rep(checked, length=length(items)) + + out <- data.frame(items=items, checked=checked, icons=icons, tooltips=tooltips, + stringsAsFactors=FALSE) + } + return(out) + }, + get_value=function(drop=TRUE, ...) { + get_items(get_index()) + }, + set_value=function(value, drop=TRUE, ...) { + ind <- match(value, get_items()) + ind <- ind[!is.na(ind)] + set_index(ind) + }, + get_index = function(...) { + store <- widget$getModel() + vals <- store[,2, drop=TRUE] + which(vals) + }, + set_index=function(value, ...) { + if(is.numeric(value)) { + tmp <- rep(FALSE, length.out=get_length()) + tmp[value] <- TRUE + value <- tmp + } + store <- widget$getModel() + store[,2] <- value + }, + get_items = function(i, ...) { + store <- widget$getModel() + items <- store[,1, drop=TRUE] + items[i] + }, + set_items = function(value, i, ...) { + items <- make_items(value) + + if(missing(i)) { + ## replace the store + newStore <- rGtkDataFrame(items) + widget$setModel(newStore) + } else { + if(is.logical(i)) + i <- which(i) + + store[i,] <- items + } + + }, + get_length = function() { + "Number of items to choose from" + length(get_items()) + }, + ## handlers + handler_widget=function() { + ## put handler on cell renderer, not widget + view_column <- widget$getColumn(0) + cell_renderer <- view_column$getCellRenderers()[[1]] + cell_renderer + }, + add_handler_changed = function(handler, action=NULL, ...) { + add_handler("toggled", handler, action, ...) + } + )) + +## ##' exported Subclass for users to subclass +## ##' +## ##' @exportClasses GCheckboxGroupRGtk2 +## GCheckboxGroupRGtk2 <- setRefClass("GCheckboxGroupRGtk2", +## contains="GCheckboxGroup") diff --git a/R/gcombobox.R b/R/gcombobox.R new file mode 100644 index 0000000..6715a3f --- /dev/null +++ b/R/gcombobox.R @@ -0,0 +1,205 @@ +##' @include GWidget.R +NULL + +##' Toolkit constructor +##' +##' @export +##' @rdname gWidgets2RGtk2-undocumented +.gcombobox.guiWidgetsToolkitRGtk2 <- function(toolkit, + items, selected = 1, editable = FALSE, coerce.with = NULL, + handler = NULL,action = NULL, container = NULL, ... ) { + + if(editable) + GComboBoxWithEntry$new(toolkit, + items, selected = selected, coerce.with = coerce.with, + handler = handler,action = action, container = container, ...) + else + GComboBoxNoEntry$new(toolkit, + items, selected = selected, coerce.with = coerce.with, + handler = handler,action = action, container = container, ...) + +} + + +## We create two subclasses of this to handle editable and non-editable situation. These methods end up being in common for both. +GComboBox <- setRefClass("GComboBox", + contains="GWidget", + methods=list( + get_index = function(...) { + widget$getActive() + 1L + }, + set_index = function(value,...) { + value <- min(max(-1, as.integer(value)), get_length()) + widget$setActive(value - 1L) + }, + add_handler_changed=function(handler, action=NULL, ...) { + add_handler_clicked(handler, action=NULL, ...) + }, + add_handler_clicked = function(handler, action=NULL, ...) { + add_handler("changed", handler, action=action, ...) + }, + check_windows = function(items) { + "Hack to make width under windows work better" + if(.Platform$OS == "windows") { + if(dim(items)[1] > 0) { + colChars <- max(sapply(items[,1,drop=TRUE],nchar)) + if(colChars < 3) + widget$setWidthRequest(15*(4 + colChars)) + } + } + } + )) + +## combobox without entry can have icons, use rGtkDataFrame +GComboBoxNoEntry <- setRefClass("GComboBoxNoEntry", + contains="GComboBox", + methods=list( + initialize=function(toolkit=NULL, + items, + selected = 1, # use 0 for blank + coerce.with = NULL, + handler, action, container, ...) { + + store <- rGtkDataFrame(items) + ## drop down list, not combo + widget <<- gtkComboBoxNewWithModel(store) + cellrenderer <- gtkCellRendererTextNew() + widget$PackStart(cellrenderer, expand=TRUE) + widget$AddAttribute(cellrenderer,"text", 0) + ## icons + if(ncol(items) >= 2) { + cellrenderer <- gtkCellRendererPixbufNew() + widget$PackStart(cellrenderer, expand=FALSE) + widget$AddAttribute(cellrenderer, "stock-id", 1) + + if(ncol(items) >= 3) { + message("tooltips are not implemented") + } + } + + widget$show() + widget$setActive(selected - 1L) + + check_windows(items) + + initFields(block=widget, + coerce_with=coerce.with + ) + + add_to_parent(container, .self, ...) + + handler_id <<- add_handler_changed(handler, action) + + callSuper(toolkit) + }, + get_value=function( ...) { + widget$getModel()[get_index(), 1] + }, + set_value=function(value, ...) { + ind <- pmatch(value, get_items(drop=TRUE)) + if(!is.na(ind)) + set_index(ind) + else + message("No match for ", value) + }, + get_items = function(i, j, ..., drop=TRUE) { + store <- widget$getModel() + if(drop) + store[,1, drop=TRUE] + else + store[,] + }, + set_items = function(value, i, j, ...) { + "Set items. Indexing is ignored" + + items <- gWidgets2:::.make_gcombobox_items(value) + store <- rGtkDataFrame(items) + if(ncol(store) != ncol(widget$getModel())) + stop("Must keep same number of columns when replacing values") + widget$setModel(store) + set_index(0L) + }, + get_length = function(...) { + nrow(widget$getModel()) + } + )) + +## The editable code is *different* from the non-editable code, as the +## gtkComboBoxNewWithEntry method isn't there yet. Instead we need to use +## a convenience function and manipulate the values with that. +## This method is deprecated as of 2.24, but that isn't what I have installed +GComboBoxWithEntry <- setRefClass("GComboBoxWithEntry", + contains="GComboBox", + fields=list( + poss_items="ANY" + ), + methods=list( + initialize=function(toolkit=NULL, + items, + selected = 1, # use 0 for blank + coerce.with = NULL, + handler, action, container, ...) { + + poss_items <<- items[,1, drop=TRUE] + + widget <<- gtkComboBoxEntryNewText() + sapply(poss_items, gtkComboBoxAppendText, object=widget) + + widget$show() + widget$setActive(selected - 1L) + + ## set size if really small under windows + check_windows(items) + + initFields(block=widget, + coerce_with=coerce.with + ) + + add_to_parent(container, .self, ...) + + handler_id <<- add_handler_changed(handler, action) + + callSuper(toolkit) + }, + get_value=function( ...) { + widget$getChild()$getText() + }, + set_value=function(value, ...) { + widget$getChild()$setText(value) + }, + get_items = function(i, j, ..., drop=TRUE) { + poss_items + }, + set_items = function(value, i, j, ...) { + "Set items. Indexing is ignored" + ## remove, then append + sapply(rev(seq_len(get_length())), function(i) widget$removeText(i - 1L)) + items <- value[,1, drop=TRUE] + sapply(items, gtkComboBoxAppendText, object=widget) + poss_items <<- items + set_value("") + }, + get_length = function(...) { + widget$getModel()$iterNChildren(NULL) + }, + add_handler_edited = function(handler, action=NULL, ...) { + "For editing -- need a better name XXX" + gSignalConnect(widget$getChild(), "activate", f=function(h, ...) { + handler(h, ...) + }, data=list(obj=obj, action=action,...), + user.data.first = TRUE) + }, + add_handler_keystroke=function(handler, action=NULL, ...) { + gSignalConnect(widget$getChild(), "keystroke", keystroke_handler, + data=list(obj=obj, action=action,...), + user.data.first = TRUE) + } + + )) + + +## ##' exported Subclass for users to subclass +## ##' +## ##' @exportClasses GComboBoxRGtk2 +## GComboBoxRGtk2 <- setRefClass("GComboBoxRGtk2", +## contains="GComboBox") diff --git a/R/gedit.R b/R/gedit.R new file mode 100644 index 0000000..0d5656b --- /dev/null +++ b/R/gedit.R @@ -0,0 +1,181 @@ +##' @include GWidget.R +NULL + +##' Toolkit gedit constructor +##' +##' @export +##' @rdname gWidgets2RGtk2-undocumented +.gedit.guiWidgetsToolkitRGtk2 <- function(toolkit, + text = "", width = 25, coerce.with = NULL, initial.msg=initial.msg, + handler = NULL,action = NULL, container = NULL, ... ) { + GEdit$new( toolkit, text = "", width = 25, coerce.with = coerce.with, initial.msg=initial.msg, + handler = handler,action = action, container = container, ...) +} + + +##' Single line edit class +##' +##' We add a few methods beyond the spec: set_error, clear_error, validate_value, +GEdit <- setRefClass("GEdit", + contains="GWidget", + fields=list( + init_msg="character", + init_msg_flag="logical", + completion="ANY", + validator="ANY" + ), + methods=list( + initialize=function( toolkit=NULL, + text = "", width = 25, coerce.with = NULL, + initial.msg="", + handler = NULL, action = NULL, container = NULL, ...) { + + widget <<- gtkEntryNew() + initFields(block=widget, + coerce_with=coerce.with, + init_msg=initial.msg, + init_msg_flag=FALSE, + completion=NULL, + validator=NULL) + + ## init msg + if(nchar(init_msg) > 0) { + id <- gSignalConnect(widget, "focus-in-event", function(...) { + clear_init_txt() + }) + gSignalConnect(widget, "focus-out-event", function(...) { + if(nchar(widget$getText()) == 0) { + set_init_txt() + } + }) + } + ## overwrite? + if(nchar(text) > 0) + set_value(text) + + add_to_parent(container, .self, ...) + + + handler_id <<- add_handler_changed(handler, action) + + callSuper(toolkit) + }, + set_value=function(value, index=TRUE, drop=TRUE, ...) { + clear_init_txt() + widget$setText(value) + widget$activate() # emit signal + }, + get_value=function(index=TRUE, drop=TRUE, ...) { + if(!init_msg_flag) + widget$getText() + else + "" + }, + set_init_txt=function() { + "set initial text, gray out" + widget$modifyText(GtkStateType[1], "gray") + widget$setText(init_msg) + init_msg_flag <<- TRUE + }, + clear_init_txt=function() { + "clear out init text, set back to black" + widget$modifyText(GtkStateType[1], NULL) # should restore setting + if(init_msg_flag) + widget$setText("") + init_msg_flag <<- FALSE + }, + get_items=function(i, j, ..., drop=TRUE) { + "i for index" + if(is.null(completion)) + return(character(0)) + + store <- completion$GetModel() + nrows <- dim(store)[1] + store[i , ] + }, + set_items=function(i, j, ..., value) { + if(is.null(completion)) { + completion <<- gtkEntryCompletionNew() + model <- rGtkDataFrame(data.frame(character(1000),stringsAsFactors=FALSE)) + completion$SetModel(model) + completion$SetTextColumn(0) # Columns count from 0 -- not 1 + + ## set properties + completion$setInlineCompletion(TRUE) + completion$setInlineSelection(TRUE) + + widget$SetCompletion(completion) + } + + store <- widget$GetCompletion()$GetModel() + nrows <- dim(store)[1] + n <- length(value) + if(n > nrows) + values <- values[1:nrows] # truncate + if(missing(i)) + i <- 1:n + store[i , ] <- value + }, + get_visible = function() { + widget$getVisibility() + }, + + set_visible = function(value) { + widget$setInvisibleChar(42L) # asterisk + widget$setVisibility(as.logical(value)) + }, + + get_editable=function() { + "Can we actually edit widget?" + widget$getEditable() + }, + set_editable = function(value) { + widget$setEditable(as.logical(value)) + }, + ## Handler: changed -> clicked + add_handler_changed = function(handler, action=NULL, ...) { + if(missing(handler) || is.null(handler)) + return() + f <- function(h, widget, event, ...) { + keyval <- event$GetKeyval() + if(keyval == GDK_Return) { + handler(h, widget, event, ...) + return(TRUE) + } else { + return(FALSE) + } + } + add_handler("activate", f, action=action, ...) + }, + + + ## Extra methods + set_validator = function(FUN) { + "Set a function to do the validation" + validator <<- FUN + }, + validate_input = function() { + "Return logical indicating if input is valid" + if(is.null(validator)) + TRUE + else + validator(get_value()) + }, + set_error = function(msg) { + "Add error state and message to widget" + widget$setIconFromStock("primary", "gtk-no") + if(!missing(msg)) + widget$setIconTooltipText("primary", "asdfasf") + }, + clear_error = function() { + "Clear error message" + widget$setIconFromStock("primary", NULL) + widget$setIconTooltipText("primary", NULL) + } + )) + +## ##' exported Subclass for users to subclass +## ##' +## ##' @exportClasses GEditRGtk2 +## GEditRGtk2 <- setRefClass("GEditRGtk2", +## contains="GEdit") diff --git a/R/gexpandgroup.R b/R/gexpandgroup.R new file mode 100644 index 0000000..99dbe03 --- /dev/null +++ b/R/gexpandgroup.R @@ -0,0 +1,65 @@ +##' @include gframe.R +NULL + +##' toolkit constructor +##' +##' @export +##' @rdname gWidgets2RGtk2-undocumented +.gexpandgroup.guiWidgetsToolkitRGtk2 <- function(toolkit, + text, markup, horizontal=TRUE, + handler=NULL, action=NULL, + container=NULL, ...) { + GExpandGroup$new(toolkit, text=text, markup=markup, horizontal=horizontal, handler=handler, action=action, container=container, ...) +} + +##' base class for gframe +GExpandGroup <- setRefClass("GExpandGroup", + contains="GFrame", + methods=list( + initialize=function(toolkit=NULL, text, markup=FALSE, horizontal=TRUE, handler, action, container=NULL, ...) { + + horizontal <<- horizontal + if(is(widget, "uninitializedField")) + make_widget(text, markup) + + handler_id <<- add_handler_changed(handler, action) + add_to_parent(container, .self, ...) + + callSuper(toolkit, horizontal=horizontal, ...) + }, + make_widget = function(text, markup) { + if(horizontal) + widget <<- gtkHBox() + else + widget <<- gtkVBox() + + markup <<- markup + block <<- gtkExpanderNew() + if(markup) + block$setUseMarkup(TRUE) + block$add(widget) + + set_names(text) + }, + get_names=function(...) { + block$getLabel() + }, + set_names=function(value, ...) { + block$setLabel(value) + }, + get_visible = function() { + block$getExpanded() + }, + set_visible = function(value) { + block$setExpanded(as.logical(value)) + }, + add_handler_changed=function(handler, action, ...) { + add_handler("activate", handler, action, ...) + } + )) + +## ##' exported Subclass for users to subclass +## ##' +## ##' @exportClasses GExpandGroupRGtk2 +## GExpandGroupRGtk2 <- setRefClass("GExpandGroupRGtk2", +## contains="GExpandGroup") diff --git a/R/gframe.R b/R/gframe.R new file mode 100644 index 0000000..8bb0677 --- /dev/null +++ b/R/gframe.R @@ -0,0 +1,57 @@ +##' @include ggroup.R +NULL + +##' gframe constructor +##' +##' @export +##' @rdname gWidgets2RGtk2-undocumented +.gframe.guiWidgetsToolkitRGtk2 <- function(toolkit, text, markup, pos, horizontal=TRUE, container=NULL, ...) { + GFrame$new(toolkit, text, markup, pos, horizontal, container, ...) +} + +## base class for gframe +GFrame <- setRefClass("GFrame", + contains="GGroup", + fields=list( + markup="logical" + ), + methods=list( + initialize=function(toolkit=NULL, text="", markup=FALSE, pos=3, horizontal=TRUE, container=NULL, ...) { + + horizontal <<- horizontal + + if(is(widget, "uninitializedField")) + make_widget(text, markup, pos) + + add_to_parent(container, .self, ...) + + callSuper(toolkit, horizontal=horizontal, ...) + }, + make_widget = function(text, markup, pos) { + if(horizontal) + widget <<- gtkHBox() + else + widget <<- gtkVBox() + + markup <<- markup + block <<- gtkFrameNew() + block$add(widget) + + block$SetLabelAlign(pos,0.5) + label <- gtkLabelNew() + block$setLabelWidget(label) + set_names(text) + }, + get_names=function(...) { + label <- block$getLabelWidget() + label$getLabel() + }, + set_names=function(value, ...) { + label <- block$getLabelWidget() + if(markup) + label$setMarkup(value) + else + label$setLabel(value) + } + )) + diff --git a/R/ggroup.R b/R/ggroup.R new file mode 100644 index 0000000..aba402b --- /dev/null +++ b/R/ggroup.R @@ -0,0 +1,169 @@ +##' @include GContainer.R +NULL + +##' toolkit constructor for ggroup +##' +##' @export +##' @rdname gWidgetsRGtk2-undocumented +.ggroup.guiWidgetsToolkitRGtk2 <- function(toolkit, horizontal=TRUE, spacing=5, use.scrollwindow=FALSE, container=NULL, ...) { + GGroup$new(toolkit, horizontal, spacing=spacing, use.scrollwindow=use.scrollwindow, container, ...) +} + +## TODO XXX raise on drag motion + +##' base class for box containers. +GGroup <- setRefClass("GGroup", + contains="GContainer", + + + fields=list( + horizontal="logical" + ), + methods=list( + + ## main intialize method + initialize=function(toolkit=NULL, + horizontal=TRUE, spacing=5, + use.scrollwindow=FALSE, + container=NULL, ...) { + + horizontal <<- horizontal + ## To be able to subclass we define widget in separate method + if(is(widget, "uninitializedField")) + make_widget(use.scrollwindow, spacing) + + add_to_parent(container, .self, ...) + + callSuper(toolkit) + }, + + ## Make a widget, for subclassing + make_widget = function(use.scrollwindow, spacing) { + if(horizontal) + widget <<- gtkHBox(homogeneous=FALSE, spacing=spacing) + else + widget <<- gtkVBox(homogeneous=FALSE, spacing=spacing) + widget$SetBorderWidth(0L) + + if(use.scrollwindow) { + block <<- gtkScrolledWindowNew() + block$SetPolicy("GTK_POLICY_AUTOMATIC","GTK_POLICY_AUTOMATIC") + block$AddWithViewport(widget) + } else { + block <<- widget + } + }, + + + ## Main add method + add_child = function(child, expand, fill, anchor, ...) { + "Add child to box container. Child can be RGtk2object or GComponent. We use expand=TRUE, fill=TRUE as a default for containers, and expand=FALSE, fill=FALSE, as the default for widgets. These will usually need tweeking" + toolkit_child <- getBlock(child) + + theArgs <- list(...) ## padding (around each) + + ## get expand, anchor, fill + expand <- getWithDefault(expand, ifelse(is(child, "GContainer"), TRUE, FALSE)) + fill <- getWithDefault(fill, ifelse(is(child, "GContainer"), TRUE, FALSE)) + if(!is.null(theArgs$align)) + theArgs$anchor <- theArgs$align + anchor <- getWithDefault(anchor, NULL) + + + if(!is.null(anchor)) { # put in [0,1]^2 + anchor <- (anchor+1)/2 # [0,1] + anchor[2] <- 1 - anchor[2] # flip yalign + } + + ## need to map values of expand, fill, anchor into values for + ## expand, fill and alignment, + ## We do things differently if there is a gtkAlignment for a block + if(is(toolkit_child, "GtkAlignment")) { + if(expand && (fill =="both" || fill == "x")) { + toolkit_child['xscale'] <- 1 + } + if(expand && (fill == "both" || fill == "y")) { + toolkit_child['yscale'] <- 1 + } + + if(expand && fill == "") { + toolkit_child['xscale'] <- toolkit_child['yscale'] <- 1 + } + + + if(!is.null(anchor)) { + toolkit_child['xalign'] <- anchor[1] + toolkit_child['yalign'] <- anchor[2] + } + fill <- TRUE + padding <- 0 + } else { + ## anchor argument + if(!is.null(anchor)) + setXYalign(toolkit_child, getWidget(child), anchor) + + ## padding + padding <- getWithDefault(theArgs$padding, 0L) + + if(!is.null(fill)) { + if(fill == "both") { + fill <- TRUE + } else { + if(fill == "x" && horizontal) + fill <- TRUE + else if(fill == "y" && !horizontal) + fill <- TRUE + } + } + } + ## all done + widget$packStart(toolkit_child, expand=expand, fill=fill, padding=padding) + + ## Internal bookkeeping, add to lists + if(is(child, "GComponent")) + child$set_parent(.self) + children <<- c(children, child) + }, + + + ## Remove a child from list. Can be added back in, if not garbage collected + remove_child = function(child) { + "remove child from box container" + children <<- Filter(function(x) !identical(x, child), children) + child$set_parent(NULL) + widget$remove(getBlock(child)) + }, + + ## [ for returning children + get_items = function(i, j, ..., drop=TRUE) { + "Return children" + out <- children[i] + if(drop && length(out) == 1) + out[[1]] + else + out + }, + + ## svalue (borderwidth, spacing -- which is it...) + get_value=function() { + widget$getBorderWidth() + }, + set_value=function(value) { + widget$setBorderWidth(as.numeric(value)[1]) + }, + + ## size + get_size=function() { + getBlock(widget)$sizeRequest() + }, + set_size=function(value) { + tmp <- getBlock(widget) # size of block, if scrolled window + value <- as.integer(value) + tmp$setSizeRequest(value[1], value[2]) + } + + + + )) + + diff --git a/R/glabel.R b/R/glabel.R new file mode 100644 index 0000000..7437d6d --- /dev/null +++ b/R/glabel.R @@ -0,0 +1,116 @@ +##' @include GWidget.R +NULL + +##' Toolkit label constructor +##' +##' @export +##' @rdname gWidgets2RGtk2-undocumented +.glabel.guiWidgetsToolkitRGtk2 <- function(toolkit, text="", markup=FALSE, editable=FALSE, + handler=NULL, action=NULL, container=NULL, + ...) { + Glabel$new(toolkit, text, markup, editable, handler, action, container, ...) +} + +##' label class +Glabel <- setRefClass("Glabel", + contains="GWidget", + fields=list( + markup="ANY", + editable="logical", + edit_widget = "ANY", + state="character" + ), + methods=list( + + + initialize=function(toolkit=NULL, text, markup=FALSE, editable=FALSE, handler, action, container, ...) { + + widget <<- gtkLabel() + widget$setSelectable(TRUE) + if(markup) + widget$setUseMarkup(TRUE) + + ## we put in an event box to catch events for the handler and editable stuff. + ## Likely that should just be done away with, but here it is. + block <<- gtkEventBoxNew() + block$SetVisibleWindow(FALSE) + block$add(widget) + + initFields( + markup=markup, + editable=editable + ) + add_to_parent(container, .self, ...) + + set_value(text) + + if(editable) { + ## Set up widget to toggle between + state <<- "label" + widget$setSelectable(FALSE) + edit_widget <<- gtkEntryNew() + gSignalConnect(edit_widget, "activate", function(e) { + show_label_widget() + }) + ## event box handler + handler <- function(h, ...) { + if(state == "label") { + show_edit_widget() + } else { + show_label_widget() + } + } + } + + handler_id <<- add_handler_changed(handler, action) + + callSuper(toolkit) + }, + + + ## set the value + set_value=function(value, index=TRUE, drop=TRUE, ...) { + value <- paste(value, collapse="\n") + if(markup) + widget$setMarkup(value) + else + widget$setLabel(value) + }, + ## tricky part is for markup + get_value=function(index=TRUE, drop=TRUE, ...) { + value <- widget$getLabel() + if(markup) + value <- gsub("<[^>]*>","",value) + value + }, + + ## methods for editing + show_edit_widget = function() { + edit_widget$setText(get_value()) + block$remove(widget) + block$add(edit_widget) + state <<- "edit" + }, + show_label_widget = function() { + set_value(edit_widget$getText()) + block$remove(edit_widget) + block$add(widget) + state <<- "label" + }, + ## Handler + handler_widget = function() block, # put on block,not widget + add_handler_changed=function(handler, action=NULL, ...) { + add_handler_clicked(handler, action=action, ...) + }, + add_handler_clicked=function(handler, action=NULL, ...) { + add_event_handler("button-press-event", handler, action, ...) + }, + + + ## secret methods + set_angle = function(angle) { + "Rotate text by angle degrees ccw" + widget$setAngle(as.integer(angle)[1]) + } + )) + diff --git a/R/glayout.R b/R/glayout.R new file mode 100644 index 0000000..8560301 --- /dev/null +++ b/R/glayout.R @@ -0,0 +1,127 @@ +##' @include GContainer.R +NULL + +##' Toolkit constructor +##' +##' @export +##' @rdname gWidgets2RGtk2-undocumented +.glayout.guiWidgetsToolkitRGtk2 <- function(toolkit, + homogeneous = FALSE, spacing = 10, + container = NULL, ... ) { + GLayout$new(toolkit=toolkit, homogeneous=homogeneous, spacing=spacing, container = container, ...) +} + + +## layout class +GLayout <- setRefClass("GLayout", + contains="GContainer", + fields=list( + child_positions="list" + ), + methods=list( + initialize=function(toolkit=NULL, + homogeneous = FALSE, spacing = 10, + container = NULL, ... + ) { + + widget <<- gtkTableNew(homogeneous = homogeneous) + ## homogeneous spacing + widget$SetRowSpacings(spacing) + widget$SetColSpacings(spacing) + + initFields(block=widget, + child_positions=list() + ) + + add_to_parent(container, .self, ...) + + callSuper(toolkit) + }, + get_dim=function(...) { + "current size of table" + c(nrow=widget$getNrows(), ncol=widget$getNcols()) + }, + get_items = function(i, j, ..., drop=TRUE) { + ind <- sapply(child_positions, function(comp) { + i[1] %in% comp$x && j[1] %in% comp$y + }) + if(any(ind)) + return(child_positions[ind][[1]]$child) # first + else + NA + }, + set_items = function(value, i, j, expand=FALSE, fill=FALSE, anchor=NULL) { + "Main method to add children" + + if(missing(j)) { + cat(gettext("glayout: [ needs to have a column specified.")) + return() + } + + if(missing(i)) + i <- get_dim()[1] + 1 + + if(is.character(value)) { + value <- glabel(value, toolkit=toolkit) + } + + ## widgets + child <- getBlock(value) + + + if(!is.null(anchor)) { # put in [0,1]^2 + anchor <- (anchor+1)/2 # [0,1] + anchor[2] <- 1 - anchor[2] # flip yalign + } + + + ## we do things differently if there is a gtkAlignment for a block + if(is(child, "GtkAlignment")) { + if(expand && (fill =="both" || fill == "x")) { + child['xscale'] <- 1 + } + + if(expand && (fill == "both" || fill == "y")) { + child['yscale'] <- 1 + } + + if(expand && fill == "") { + child['xscale'] <- child['yscale'] <- 1 + } + + if(!is.null(anchor)) { + child['xalign'] <- anchor[1] + child['yalign'] <- anchor[2] + } + } else { + ## in gtkstuff + setXYalign(child, getBlock(value), anchor) + } + + ## resize table widget if needed + d <- get_dim() + nr <- max(i); nc <- max(j) + if( nr > d[1] || nc > d[2]) + widget$Resize(max(max(i), nr), max(max(j), nc)) + + if(expand) + opts <- c("fill","expand","shrink") + else + opts <- c("fill") + + widget$Attach(child, + min(j)-1, max(j), min(i)-1, max(i), + xoptions=opts, yoptions=opts) + + + ## Internal bookkeeping, add to lists + if(is(value, "GComponent")) + value$set_parent(.self) + children <<- c(children, value) + ## store for [ method + l <- child_positions + l[[as.character(length(l) + 1)]] <- list(x=i, y=j, child=value) + child_positions <<- l + } + )) + diff --git a/R/gnotebook.R b/R/gnotebook.R new file mode 100644 index 0000000..e0b844e --- /dev/null +++ b/R/gnotebook.R @@ -0,0 +1,132 @@ +##' @include GContainer.R +NULL + +##' Toolkit constructor +##' +##' @export +##' @rdname gWidgets2RGtk2-undocumented +.gnotebook.guiWidgetsToolkitRGtk2 <- function(toolkit, + tab.pos = 3, + container = NULL, ... ) { + GNotebook$new(toolkit, tab.pos, + container = container, ...) +} + + + +GNotebook <- setRefClass("GNotebook", + contains="GContainer", + methods=list( + initialize=function(toolkit=NULL, tab.pos=3, + container=NULL, ...) { + + ## To be able to subclass we define widget in separate method + if(is(widget, "uninitializedField")) + make_widget(tab.pos) + + add_to_parent(container, .self, ...) + + callSuper(toolkit) + }, + make_widget = function(tab.pos) { + widget <<- gtkNotebookNew() + widget$SetScrollable(TRUE) + + + ## tab placement: 1,2,3,4 -> 3,0,2,1 + types <- c("bottom","left","top","right") + tabposition <- GtkPositionType[types] + widget$SetTabPos(tabposition[tab.pos]) + + + initFields(block=widget) + }, + get_value=function( ...) { + widget$getCurrentPage() + 1L + }, + set_value=function(value, ...) { + nPages <- widget$GetNPages() + widget$SetCurrentPage(min(nPages,as.numeric(value)-1)) + }, + get_index = function(...) { + get_value() + }, + set_index = function(value,...) { + set_value(value) + }, + get_names = function(...) { + n <- widget$getNPages() + if(n == 0) + return(character(0)) + sapply(seq_len(n), function(i) { + label <- widget$getTabLabel(getBlock(get_items(i, drop=TRUE))) + label[[1]]$getText() + }) + }, + set_names = function(value, ...) { + n <- widget$getNPages() + sapply(seq_len(n), function(i) { + label <- widget$getTabLabel(getBlock(get_items(i, drop=TRUE))) + label[[1]]$setText(value[i]) + }) + invisible() + }, + get_items = function(i, j, ..., drop=TRUE) { + "Return child at ith spot" + items <- children[i] + if(drop && length(items) == 1) + items[[1]] + else + items + }, + get_length = function(...) { + "Nmber of pages" + widget$GetNPages() + }, + ## + make_label = function(child, label, close.button=FALSE, ...) { + ## make a label widget, possibly with close buttons, ... + hbox <- gtkHBox() + l <- gtkLabel(label) + hbox$packStart(l, expand=TRUE, fill=TRUE) + if(!is.null(close.button) && close.button) { + evb <- gtkEventBox() + evb$setVisibleWindow(FALSE) + hbox$packEnd(evb) + img <- gtkImageNew() + img$setFromStock("gtk-close", size=GtkIconSize['small-toolbar']) + evb$add(img) + gSignalConnect(evb, "button-press-event", f=function(data, ...) { + data$widget$remove_child(data$child) + }, data=list(widget=.self, child=child), user.data.first=TRUE) + } + hbox + }, + add_child=function(child, label="", index=NULL, close.button=FALSE, ...) { + label_widget <- make_label(child, label, close.button, ...) ## XXX + + if(is.null(index)) + page_no <- widget$appendPage(getBlock(child), label_widget) + else if(index < 1) + page_no <- widget$prependPage(getBlock(child), label_widget) + else + page_no <- widget$insertPage(getBlock(child), label_widget, position=index-1L) + set_value(page_no + 1) + + ## Internal bookkeeping, add to lists + if(is(child, "GComponent")) + child$set_parent(.self) + children <<- c(children, child) + }, + remove_child = function(child) { + ## remove from children + children <<- Filter(function(i) !identical(i, child), children) + ## remove from widget + widget$remove(getBlock(child)) + }, + remove_current_page = function() { + child <- get_items(get_index()) + remove_child(child) + } + )) + diff --git a/R/gpanedgroup.R b/R/gpanedgroup.R new file mode 100644 index 0000000..e092345 --- /dev/null +++ b/R/gpanedgroup.R @@ -0,0 +1,90 @@ +##' @include GContainer.R +NULL + +##' Toolkit constructor +##' +##' @export +##' @rdname gWidgets2RGtk2-undocumented +.gpanedgroup.guiWidgetsToolkitRGtk2 <- function(toolkit, + horizontal = TRUE, + container = NULL, ... ) { + GPanedGroup$new(toolkit, + horizontal=horizontal, + container = container, ...) +} + + +## main class +GPanedGroup <- setRefClass("GPanedGroup", + contains="GContainer", + fields=list( + horizontal="logical" + ), + methods=list( + initialize=function(toolkit=NULL, + horizontal=TRUE, + container=NULL, ...) { + if(horizontal) + widget <<- gtkHPanedNew() + else + widget <<- gtkVPanedNew() + + + initFields(block=widget, + horizontal=horizontal + ) + add_to_parent(container, .self, ...) + callSuper(toolkit) + }, + get_value = function(...) { + "get sash position" + pos <- widget$getPosition() + sz <- get_size() + + if(horizontal) + pos/sz[1] + else + pos/sz[2] + }, + set_value = function(value, ...) { + "Set sash position" + sz <- get_size() + + if(horizontal) + pos <- as.integer(value*sz[1]) + else + pos <- as.integer(value*sz[2]) + widget$setPosition(pos) + }, + get_items = function(i, j, ..., drop=TRUE) { + children[[i, drop=drop]] + }, + get_length = function() { + length(children) + }, + add_child=function(child, expand=NULL, fill=NULL, anchor=NULL) { + "Add one of two possible children" + n <- get_length() + if(n >= 2) { + message("Already have two children. Remove one?") + return() + } + + if(n == 0) { + widget$pack1(getBlock(child)) + } else if(n == 1) { + widget$pack2(getBlock(child)) + } + ## Internal bookkeeping, add to lists + if(is(child, "GComponent")) + child$set_parent(.self) + children <<- c(children, child) + }, + remove_child=function(child) { + "remove child from paned container" + children <<- Filter(function(x) !identical(x, child), children) + child$set_parent(NULL) + widget$remove(getBlock(child)) + } + )) + diff --git a/R/gradio.R b/R/gradio.R new file mode 100644 index 0000000..5771080 --- /dev/null +++ b/R/gradio.R @@ -0,0 +1,76 @@ +##' @include GWidget.R +NULL + +##' Toolkit constructor +##' +##' @export +##' @rdname gWidgets2RGtk2-undocumented +.gradio.guiWidgetsToolkitRGtk2 <- function(toolkit, + items,selected=1, horizontal=FALSE, handler=NULL, + action=NULL, container=NULL, ... + ) { + + GRadio$new(toolkit, items, selected, horizontal, + handler, action, container, ...) +} + + +##' readio button class +GRadio <- setRefClass("GRadio", + contains="GWidgetWithItems", + methods=list( + initialize=function(toolkit, items, selected, horizontal, + handler, action, container, ...) { + widget <<- NULL + widgets <<- list() + if(horizontal) + block <<- gtkHBox() + else + block <<- gtkVBox() + + set_items(value=items) + + add_to_parent(container, .self, ...) + + handler_id <<- add_handler_changed(handler, action) + + callSuper(toolkit) + }, + get_value=function(drop=TRUE, ...) { + get_items(get_index()) + }, + set_value=function(value, drop=TRUE, ...) { + set_index(pmatch(value, get_items())) + }, + get_index = function(...) { + which(sapply(widgets, gtkToggleButtonGetActive)) + }, + set_index = function(value, ...) { + widgets[[value[1]]]$setActive(TRUE) + }, + get_items = function(i, ...) { + items <- sapply(widgets, gtkButtonGetLabel) + items[i] + }, + set_items = function(value, i, ...) { + ## make widgets + radiogp <- gtkRadioButton(label=value[1]) + sapply(value[-1], gtkRadioButtonNewWithLabelFromWidget, + group = radiogp) + widgets <<- rev(radiogp$getGroup()) + ## pack in widgets + sapply(block$getChildren(), gtkContainerRemove, object=block) # remove old + sapply(widgets, gtkBoxPackStart, object=block, padding=2) + + ## add handler to each button to call back to observers + sapply(widgets, gSignalConnect, signal="toggled", f = function(self, w, ...) { + if(w$getActive()) + self$notify_observers(signal="toggled", ...) + }, data=.self, user.data.first=TRUE) + invisible() + }, + add_handler_changed=function(handler, action=NULL, ...) { + add_handler("toggled", handler, action=action, ...) + } + )) + diff --git a/R/gseparator.R b/R/gseparator.R new file mode 100644 index 0000000..f4a2c73 --- /dev/null +++ b/R/gseparator.R @@ -0,0 +1,33 @@ +##' @include GWidget.R +NULL + +##' Toolkit constructor +##' +##' @export +##' @rdname gWidgets2RGtk2-undocumented +.gseparator.guiWidgetsToolkitRGtk2 <- function(toolkit, + horizontal = TRUE, + container = NULL, ... ) { + GSeparator$new(toolkit, horizontal=horizontal, container = container, ...) +} + + +GSeparator <- setRefClass("GSeparator", + contains="GWidget", + methods=list( + initialize=function(toolkit, + horizontal=TRUE, container=NULL, + ...) { + + if(horizontal) + widget <<- gtkHSeparatorNew() + else + widget <<- gtkVSeparatorNew() + + initFields(block=widget) + add_to_parent(container, .self, ...) + + callSuper(toolkit) + } + )) + diff --git a/R/gslider.R b/R/gslider.R new file mode 100644 index 0000000..e3111af --- /dev/null +++ b/R/gslider.R @@ -0,0 +1,82 @@ +##' @include GWidget.R +NULL + +##' Toolkit constructor +##' +##' @export +##' @rdname gWidgets2RGtk2-undocumented +.gslider.guiWidgetsToolkitRGtk2 <- function(toolkit, + from = 0, to = 100, by = 1, value = from, horizontal = TRUE, + handler = NULL, action = NULL, container = NULL, ... ) { + GSlider$new(toolkit, + from, to, by, value, horizontal, + handler,action, container, ...) +} + + +## glider class +GSlider <- setRefClass("GSlider", + contains="GWidget", + fields=list( + items = "ANY" + ), + methods=list( + initialize=function(toolkit, + from, to, by, value, horizontal, + handler, action, container, ...) { + if(length(from) == 1) + x <- seq(from, to, by) + else + x <- from + x <- sort(unique(x)) + items <<- x + + if (horizontal) + widget <<- gtkHScaleNewWithRange(1L, length(items), 1L) + else + widget <<- gtkVScaleNewWithRange(1L, length(items), 1L) + + gSignalConnect(widget, "format-value", function(widget, value, ...) { + ## value is index + format(items[as.integer(value)], digits=3) + }) + set_value(value[1]) + + initFields(block=widget) + + add_to_parent(container, .self, ...) + + handler_id <<- add_handler_changed(handler, action) + + callSuper(toolkit) + }, + get_value=function(drop=TRUE, ...) { + items[get_index()] + }, + set_value=function(value, drop=TRUE, ...) { + i <- pmatch(value, items) + set_index(i) + }, + get_index = function(...) { + widget$getValue() + }, + set_index = function(value,...) { + if(!is_empty(value)) + widget$setValue(value) # widget uses index 1, ..., n + }, + get_items = function(i, ...) { + items + }, + set_items = function(value, i, ...) { + cur <- get_value() + items <<- sort(unique(value)) + widget$setRange(1, length(value)) + widget$setIncrements(1L, 1L) # button 1, button 2 + + set_value(cur) + }, + add_handler_changed=function(handler, action=NULL, ...) { + add_handler("value-changed", handler, action=action, ...) + } + )) + diff --git a/R/gspinbutton.R b/R/gspinbutton.R new file mode 100644 index 0000000..9fea433 --- /dev/null +++ b/R/gspinbutton.R @@ -0,0 +1,69 @@ +##' @include GWidget.R +NULL + +##' Toolkit XXX constructor +##' +##' @export +##' @rdname gWidgets2RGtk2-undocumented +.gspinbutton.guiWidgetsToolkitRGtk2 <- function(toolkit, + from = 0, to = 10, by = 1, value = from, digits = 0, + handler = NULL,action = NULL, container = NULL, ... ) { + GSpinbutton$new( toolkit, from , to , by, value, digits, + handler = handler, action = action, container = container, ...) +} + + +## spingbutton class +GSpinbutton <- setRefClass("GSpinbutton", + contains="GWidget", + methods=list( + initialize=function(toolkit, + from = 0, to = 10, by = 1, value = from, digits = 0, + handler, action, container, ...) { + + if(digits == 0 && as.logical((by %% 1))) # FALSE if integer o/w T + digits <- abs(floor(log(by,10))) + + adjustment <- gtkAdjustmentNew(value=value, lower=from, + upper=to,step.incr=by) + widget <<- gtkSpinButtonNew(adjustment, (to-from)/by, digits=digits) + set_value(value) + + initFields(block=widget) + + add_to_parent(container, .self, ...) + + handler_id <<- add_handler_changed(handler, action) + + callSuper(toolkit) + }, + get_value=function(drop=TRUE, ...) { + widget$getValue() + }, + set_value=function(value, drop=TRUE, ...) { + widget$setValue(value) + }, + set_items = function(value, i, ...) { + ## check that value is a regular sequence + if(length(value) <=1) { + message("Can only assign a vector with equal steps, as produced by seq, say") + return() + } + if(length(value) > 2 && + !all.equal(diff(diff(value)), rep(0, length(value) - 2))) { + message("Can only assign a vector with equal steps, as produced by seq, say") + return() + } + ## get current value, increment + cur <- get_value() + inc <- head(diff(value), n=1) + + widget$setRange(min(value), max(value)) + widget$setIncrements(inc, inc) # button 1, button 2 + set_value(cur) + }, + add_handler_changed=function(handler, action=NULL, ...) { + add_handler("value-changed", handler, action=action, ...) + } + )) + diff --git a/R/gstackwidget.R b/R/gstackwidget.R new file mode 100644 index 0000000..c0f0482 --- /dev/null +++ b/R/gstackwidget.R @@ -0,0 +1,54 @@ +##' @include GContainer.R +NULL + +##' Toolkit constructor +##' +##' @export +##' @rdname gWidgets2RGtk2-undocumented +.gstackwidget.guiWidgetsToolkitRGtk2 <- function(toolkit, + container = NULL, ... ) { + GStackWidget$new(toolkit, + container = container, ...) +} + + + +GStackWidget <- setRefClass("GStackWidget", + contains="GNotebook", + methods=list( + initialize=function(toolkit=NULL, + container=NULL, ...) { + + ## To be able to subclass we define widget in separate method + if(is(widget, "uninitializedField")) + make_widget() + + add_to_parent(container, .self, ...) + + callSuper(toolkit, container=container) + }, + make_widget = function() { + widget <<- gtkNotebookNew() + widget$setShowTabs(FALSE) + initFields(block=widget) + }, + get_names=function(...) {}, + set_names=function(...) {}, + add_child=function(child, index=NULL, ...) { + "Similar to GNotebook's, but without label and close button code" + + if(is.null(index)) + page_no <- widget$appendPage(getBlock(child)) + else if(index < 1) + page_no <- widget$prependPage(getBlock(child)) + else + page_no <- widget$insertPage(getBlock(child), position=index-1L) + set_value(page_no + 1L) + + ## Internal bookkeeping, add to lists + if(is(child, "GComponent")) + child$set_parent(.self) + children <<- c(children, child) + } + )) + diff --git a/R/gtext.R b/R/gtext.R new file mode 100644 index 0000000..0916029 --- /dev/null +++ b/R/gtext.R @@ -0,0 +1,200 @@ +##' @include GWidget.R +NULL + + +## font sizes +fontSizes <- c( + "xx-large"= PANGO_SCALE_XX_LARGE, + "x-large" = PANGO_SCALE_X_LARGE, + "large" = PANGO_SCALE_LARGE, + "medium" = PANGO_SCALE_MEDIUM, + "small" = PANGO_SCALE_SMALL, + "x-small" = PANGO_SCALE_X_SMALL, + "xx-small" = PANGO_SCALE_XX_SMALL + ) + +## Make a tag table to be shared. We use memoise as we only need to make this once. +make_tag_table <- memoise(function() { + ## font colors + fontColors <- sapply(colors(), identity) + + ## list of fonts + font_list <- list(weight=PangoWeight, + style=PangoStyle, + family=sapply(c("sans", "helvetica", "times", "monospace"), identity), + scale=fontSizes, # not size! + foreground=fontColors, + background=fontColors) + + ## global tag table + tag_table <- gtkTextTagTableNew() + ## populate tag table from above + for(nm in names(font_list)) { + for(i in names(font_list[[nm]])) { + tt <- gtkTextTagNew(sprintf("%s-%s", nm, i)) # family-Monospace, say + tt[nm] <- font_list[[nm]][i] + tag_table$add(tt) + } + } + + tag_table +}) + +##' toolkit implementation +##' +##' @export +##' @rdname gWidgets2RGtk2-undocumented +.gtext.guiWidgetsToolkitRGtk2 <- function(toolkit, + text = NULL, width = NULL, height = 300, font.attr = NULL, + wrap = TRUE, + handler = NULL, action = NULL, container = NULL,... ) { + + GText$new(toolkit, + text = text, width = width, height = height, + font.attr = font.attr, wrap = wrap, + handler = handler, action = action, container = container, ... + ) + +} + + +GText <- setRefClass("GText", + contains="GWidget", + fields=list( + buffer="ANY" + ), + methods=list( + initialize=function(toolkit=NULL, + text = NULL, width = NULL, height = 300, + font.attr = NULL, wrap = TRUE, + handler=NULL, action=NULL, container=NULL, ...) { + + buffer <<- gtkTextBufferNew(make_tag_table()) + widget <<- gtkTextViewNewWithBuffer(buffer) + widget$SetLeftMargin(10) + widget$SetRightMargin(10) + if(wrap) + widget$SetWrapMode(GtkWrapMode['word']) + else + widget$SetWrapMode(GtkWrapMode['none']) + + block <<- gtkScrolledWindowNew() + block$SetPolicy("GTK_POLICY_AUTOMATIC","GTK_POLICY_AUTOMATIC") + if(!is.null(width)) + sw$SetSizeRequest(width,height) + + block$add(widget) + widget$show() + + set_font(font.attr) # buffer font + insert_text(text, where="beginning", font.attr=NULL, do.newline=FALSE) + + add_to_parent(container, .self, ...) + + handler_id <<- add_handler_changed(handler, action) + + callSuper(toolkit) + }, + get_value=function(drop=FALSE, ...) { + "Return text, or selected text if drop=TRUE" + if(is.null(drop) || drop == FALSE) { + start <- buffer$GetStartIter()$iter + end <- buffer$GetEndIter()$iter + } else { + ## return only **selected** text + ## if drop==TRUE + bounds <- buffer$GetSelectionBounds() + if(bounds$retval == FALSE) + return("") # no selectin + start <- bounds$start + end <- bounds$end + } + buffer$GetText(start, end) # has embedded "\n" + }, + set_value=function(value, ...) { + "Replace all text, pasted together with newline" + value <- paste(value, collapse="\n") + buffer$setText(value) + }, + get_index = function(...) { + stop("Not defined") + }, + set_index = function(value,...) { + stop("Not defined") + }, + get_items = function(i, j, ..., drop=TRUE) { + stop("Not defined") + }, + set_items = function(value, i, j, ...) { + stop("Not defined") + }, + set_font = function(font.attr) { + "Set font for selection or entire buffer if no selection" + + font.attr <- sapply(font.attr, identity, simplify=FALSE) + if(length(font.attr) == 0) + return() + + tag_table <- buffer$getTagTable() + bounds <- buffer$GetSelectionBounds() + + if(bounds$retval == FALSE) { + ## if no text selected, we set for entire buffer + ## change entire buffer -- new as of 0.64 + start <- buffer$GetStartIter()$iter + end <- buffer$GetEndIter()$iter + buffer$removeAllTags(start, end) # remove, the reset below + } else { + start <- bounds$start + end <- bounds$end + } + + for(i in names(font.attr)) { + if(i == "size") + tag_nm <- sprintf("%s-%s", "scale", tolower(font.attr[i])) + else + tag_nm <- sprintf("%s-%s", i, tolower(font.attr[i])) + buffer$ApplyTagByName(tag_nm, start, end) + } + }, + insert_text=function(value, where, font.attr=NULL, do.newline, ...) { + "Insert text into buffer. Font.attr is a vector (or list) with named quantities" + if(is_empty(value)) + return() + + iter <- switch(where, + "end"=buffer$GetEndIter()$iter, + "beginning"=buffer$GetStartIter()$iter, + buffer$getIterAtMark("insert")) + + value <- paste(c(value,""), collapse=ifelse(do.newline, "\n", "")) + arg_list <- list(object=buffer, iter=iter, text=value) + + if(!is.null(font.attr) && length(font.attr)) { + for(i in names(font.attr)) { + if(i == "size") + arg_list[[length(arg_list) + 1]] <- sprintf("%s-%s", "scale", tolower(font.attr[i])) + else + arg_list[[length(arg_list) + 1]] <- sprintf("%s-%s", i, tolower(font.attr[i])) + } + } + do.call("gtkTextBufferInsertWithTagsByName",arg_list) + + ## scroll to end -- if appended to end + if(where == "end") { + gdkWindowProcessAllUpdates() + while (gtkEventsPending()) + gtkMainIterationDo(blocking=FALSE) + + end <- buffer$getEndIter()$iter + widget$scrollToIter(end, within.margin = 0, use.align=TRUE) + } + + }, + add_handler_changed=function(handler, action=NULL, ...) { + add_handler_keystroke(handler, action=action, ...) + } + )) + + + diff --git a/R/gtimer.R b/R/gtimer.R new file mode 100644 index 0000000..a29a570 --- /dev/null +++ b/R/gtimer.R @@ -0,0 +1,54 @@ +##' @include GWidget.R +NULL + +##' S3 method for gtimer +##' +##' @export +##' @rdname gWidgets2RGtk2-undocumented +.gtimer.guiWidgetsToolkitRGtk2 <- function(toolkit, ms, FUN, data=NULL, one.shot=FALSE, start=TRUE) + GTimer$new(ms, FUN, one.shot=FALSE, start=TRUE) + +##' Timer for gWidgets. +GTimer <- setRefClass("GTimer", + fields=list( + "oneShot"="logical", + "started" = "logical", + interval="integer", + FUN="ANY", + ID = "ANY" + ), + methods=list( + initialize=function(ms, FUN, one.shot=FALSE, start=TRUE) { + + f <- function(...) { + FUN(...) + if(one.shot) { + stop_timer() + FALSE + } else { + TRUE + } + } + + + initFields(started=FALSE, + interval=as.integer(ms), + oneShot=one.shot, + FUN=f + ) + + if(start) + start_timer() + + .self + }, + start_timer = function() { + if(!started) { + ID <<- gTimeoutAdd(interval, FUN, data = NULL) + } + started <<- TRUE + }, + stop_timer = function() { + gSourceRemove(ID) + started <<- FALSE + })) diff --git a/R/gtk-misc.R b/R/gtk-misc.R new file mode 100644 index 0000000..d84ae66 --- /dev/null +++ b/R/gtk-misc.R @@ -0,0 +1,88 @@ +##' @include misc.R +NULL + +##' method for stopping getWidget +##' +##' @export +##' @rdname gWidgetsRGtk2-undocumented +getWidget.RGtkObject <- function(obj) obj + +##' S3 method for stopping getBlock +##' +##' @export +##' @rdname gWidgetsRGtk2-undocumented +getBlock.RGtkObject <- function(obj) obj + + + + +## set alignment +#Sets the alignment of the child. This property has no effect unless the child is a GtkMisc or a GtkAligment. +# xalign : the horizontal position of the child, 0.0 is left aligned, 1.0 is right aligned +# yalign : the vertical position of the child, 0.0 is top aligned, 1.0 is bottom aligned + +setXYalign <- function(child, childWidget, anchor) { + if(is(child,"GtkMisc") || is(child,"GtkAlignment")) { + child['xalign'] <- anchor[1] + child['yalign'] <- anchor[2] + } else if(!is.null(childWidget)) { + if(is(childWidget,"GtkMisc") || is(childWidget,"GtkAlignment")) { + childWidget['xalign'] <- anchor[1] + childWidget['yalign'] <- anchor[2] + } + } +} + + + +##' Font method for gtk object +##' +##' @export +##' @rdname font +"font<-.RGtkObject" <- function(obj, value) { + ## set fonts from value + ## value might be a vector, we use a list -- from .fixFontMessUp + if(!is.list(value)) + value <- sapply(value, identical, simplify=FALSE) + + string <- "" + + + ## do family, weight, style + for(i in c("family", "weight", "style")) { + if(!is.null(value[[i]])) { + x <- .font.styles[[i]] + ind <- charmatch(value[[i]], x) + if(!is.na(ind)) { + string <- paste(string, x[ind[1]], sep=" ") + if(i == "family") + string <- paste(string,",", sep="") + } + } + } + + ## size can be integer or name -- relative to 12pt + + if(!is.null(value$size)) { + ## is it numeric or character? + warn <- getOption("warn"); options(warn=2) # hack to avoid warning -- we want an error here + out <- try(as.integer(value[['size']]), silent=TRUE) + options(warn=warn) + if(!inherits(out, "try-error")) + string <- Paste(string," ",out) + else if (!is.na(ind <- charmatch(value[['size']], names(fontSizes)))) # fuzzy match? + string <- Paste(string, " ", paste(ceiling(12*fontSizes[ind[1]]),"px", sep="")) + } + string <- gsub(",$","",string) # strip , if present + + if(string != "") { + fontDescr = pangoFontDescriptionFromString(string) + obj$ModifyFont(fontDescr) + } + + ## colors + if(!is.null(value$color)) + obj$modifyFg(GtkStateType[1], value[['color']]) + +} + diff --git a/R/gwindow.R b/R/gwindow.R new file mode 100644 index 0000000..17990e4 --- /dev/null +++ b/R/gwindow.R @@ -0,0 +1,137 @@ +##' @include GContainer.R +NULL + +##' toolkit constructor for gwindow +##' +##' @export +##' @rdname gWidgetsRGtk2-undocumented +.gwindow.guiWidgetsToolkitRGtk2 <- function(toolkit, title, visible=visible, name, width, height, parent, handler, action, ...) { + GWindow$new(toolkit, title, visible=visible, name, width, height, parent, handler, action, ...) +} + +##' Main class for gwindow instances +GWindow <- setRefClass("GWindow", + contains="GContainer", + fields=list( + menubar_area="ANY", + toolbar_area="ANY", + infobar_area="ANY", + content_area="ANY", + statusbar_area="ANY" + ), + methods=list( + initialize=function(toolkit=NULL, title="", visible=TRUE, name=NULL, width=NULL, height=NULL, + parent=NULL, handler, action, ...) { + + widget <<- gtkWindow(show=visible) + set_value(title) + initFields(toolkit=toolkit, block=NULL, + menubar_area=gtkHBox(), + toolbar_area=gtkHBox(), + infobar_area=gtkInfoBar(show=FALSE), + content_area=gtkHBox() + ) + init_infobar() + + ## add areas to widget. For now we have simple + layout_widget() + + + ## process parent (make transient for, location, .... + ## size of widget ... + ## handler for window close + + callSuper(...) + }, + layout_widget = function() { + ## we make a stack of widgets, content_area is the key one + tbl <- gtkTable(rows=4, columns=1, homogeneous=FALSE) + tbl$SetColSpacings(0) + tbl$SetRowSpacings(0) + tbl$Attach(menubar_area, 0,1,0,1, yoptions = c("fill")) + tbl$Attach(toolbar_area, 0,1,1,2, yoptions = c("fill")) + tbl$Attach(infobar_area, 0,1,2,3, xoptions=c("shrink", "fill"), yoptions = c("shrink")) + tbl$AttachDefaults(content_area, 0,1,3,4) + ## size grip issue if no statusbar + ##content_area['border-width'] <<- 13 + ## XXX status bar is too short for labels + + widget$add(tbl) + }, + init_infobar=function() { + infobar_area$setNoShowAll(TRUE) + infobar_area$setMessageType("warning") + infobar_area$addButton(button.text = "gtk-ok", + response.id = GtkResponseType['ok']) + gSignalConnect(infobar_area, "response", + function(infobar_area, resp.id) infobar_area$hide()) + gSignalConnect(infobar_area, "response", + function(infobar_area, resp.id) infobar_area$hide()) + }, + ## Widget methods + get_value = function(...) widget$getTitle(), + set_value = function(value, ...) widget$setTitle(paste(value, collapse=" ")), + set_focus = function(value) { + if(value) + widget$present() + }, + get_size = function() { + theSize <- widget$GetSize() + return(unlist(theSize[2:3])) + }, + update_widget=function(...) { + widget$setSizeRequest(-1, -1) + }, + ## + ## add methods + add_child=function(child, ...) { + if(missing(child) || is.null(child)) + return() + ## clear out old (only one child allowed) + sapply(content_area$getChildren(), content_area$remove) + ## add. Child can be RGtk2Object or GComponent + content_area$packStart(getBlock(child), expand=TRUE, fill=TRUE) + ## bookkeep if possible + if(is(child, "GComponent")) + child$set_parent(.self) + }, + remove_child=function(child) { + child$set_parent(NULL) + content_area$remove(getBlock(child)) + }, + dispose_window = function() { + "close window" + widget$destroy() + }, + add_menubar=function(child, ...) { + menubar_area$packStart(getBlock(child), expand=TRUE, fill=TRUE) + }, + add_toolbar=function(child, ...) { + toolbar_area$packStart(getBlock(child), expand=TRUE, fill=TRUE) + }, + add_statusbar=function(child, ...) { + tbl <- widget[[1]] + statusbar_area <<- getWidget(child) # RGtk2 object + tbl$Attach(getBlock(child), 0,1,5,6, yoptions = c("fill")) + }, + ## set infobar message + set_infobar=function(msg, ...) { + label <- gtkLabel(msg) + curChildren <- infobar_area$getContentArea()$getChildren() + if(length(curChildren)) + sapply(curChildren, infobar_area$getContentArea()$remove) + infobar_area$getContentArea()$packStart(label, expand=TRUE, fill=TRUE) + infobar_area$show() + }, + ## set statusbar message + set_statusbar=function(msg, ...) { + statusbar_area$push(1L, msg) + }, + ## clear statusbar message + clear_statusbar=function(msg, ...) { + statusbar_area$push(1L, "") # bypass stack + } + )) + + + diff --git a/R/icons.R b/R/icons.R new file mode 100644 index 0000000..f5366d5 --- /dev/null +++ b/R/icons.R @@ -0,0 +1,96 @@ +##' @include misc.R +NULL + +##' add stock icons +##' +##' @export +##' @rdname gWidgets-undocumented +.addStockIcons.guiWidgetsToolkitRGtk2 <- function(toolkit, iconNames, iconFiles,... ) { + .GWidgetsRGtk2Icons$add_to_gtk_stock_icons(iconNames, iconFiles) +} + +##' Returns list of stock ids +##' +##' @export +##' @rdname gWidgets-undocumented +.getStockIcons.guiWidgetsToolkitRGtk2 <- function(toolkit, ...) { + lst <- gtkStockListIds() + sapply(unlist(lst), identity, simplify=FALSE) +} + +##' return stock id +##' +##' @export +##' @rdname gWidgets-undocumented +.getStockIconByName.guiWidgetsToolkitRGtk2 <- function(toolkit, name, ...) { + icons <- getStockIcons(toolkit) + + sapply(name, function(icon) { + tmp <- icons[[icon, exact=TRUE]] + if(is.null(tmp)) + tmp <- icons[[sprintf("gtk-%s", icon)]] + if(is.null(tmp)) + tmp <- icons[[sprintf("gw-%s", icon)]] + tmp + }) +} + + +##' helper function +##' +##' @export +##' @rdname gWidgets-undocumented +addToGtkStockIcons <- function(iconNames, iconFiles) { + + iconfactory <- gtkIconFactoryNew() + for(i in seq_along(iconNames)) { + iconsource <- gtkIconSourceNew() + iconsource$SetFilename(iconFiles[i]) + + iconset <- gtkIconSetNew() + iconset$AddSource(iconsource) + + stockName <- paste("gw-", iconNames[i], sep="") + + iconfactory$Add(stockName, iconset) + + items <- list(test=list(stockName, iconNames[i],"","","")) + gtkStockAdd(items) + } + + iconfactory$AddDefault() + invisible(TRUE) +} + +GWidgetsRGtk2Icons <- setRefClass("GWidgetsRGtk2Icons", + contains="GWidgets2Icons", + methods=list( + update_icons=function() { + callSuper() # makes icons in icons + add_to_gtk_stock_icons(names(icons), icons) + }, + add_to_gtk_stock_icons = function(iconNames, iconFiles) { + iconfactory <- gtkIconFactoryNew() + for(i in seq_along(iconNames)) { + iconsource <- gtkIconSourceNew() + iconsource$SetFilename(iconFiles[i]) + + iconset <- gtkIconSetNew() + iconset$AddSource(iconsource) + + stockName <- paste("gw-", iconNames[i], sep="") + + iconfactory$Add(stockName, iconset) + + items <- list(test=list(stockName, iconNames[i],"","","")) + gtkStockAdd(items) + } + + iconfactory$AddDefault() + invisible(TRUE) + } + + )) + +.GWidgetsRGtk2Icons <- GWidgetsRGtk2Icons$new() + diff --git a/R/misc.R b/R/misc.R new file mode 100644 index 0000000..e418406 --- /dev/null +++ b/R/misc.R @@ -0,0 +1,8 @@ +## miscellaneous functions + +##' toolkit class for RGtk2 +##' +##' @importClassesFrom gWidgets2 guiWidgetsToolkit +##' @export +setClass("guiWidgetsToolkitRGtk2", + contains="guiWidgetsToolkit") diff --git a/README b/README new file mode 100644 index 0000000..a50478b --- /dev/null +++ b/README @@ -0,0 +1,2 @@ +Toolkit implementation of gWidgets2 for RGtk2 + diff --git a/TODO.txt b/TODO.txt new file mode 100644 index 0000000..4d3fbdc --- /dev/null +++ b/TODO.txt @@ -0,0 +1,42 @@ +common.R +dnd.R +DONE gaction.R +DONE gbutton.R +DONE gcalendar.R +DONE gcheckbox.R +DONE gcheckboxgroup.R +DONE gcomobox.R +gcommandline.R +gdfedit.R +gdf.R +gdfnotebook.R +gdialogs.R +DONE gedit.R +DONE gexpandgroup.R +gfile.R +DONE gframe.R +ggraphics.R +ggraphicsnotebook.R +DONE ggroup.R +ghelp.R +ghtml.R +gimage.R +DONE glabel.R +DONE glayout.R +gmenu.R +DONE gnotebook.R +DONE gpanedgroup.R +DONE gradio.R +DONE gseparator.R +DONE gslider.R +DONE gspinbutton.R +gstatusbar.R +gtable.R +DONE gtext.R +gtkStuff.R +gtoolbar.R +gtree.R +gvarbrowser.R +DONE gwindow.R +DONE icons.R + diff --git a/man/GButton.Rd b/man/GButton.Rd new file mode 100644 index 0000000..f52902b --- /dev/null +++ b/man/GButton.Rd @@ -0,0 +1,7 @@ +\name{GButton} +\alias{GButton} +\title{Button class} +\description{ + Button class +} + diff --git a/man/GCheckbox.Rd b/man/GCheckbox.Rd new file mode 100644 index 0000000..633fcc6 --- /dev/null +++ b/man/GCheckbox.Rd @@ -0,0 +1,7 @@ +\name{GCheckbox} +\alias{GCheckbox} +\title{Basic check box} +\description{ + Basic check box +} + diff --git a/man/GCheckboxGroup.Rd b/man/GCheckboxGroup.Rd new file mode 100644 index 0000000..dd00caa --- /dev/null +++ b/man/GCheckboxGroup.Rd @@ -0,0 +1,7 @@ +\name{GCheckboxGroup} +\alias{GCheckboxGroup} +\title{Single line edit class} +\description{ + Single line edit class +} + diff --git a/man/GCheckboxGroupTable.Rd b/man/GCheckboxGroupTable.Rd new file mode 100644 index 0000000..b424b34 --- /dev/null +++ b/man/GCheckboxGroupTable.Rd @@ -0,0 +1,7 @@ +\name{GCheckboxGroupTable} +\alias{GCheckboxGroupTable} +\title{table with checkboxes} +\description{ + table with checkboxes +} + diff --git a/man/GComponent.Rd b/man/GComponent.Rd new file mode 100644 index 0000000..645af26 --- /dev/null +++ b/man/GComponent.Rd @@ -0,0 +1,9 @@ +\name{GComponent} +\alias{GComponent} +\title{Base Class for widgets and containers} +\description{ + GComponent as parent for GContainer and GWidget. Here we + place GtkWidget and GtkObject methods. Container methods + in GContainer +} + diff --git a/man/GComponentRGtk2.Rd b/man/GComponentRGtk2.Rd new file mode 100644 index 0000000..116a1b7 --- /dev/null +++ b/man/GComponentRGtk2.Rd @@ -0,0 +1,7 @@ +\name{GComponentRGtk2} +\alias{GComponentRGtk2} +\title{exported Subclass of GComponent for users to subclass} +\description{ + exported Subclass of GComponent for users to subclass +} + diff --git a/man/GContainer.Rd b/man/GContainer.Rd new file mode 100644 index 0000000..f7f85cc --- /dev/null +++ b/man/GContainer.Rd @@ -0,0 +1,7 @@ +\name{GContainer} +\alias{GContainer} +\title{Base class for container objects} +\description{ + Base class for container objects +} + diff --git a/man/GEdit.Rd b/man/GEdit.Rd new file mode 100644 index 0000000..47a50c3 --- /dev/null +++ b/man/GEdit.Rd @@ -0,0 +1,8 @@ +\name{GEdit} +\alias{GEdit} +\title{Single line edit class} +\description{ + We add a few methods beyond the spec: set_error, + clear_error, validate_value, +} + diff --git a/man/GExpandGroup.Rd b/man/GExpandGroup.Rd new file mode 100644 index 0000000..361d4f6 --- /dev/null +++ b/man/GExpandGroup.Rd @@ -0,0 +1,7 @@ +\name{GExpandGroup} +\alias{GExpandGroup} +\title{base class for gframe} +\description{ + base class for gframe +} + diff --git a/man/GFrame.Rd b/man/GFrame.Rd new file mode 100644 index 0000000..cd98760 --- /dev/null +++ b/man/GFrame.Rd @@ -0,0 +1,7 @@ +\name{GFrame} +\alias{GFrame} +\title{base class for gframe} +\description{ + base class for gframe +} + diff --git a/man/GGroup.Rd b/man/GGroup.Rd new file mode 100644 index 0000000..364716a --- /dev/null +++ b/man/GGroup.Rd @@ -0,0 +1,7 @@ +\name{GGroup} +\alias{GGroup} +\title{base class for box containers.} +\description{ + base class for box containers. +} + diff --git a/man/GRadio.Rd b/man/GRadio.Rd new file mode 100644 index 0000000..3d494dd --- /dev/null +++ b/man/GRadio.Rd @@ -0,0 +1,7 @@ +\name{GRadio} +\alias{GRadio} +\title{readio button class} +\description{ + readio button class +} + diff --git a/man/GTimer.Rd b/man/GTimer.Rd new file mode 100644 index 0000000..97bc045 --- /dev/null +++ b/man/GTimer.Rd @@ -0,0 +1,7 @@ +\name{GTimer} +\alias{GTimer} +\title{Timer for gWidgets.} +\description{ + Timer for gWidgets. +} + diff --git a/man/GToggleButton.Rd b/man/GToggleButton.Rd new file mode 100644 index 0000000..61052d4 --- /dev/null +++ b/man/GToggleButton.Rd @@ -0,0 +1,7 @@ +\name{GToggleButton} +\alias{GToggleButton} +\title{Basic toggle button} +\description{ + Basic toggle button +} + diff --git a/man/GWidget.Rd b/man/GWidget.Rd new file mode 100644 index 0000000..afa2e88 --- /dev/null +++ b/man/GWidget.Rd @@ -0,0 +1,7 @@ +\name{GWidget} +\alias{GWidget} +\title{Base class for widget objects} +\description{ + Base class for widget objects +} + diff --git a/man/GWidgetWithItems.Rd b/man/GWidgetWithItems.Rd new file mode 100644 index 0000000..99322b9 --- /dev/null +++ b/man/GWidgetWithItems.Rd @@ -0,0 +1,8 @@ +\name{GWidgetWithItems} +\alias{GWidgetWithItems} +\title{Class to hold widget with items where handlers apply to each item} +\description{ + Class to hold widget with items where handlers apply to + each item +} + diff --git a/man/GWindow.Rd b/man/GWindow.Rd new file mode 100644 index 0000000..e682182 --- /dev/null +++ b/man/GWindow.Rd @@ -0,0 +1,7 @@ +\name{GWindow} +\alias{GWindow} +\title{Main class for gwindow instances} +\description{ + Main class for gwindow instances +} + diff --git a/man/Glabel.Rd b/man/Glabel.Rd new file mode 100644 index 0000000..8e80df3 --- /dev/null +++ b/man/Glabel.Rd @@ -0,0 +1,7 @@ +\name{Glabel} +\alias{Glabel} +\title{label class} +\description{ + label class +} + diff --git a/man/font.Rd b/man/font.Rd new file mode 100644 index 0000000..a821505 --- /dev/null +++ b/man/font.Rd @@ -0,0 +1,7 @@ +\name{font<-.RGtkObject} +\alias{font<-.RGtkObject} +\title{Font method for gtk object} +\description{ + Font method for gtk object +} + diff --git a/man/gWidgets-undocumented.Rd b/man/gWidgets-undocumented.Rd new file mode 100644 index 0000000..2a81529 --- /dev/null +++ b/man/gWidgets-undocumented.Rd @@ -0,0 +1,27 @@ +\name{.addStockIcons.guiWidgetsToolkitRGtk2} +\alias{.addStockIcons.guiWidgetsToolkitRGtk2} +\alias{.getStockIconByName.guiWidgetsToolkitRGtk2} +\alias{.getStockIcons.guiWidgetsToolkitRGtk2} +\alias{addToGtkStockIcons} +\title{add stock icons} +\usage{ + .addStockIcons.guiWidgetsToolkitRGtk2(toolkit, iconNames, + iconFiles, ...) + + .getStockIcons.guiWidgetsToolkitRGtk2(toolkit, ...) + + .getStockIconByName.guiWidgetsToolkitRGtk2(toolkit, name, + ...) + + addToGtkStockIcons(iconNames, iconFiles) +} +\description{ + add stock icons + + Returns list of stock ids + + return stock id + + helper function +} + diff --git a/man/gWidgets2RGtk2-package.Rd b/man/gWidgets2RGtk2-package.Rd new file mode 100644 index 0000000..a8727da --- /dev/null +++ b/man/gWidgets2RGtk2-package.Rd @@ -0,0 +1,17 @@ +\name{gWidgets2RGtk2-package} +\alias{gWidgets2RGtk2-package} +\alias{gWidgets2RGtk2} +\docType{package} +\title{ +Toolkit implementation of gWidgets API +} +\description{ +The gWidgets2 API provides an abstract means to interact with an underlying graphical toolkit library. This package provides the connectino between gWidgets2 and RGtk2. +} +\author{ +John Verzani +} +\references{ +http://CRAN.R-project.org/doc/Rnews/Rnews_2007-3.pdf +} +\keyword{ package } diff --git a/man/gWidgets2RGtk2-undocumented.Rd b/man/gWidgets2RGtk2-undocumented.Rd new file mode 100644 index 0000000..2bc88d2 --- /dev/null +++ b/man/gWidgets2RGtk2-undocumented.Rd @@ -0,0 +1,138 @@ +\name{.gbutton.guiWidgetsToolkitRGtk2} +\alias{.gaction.guiWidgetsToolkitRGtk2} +\alias{.gbutton.guiWidgetsToolkitRGtk2} +\alias{.gcalendar.guiWidgetsToolkitRGtk2} +\alias{.gcheckbox.guiWidgetsToolkitRGtk2} +\alias{.gcheckboxgroup.guiWidgetsToolkitRGtk2} +\alias{.gcombobox.guiWidgetsToolkitRGtk2} +\alias{.gedit.guiWidgetsToolkitRGtk2} +\alias{.gexpandgroup.guiWidgetsToolkitRGtk2} +\alias{.gframe.guiWidgetsToolkitRGtk2} +\alias{.glabel.guiWidgetsToolkitRGtk2} +\alias{.glayout.guiWidgetsToolkitRGtk2} +\alias{.gnotebook.guiWidgetsToolkitRGtk2} +\alias{.gpanedgroup.guiWidgetsToolkitRGtk2} +\alias{.gradio.guiWidgetsToolkitRGtk2} +\alias{.gseparator.guiWidgetsToolkitRGtk2} +\alias{.gslider.guiWidgetsToolkitRGtk2} +\alias{.gspinbutton.guiWidgetsToolkitRGtk2} +\alias{.gstackwidget.guiWidgetsToolkitRGtk2} +\alias{.gtext.guiWidgetsToolkitRGtk2} +\alias{.gtimer.guiWidgetsToolkitRGtk2} +\title{Toolkit button constructor} +\usage{ + .gbutton.guiWidgetsToolkitRGtk2(toolkit, text, handler, + action, container, ...) + + .gframe.guiWidgetsToolkitRGtk2(toolkit, text, markup, + pos, horizontal = TRUE, container = NULL, ...) + + .glabel.guiWidgetsToolkitRGtk2(toolkit, text = "", markup + = FALSE, editable = FALSE, handler = NULL, action = NULL, + container = NULL, ...) + + .gtimer.guiWidgetsToolkitRGtk2(toolkit, ms, FUN, data = + NULL, one.shot = FALSE, start = TRUE) + + .gedit.guiWidgetsToolkitRGtk2(toolkit, text = "", width = + 25, coerce.with = NULL, initial.msg = initial.msg, + handler = NULL, action = NULL, container = NULL, ...) + + .gcheckbox.guiWidgetsToolkitRGtk2(toolkit, text, checked + = FALSE, use.togglebutton = FALSE, handler = NULL, action + = NULL, container = NULL, ...) + + .gcheckboxgroup.guiWidgetsToolkitRGtk2(toolkit = NULL, + items, checked = FALSE, horizontal = FALSE, use.table = + FALSE, handler = NULL, action = NULL, container = NULL, + ...) + + .gradio.guiWidgetsToolkitRGtk2(toolkit, items, selected = + 1, horizontal = FALSE, handler = NULL, action = NULL, + container = NULL, ...) + + .gnotebook.guiWidgetsToolkitRGtk2(toolkit, tab.pos = 3, + container = NULL, ...) + + .gslider.guiWidgetsToolkitRGtk2(toolkit, from = 0, to = + 100, by = 1, value = from, horizontal = TRUE, handler = + NULL, action = NULL, container = NULL, ...) + + .gspinbutton.guiWidgetsToolkitRGtk2(toolkit, from = 0, to + = 10, by = 1, value = from, digits = 0, handler = NULL, + action = NULL, container = NULL, ...) + + .gexpandgroup.guiWidgetsToolkitRGtk2(toolkit, text, + markup, horizontal = TRUE, handler = NULL, action = NULL, + container = NULL, ...) + + .gstackwidget.guiWidgetsToolkitRGtk2(toolkit, container = + NULL, ...) + + .glayout.guiWidgetsToolkitRGtk2(toolkit, homogeneous = + FALSE, spacing = 10, container = NULL, ...) + + .gpanedgroup.guiWidgetsToolkitRGtk2(toolkit, horizontal = + TRUE, container = NULL, ...) + + .gseparator.guiWidgetsToolkitRGtk2(toolkit, horizontal = + TRUE, container = NULL, ...) + + .gtext.guiWidgetsToolkitRGtk2(toolkit, text = NULL, width + = NULL, height = 300, font.attr = NULL, wrap = TRUE, + handler = NULL, action = NULL, container = NULL, ...) + + .gcombobox.guiWidgetsToolkitRGtk2(toolkit, items, + selected = 1, editable = FALSE, coerce.with = NULL, + handler = NULL, action = NULL, container = NULL, ...) + + .gaction.guiWidgetsToolkitRGtk2(toolkit, label, tooltip = + NULL, icon = NULL, key.accel = NULL, handler = NULL, + action = NULL, parent = NULL, ...) + + .gcalendar.guiWidgetsToolkitRGtk2(toolkit, text = "", + format = "\%Y-\%m-\%d", handler = NULL, action = NULL, + container = NULL, ...) +} +\description{ + Toolkit button constructor + + gframe constructor + + Toolkit label constructor + + S3 method for gtimer + + Toolkit gedit constructor + + Toolkit XXX constructor + + Toolkit XXX constructor + + Toolkit constructor + + Toolkit constructor + + Toolkit constructor + + Toolkit XXX constructor + + toolkit constructor + + Toolkit constructor + + Toolkit constructor + + Toolkit constructor + + Toolkit constructor + + toolkit implementation + + Toolkit constructor + + Toolkit constructor + + Toolkit constructor +} + diff --git a/man/gWidgetsRGtk2-undocumented.Rd b/man/gWidgetsRGtk2-undocumented.Rd new file mode 100644 index 0000000..16817b4 --- /dev/null +++ b/man/gWidgetsRGtk2-undocumented.Rd @@ -0,0 +1,29 @@ +\name{getWidget.RGtkObject} +\alias{.ggroup.guiWidgetsToolkitRGtk2} +\alias{.gwindow.guiWidgetsToolkitRGtk2} +\alias{getBlock.RGtkObject} +\alias{getWidget.RGtkObject} +\title{method for stopping getWidget} +\usage{ + getWidget.RGtkObject(obj) + + getBlock.RGtkObject(obj) + + .gwindow.guiWidgetsToolkitRGtk2(toolkit, title, visible = + visible, name, width, height, parent, handler, action, + ...) + + .ggroup.guiWidgetsToolkitRGtk2(toolkit, horizontal = + TRUE, spacing = 5, use.scrollwindow = FALSE, container = + NULL, ...) +} +\description{ + method for stopping getWidget + + S3 method for stopping getBlock + + toolkit constructor for gwindow + + toolkit constructor for ggroup +} + diff --git a/man/guiWidgetsToolkitRGtk2.Rd b/man/guiWidgetsToolkitRGtk2.Rd new file mode 100644 index 0000000..1990ea4 --- /dev/null +++ b/man/guiWidgetsToolkitRGtk2.Rd @@ -0,0 +1,7 @@ +\name{guiWidgetsToolkitRGtk2} +\alias{guiWidgetsToolkitRGtk2} +\title{toolkit class for RGtk2} +\description{ + toolkit class for RGtk2 +} + diff --git a/template.R b/template.R new file mode 100644 index 0000000..0f5c907 --- /dev/null +++ b/template.R @@ -0,0 +1,55 @@ +##' @include GWidget.R +NULL + +##' Toolkit constructor +##' +##' @export +##' @rdname gWidgets2RGtk2-undocumented +.XXX.guiWidgetsToolkitRGtk2 <- function(toolkit, + + handler = NULL,action = NULL, container = NULL, ... ) { + GXXX$new( + handler = handler,action = action, container = container, ...) +} + + +## XXX +GXXX <- setRefClass("GXXX", + contains="GWidget", + methods=list( + initialize=function(toolkit=NULL, + handler=NULL, action=NULL, container=NULL, ...) { + + widget <<- XXX + + initFields(block=widget) + + add_to_parent(container, .self, ...) + + handler_id <<- add_handler_changed(handler, action) + + callSuper(toolkit) + }, + get_value=function( ...) { + + }, + set_value=function(value, ...) { + + }, + get_index = function(...) { + + }, + set_index = function(value,...) { + + }, + get_items = function(i, j, ..., drop=TRUE) { + + }, + set_items = function(value, i, j, ...) { + + }, + add_handler_changed=function(handler, action=NULL, ...) { + add_handler_clicked(handler, action=action, ...) + } + )) +