rndk 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +23 -0
  3. data/COPYING +137 -0
  4. data/Gemfile +4 -0
  5. data/README.md +100 -0
  6. data/Rakefile +3 -0
  7. data/TODO +68 -0
  8. data/demos/appointment.rb +346 -0
  9. data/demos/clock.rb +56 -0
  10. data/examples/01-hello-world.rb +56 -0
  11. data/examples/05-position-widget.rb +108 -0
  12. data/lib/rndk.rb +912 -0
  13. data/lib/rndk/alphalist.rb +572 -0
  14. data/lib/rndk/button.rb +370 -0
  15. data/lib/rndk/buttonbox.rb +359 -0
  16. data/lib/rndk/calendar.rb +766 -0
  17. data/lib/rndk/core/display.rb +63 -0
  18. data/lib/rndk/core/draw.rb +238 -0
  19. data/lib/rndk/core/quick_widgets.rb +106 -0
  20. data/lib/rndk/core/screen.rb +269 -0
  21. data/lib/rndk/core/traverse.rb +289 -0
  22. data/lib/rndk/core/widget.rb +506 -0
  23. data/lib/rndk/dialog.rb +367 -0
  24. data/lib/rndk/dscale.rb +13 -0
  25. data/lib/rndk/entry.rb +575 -0
  26. data/lib/rndk/fscale.rb +61 -0
  27. data/lib/rndk/fselect.rb +940 -0
  28. data/lib/rndk/fslider.rb +80 -0
  29. data/lib/rndk/graph.rb +401 -0
  30. data/lib/rndk/histogram.rb +412 -0
  31. data/lib/rndk/itemlist.rb +474 -0
  32. data/lib/rndk/label.rb +218 -0
  33. data/lib/rndk/marquee.rb +244 -0
  34. data/lib/rndk/matrix.rb +1189 -0
  35. data/lib/rndk/mentry.rb +619 -0
  36. data/lib/rndk/menu.rb +478 -0
  37. data/lib/rndk/radio.rb +538 -0
  38. data/lib/rndk/scale.rb +538 -0
  39. data/lib/rndk/scroll.rb +633 -0
  40. data/lib/rndk/scroller.rb +183 -0
  41. data/lib/rndk/selection.rb +630 -0
  42. data/lib/rndk/slider.rb +545 -0
  43. data/lib/rndk/swindow.rb +766 -0
  44. data/lib/rndk/template.rb +560 -0
  45. data/lib/rndk/uscale.rb +14 -0
  46. data/lib/rndk/uslider.rb +14 -0
  47. data/lib/rndk/version.rb +6 -0
  48. data/lib/rndk/viewer.rb +825 -0
  49. data/rndk.gemspec +35 -0
  50. metadata +141 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a5b6103e3b2539bf72321942974536d2688cdf41
