File: tcltk2-Internal.R

package info (click to toggle)
r-cran-tcltk2 1.2-10-1
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 5,356 kB
  • ctags: 1,386
  • sloc: tcl: 37,888; ansic: 792; python: 324; sh: 68; sed: 16; makefile: 1
file content (312 lines) | stat: -rwxr-xr-x 10,945 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
### tcltk2-Internal.R - Hidden functions for tcltk2
### Copyright (c), Philippe Grosjean (phgrosjean@sciviews.org)

.onLoad <- function(libname, pkgname) {
	libdir <- file.path(libname, pkgname, "tklibs")

	## A slightly modified version of addTclPath() that works also within SciViews
	addTclPath <- function (path = ".") {
		if (.Platform$OS.type == "windows") 
		    path <- gsub("\\\\", "/", path)
		a <- tclvalue(tcl("set", "::auto_path"))
		paths <- strsplit(a, " ", fixed = TRUE)[[1L]]
		if (!path %in% paths) 
		    tcl("lappend", "::auto_path", path)
	}
    res <- addTclPath(libdir)	# extend the Tcl/Tk path

    ## Make sure that Tcl/Tk locale is the same one as current R locale
	lang <- getLanguage()
	if (lang != "") {  # Set the same language for Tcl/Tk
		res <- tclRequire("msgcat")
	    if (inherits(res, "tclObj")) tcl("::msgcat::mclocale", lang)
	}

    if (is.tk()) {
		## Here is how we could install the supplementary material in Tcl/Tk
	
		## This is for a better management of scrollbars in listbox, text, canvas
		tclRequire("autoscroll") # Version 1.1
		tcl("source", file.path(libdir, "scrolledWidget.tcl"))
		
		##tclRequire("choosefont")      # Version 0.2
		##tclRequire("ctext")			# Version 3.1
		##tclRequire("cursor")       	# Version 0.1
		##tclRequire("mclistbox")    	# Version 1.2
		##tclRequire("swaplist")    	# Version 0.2
		##tclRequire("tablelist")    	# Version 5.5
		##Not provided any more -> tclRequire("Tktable")   		# Version 2.9

		## The following code is not implemented as Tcl package... just source it
		tcl("source", file.path(libdir, "notebook1.3", "notebook.tcl"))
	    tcl("source", file.path(libdir, "tree1.7", "tree.tcl"))

		## Do we try to load the tile widgets? (only if Tcl./Tk < 8.5)
		if (as.numeric(.Tcl("set ::tcl_version")) < 8.5) {
###				tcl("source", file.path(libdir, "fonts.tcl"))
				## Define fonts used in Tk (note: must be done AFTER loading tile!)
				## Default values for system fonts are calculated by tile...
				## but they should be computed from the system, actually
				## We collect back those values calculated by tile and possibly override
				## them with better values
###				tk2font.setstyle(system = TRUE, default.styles = TRUE, text = TRUE)
				### TODO: reflect possible changes to other graphical toolkits (how?)
		} else {	# There is a bug in mclistbox with Tcl/Tk 8.5
			## Patch by Christiane Raemsch, slightly modified by Ph. Grosjean
			## This is essentially the listbox procedure, but with an additional
			## focus argument required by mclistbox
			.Tcl('proc ::tk::ListboxBeginSelect {w el {focus 0}} {
				variable ::tk::Priv
				if {[$w cget -selectmode] eq "multiple"} {
					if {[$w selection includes $el]} {
						$w selection clear $el
					} else {
						$w selection set $el
					}
				} else {
					$w selection clear 0 end
					$w selection set $el
					$w selection anchor $el
					set Priv(listboxSelection) {}
					set Priv(listboxPrev) $el
				}
				event generate $w <<ListboxSelect>>
				if {$focus && [winfo exists $w]} {
					focus $w
				}
			}')
		}
		
		## Load additional ttk themes - No: load only on demand!
		## Not done any more on startup, done on demand in tk2theme() now
		#try(tclRequire("ttk::theme::plastik"), silent = TRUE)
		#try(tclRequire("ttk::theme::keramik"), silent = TRUE)
		#try(tclRequire("ttk::theme::keramik_alt"), silent = TRUE)
		#try(tclRequire("ttk::theme::clearlooks"), silent = TRUE)
		#try(tclRequire("ttk::theme::radiance"), silent = TRUE)
		
		## Which ttk theme should we use?
		## If the user specified a default theme, use it
		if (!.loadTheme()) {
			## ...otherwise, try to guess the best default value
			themes <- try(tk2theme.list(), silent = TRUE)
			if (!inherits(themes, "try-error")) {
				if ("aqua" %in% themes) { # This must be aquaTk on a Mac
					try(tk2theme("aqua"), silent = TRUE)
				} else if ("vista" %in% themes) { # This must be Vista or Win 7
					try(tk2theme("vista"), silent = TRUE)
				} else if ("xpnative" %in% themes) { # This must be XP
					try(tk2theme("xpnative"), silent = TRUE)
				} else if ("winnative" %in% themes) { # This must be a pre-XP windows
					try(tk2theme("winnative"), silent = TRUE)
				} else if (.isUbuntu()) {
					try(tk2theme("radiance"), silent = TRUE)
					## Special treatment for Ubuntu: change fonts to Ubuntu and Ubuntu mono
					## and use white text on black for tooltips
					tkfont.configure("TkDefaultFont", family = "Ubuntu", size = 11)
					tkfont.configure("TkMenuFont", family = "Ubuntu", size = 11)
					tkfont.configure("TkCaptionFont", family = "Ubuntu", size = 10)
					tkfont.configure("TkSmallCaptionFont", family = "Ubuntu", size = 9)
					tkfont.configure("TkTooltipFont", family = "Ubuntu", size = 9)
					tkfont.configure("TkMenuFont", family = "Ubuntu", size = 11)
					tkfont.configure("TkHeadingFont", family = "Ubuntu", size = 12)
					tkfont.configure("TkIconFont", family = "Ubuntu", size = 11)
					tkfont.configure("TkTextFont", family = "Ubuntu", size = 11)
					tkfont.configure("TkFixedFont", family = "Ubuntu Mono", size = 11)
					res <- tclRequire("tooltip")
					if (inherits(res, "tclObj")) {
						.Tcl(paste("set ::tooltip::labelOpts [list -highlightthickness 0",
							"-relief solid -bd 1 -background black -fg white]"))
					}
				} else { # A modern "default" theme that fit not too bad in many situations
					try(tk2theme("clearlooks"), silent = TRUE)
				}
			}
		}
		## Save default font as TkSysDefaultFont
		tk2font.set("TkSysDefaultFont", tk2font.get("TkDefaultFont"))
	}
	
	## Windows only
    if (.Platform$OS.type == "windows") {
		try(tclRequire("dde"), silent = TRUE)       # Version 1.2.2
        ## Not loaded automatically!
        #tclRequire("registry")  # Version 1.1.3
		## Support for winico.dll is drop from version 1.2-1!
    #    if (nzchar(r_arch <- .Platform$r_arch))
	#		tcl("load", file.path(libname, pkgname, "libs", r_arch, "Winico06.dll"))
	#	else
	#		tcl("load", file.path(libname, pkgname, "libs", "Winico06.dll"))
		## Also register the DDE server as TclEval|R
        try(tk2dde("R"), silent = TRUE)
    }
}

