/
gaston_figures.jl
151 lines (121 loc) · 3.85 KB
/
gaston_figures.jl
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
"""
figure(handle::Int = 0) -> Int
Select a figure with the specified handle, or with the next available handle
if none is specified. Make the specified figure current. If the figure exists,
display it.
"""
function figure(handle::Int = 0)
global gnuplot_state
# make sure handleandle is valid
handle < 0 && throw(DomainError(handle, "handleandle must be a positive integer or 0"))
# determine figure handleandle
handle == 0 && (handle = nexthandle())
# set current figure to handle
gnuplot_state.current = handle
# if figure exists, display it
if handle in gethandles()
i = findfigure(handle)
fig = gnuplot_state.figs[i]
display(fig)
else
# if it doesn't, create it
fig = newfigure(handle)
end
return handle
end
"""
closefigure(handle::Int...) -> Int
Close one or more figures, specified by their handles.
If no arguments are given, the current figure is closed.
Returns a handle to the current figure.
"""
function closefigure(x...)
isempty(x) && (x = (gnuplot_state.current,))
any(i -> i::Int<1, x) && throw(DomainError(x, " all handles must be positive integers"))
curr = gnuplot_state.current
for handle ∈ x
handles = gethandles()
handle ∉ handles && continue
curr = closesinglefigure(handle)
end
gnuplot_state.current = curr
return curr
end
"""
closeall() -> Int
Closes all existing figures. Returns the number of closed figures.
"""
function closeall()
global gnuplot_state
h = gethandles()
closed = length(h)
closed > 0 && closefigure(h...)
gnuplot_state.current = nothing
return closed
end
# Create a new figure and return it, with the specified handle (or the next
# available one if # handle == 0, and with the specified dimensions, axesconf
# and curve. Update Gaston state as necessary.
function newfigure(handle = 0)
# make sure handle is valid
handle === nothing && (handle = 0) # no figures exist yet
handle < 0 && throw(DomainError(handle,"handle must be a positive integer or 0"))
# if h == 0, determine next available handle
handle == 0 && (handle = nexthandle())
# create and push or update, as necessary
if handle in gethandles()
# pre-existing; reset figure without creating a new one
fig = gnuplot_state.figs[findfigure(handle)]
fig.layout = (0,0)
fig.subplots = [Plot()]
else
# new; create and push
fig = Figure(handle)
push!(gnuplot_state.figs, fig)
end
# make this figure current
gnuplot_state.current = handle
return fig
end
# close a single figure, assuming arguments are valid; returns handle of
# the new current figure
function closesinglefigure(handle::Int)
global gnuplot_state
term = config[:term]
term ∈ term_window && gnuplot_send("set term $term $handle close")
# remove figure from global state
filter!(h->h.handle!=handle,gnuplot_state.figs)
# update state
gnuplot_state.current = mostrecenthandle()
return gnuplot_state.current
end
# Return index to figure with handle `c`. If no such figure exists, returns 0.
function findfigure(c)
global gnuplot_state
i = 0
for j = 1:length(gnuplot_state.figs)
if gnuplot_state.figs[j].handle == c
i = j
break
end
end
return i
end
# return array of existing handles
function gethandles()
[f.handle for f in gnuplot_state.figs]
end
# Return the next available handle (smallest non-used positive integer)
function nexthandle()
isempty(gnuplot_state.figs) && return 1
handles = gethandles()
mh = maximum(handles)
for i = 1:mh+1
!in(i,handles) && return i
end
end
# Return the most-recently added handle
function mostrecenthandle()
isempty(gnuplot_state.figs) && return nothing
return gnuplot_state.figs[end].handle
end