4
+ data.tar.gz: 5890e72b066792bf7c11e0810aa6fec292c287d8
5
+ SHA512:
6
+ metadata.gz: 4236e304d133df93247638b65dba122a1b434f6934f6635e4de784aa169696e773c874efdcb2835713390ee10e7c683b53a71594d9d1eb8b8f01d26d5a3d5af5
7
+ data.tar.gz: 18585b599021f220cc26fb9e2127b04727ef7d757b965be78b8e33d66ea27e3ef11f83a0f8013d53cd01b733eb7bc88925a9a40539ffbccf6b7647a946d0e5ec
data/.gitignore ADDED
@@ -0,0 +1,23 @@
1
+ # Files starting with 'NOPE' are a way for me
2
+ # to ignore files that I'm still converting from
3
+ # old CDK style to current RNDK format.
4
+ NOPE*
5
+
6
+ # "regular" files to ignore
7
+ *.gem
8
+ *.rbc
9
+ .bundle
10
+ .config
11
+ .yardoc
12
+ Gemfile.lock
13
+ InstalledFiles
14
+ _yardoc
15
+ coverage
16
+ doc/
17
+ lib/bundler/man
18
+ pkg
19
+ rdoc
20
+ spec/reports
21
+ test/tmp
22
+ test/version_tmp
23
+ tmp
data/COPYING ADDED
@@ -0,0 +1,137 @@
1
+ RNDK copyright Alexandre Dantas 2013
2
+
3
+ Normally I'd use GPL, but since I don't know if I can simply do that,
4
+ I'll keep the same license as Chris Sauro on his original ruby CDK port.
5
+ See right below.
6
+
7
+ ================================================================================
8
+
9
+ Original Ruby CDK port copyright Chris Sauro 2013
10
+
11
+ Like Thomas, I am keeping this under a BSD license but I am changing to the
12
+ 3-clause version rather than the old 4-clause version. The text of this
13
+ license is copied below and the original COPYING file is available below
14
+ that. -CS
15
+
16
+ ================================================================================
17
+
18
+ Copyright (c) 2013, Chris Sauro
19
+ All rights reserved.
20
+
21
+ Redistribution and use in source and binary forms, with or without
22
+ modification, are permitted provided that the following conditions are met:
23
+ * Redistributions of source code must retain the above copyright
24
+ notice, this list of conditions and the following disclaimer.
25
+ * Redistributions in binary form must reproduce the above copyright
26
+ notice, this list of conditions and the following disclaimer in the
27
+ documentation and/or other materials provided with the distribution.
28
+ * Neither the name of Chris Sauro nor the
29
+ names of its contributors may be used to endorse or promote products
30
+ derived from this software without specific prior written permission.
31
+
32
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
33
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
34
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
35
+ DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
36
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
38
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
39
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
41
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42
+
43
+ ================================================================================
44
+
45
+ Modifications copyright Thomas Dickey 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
46
+
47
+ The software and documentation are still under the same licensing are the
48
+ original Cdk, but noting that substantial work and enhancements have been made,
49
+ I've added my name as needed -TD
50
+
51
+ The original COPYING file follows (with corrections as noted in CHANGES).
52
+
53
+ ================================================================================
54
+
55
+ Cdk Copying Guide
56
+ Copyright Mike Glover, 1995, 1996, 1997, 1998, 1999
57
+ -------------------------------------------------------------------------------
58
+ In order to copy Cdk around I have some requirements that will protect me,
59
+ and possibly even you. First thing, I feel I should say that this little project
60
+ of mine has taken quite a bit 'free' time and I have put a lot of work
61
+ into it. I do ask that if anyone asks you about Cdk, tell them where you got it
62
+ and who wrote it. If you see Cdk installed without this file on the system
63
+ somewhere, then assume the copy the person has is a 'corrupt' version. I will
64
+ not be responsible for any unfortunate results if someone else makes a personal
65
+ modification to the Cdk library. I will also not be responsible if for some
66
+ reason the installation of Cdk creates a negative effect on your machine. You
67
+ do have my word that there are no "Trojan horses", worms, or other security
68
+ worries lurking in this code. If there are I did not put them there and you
69
+ should remove the version of Cdk you have and go get a proper copy. I hate
70
+ virus writers as much as anyone else!
71
+
72
+ Instead of writing my own license (I'm a programmer, not a lawyer!) I'm going
73
+ to adapt the BSD public license on public software. If you do not agree to
74
+ this license then remove the Cdk distribution and we all will be happier in
75
+ the end. Here is the complete BSD public license in its true form, for
76
+ reference.
77
+
78
+ I will say one thing, Cdk is my copyright. I will continue to support any
79
+ released versions out there as long as they are in their released form. I am
80
+ releasing this into the "public" because I feel I have benefited from other
81
+ people's hard work, I'd like to chip into the pot as well. This does NOT make
82
+ Cdk public domain though. Cdk is still my copyright, and owned by me, I am
83
+ merely stating this so I don't see 40 different versions of my code floating
84
+ around with other people's names attached.
85
+
86
+ With that ugly stuff said, I will happily take any comments or questions about
87
+ Cdk. Input is more than welcomed. In fact I encourage it. Feel free to mail
88
+ me and ask questions you think the supplied documents don't cover. If I get
89
+ enough I may build a FAQ to help newcomers. (We'll see how Cdk is accepted
90
+ though).
91
+
92
+ For you Perl programmers, there is a Perl5 extension to Cdk. Look at your
93
+ closest CPAN site under authors/id/GLOVER.
94
+
95
+ If you want to get a hold of me mail me at one of the following:
96
+ glover@credit.erin.utoronto.ca
97
+ mike@vexus.ca
98
+
99
+ The CDK Web page has several homes. They are:
100
+ http://www.vexus.ca/CDK.html (official)
101
+ http://www.datasoft.on.ca/~cdk (Sponsored by the nice folks at Datasoft)
102
+
103
+ ttfn,
104
+ Mike
105
+ -------------------------------------------------------------------------------
106
+
107
+ Copyright (c) 1999, Mike Glover
108
+ All rights reserved.
109
+
110
+ Redistribution and use in source and binary forms, with or without
111
+ modification, are permitted provided that the following conditions
112
+ are met:
113
+ 1. Redistributions of source code must retain the above copyright
114
+ notice, this list of conditions and the following disclaimer.
115
+ 2. Redistributions in binary form must reproduce the above copyright
116
+ notice, this list of conditions and the following disclaimer in the
117
+ documentation and/or other materials provided with the distribution.
118
+ 3. All advertising materials mentioning features or use of this software
119
+ must display the following acknowledgment:
120
+ This product includes software developed by Mike Glover
121
+ and contributors.
122
+ 4. Neither the name of Mike Glover, nor the names of contributors
123
+ may be used to endorse or promote products derived from this software
124
+ without specific prior written permission.
125
+
126
+ THIS SOFTWARE IS PROVIDED BY MIKE GLOVER AND CONTRIBUTORS ``AS IS'' AND
127
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
128
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
129
+ ARE DISCLAIMED. IN NO EVENT SHALL MIKE GLOVER OR CONTRIBUTORS BE LIABLE
130
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
131
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
132
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
133
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
134
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
135
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
136
+ SUCH DAMAGE.
137
+
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rndk.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,100 @@
1
+ # Ruby Ncurses Development Kit (RNDK)
2
+
3
+ `rndk` aims to be a powerful, well-documented and easy-to-use
4
+ Ncurses Development Kit in Ruby. Besides abstracting away Ncurses'
5
+ details, it provides some widgets for rapid console app development.
6
+
7
+ It means that you'll be able to master the dark arts of text-based
8
+ applications, easily creating nice apps for the console.
9
+
10
+ `RNDK` is a fork from `tawny-cdk`, a [Chris Sauro Ruby port][tawny]
11
+ of [Thomas Dickey's Curses Development Kit][cdk] (in C).
12
+
13
+ Currently implemented widgets:
14
+
15
+ * Alphalist
16
+ * Button
17
+ * Buttonbox
18
+ * Calendar
19
+ * Dialog
20
+ * Entry
21
+ * File Selector
22
+ * Graph
23
+ * Histogram
24
+ * Item List
25
+ * Label
26
+ * Matrix
27
+ * Marquee
28
+ * Menu
29
+ * Multiple Line Entry
30
+ * Radio List
31
+ * Scale
32
+ * Scrolling List
33
+ * Scrolling Window
34
+ * Selection List
35
+ * Slider
36
+ * Template
37
+ * Viewer
38
+
39
+ ## WARNING
40
+
41
+ This is a very unstable Work-in-Progress library.
42
+
43
+ I'm currently reviewing `tawny-cdk`'s API, so a lot of things are
44
+ changing real fast.
45
+
46
+ Be sure to know that whenever I remove this notice, things will be
47
+ nicer.
48
+
49
+ For now, I recommend you to **not** use `rndk` for production
50
+ programs!
51
+
52
+ ## Requirements
53
+
54
+ `rndk` requires the gem `ffi-ncurses`.
55
+
56
+ ## Installation
57
+
58
+ Add this line to your application's Gemfile:
59
+
60
+ gem 'rndk'
61
+
62
+ And then execute:
63
+
64
+ $ bundle
65
+
66
+ Or install it yourself as:
67
+
68
+ $ gem install rndk
69
+
70
+ ## Usage
71
+
72
+ The `examples` directory contains lots of sample usages for every
73
+ widget available. To execute them, go to the `rndk` root folder
74
+ and run:
75
+
76
+ ruby -Ilib examples/YOUR_EXAMPLE_HERE
77
+
78
+ There's also some more comples demo applications under the `demos`
79
+ directory. Do the same:
80
+
81
+ ruby -Ilib demos/YOUR_DEMO_HERE
82
+
83
+ ## Contributing
84
+
85
+ Currently `rndk` has a C-like API, since it was directly taken
86
+ from `cdk`. The top priority is to make it more rubyish (maybe
87
+ studying [rbcurse]?).
88
+
89
+ Also, see the `TODO` file.
90
+
91
+ 1. Fork it
92
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
93
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
94
+ 4. Push to the branch (`git push origin my-new-feature`)
95
+ 5. Create new Pull Request
96
+
97
+ [tawny]:https://github.com/masterzora/tawny-cdk
98
+ [cdk]:http://invisible-island.net/cdk/
99
+ [rbcurse]:https://github.com/rkumar/rbcurse
100
+
data/Rakefile ADDED
@@ -0,0 +1,3 @@
1
+ # See default bundler take tasks with `rake -T`
2
+ require "bundler/gem_tasks"
3
+
data/TODO ADDED
@@ -0,0 +1,68 @@
1
+ RNDK TODO List
2
+ (forked from Tawny-Cdk's TODO List)
3
+ ------------------------------------------------------------------------------
4
+
5
+ Now that Tawny CDK is basically a complete copy of Thomas Dickey version of
6
+ Mike Glover's CDK it is essentially usable, but there's still a lot to do:
7
+
8
+ * Documentation
9
+ - Most of the original comments from the .c files were preserved but many
10
+ of those are less than helpful and some areas where they might be more
11
+ helpful are lacking. Further, the .h files have a few potentially
12
+ useful comments that were not preserved. Further, module, class, and
13
+ method docs are either lacking or nonexistent in most places. Tawny CDK
14
+ won't see a major version release until some better docs are in place.
15
+ * Code cleanup
16
+ - This project was how I learned Ruby so there are probably a fair number
17
+ of Ruby conventions being broken all over the place. This goes double
18
+ since I stayed fairly close to the original C in some places where it
19
+ wasn't necessarily appropriate.
20
+ * Continue restructuring
21
+ - Related to but distinct from the cleanup. The original C code was a
22
+ very impressive approximation of polymorphic object-oriented code.
23
+ Since Ruby is actually object-oriented I've mostly translated this into
24
+ this paradigm but some work still remains. Some of the codebase can
25
+ definitely benefit from a more aggressive approach to the object
26
+ orientation and polymorphic behaviour. Further, I need to take a more
27
+ critical eye at seeing what works better as inherited classes and what
28
+ works better as mixins since apparently those are different things in
29
+ Ruby.
30
+ * Error handling
31
+ - In part to allow for more rapid development and in part because I still
32
+ need to get more familiar with Ruby's exception handling but the code
33
+ is nowhere near as robust as it should be. In some cases, such as a lot
34
+ of the file handling, this means implementing intelligent rescues. In
35
+ other cases this means dealing more robustly with sensible but unexpected
36
+ parameter types.
37
+ * Package it all up
38
+ - Tawny CDK won't see a major version release until I work on packaging it
39
+ all up.
40
+ * Compatiblity version
41
+ - Right now I've significantly renamed and restructured a lot of things to
42
+ better facilitate development but have still attempted to remain somewhat
43
+ faithful to the original version. At some point I'd like to fix this with
44
+ a sort of split: a less faithful 'primary' version that makes more sense
45
+ in Ruby and a as-faithful-as-possible 'compatibility' version that wraps
46
+ the primary version into the same (more-or-less) names and structure as
47
+ the original.
48
+ * Support other Curses packages
49
+ - Right now this is all developed for a very specific Ncurses package.
50
+ Ruby has multiple Curses packages so it would be nice to provide broader
51
+ support.
52
+ * Fixes
53
+ - The code has a few "FIXME(original)" tags strewn around. Some of these
54
+ appear to be significantly easier to fix in Ruby and might even provide
55
+ some insight to allow me to kick fixes back to Thomas's project.
56
+ * The Cdk TODO List
57
+ - The Dickey/Glover version has its own TODO list with several items that
58
+ would be interesting to add. As with fixes, some of them may be easier
59
+ to implement in the Ruby version and then use the insights gained to
60
+ kick back to the C.
61
+ * Collections
62
+ - It's simple: a widget that is really a collection of widgets. Fully take
63
+ advantage of real object-orientation and polymorphism and make a widget
64
+ that collects widgets and handles them as one. Have its activate really
65
+ activate the focused widget, move affect all widgets in the collection as
66
+ one, and things like that. Basically, make it really easy to combine
67
+ widgets in useful manners
68
+
@@ -0,0 +1,346 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Shows a book where you can create appointments of different
4
+ # kinds, save and restore them on a file.
5
+ #
6
+ # The keybindings are:
7
+ #
8
+ # * 'm' create appointment at selected day
9
+ # * 'r' remove appointment at selected day
10
+ # * '?' displays appointment for selected day
11
+ # * 'enter' or 'tab' quits
12
+ #
13
+ # It automatically creates file `/tmp/appointments.dat` on the
14
+ # current directory
15
+ require 'ostruct'
16
+ require 'rndk/calendar'
17
+ require 'rndk/itemlist'
18
+ require 'rndk/entry'
19
+
20
+ class Appointment
21
+ MAX_MARKERS = 2000
22
+ GPAppointmentAttributes = [
23
+ Ncurses::A_BLINK,
24
+ Ncurses::A_BOLD,
25
+ Ncurses::A_REVERSE,
26
+ Ncurses::A_UNDERLINE,
27
+ ]
28
+
29
+ AppointmentType = [
30
+ :BIRTHDAY,
31
+ :ANNIVERSARY,
32
+ :APPOINTMENT,
33
+ :OTHER,
34
+ ]
35
+
36
+ # This reads a given appointment file.
37
+ def Appointment.readAppointmentFile(filename, app_info)
38
+ appointments = 0
39
+ segments = 0
40
+ lines = []
41
+
42
+ # Read the appointment file.
43
+ lines_read = RNDK.readFile(filename, lines)
44
+ if lines_read == -1
45
+ app_info.count = 0
46
+ return
47
+ end
48
+
49
+ # Split each line up and create an appointment.
50
+ (0...lines_read).each do |x|
51
+ temp = lines[x].split(RNDK.CTRL('V').chr)
52
+ segments = temp.size
53
+
54
+ # A valid line has 5 elements:
55
+ # Day, Month, Year, Type, Description.
56
+ if segments == 5
57
+ app_info.appointment << OpenStruct.new
58
+ e_type = Appointment::AppointmentType[temp[3].to_i]
59
+
60
+ app_info.appointment[appointments].day = temp[0].to_i
61
+ app_info.appointment[appointments].month = temp[1].to_i
62
+ app_info.appointment[appointments].year = temp[2].to_i
63
+ app_info.appointment[appointments].type = e_type
64
+ app_info.appointment[appointments].description = temp[4]
65
+ appointments += 1
66
+ end
67
+ end
68
+
69
+ # Keep the amount of appointments read.
70
+ app_info.count = appointments
71
+ end
72
+
73
+ # This saves a given appointment file.
74
+ def Appointment.saveAppointmentFile(filename, app_info)
75
+ # TODO: error handling
76
+ fd = File.new(filename, 'w')
77
+
78
+ # Start writing.
79
+ app_info.appointment.each do |appointment|
80
+ if appointment.description != ''
81
+ fd.puts '%d%c%d%c%d%c%d%c%s' % [
82
+ appointment.day, RNDK.CTRL('V').chr,
83
+ appointment.month, RNDK.CTRL('V').chr,
84
+ appointment.year, RNDK.CTRL('V').chr,
85
+ Appointment::AppointmentType.index(appointment.type),
86
+ RNDK.CTRL('V').chr, appointment.description]
87
+ end
88
+ end
89
+ fd.close
90
+ end
91
+
92
+ # This program demonstrates the Rndk calendar widget.
93
+ def Appointment.main
94
+
95
+ # Get the current dates and set the default values for
96
+ # the day/month/year values for the calendar.
97
+ date_info = Time.now.gmtime
98
+ day = date_info.day
99
+ month = date_info.mon
100
+ year = date_info.year
101
+
102
+ title = "<C></U>RNDK Appointment Book\nPress 'h' for help\n<C><#HL(30)>\n"
103
+
104
+ filename = ''
105
+
106
+ # Create the appointment book filename.
107
+ filename = "/tmp/appointments.dat"
108
+
109
+ appointment_info = OpenStruct.new
110
+ appointment_info.count = 0
111
+ appointment_info.appointment = []
112
+
113
+ # Read the appointment book information.
114
+ readAppointmentFile(filename, appointment_info)
115
+
116
+ # Set up RNDK
117
+ curses_win = Ncurses.initscr
118
+ rndkscreen = RNDK::Screen.new(curses_win)
119
+
120
+ # Set up RNDK colors
121
+ RNDK::Draw.initRNDKColor
122
+
123
+ # Create the calendar widget.
124
+ calendar = RNDK::CALENDAR.new(rndkscreen,
125
+ RNDK::CENTER,
126
+ RNDK::CENTER,
127
+ title, day, month, year,
128
+ Ncurses::A_NORMAL, Ncurses::A_NORMAL, Ncurses::A_NORMAL, Ncurses::A_REVERSE,
129
+ true, false)
130
+
131
+ # Is the widget nil?
132
+ if calendar.nil?
133
+ rndkscreen.destroy
134
+ RNDK::Screen.end_rndk
135
+
136
+ puts "Cannot create the calendar. Is the window too small?"
137
+ exit 1
138
+ end
139
+
140
+ # This adds a marker to the calendar.
141
+ create_calendar_mark_cb = lambda do |object_type, calendar, info, key|
142
+ items = [
143
+ 'Birthday',
144
+ 'Anniversary',
145
+ 'Appointment',
146
+ 'Other',
147
+ ]
148
+
149
+ # Create the itemlist widget.
150
+ itemlist = RNDK::ITEMLIST.new(calendar.screen,
151
+ RNDK::CENTER, RNDK::CENTER, '', 'Select Appointment Type: ',
152
+ items, items.size, 0, true, false)
153
+
154
+ # Get the appointment type from the user.
155
+ selection = itemlist.activate([])
156
+
157
+ # They hit escape, kill the itemlist widget and leave.
158
+ if selection == -1
159
+ itemlist.destroy
160
+ calendar.draw(calendar.box)
161
+ return false
162
+ end
163
+
164
+ # Destroy the itemlist and set the marker.
165
+ itemlist.destroy
166
+ calendar.draw(calendar.box)
167
+ marker = Appointment::GPAppointmentAttributes[selection]
168
+
169
+ # Create the entry field for the description.
170
+ entry = RNDK::ENTRY.new(calendar.screen, RNDK::CENTER, RNDK::CENTER,
171
+ '<C>Enter a description of the appointment.',
172
+ 'Description: ', Ncurses::A_NORMAL, '.'.ord, :MIXED, 40, 1, 512,
173
+ true, false)
174
+
175
+ # Get the description.
176
+ description = entry.activate([])
177
+ if description == 0
178
+ entry.destroy
179
+ calendar.draw(calendar.box)
180
+ return false
181
+ end
182
+
183
+ # Destroy the entry and set the marker.
184
+ description = entry.info
185
+ entry.destroy
186
+ calendar.draw(calendar.box)
187
+
188
+ # Set the marker.
189
+ calendar.setMarker(calendar.day, calendar.month, calendar.year, marker)
190
+
191
+ # Keep the marker.
192
+ info.appointment << OpenStruct.new
193
+ current = info.count
194
+
195
+ info.appointment[current].day = calendar.day
196
+ info.appointment[current].month = calendar.month
197
+ info.appointment[current].year = calendar.year
198
+ info.appointment[current].type = Appointment::AppointmentType[selection]
199
+ info.appointment[current].description = description
200
+ info.count += 1
201
+
202
+ # Redraw the calendar.
203
+ calendar.draw(calendar.box)
204
+ return false
205
+ end
206
+
207
+ # This removes a marker from the calendar.
208
+ remove_calendar_mark_cb = lambda do |object_type, calendar, info, key|
209
+ info.appointment.each do |appointment|
210
+ if appointment.day == calendar.day &&
211
+ appointment.month == calendar.month &&
212
+ appointment.year == calendar.year
213
+ appointment.description = ''
214
+ break
215
+ end
216
+ end
217
+
218
+ # Remove the marker from the calendar.
219
+ calendar.removeMarker(calendar.day, calendar.month, calendar.year)
220
+
221
+ # Redraw the calendar.
222
+ calendar.draw(calendar.box)
223
+ return false
224
+ end
225
+
226
+ # This displays the marker(s) on the given day.
227
+ display_calendar_mark_cb = lambda do |object_type, calendar, info, key|
228
+ found = 0
229
+ type = ''
230
+ mesg = []
231
+
232
+ # Look for the marker in the list.
233
+ info.appointment.each do |appointment|
234
+ # Get the day month year.
235
+ day = appointment.day
236
+ month = appointment.month
237
+ year = appointment.year
238
+
239
+ # Determine the appointment type.
240
+ if appointment.type == :BIRTHDAY
241
+ type = 'Birthday'
242
+ elsif appointment.type == :ANNIVERSARY
243
+ type = 'Anniversary'
244
+ elsif appointment.type == :APPOINTMENT
245
+ type = 'Appointment'
246
+ else
247
+ type = 'Other'
248
+ end
249
+
250
+ # Find the marker by the day/month/year.
251
+ if day == calendar.day && month == calendar.month &&
252
+ year == calendar.year && appointment.description != ''
253
+ # Create the message for the label widget.
254
+ mesg << '<C>Appointment Date: %02d/%02d/%d' % [
255
+ day, month, year]
256
+ mesg << ' '
257
+ mesg << '<C><#HL(35)>'
258
+ mesg << ' Appointment Type: %s' % [type]
259
+ mesg << ' Description :'
260
+ mesg << ' %s' % [appointment.description]
261
+ mesg << '<C><#HL(35)>'
262
+ mesg << ' '
263
+ mesg << '<C>Press space to continue.'
264
+
265
+ found = 1
266
+ break
267
+ end
268
+ end
269
+
270
+ # If we didn't find the marker, create a different message.
271
+ if found == 0
272
+ mesg << '<C>There is no appointment for %02d/%02d/%d' % [calendar.day, calendar.month, calendar.year]
273
+ mesg << '<C><#HL(30)>'
274
+ mesg << '<C>Press space to continue.'
275
+ end
276
+
277
+ # Create the label widget
278
+ label = RNDK::LABEL.new(calendar.screen, RNDK::CENTER, RNDK::CENTER, mesg, mesg.size, true, false)
279
+ label.draw(label.box)
280
+ label.wait(' ')
281
+ label.destroy
282
+
283
+ # Redraw the calendar
284
+ calendar.draw(calendar.box)
285
+ return false
286
+ end
287
+
288
+ # Shows a help popup with keybindings.
289
+ show_help = lambda do |object_type, calendar, info, key|
290
+ msg = ["Keybindings:",
291
+ " 'm' create appointment at selected day",
292
+ " 'r' remove appointment at selected day",
293
+ " '?' displays appointment for selected day",
294
+ " 'enter' or 'tab' quits"]
295
+
296
+ rndkscreen.popupLabel msg
297
+ end
298
+
299
+ # Now we bind actions to the calendar.
300
+ # Create a key binding to mark days on the calendar.
301
+ calendar.bind(:CALENDAR, 'm', create_calendar_mark_cb, appointment_info)
302
+ calendar.bind(:CALENDAR, 'M', create_calendar_mark_cb, appointment_info)
303
+ calendar.bind(:CALENDAR, 'r', remove_calendar_mark_cb, appointment_info)
304
+ calendar.bind(:CALENDAR, 'R', remove_calendar_mark_cb, appointment_info)
305
+ calendar.bind(:CALENDAR, '?', display_calendar_mark_cb, appointment_info)
306
+ calendar.bind(:CALENDAR, 'h', show_help, nil)
307
+
308
+ # Set all the appointments read from the file.
309
+ appointment_info.appointment.each do |appointment|
310
+ marker = Appointment::GPAppointmentAttributes[Appointment::AppointmentType.index(appointment.type)]
311
+
312
+ calendar.setMarker(appointment.day,
313
+ appointment.month,
314
+ appointment.year,
315
+ marker)
316
+ end
317
+
318
+ # Draw the calendar widget.
319
+ calendar.draw(calendar.box)
320
+
321
+ # Let the user play with the widget.
322
+ calendar.activate([])
323
+
324
+ # Save the appointment information.
325
+ Appointment.saveAppointmentFile(filename, appointment_info)
326
+
327
+ # Clean up.
328
+ calendar.destroy
329
+ rndkscreen.destroy
330
+ RNDK::Screen.end_rndk
331
+ end
332
+ end
333
+
334
+
335
+ begin
336
+ Appointment.main
337
+
338
+ # In case something goes wrong
339
+ rescue Exception => e
340
+ RNDK::Screen.end_rndk
341
+
342
+ puts e
343
+ puts e.inspect
344
+ puts e.backtrace
345
+ end
346
+