.onUnload <- function (libpath)
{
    # PhG: was .Last.lib()
	## Remove all currently scheduled tasks
	tclTaskDelete(id = NULL)
}

.saveTheme <- function ()
	cat(tk2theme(), "\n", sep = "", file = "~/.Rtk2theme")
	
.loadTheme <- function () {
	if (file.exists("~/.Rtk2theme")) {
		theme <- try(readLines("~/.Rtk2theme")[1], silent = TRUE)
		if (inherits(theme, 'try-error')) return(FALSE)
		## Try changing the tk2theme according to this value
		res <- try(tk2theme(theme), silent = TRUE)
		return(!inherits(res, "try-error"))
	} else return(FALSE)
}

.isUbuntu <- function () {
	## Note: take care not to call 'cat' on Windows: it is usually *not* there!
	if (.Platform$OS.type == "windows" || grepl("^mac", .Platform$pkgType))
		return(FALSE)	# This is either Windows or Mac OS X!
	grepl("^Ubuntu", suppressWarnings(try(system("cat /etc/issue",
		intern = TRUE, ignore.stderr = TRUE), silent = TRUE))[1])	
}

.mergeList <- function (l1, l2)
{
	## For named lists, overwrite items of l1 present in l2
	nms <- names(l2)
	## Deal with named items
	if (length(nms)) {
		named <- nms != ""
		if (any(named)) {
			l2n <- l2[named]
			nmsn <- nms[named]
			for (i in 1:length(nmsn)) l1[[nmsn[i]]] <- l2n[[nmsn[i]]]
		}
		## Keep only non named items in l2
		l2 <- l2[!named]
	}
	## Deal with non named items in l2
	if (length(l2)) { # Unnamed list
		n1 <- length(l1)
		n2 <- length(l2)
		for (i in 1:n2) l1[[n1 + i]] <- l2[[i]]
	}
	return(l1)
}

