telescope-term 0.7 → 1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/telescope +479 -606
- metadata +13 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6a927518be7d857221796c64555e4fec64668911d1279ac9f116ce7b53e17d7d
|
4
|
+
data.tar.gz: c5107d1239cde8bc48b26e7daefb13ed0d65f16e2fe2bbbde1567f96ac79656b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 230a99f5e65020b070110bf2b234638a44fc47f0f9f799f7b7114f2f8b9bda342952d5e1d4a9257bfdff69bcc5404cac76923b823809245ee59cd885b9e70240
|
7
|
+
data.tar.gz: 9c2f836f026ca88f523cd296290a8f7ac64f3ed813002b6575732b7c5624060a6a9f3f053931cf706efbdc31d2e6328df99395c7671260994f3a09fb78370485
|
data/bin/telescope
CHANGED
@@ -1,637 +1,510 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# encoding: utf-8
|
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
|
-
if `tput cols`.to_i < 140
|
29
|
-
puts "You must run Telescope with a minimum tarminal width of 140 chracters."
|
3
|
+
|
4
|
+
# SCRIPT INFO {{{1
|
5
|
+
# Name: Telescope - a tool for amateur astronomers
|
6
|
+
# Language: Pure Ruby, best viewed in VIM
|
7
|
+
# Author: Geir Isene <g@isene.com>
|
8
|
+
# Web_site: http://isene.com/
|
9
|
+
# Github: https://github.com/isene/telescope
|
10
|
+
# License: I release all copyright claims. This code is in the public domain.
|
11
|
+
# Permission is granted to use, copy modify, distribute, and sell
|
12
|
+
# this software for any purpose. I make no guarantee about the
|
13
|
+
# suitability of this software for any purpose and I am not liable
|
14
|
+
# for any damages resulting from its use. Further, I am under no
|
15
|
+
# obligation to maintain or extend this software. It is provided
|
16
|
+
# on an 'as is' basis without any expressed or implied warranty.
|
17
|
+
# Docs: Apart from the extensive documentation found on Github, you can
|
18
|
+
# get a great understanding of the code itself by simply sending
|
19
|
+
# or pasting this whole file into you favorite AI for coding with
|
20
|
+
# a prompt like this: "Help me understand every part of this code".
|
21
|
+
|
22
|
+
# SETUP {{{1
|
23
|
+
begin
|
24
|
+
require 'rcurses'
|
25
|
+
class Object
|
26
|
+
include Rcurses
|
27
|
+
include Rcurses::Input
|
30
28
|
end
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
Curses.start_color
|
38
|
-
Curses.curs_set(0)
|
39
|
-
Curses.noecho
|
40
|
-
Curses.cbreak
|
41
|
-
Curses.stdscr.keypad = true
|
29
|
+
rescue StandardError => e
|
30
|
+
puts 'Telescope is built using rcurses (https://github.com/isene/rcurses). Install rcurses to run Telescope.'
|
31
|
+
exit 1
|
32
|
+
end
|
33
|
+
Pane = Rcurses::Pane
|
34
|
+
require 'date'
|
42
35
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
36
|
+
# Persistence paths
|
37
|
+
SAVE = File.join(Dir.home, '.telescope')
|
38
|
+
|
39
|
+
# HELP TEXT {{{1
|
40
|
+
HELP1 = " WELCOME TO THE TERMINAL TELESCOPE APPLICATION\n".b + '
|
41
|
+
This can help structure your telescopes and eyepieces.
|
42
|
+
It will calculate properties of your scopes and EPs.
|
43
|
+
Scope+EP combination properties are also calculated.
|
44
|
+
|
45
|
+
Anything you like to have changed or bugs fixed,
|
46
|
+
create an issue: https://github.com/isene/telescope
|
47
|
+
...or drop me an e-mail: g@isene.com.
|
48
|
+
|
49
|
+
Press any key to show more help text.
|
50
|
+
'
|
48
51
|
|
49
|
-
|
50
|
-
|
52
|
+
HELP2 = " TERMININAL TELESCOPE APPLICATION\n\n Keys and their actions\n".b + '
|
53
|
+
t Add telescope (name,app,fl)
|
54
|
+
e Add eyepiece (name,fl,afov)
|
55
|
+
ENTER Edit selected
|
56
|
+
TAB Switch panels
|
57
|
+
UP/DOWN Move cursor
|
58
|
+
Shift-UP Move item up
|
59
|
+
Shift-DOWN Move item down
|
60
|
+
HOME/END Jump to start/end
|
61
|
+
o Toggle order by Telescope APP and Eyepiece FL
|
62
|
+
SPACE Tag/untag
|
63
|
+
u Untag all
|
64
|
+
Ctrl-o Create observation log with tagged equipment
|
65
|
+
D Delete item
|
66
|
+
r Refresh all panes
|
67
|
+
q/Q Quit (save/no save)
|
68
|
+
? Help'.fg(230)
|
51
69
|
|
52
|
-
|
53
|
-
|
70
|
+
HELP3 = " Abbreviations and their meaning\n".b + '
|
71
|
+
APP = Telescope apperature (in millimeters)
|
72
|
+
TFL = Telescope focal length (in millimeters)
|
73
|
+
F/? = Telescope focal ratio
|
74
|
+
<MGN = Magnitude limit (dimmest object visible)
|
75
|
+
xEYE = Times eye light gathering
|
76
|
+
MINx = Minimum magnification
|
77
|
+
MAXx = Maximum magnification
|
78
|
+
SEP-R = Rayleigh separation criterion
|
79
|
+
SEP-D = Dawes separation limit
|
80
|
+
*FLD = EP for star fields
|
81
|
+
GLXY = EP for galaxies & nebulae
|
82
|
+
PLNT = EP for planets, globular clusters
|
83
|
+
DBL* = EP for double stars & planetary details
|
84
|
+
>2*< = EP for tight double stars
|
85
|
+
MOON = Smallest detail visible on Moon
|
86
|
+
SUN = Smallest detail visible on Sun
|
87
|
+
|
88
|
+
FL = EP focal length (in millimeters)
|
89
|
+
AFOV = EP apparent field of view
|
90
|
+
MAGX = Magnification (w/selected telescope)
|
91
|
+
TFOV = True field of view (w/selected telescope)
|
92
|
+
PPL = Exit pupil (w/selected telescope)
|
93
|
+
2BLW = With a 2xBarlow (magnification, then rest)'.fg(229)
|
94
|
+
|
95
|
+
# CLEAR CURSES ON EXIT {{{1
|
96
|
+
at_exit do
|
97
|
+
$stdin.cooked!
|
98
|
+
$stdin.echo = true
|
99
|
+
Rcurses.clear_screen
|
100
|
+
Cursor.show
|
54
101
|
end
|
55
|
-
|
56
|
-
|
102
|
+
|
103
|
+
# INITIALIZATION {{{1
|
104
|
+
# Data stores
|
105
|
+
@ts = [] # Telescopes: [name, app, fl]
|
106
|
+
@ep = [] # Eyepieces: [name, fl, afov]
|
107
|
+
@tstag = [] # Telescope tags
|
108
|
+
@eptag = [] # Eyepiece tags
|
109
|
+
@cursor_ts = 0 # Telescope cursor index
|
110
|
+
@cursor_ep = 0 # Eyepiece cursor index
|
111
|
+
|
112
|
+
# Load saved data if present
|
113
|
+
SAVE = File.join(Dir.home, '.telescope') # Persistence path
|
114
|
+
|
115
|
+
if File.exist?(SAVE)
|
116
|
+
load SAVE # expects plaintext: @ts = [...] and @ep = [...]
|
117
|
+
else
|
118
|
+
@ts = []
|
119
|
+
@ep = []
|
57
120
|
end
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
121
|
+
|
122
|
+
@ts_unsorted = @ts.dup
|
123
|
+
@ep_unsorted = @ep.dup
|
124
|
+
|
125
|
+
# Initialize tag arrays to match loaded data
|
126
|
+
@tstag = Array.new(@ts.size, false)
|
127
|
+
@eptag = Array.new(@ep.size, false)
|
128
|
+
|
129
|
+
# CLASS EXTENSIONS {{{1
|
130
|
+
# Numeric formatting helper
|
131
|
+
class Numeric
|
132
|
+
def deg; self * Math::PI / 180; end
|
133
|
+
def rad; self * 180 / Math::PI; end
|
134
|
+
def rts(n); format("%.#{n}f", self) end
|
68
135
|
end
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
# self.fg is set for the foreground color (and is used if self.color is not set)
|
75
|
-
# self.bg is set for the background color (and is used if self.color is not set)
|
76
|
-
# self.attr is set for text attributes like Curses::A_BOLD
|
77
|
-
def clr # Clears the whole window
|
78
|
-
self.setpos(0, 0)
|
79
|
-
self.maxy.times {self.deleteln()}
|
80
|
-
self.refresh
|
81
|
-
self.setpos(0, 0)
|
82
|
-
end
|
83
|
-
def clr_to_cur_line
|
84
|
-
l = self.cury
|
85
|
-
self.setpos(0, 0)
|
86
|
-
l.times {self.deleteln()}
|
87
|
-
self.refresh
|
88
|
-
end
|
89
|
-
def clr_from_cur_line
|
90
|
-
l = self.cury
|
91
|
-
(self.maxy - l).times {self.deleteln()}
|
92
|
-
self.refresh
|
93
|
-
self.setpos(l, 0)
|
94
|
-
end
|
95
|
-
def fill # Fill window with color as set by self.color (or self.bg if not set)
|
96
|
-
self.setpos(0, 0)
|
97
|
-
self.fill_from_cur_pos
|
98
|
-
end
|
99
|
-
def fill_to_cur_pos # Fills the window up to current line
|
100
|
-
x = self.curx
|
101
|
-
y = self.cury
|
102
|
-
self.setpos(0, 0)
|
103
|
-
blank = " " * self.maxx
|
104
|
-
if self.color == nil
|
105
|
-
self.bg = 0 if self.bg == nil
|
106
|
-
self.fg = 255 if self.fg == nil
|
107
|
-
init_pair(self.fg, self.fg, self.bg)
|
108
|
-
y.times {self.attron(color_pair(self.fg)) {self << blank}}
|
109
|
-
else
|
110
|
-
y.times {self.attron(color_pair(self.color)) {self << blank}}
|
111
|
-
end
|
112
|
-
self.refresh
|
113
|
-
self.setpos(y, x)
|
114
|
-
end
|
115
|
-
def fill_from_cur_pos # Fills the rest of the window from current line
|
116
|
-
x = self.curx
|
117
|
-
y = self.cury
|
118
|
-
self.setpos(y, 0)
|
119
|
-
blank = " " * self.maxx
|
120
|
-
if self.color == nil
|
121
|
-
self.bg = 0 if self.bg == nil
|
122
|
-
self.fg = 255 if self.fg == nil
|
123
|
-
init_pair(self.fg, self.fg, self.bg)
|
124
|
-
self.maxy.times {self.attron(color_pair(self.fg)) {self << blank}}
|
125
|
-
else
|
126
|
-
self.maxy.times {self.attron(color_pair(self.color)) {self << blank}}
|
127
|
-
end
|
128
|
-
self.refresh
|
129
|
-
self.setpos(y, x)
|
130
|
-
end
|
131
|
-
def p(text) # Puts text to window
|
132
|
-
self.attr = 0 if self.attr == nil
|
133
|
-
if self.color == nil
|
134
|
-
self.bg = 0 if self.bg == nil
|
135
|
-
self.fg = 255 if self.fg == nil
|
136
|
-
init_pair(self.fg, self.fg, self.bg)
|
137
|
-
self.attron(color_pair(self.fg) | self.attr) { self << text }
|
138
|
-
else
|
139
|
-
self.attron(color_pair(self.color) | self.attr) { self << text }
|
140
|
-
end
|
141
|
-
self.refresh
|
142
|
-
end
|
143
|
-
def pclr(text) # Puts text to window and clears the rest of the window
|
144
|
-
self.p(text)
|
145
|
-
self.clr_from_cur_line
|
146
|
-
end
|
147
|
-
def paclr(fg, bg, attr, text) # Puts text to window with full set of attributes and clears rest of window
|
148
|
-
self.paclr(fg, bg, attr, text)
|
149
|
-
self.clr_from_cur_line
|
150
|
-
end
|
151
|
-
def pa(fg, bg, attr, text) # Puts text to window with full set of attributes
|
152
|
-
self.fg = fg
|
153
|
-
self.bg = bg
|
154
|
-
self.attr = attr
|
155
|
-
init_pair(self.fg, self.fg, self.bg)
|
156
|
-
self.attron(color_pair(self.fg) | self.attr) { self << text }
|
157
|
-
self.refresh
|
136
|
+
|
137
|
+
# Pane class extension
|
138
|
+
module Rcurses
|
139
|
+
class Pane
|
140
|
+
attr_accessor :index
|
158
141
|
end
|
159
142
|
end
|
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
|
-
|
143
|
+
|
144
|
+
# OPTICAL FORMULAS {{{1
|
145
|
+
def tfr(app, tfl); (tfl.to_f / app); end
|
146
|
+
def mlim(app); (5 * Math::log(app / 10, 10) + 7.5); end
|
147
|
+
def xeye(app); (app.to_f ** 2 / 49); end
|
148
|
+
def minx(app, tfl); (tfl / (7 * tfr(app, tfl))); end
|
149
|
+
def mine(app, tfl); (7 * tfr(app, tfl)); end
|
150
|
+
def maxx(app); (2 * app.to_f); end
|
151
|
+
def maxe(app, tfl); (tfl / maxx(app)); end
|
152
|
+
def sepr(app); (3600.0 * Math::asin(671E-6 / app).rad); end
|
153
|
+
def sepd(app); (115.824 / app); end
|
154
|
+
def e_st(app, tfl); (6.4 * tfl / app); end
|
155
|
+
def e_gx(app, tfl); (3.6 * tfl / app); end
|
156
|
+
def e_pl(app, tfl); (2.1 * tfl / app); end
|
157
|
+
def e_2s(app, tfl); (1.3 * tfl / app); end
|
158
|
+
def e_t2(app, tfl); (0.7 * tfl / app); end
|
159
|
+
def moon(tfl); (384E6*Math::tan((115.824.deg / tfl)/360)); end
|
160
|
+
def sun(tfl); (moon(tfl) / 2.5668); end
|
161
|
+
def tfov(tfl, epfl, afov); (afov.to_f / magx(tfl, epfl)); end
|
162
|
+
def pupl(app, tfl, epfl); (app.to_f / magx(tfl, epfl)); end
|
163
|
+
def magx(tfl, epfl); (tfl.to_f / epfl); end
|
164
|
+
|
165
|
+
# FUNCTIONS {{{1
|
166
|
+
def refresh_all #{{{2
|
167
|
+
Rcurses.clear_screen
|
168
|
+
@pTS.border = false
|
169
|
+
@pEP.border = false
|
170
|
+
@focus.border = true
|
171
|
+
@pTS.full_refresh
|
172
|
+
@pTSh.full_refresh
|
173
|
+
@pEP.full_refresh
|
174
|
+
@pEPh.full_refresh
|
175
|
+
@pST.refresh
|
190
176
|
end
|
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
|
-
return if @ts.length == 5
|
231
|
-
ret = w_cm_getstr("", "Telescope, App, FL").split(",")
|
232
|
-
return if ret.length != 3
|
233
|
-
ret[1] = ret[1].to_i
|
234
|
-
ret[2] = ret[2].to_i
|
235
|
-
ret[1] = 1 if ret[1] == 0
|
236
|
-
ret[2] = 1 if ret[2] == 0
|
237
|
-
@ts[@ts.length] = ret
|
238
|
-
when 'e' # Add an eyepiece
|
239
|
-
ret = w_cm_getstr("", "Eyepiece, FL, AFOV").split(",")
|
240
|
-
return if ret.length != 3
|
241
|
-
ret[1] = ret[1].to_f
|
242
|
-
ret[2] = ret[2].to_i
|
243
|
-
ret[1] = 1 if ret[1] == 0
|
244
|
-
ret[2] = 1 if ret[2] == 0
|
245
|
-
@ep[@ep.length] = ret
|
246
|
-
when 'D' # Delete selected item (telescope or eyepiece)
|
247
|
-
if @tsmark
|
248
|
-
@ts.delete_at(@tsmark)
|
249
|
-
@tsmark -= 1
|
250
|
-
elsif @epmark
|
251
|
-
@ep.delete_at(@epmark)
|
252
|
-
@epmark -= 1
|
253
|
-
end
|
254
|
-
when 'T' # Sort telescopes by next column (Name, APP, FL)
|
255
|
-
if @t_sort == false or @t_sort == 2
|
256
|
-
@t_sort = 0
|
257
|
-
else
|
258
|
-
@t_sort += 1
|
259
|
-
end
|
260
|
-
@ts = @ts.sort {|a,b| b[@t_sort] <=> a[@t_sort]}
|
261
|
-
when 'E' # Sort eyepiece by next column (Name, FL, AFOV)
|
262
|
-
if @e_sort == false or @e_sort == 2
|
263
|
-
@e_sort = 0
|
264
|
-
else
|
265
|
-
@e_sort += 1
|
266
|
-
end
|
267
|
-
@ep = @ep.sort {|a,b| b[@e_sort] <=> a[@e_sort]}
|
268
|
-
when 'UP' # Move to one item up
|
269
|
-
if @tsmark
|
270
|
-
if @tsmark == 0
|
271
|
-
@tsmark = false
|
272
|
-
else
|
273
|
-
@tsmark -= 1
|
274
|
-
end
|
275
|
-
elsif @epmark
|
276
|
-
if @epmark == 0
|
277
|
-
@epmark = false
|
278
|
-
@tsmark = @ts.length - 1
|
279
|
-
else
|
280
|
-
@epmark -= 1
|
281
|
-
end
|
282
|
-
else
|
283
|
-
@epmark = @ep.length - 1
|
284
|
-
end
|
285
|
-
when 'DOWN' # Move to one item down
|
286
|
-
if @tsmark
|
287
|
-
if @tsmark == @ts.length - 1
|
288
|
-
@tsmark = false
|
289
|
-
@epmark = 0
|
290
|
-
else
|
291
|
-
@tsmark += 1
|
292
|
-
end
|
293
|
-
elsif @epmark
|
294
|
-
if @epmark == @ep.length - 1
|
295
|
-
@epmark = false
|
296
|
-
else
|
297
|
-
@epmark += 1
|
298
|
-
end
|
299
|
-
else
|
300
|
-
@tsmark = 0
|
301
|
-
end
|
302
|
-
when 'PgUP' # Move selected item up by one
|
303
|
-
if @tsmark
|
304
|
-
t = @ts.delete_at(@tsmark)
|
305
|
-
@tsmark -= 1 unless @tsmark == 0
|
306
|
-
@ts.insert(@tsmark, t)
|
307
|
-
elsif @epmark
|
308
|
-
e = @ep.delete_at(@epmark)
|
309
|
-
@epmark -= 1 unless @epmark == 0
|
310
|
-
@ep.insert(@epmark, e)
|
311
|
-
end
|
312
|
-
when 'PgDOWN' # Move selected item by one down
|
313
|
-
if @tsmark
|
314
|
-
t = @ts.delete_at(@tsmark)
|
315
|
-
@tsmark += 1 unless @tsmark == @ts.length
|
316
|
-
@ts.insert(@tsmark, t)
|
317
|
-
elsif @epmark
|
318
|
-
e = @ep.delete_at(@epmark)
|
319
|
-
@epmark += 1 unless @epmark == @ep.length
|
320
|
-
@ep.insert(@epmark, e)
|
321
|
-
end
|
322
|
-
when 'HOME' # Jump to first item in the panel
|
323
|
-
if @tsmark
|
324
|
-
@tsmark = 0
|
325
|
-
elsif @epmark
|
326
|
-
@epmark = 0
|
327
|
-
end
|
328
|
-
when 'END' # Move to last item in the panel
|
329
|
-
if @tsmark
|
330
|
-
@tsmark = @ts.length - 1
|
331
|
-
elsif @epmark
|
332
|
-
@epmark = @ep.length - 1
|
333
|
-
end
|
334
|
-
when ' ' # Tag selected item to be used in observation file/log
|
335
|
-
if @tsmark
|
336
|
-
@tstag.include?(@tsmark) ? @tstag.delete(@tsmark) : @tstag.push(@tsmark)
|
337
|
-
@tsmark += 1 unless @tsmark == @ts.length - 1
|
338
|
-
elsif @epmark
|
339
|
-
@eptag.include?(@epmark) ? @eptag.delete(@epmark) : @eptag.push(@epmark)
|
340
|
-
@epmark += 1 unless @epmark == @ep.length - 1
|
341
|
-
end
|
342
|
-
when 'u' # Untag all tagget items
|
343
|
-
@tstag.clear
|
344
|
-
@eptag.clear
|
345
|
-
when 'o' # Create observation file/log and show content in lower panel
|
346
|
-
observe
|
347
|
-
when 'b' # Create backup file (~/.telescope.bu) with current items
|
348
|
-
File.write(Dir.home+'/.telescope.bu',"@ts = #{@ts}\n@ep = #{@ep}")
|
349
|
-
when 'B' # Read items from backup file
|
350
|
-
if File.exist?(Dir.home+'/.telescope.bu')
|
351
|
-
load(Dir.home+'/.telescope.bu')
|
352
|
-
end
|
353
|
-
when 'r' # Hard refres panels
|
354
|
-
@break = true
|
355
|
-
when 'q' # Exit after saving items to ~/.telescope
|
356
|
-
File.write(Dir.home+'/.telescope',"@ts = #{@ts}\n@ep = #{@ep}")
|
357
|
-
exit 0
|
358
|
-
when 'Q' # Exit without saving items
|
359
|
-
exit 0
|
360
|
-
else
|
177
|
+
|
178
|
+
def render_ts #{{{2
|
179
|
+
@pTS.clear
|
180
|
+
@ts.each_with_index do |t, i|
|
181
|
+
@pTS.text += "\n"
|
182
|
+
name = t[0]
|
183
|
+
app = t[1].to_i
|
184
|
+
tfl = t[2].to_i
|
185
|
+
tag_ts = @tstag[i] ? ' ' + '▐'.b.fg(46) : ' '
|
186
|
+
txt = tag_ts
|
187
|
+
txt += name.to_s.ljust(18)
|
188
|
+
txt += app.to_s.rjust(7)
|
189
|
+
txt += tfl.to_s.rjust(8)
|
190
|
+
txt += tfr(app, tfl).rts(1).rjust(6)
|
191
|
+
txt += mlim(app).rts(1).rjust(6)
|
192
|
+
txt += xeye(app).rts(0).rjust(6)
|
193
|
+
min = mine(app, tfl).rts(0)
|
194
|
+
min += "(" + minx(app, tfl).rts(0) + "x)"
|
195
|
+
txt += min.rjust(10)
|
196
|
+
max = maxe(app, tfl).rts(0)
|
197
|
+
max += "(" + maxx(app).rts(0) + "x)"
|
198
|
+
txt += max.rjust(9)
|
199
|
+
txt += sepr(app).rts(2).rjust(7) + '"'
|
200
|
+
txt += sepd(app).rts(2).rjust(6) + '"'
|
201
|
+
txt += e_st(app, tfl).rts(0).rjust(7)
|
202
|
+
txt += e_gx(app, tfl).rts(0).rjust(6)
|
203
|
+
txt += e_pl(app, tfl).rts(0).rjust(6)
|
204
|
+
txt += e_2s(app, tfl).rts(0).rjust(6)
|
205
|
+
txt += e_t2(app, tfl).rts(0).rjust(6)
|
206
|
+
txt += moon(tfl).rts(0).rjust(7)
|
207
|
+
txt += sun(tfl).rts(0).rjust(6)
|
208
|
+
txt[0] = '→' if i == @pTS.index
|
209
|
+
# ANSI safe padding
|
210
|
+
pad = @pTS.w - Rcurses.display_width(txt.pure)
|
211
|
+
pad = 0 if pad.negative?
|
212
|
+
txt += ' ' * pad
|
213
|
+
txt = txt.bg(234) if i == @pTS.index
|
214
|
+
txt = txt.fg(248) if i != @pTS.index
|
215
|
+
@pTS.text += txt
|
361
216
|
end
|
217
|
+
@pTS.refresh
|
218
|
+
@pTSh.full_refresh
|
362
219
|
end
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
enum = "ABCDE"
|
374
|
-
@tstag.each_with_index do |t, i|
|
375
|
-
d = @ts[t][1]
|
376
|
-
f = @ts[t][2]
|
377
|
-
obs += "Telescope (#{enum[i]}): " + @ts[t][0].ljust(15) + " ("
|
378
|
-
obs += d.to_s + "mm/" + f.to_s + "mm f/" + (f/d.to_f).truncate(1).to_s + ")"
|
379
|
-
mag = (5 * Math::log(d/10, 10) + 7.5).truncate(1).to_s
|
380
|
-
obs += " Max MAG: " + mag
|
381
|
-
sepd = (115.824/d).truncate(2).to_s
|
382
|
-
sepr = (3600*Math::asin(671E-6/d).rad).truncate(2).to_s
|
383
|
-
obs += " Min SEP: " + sepd + "/" + sepr + "\n"
|
384
|
-
end
|
385
|
-
obs += "No telescope(s) chosen for the observation\n" if @tstag.empty?
|
386
|
-
obs += "─" * 100 + "\n"
|
387
|
-
@eptag.each_with_index do |e, i|
|
388
|
-
m = @ep[e][1]
|
389
|
-
a = @ep[e][2]
|
390
|
-
obs += "Eyepiece (#{i+1}): " + @ep[e][0].ljust(15) + " ("
|
391
|
-
obs += m.to_s.rjust(4) + "mm/" + a.to_s.rjust(3) + "°) "
|
392
|
-
@tstag.each_with_index do |t, j|
|
393
|
-
d = @ts[t][1]
|
394
|
-
f = @ts[t][2]
|
395
|
-
obs += enum[j] + ": "
|
396
|
-
mag = (f.to_f/m)
|
397
|
-
obs += mag.truncate(1).to_s.rjust(5) + "x ("
|
398
|
-
fov = a/mag
|
399
|
-
deg = fov.to_i
|
400
|
-
mins = ((fov - fov.to_i) * 60)
|
401
|
-
min = mins.to_i
|
402
|
-
sec = ((mins - min) * 60).to_i
|
403
|
-
deg == 0 ? dgo = " " : dgo = deg.to_s + "°"
|
404
|
-
mno = min.to_s.rjust(2, " ") + "'"
|
405
|
-
sco = sec.to_s.rjust(2, " ") + "\""
|
406
|
-
obs += (dgo + mno + sco) + ") "
|
407
|
-
end
|
408
|
-
obs += "\n"
|
409
|
-
end
|
410
|
-
obs += "No eyepiece(s) chosen for the observation\n" if @eptag.empty?
|
411
|
-
obs += "─" * 100 + "\n\n"
|
412
|
-
obs += "Object: Equipment: Observation:\n" * 8
|
413
|
-
@w_ep.clr
|
414
|
-
@w_ep.pa(255, 0, 0, obs)
|
415
|
-
@w_ep.p("\n...Press any key to continue")
|
416
|
-
File.write(file, obs)
|
417
|
-
getch
|
220
|
+
|
221
|
+
def ep_nice(app, tfl, e) #{{{2
|
222
|
+
r = (tfl / app)
|
223
|
+
out = ' '
|
224
|
+
out += (e/6 > r ? ' ✓'.fg(112) : ' ✗'.fg(208))
|
225
|
+
out += (e/3 > r && e/6 <= r ? ' ✓'.fg(112) : ' ✗'.fg(208))
|
226
|
+
out += (e/1.5 > r && e/3 <= r ? ' ✓'.fg(112) : ' ✗'.fg(208))
|
227
|
+
out += (e >= r && e/1.5 <= r ? ' ✓'.fg(112) : ' ✗'.fg(208))
|
228
|
+
out += (e < r ? ' ✓'.fg(112) : ' ✗'.fg(208))
|
229
|
+
out
|
418
230
|
end
|
419
231
|
|
420
|
-
|
421
|
-
|
422
|
-
@
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
@w_ts.pa(219, 0, attr, out) # RC-SEP
|
463
|
-
moon = (384E6*Math::tan((115.824.deg/d)/3600))
|
464
|
-
out = moon.to_i.to_s.rjust(6) + "m"
|
465
|
-
@w_ts.pa(225, 0, attr, out) # MOON
|
466
|
-
out = (moon/2.5668).to_i.to_s.rjust(5) + "km"
|
467
|
-
@w_ts.pa(225, 0, attr, out) # SUN
|
468
|
-
@w_ts.p("\n")
|
232
|
+
def render_ep #{{{2
|
233
|
+
app = @ts[@pTS.index][1].to_f
|
234
|
+
tfl = @ts[@pTS.index][2].to_f
|
235
|
+
@pEP.text = "\n"
|
236
|
+
@ep.each_with_index do |e, i|
|
237
|
+
name = e[0]
|
238
|
+
epfl = e[1].to_f
|
239
|
+
afov = e[2].to_f
|
240
|
+
tag_ep = @eptag[i] ? ' ' + '▐'.b.fg(46) : ' '
|
241
|
+
txt = tag_ep
|
242
|
+
txt += name.to_s.ljust(18)
|
243
|
+
txt += epfl.to_s.rjust(7)
|
244
|
+
txt += afov.to_s.rjust(8)
|
245
|
+
txt += magx(tfl, epfl).rts(0).rjust(8) + 'x'
|
246
|
+
fov = tfov(tfl, epfl, afov)
|
247
|
+
deg = fov.to_i
|
248
|
+
min = ((fov - deg) * 60).to_i
|
249
|
+
sec = ((fov - deg - min/60.0) * 3600).to_i
|
250
|
+
min_s = format('%02d', min)
|
251
|
+
sec_s = format('%02d', sec)
|
252
|
+
dms = "#{deg}°#{min_s}'#{sec_s}\""
|
253
|
+
txt += dms.rjust(11)
|
254
|
+
txt += pupl(app, tfl, epfl).rts(1).rjust(6)
|
255
|
+
txt += (magx(tfl, epfl) * 2).rts(0).rjust(8) + 'x'
|
256
|
+
tfov2 = tfov(tfl, epfl, afov) / 2.0
|
257
|
+
deg2 = tfov2.to_i
|
258
|
+
min2 = ((tfov2 - deg2) * 60).to_i
|
259
|
+
sec2 = ((tfov2 - deg2 - min2/60.0) * 3600).to_i
|
260
|
+
min2_s = format('%02d', min2)
|
261
|
+
sec2_s = format('%02d', sec2)
|
262
|
+
dms2 = "#{deg2}°#{min2_s}'#{sec2_s}\""
|
263
|
+
txt += dms2.rjust(11)
|
264
|
+
txt += (pupl(app, tfl, epfl) / 2).rts(1).rjust(6)
|
265
|
+
txt = txt.fg(248) if i != @pEP.index
|
266
|
+
txt += ep_nice(app, tfl, epfl)
|
267
|
+
txt[0] = '→' if i == @pEP.index
|
268
|
+
# ANSI safe padding
|
269
|
+
pad = @pEP.w - Rcurses.display_width(txt.pure)
|
270
|
+
pad = 0 if pad.negative?
|
271
|
+
txt += ' ' * pad
|
272
|
+
txt = txt.bg(234) if i == @pEP.index
|
273
|
+
@pEP.text += txt
|
469
274
|
end
|
470
|
-
@
|
471
|
-
|
472
|
-
def magx(d, f, r)
|
473
|
-
m = d * r
|
474
|
-
e = f / m
|
475
|
-
return (m.to_i.to_s + "(" + e.to_i.to_s + ")").rjust(8)
|
275
|
+
@pEP.refresh
|
276
|
+
@pEPh.full_refresh
|
476
277
|
end
|
477
278
|
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
attr = attr | Curses::A_UNDERLINE if @eptag.include?(i)
|
507
|
-
@w_ep.pa(253, 0, attr, out)
|
508
|
-
@ts.each do |scope|
|
509
|
-
d = scope[1]
|
510
|
-
f = scope[2]
|
511
|
-
mag = (f.to_f/m)
|
512
|
-
@w_ep.pa(254, 0, attr, " │")
|
513
|
-
out = mag.truncate(1).to_s.rjust(6)
|
514
|
-
@w_ep.pa(156, 0, attr, out)
|
515
|
-
fov = a/mag
|
516
|
-
deg = fov.to_i
|
517
|
-
mins = ((fov - fov.to_i) * 60)
|
518
|
-
min = mins.to_i
|
519
|
-
sec = ((mins - min) * 60).to_i
|
520
|
-
deg == 0 ? dgo = " " : dgo = deg.to_s + "°"
|
521
|
-
mno = min.to_s.rjust(2, " ") + "'"
|
522
|
-
sco = sec.to_s.rjust(2, " ") + "\""
|
523
|
-
out = (dgo + mno + sco).rjust(10)
|
524
|
-
@w_ep.pa(222, 0, attr, out)
|
525
|
-
out = (d/mag).truncate(1).to_s.rjust(6)
|
526
|
-
@w_ep.pa(209, 0, attr, out)
|
279
|
+
def observe #{{{2
|
280
|
+
# Prepare file header
|
281
|
+
date = Date.today.iso8601
|
282
|
+
file = File.join(Dir.home, "#{date}_observation.txt")
|
283
|
+
|
284
|
+
obs = +"Observation file: #{file}\n"
|
285
|
+
obs << "Observation date: #{date}\n\n"
|
286
|
+
obs << "This file lists the intended equipment for the observation date.\n"
|
287
|
+
obs << "Reference observations with telescope letter and eyepiece numbers (like A2, B1, etc.)\n\n"
|
288
|
+
obs << ("─" * 100) << "\n"
|
289
|
+
|
290
|
+
enum = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
291
|
+
|
292
|
+
# Collect and print selected telescopes
|
293
|
+
sel_ts = @tstag.each_index.select { |i| @tstag[i] }
|
294
|
+
if sel_ts.empty?
|
295
|
+
obs << "No telescope(s) chosen for the observation\n"
|
296
|
+
else
|
297
|
+
sel_ts.each_with_index do |ts_idx, idx|
|
298
|
+
name, app_str, tfl_str = @ts[ts_idx]
|
299
|
+
app, tfl = app_str.to_f, tfl_str.to_f
|
300
|
+
|
301
|
+
obs << format(
|
302
|
+
"Telescope (%s): %-15s (%3.0fmm/%4.0fmm f/%.1f)",
|
303
|
+
enum[idx], name, app, tfl, tfr(app, tfl)
|
304
|
+
)
|
305
|
+
obs << format(" Max MAG: %.1f", mlim(app))
|
306
|
+
obs << format(" Min SEP: %.2f/%.2f\n", sepd(app), sepr(app))
|
527
307
|
end
|
528
|
-
@w_ep.p("\n")
|
529
308
|
end
|
530
|
-
@w_ep.clr_from_cur_line
|
531
|
-
end
|
532
309
|
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
text[pos] = ""
|
568
|
-
when 'BACK'
|
569
|
-
unless pos == 0
|
570
|
-
pos -= 1
|
571
|
-
text[pos] = ""
|
572
|
-
end
|
573
|
-
when 'WBACK'
|
574
|
-
unless pos == 0
|
575
|
-
until text[pos - 1] == " " or pos == 0
|
576
|
-
pos -= 1
|
577
|
-
text[pos] = ""
|
578
|
-
end
|
579
|
-
if text[pos - 1] == " "
|
580
|
-
pos -= 1
|
581
|
-
text[pos] = ""
|
582
|
-
end
|
310
|
+
obs << ("─" * 100) << "\n"
|
311
|
+
|
312
|
+
# Collect and print selected eyepieces (with per‐telescope TFOV)
|
313
|
+
sel_ep = @eptag.each_index.select { |i| @eptag[i] }
|
314
|
+
if sel_ep.empty?
|
315
|
+
obs << "No eyepiece(s) chosen for the observation\n"
|
316
|
+
else
|
317
|
+
sel_ep.each_with_index do |ep_idx, ep_num|
|
318
|
+
name, epfl_str, afov_str = @ep[ep_idx]
|
319
|
+
epfl, afov = epfl_str.to_f, afov_str.to_f
|
320
|
+
|
321
|
+
obs << format(
|
322
|
+
"Eyepiece (%d): %-15s (%4.0fmm/%3.0f°) ",
|
323
|
+
ep_num+1, name, epfl, afov
|
324
|
+
)
|
325
|
+
|
326
|
+
sel_ts.each_with_index do |ts_idx, ts_num|
|
327
|
+
app, tfl = @ts[ts_idx][1].to_f, @ts[ts_idx][2].to_f
|
328
|
+
mag = magx(tfl, epfl)
|
329
|
+
tf = tfov(tfl, epfl, afov)
|
330
|
+
|
331
|
+
# Break TFOV into deg, min, sec
|
332
|
+
deg = tf.to_i
|
333
|
+
min = ((tf - deg)*60).to_i
|
334
|
+
sec = ((tf - deg - min/60.0)*3600).to_i
|
335
|
+
angle = format(
|
336
|
+
"%2s%2d'%2d\"",
|
337
|
+
(deg.zero? ? " " : "#{deg}°"),
|
338
|
+
min, sec
|
339
|
+
)
|
340
|
+
obs << format(
|
341
|
+
"%s:%5.1fx (%s) ",
|
342
|
+
enum[ts_num], mag, angle
|
343
|
+
)
|
583
344
|
end
|
584
|
-
|
585
|
-
|
586
|
-
pos = 0
|
587
|
-
when /^.$/
|
588
|
-
text.insert(pos,chr)
|
589
|
-
pos += 1
|
345
|
+
|
346
|
+
obs << "\n"
|
590
347
|
end
|
591
348
|
end
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
349
|
+
|
350
|
+
obs << ("─" * 100) << "\n\n"
|
351
|
+
obs << ("Object: Equipment: Observation:\n" * 8)
|
352
|
+
@pObs.clear
|
353
|
+
@pObs.say(obs)
|
354
|
+
@pST.say(" Press any key to continue")
|
355
|
+
File.write(file, obs)
|
356
|
+
getchr
|
596
357
|
end
|
597
358
|
|
598
|
-
#
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
359
|
+
# PANE SETUP {{{1
|
360
|
+
# Top telescopes, eyepieces below, status at bottom
|
361
|
+
@max_h, @max_w = IO.console.winsize
|
362
|
+
@pTS = Pane.new( 2, 2, @max_w - 2, 8, nil, nil)
|
363
|
+
@pTSh = Pane.new( 2, 2, @max_w - 2, 1, 255, "00524b")
|
364
|
+
@pTSa = Pane.new( 1, @max_h, @max_w, 1, 255, "00524b")
|
365
|
+
@pEP = Pane.new( 2, 11, @max_w - 2, @max_h - 12, nil, nil)
|
366
|
+
@pEPh = Pane.new( 2, 11, @max_w - 2, 1, 255, "4c3c1d")
|
367
|
+
@pEPa = Pane.new( 1, @max_h, @max_w, 1, 255, "4c3c1d")
|
368
|
+
@pST = Pane.new( 1, @max_h, @max_w, 1, 255, 236)
|
369
|
+
|
370
|
+
@pHlp = Pane.new( @max_w/2 - 30, @max_h/2 - 13, 60, 26, 252, 233)
|
371
|
+
@pObs = Pane.new( 8, 8, @max_w - 16, @max_h - 16, 231, 233)
|
372
|
+
|
373
|
+
@pTSh.text = ' TELESCOPES APP(mm) FL(mm) F/? <MGN xEYE MINx MAXx SEP-R SEP-D *FLD GLXY PLNT DBL* >2*< MOON SUN'.b
|
374
|
+
@pEPh.text = ' EYEPIECES FL(mm) AFOV'.b
|
375
|
+
@pEPh.text += ' MAGX TFOV PPL 2blw tfov ppl'.b.i.fg("00827b")
|
376
|
+
@pEPh.text += ' *FLD GLXY PLNT DBL* >2*<'.bg("4c3c1d")
|
377
|
+
@pST.text = ' t/e = Add telescope/eyepiece, ENTER = Edit item, q/Q = Quit, ? = Help'
|
378
|
+
@pHlp.border = true
|
379
|
+
@pObs.border = true
|
380
|
+
|
381
|
+
@pTSa.record = true
|
382
|
+
@pEPa.record = true
|
383
|
+
@pTS.index = 0
|
384
|
+
@pEP.index = 0
|
385
|
+
@sort_ts = false
|
386
|
+
@sort_ep = false
|
387
|
+
@ts_unsorted = @ts.dup
|
388
|
+
@ep_unsorted = @ep.dup
|
389
|
+
@focus = @pTS
|
390
|
+
@current = @ts
|
391
|
+
|
392
|
+
# TRAP WIN SIZE CHANGE {{{1
|
393
|
+
Signal.trap('WINCH') do
|
394
|
+
@h, @w = IO.console.winsize
|
395
|
+
refresh_all
|
396
|
+
end
|
397
|
+
|
398
|
+
# MAIN LOOP {{{1
|
399
|
+
refresh_all
|
400
|
+
loop do
|
401
|
+
render_ts
|
402
|
+
render_ep
|
403
|
+
@pST.text = ' t/e = Add telescope/eyepiece, ENTER = Edit item, q/Q = Quit, ? = Help'
|
404
|
+
@pST.full_refresh
|
405
|
+
ch = getchr
|
406
|
+
case ch
|
407
|
+
when 'q'
|
408
|
+
File.write(SAVE, "@ts = #{@ts.inspect}\n@ep = #{@ep.inspect}\n") && exit
|
409
|
+
when 'Q'; exit
|
410
|
+
when '?'
|
411
|
+
@pHlp.full_refresh
|
412
|
+
@pHlp.say(HELP1)
|
413
|
+
getchr
|
414
|
+
@pHlp.say(HELP2)
|
415
|
+
getchr
|
416
|
+
@pHlp.say(HELP3)
|
417
|
+
getchr
|
418
|
+
refresh_all
|
419
|
+
when 'r'
|
420
|
+
refresh_all
|
421
|
+
when 't'
|
422
|
+
inp=@pTSa.ask('name, app, fl: ','').split(', ')
|
423
|
+
next unless inp.size == 3
|
424
|
+
@ts<<inp
|
425
|
+
@tstag<<false
|
426
|
+
@ts_unsorted << inp # keep master list updated
|
427
|
+
@current = @ts
|
428
|
+
when 'e'
|
429
|
+
inp=@pEPa.ask('name, fl, afov: ','').split(', ')
|
430
|
+
next unless inp.size == 3
|
431
|
+
@ep<<inp
|
432
|
+
@eptag<<false
|
433
|
+
@ep_unsorted << inp # keep master list updated
|
434
|
+
@current = @ep
|
435
|
+
when 'ENTER'
|
436
|
+
val = @current[@focus.index].join(', ')
|
437
|
+
arr=@pST.ask('Edit: ', val).split(', '); next unless arr.size==3
|
438
|
+
@current[@focus.index] = arr
|
439
|
+
when 'D'
|
440
|
+
if @current.equal?(@ts)
|
441
|
+
removed = @ts.delete_at(@focus.index)
|
442
|
+
@ts_unsorted.delete(removed)
|
443
|
+
@tstag.delete_at(@focus.index)
|
444
|
+
else
|
445
|
+
removed = @ep.delete_at(@focus.index)
|
446
|
+
@ep_unsorted.delete(removed)
|
447
|
+
@eptag.delete_at(@focus.index)
|
448
|
+
end
|
449
|
+
when 'TAB'
|
450
|
+
@focus = (@focus == @pTS ? @pEP : @pTS)
|
451
|
+
@current = (@current == @ts ? @ep : @ts)
|
452
|
+
@pTS.border = false
|
453
|
+
@pEP.border = false
|
454
|
+
@focus.border = true
|
455
|
+
@pTS.border_refresh
|
456
|
+
@pEP.border_refresh
|
457
|
+
when 'UP'
|
458
|
+
@focus.index -= 1
|
459
|
+
@focus.index = @current.length - 1 if @focus.index < 0
|
460
|
+
when 'DOWN'
|
461
|
+
@focus.index += 1
|
462
|
+
@focus.index = 0 if @focus.index > @current.length - 1
|
463
|
+
@focus == :ts ? @cursor_ts = 0 : @cursor_ep = 0
|
464
|
+
when 'HOME'
|
465
|
+
@focus.index = 0
|
466
|
+
when 'END'
|
467
|
+
@focus.index = @current.length - 1
|
468
|
+
when 'S-UP'
|
469
|
+
@current.insert([@focus.index - 1, 0].max, @current.delete_at(@focus.index))
|
470
|
+
@focus.index -= 1 if @focus.index != 0
|
471
|
+
when 'S-DOWN'
|
472
|
+
@current.insert([@focus.index + 1, @current.size - 1].min, @current.delete_at(@focus.index))
|
473
|
+
@focus.index += 1 if @focus.index != @current.size - 1
|
474
|
+
when 'o' # Toggle-sort the currently focused list
|
475
|
+
if @current.equal?(@ts) # toggling telescopes
|
476
|
+
@sort_ts = !@sort_ts
|
477
|
+
@ts = if @sort_ts
|
478
|
+
@ts_unsorted.sort_by { |t| t[1].to_i }
|
479
|
+
else
|
480
|
+
@ts_unsorted.dup
|
481
|
+
end
|
482
|
+
@current = @ts
|
483
|
+
@pTS.index = [@pTS.index, @ts.size - 1].min
|
484
|
+
else # toggling eyepieces
|
485
|
+
@sort_ep = !@sort_ep
|
486
|
+
@ep = if @sort_ep
|
487
|
+
@ep_unsorted.sort_by { |e| e[1].to_i }
|
488
|
+
else
|
489
|
+
@ep_unsorted.dup
|
490
|
+
end
|
491
|
+
@current = @ep
|
492
|
+
@pEP.index = [@pEP.index, @ep.size - 1].min
|
631
493
|
end
|
632
|
-
|
633
|
-
|
494
|
+
when ' ' # SPACE: tag/untag current entry
|
495
|
+
if @current.equal?(@ts)
|
496
|
+
idx = @pTS.index
|
497
|
+
@tstag[idx] = !@tstag[idx]
|
498
|
+
else
|
499
|
+
idx = @pEP.index
|
500
|
+
@eptag[idx] = !@eptag[idx]
|
501
|
+
end
|
502
|
+
when 'u'
|
503
|
+
@tstag.fill(false)
|
504
|
+
@eptag.fill(false)
|
505
|
+
when 'C-O'
|
506
|
+
observe
|
634
507
|
end
|
635
508
|
end
|
636
509
|
|
637
|
-
# vim: set sw=2 sts=2 et fdm=
|
510
|
+
# vim: set sw=2 sts=2 et filetype=ruby fdm=marker fdn=2 fcs=fold\:\ :
|
metadata
CHANGED
@@ -1,40 +1,34 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: telescope-term
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0
|
4
|
+
version: '1.0'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Geir Isene
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-05-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: rcurses
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
20
|
-
- - ">="
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: 1.3.2
|
19
|
+
version: '3.5'
|
23
20
|
type: :runtime
|
24
21
|
prerelease: false
|
25
22
|
version_requirements: !ruby/object:Gem::Requirement
|
26
23
|
requirements:
|
27
24
|
- - "~>"
|
28
25
|
- !ruby/object:Gem::Version
|
29
|
-
version: '
|
30
|
-
- - ">="
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
version: 1.3.2
|
26
|
+
version: '3.5'
|
33
27
|
description: 'With this program you can list your telescopes and eyepieces and get
|
34
28
|
a set of calculations done for each scope and for the combination of scope and eyepiece.
|
35
|
-
Easy interface. Run the program, then hit ''?'' to show the help file.
|
36
|
-
|
37
|
-
|
29
|
+
Easy interface. Run the program, then hit ''?'' to show the help file. Version 1.0:
|
30
|
+
A full rewrite using the rcurses library (https://github.com/isene/rcurses) - lots
|
31
|
+
of improvements.'
|
38
32
|
email: g@isene.com
|
39
33
|
executables:
|
40
34
|
- telescope
|
@@ -47,7 +41,7 @@ licenses:
|
|
47
41
|
- Unlicense
|
48
42
|
metadata:
|
49
43
|
source_code_uri: https://github.com/isene/telescope
|
50
|
-
post_install_message:
|
44
|
+
post_install_message:
|
51
45
|
rdoc_options: []
|
52
46
|
require_paths:
|
53
47
|
- lib
|
@@ -62,8 +56,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
62
56
|
- !ruby/object:Gem::Version
|
63
57
|
version: '0'
|
64
58
|
requirements: []
|
65
|
-
rubygems_version: 3.
|
66
|
-
signing_key:
|
59
|
+
rubygems_version: 3.4.20
|
60
|
+
signing_key:
|
67
61
|
specification_version: 4
|
68
|
-
summary: Terminal program
|
62
|
+
summary: Terminal program for the amateur astronomer.
|
69
63
|
test_files: []
|