.configStd <- function (x, lstval)
{
	## These config parameters are considered as data
	## Image
	if (!is.null(lstval$image)) {
		tkconfigure(x, image = lstval$image)
		lstval$image <- NULL
	}
	## Text
	if (!is.null(lstval$text)) {
		tkconfigure(x, text = lstval$text)
		lstval$text <- NULL
	}
	## Textvariable
	if (!is.null(lstval$textvariable)) {
		tkconfigure(x, textvariable = lstval$textvariable)
		lstval$textvariable <- NULL
	}
	## Values
	if (!is.null(lstval$values)) {
		values(x) <- lstval$values
		lstval$values <- NULL
	}
	## Value
	if (!is.null(lstval$value)) {
		value(x) <- lstval$value
		lstval$value <- NULL
	}
	## Selection
	if (!is.null(lstval$selection)) {
		selection(x) <- lstval$selection
		lstval$selection <- NULL
	}
	## Label (not a Tk attribute)
	if (!is.null(lstval$label)) {
		label(x) <- lstval$label
		lstval$label <- NULL
	}
	## Tag (not a Tk attribute)
	if (!is.null(lstval$name)) {
		tag(x) <- lstval$tag
		lstval$tag <- NULL
	}
	## Tooltip
	if (!is.null(lstval$tip)) {
		tip(x) <- lstval$tip
		lstval$tip <- NULL
	}
	## Disabled (is tk 'state' parameter indeed)
	if (!is.null(lstval$disabled)) {
		disabled(x) <- lstval$disabled
		lstval$disabled <- NULL
	}
	## Return modified value list
	return(lstval)
}

.wraplength <- function (w, width)
{
	## Calculate wraplength required for tk2label widgets
	## width is expressed in characters, but wraplength must be given in pixels
	## This is stupid and requires additional computation to calculate the
	## width in pixel of an average character, like "0" to do the conversion!
	## Get the average size of one character in the current font used
	
	## If width is not set, just return a large value for wraplength
	if (!length(width)) return(1000)
	
	## Get the font and measure it	
	font <- tclvalue(tkcget(w, "-font"))
	if (font == "") font <- tk2style("tk2label", "font")
	if (font == "") {
		charsize <- 8 # Use an everage value
	} else charsize <- as.numeric(tkfont.measure(tkfont.actual(font), "0"))
	
	## Optimal wraplength is width * charsize
	return(width * charsize)
}

.TempEnv <- function ()
{
    pos <-  match("SciViews:TempEnv", search())
    if (is.na(pos)) {  # Must create it
        `SciViews:TempEnv` <- list()
        Attach <- function (...) get("attach", mode = "function")(...)
        Attach(`SciViews:TempEnv`, pos = length(search()) - 1)
        rm(`SciViews:TempEnv`)
        pos <- match("SciViews:TempEnv", search())
    }
    return(pos.to.env(pos))
}

.assignTemp <- function (x, value, replace.existing = TRUE)
    if (replace.existing || !exists(x, envir = .TempEnv(), mode = "any",
		inherits = FALSE))
        assign(x, value, envir = .TempEnv())

.getTemp <- function (x, default = NULL, mode = "any", item = NULL)
{
    if (is.null(item)) Mode <- mode else Mode <- "any"
    if  (exists(x, envir = .TempEnv(), mode = Mode, inherits = FALSE)) {
        dat <- get(x, envir = .TempEnv(), mode = Mode, inherits = FALSE)
        if (is.null(item)) return(dat) else {
            item <- as.character(item)[1]
            if (inherits(dat, "list") && item %in% names(dat)) {
                dat <- dat[[item]]
                if (mode != "any" && mode(dat) != mode) dat <- default
                return(dat)
            } else {
                return(default)
            }
        }
    } else {  # Variable not found, return the default value
        return(default)
    }
}