arcadia 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (167) hide show
  1. data/README +126 -123
  2. data/arcadia.rb +770 -756
  3. data/base/a-contracts.rb +130 -93
  4. data/base/a-ext.rb +280 -280
  5. data/base/a-libs.rb +5 -11
  6. data/base/a-utils.rb +235 -44
  7. data/conf/arcadia.conf +20 -16
  8. data/conf/arcadia.init.rb +0 -0
  9. data/conf/arcadia.res.rb +74 -0
  10. data/ext/ae-complete-code/ae-complete-code.conf +0 -0
  11. data/ext/ae-complete-code/ae-complete-code.rb +80 -79
  12. data/ext/ae-debug/ae-debug.conf +0 -0
  13. data/ext/ae-debug/ae-debug.rb +2 -6
  14. data/ext/ae-debug/debug1.57.rb +0 -0
  15. data/ext/ae-doc-code/ae-doc-code.conf +15 -0
  16. data/ext/ae-doc-code/ae-doc-code.rb +289 -0
  17. data/ext/ae-editor/ae-editor.conf +17 -8
  18. data/ext/ae-editor/ae-editor.rb +738 -396
  19. data/ext/ae-event-log/ae-event-log.conf +0 -0
  20. data/ext/ae-event-log/ae-event-log.rb +0 -0
  21. data/ext/ae-file-history/ae-file-history.conf +2 -2
  22. data/ext/ae-file-history/ae-file-history.rb +286 -290
  23. data/ext/ae-inspector/ae-inspector.conf +0 -0
  24. data/ext/ae-inspector/ae-inspector.rb +0 -0
  25. data/ext/ae-output-event/ae-output-event.conf +2 -2
  26. data/ext/ae-output/ae-output.conf +2 -2
  27. data/ext/ae-output/ae-output.rb +173 -178
  28. data/ext/ae-palette/ae-palette.conf +0 -0
  29. data/ext/ae-palette/ae-palette.rb +0 -0
  30. data/ext/ae-shell/ae-shell.conf +0 -0
  31. data/ext/ae-shell/ae-shell.rb +54 -54
  32. data/lib/tk/al-tk.rb +3076 -3082
  33. data/lib/tk/al-tk.res.rb +0 -0
  34. data/lib/tk/al-tkarcadia.rb +0 -0
  35. data/lib/tk/al-tkcustom.rb +0 -0
  36. data/lib/tkext/al-bwidget.rb +0 -0
  37. data/lib/tkext/al-iwidgets.rb +0 -0
  38. data/lib/tkext/al-tile.rb +0 -0
  39. data/lib/tkext/al-tktable.rb +0 -0
  40. data/tcl/BWidget-1.8.0/BWman/ArrowButton.html +276 -0
  41. data/tcl/BWidget-1.8.0/BWman/BWidget.html +228 -0
  42. data/tcl/BWidget-1.8.0/BWman/Button.html +273 -0
  43. data/tcl/BWidget-1.8.0/BWman/ButtonBox.html +264 -0
  44. data/tcl/BWidget-1.8.0/BWman/ComboBox.html +402 -0
  45. data/tcl/BWidget-1.8.0/BWman/Dialog.html +314 -0
  46. data/tcl/BWidget-1.8.0/BWman/DragSite.html +139 -0
  47. data/tcl/BWidget-1.8.0/BWman/DropSite.html +254 -0
  48. data/tcl/BWidget-1.8.0/BWman/DynamicHelp.html +248 -0
  49. data/tcl/BWidget-1.8.0/BWman/Entry.html +341 -0
  50. data/tcl/BWidget-1.8.0/BWman/Label.html +331 -0
  51. data/tcl/BWidget-1.8.0/BWman/LabelEntry.html +194 -0
  52. data/tcl/BWidget-1.8.0/BWman/LabelFrame.html +144 -0
  53. data/tcl/BWidget-1.8.0/BWman/ListBox.html +678 -0
  54. data/tcl/BWidget-1.8.0/BWman/MainFrame.html +283 -0
  55. data/tcl/BWidget-1.8.0/BWman/MessageDlg.html +218 -0
  56. data/tcl/BWidget-1.8.0/BWman/NoteBook.html +374 -0
  57. data/tcl/BWidget-1.8.0/BWman/PagesManager.html +180 -0
  58. data/tcl/BWidget-1.8.0/BWman/PanedWindow.html +142 -0
  59. data/tcl/BWidget-1.8.0/BWman/PanelFrame.html +153 -0
  60. data/tcl/BWidget-1.8.0/BWman/PasswdDlg.html +214 -0
  61. data/tcl/BWidget-1.8.0/BWman/ProgressBar.html +152 -0
  62. data/tcl/BWidget-1.8.0/BWman/ProgressDlg.html +145 -0
  63. data/tcl/BWidget-1.8.0/BWman/ScrollView.html +130 -0
  64. data/tcl/BWidget-1.8.0/BWman/ScrollableFrame.html +191 -0
  65. data/tcl/BWidget-1.8.0/BWman/ScrolledWindow.html +116 -0
  66. data/tcl/BWidget-1.8.0/BWman/SelectColor.html +164 -0
  67. data/tcl/BWidget-1.8.0/BWman/SelectFont.html +152 -0
  68. data/tcl/BWidget-1.8.0/BWman/Separator.html +77 -0
  69. data/tcl/BWidget-1.8.0/BWman/SpinBox.html +250 -0
  70. data/tcl/BWidget-1.8.0/BWman/StatusBar.html +147 -0
  71. data/tcl/BWidget-1.8.0/BWman/TitleFrame.html +107 -0
  72. data/tcl/BWidget-1.8.0/BWman/Tree.html +947 -0
  73. data/tcl/BWidget-1.8.0/BWman/Widget.html +502 -0
  74. data/tcl/BWidget-1.8.0/BWman/contents.html +84 -0
  75. data/tcl/BWidget-1.8.0/BWman/index.html +7 -0
  76. data/tcl/BWidget-1.8.0/BWman/navtree.html +41 -0
  77. data/tcl/BWidget-1.8.0/BWman/options.htm +458 -0
  78. data/tcl/BWidget-1.8.0/CHANGES.txt +266 -0
  79. data/tcl/BWidget-1.8.0/ChangeLog +1641 -0
  80. data/tcl/BWidget-1.8.0/LICENSE.txt +41 -0
  81. data/tcl/BWidget-1.8.0/README.txt +127 -0
  82. data/tcl/BWidget-1.8.0/arrow.tcl +551 -0
  83. data/tcl/BWidget-1.8.0/bitmap.tcl +94 -0
  84. data/tcl/BWidget-1.8.0/button.tcl +324 -0
  85. data/tcl/BWidget-1.8.0/buttonbox.tcl +403 -0
  86. data/tcl/BWidget-1.8.0/color.tcl +493 -0
  87. data/tcl/BWidget-1.8.0/combobox.tcl +809 -0
  88. data/tcl/BWidget-1.8.0/demo/basic.tcl +199 -0
  89. data/tcl/BWidget-1.8.0/demo/bwidget.xbm +46 -0
  90. data/tcl/BWidget-1.8.0/demo/demo.tcl +212 -0
  91. data/tcl/BWidget-1.8.0/demo/dnd.tcl +42 -0
  92. data/tcl/BWidget-1.8.0/demo/manager.tcl +141 -0
  93. data/tcl/BWidget-1.8.0/demo/select.tcl +59 -0
  94. data/tcl/BWidget-1.8.0/demo/tmpldlg.tcl +214 -0
  95. data/tcl/BWidget-1.8.0/demo/tree.tcl +260 -0
  96. data/tcl/BWidget-1.8.0/demo/x1.xbm +2258 -0
  97. data/tcl/BWidget-1.8.0/dialog.tcl +345 -0
  98. data/tcl/BWidget-1.8.0/dragsite.tcl +197 -0
  99. data/tcl/BWidget-1.8.0/dropsite.tcl +455 -0
  100. data/tcl/BWidget-1.8.0/dynhelp.tcl +625 -0
  101. data/tcl/BWidget-1.8.0/entry.tcl +469 -0
  102. data/tcl/BWidget-1.8.0/font.tcl +566 -0
  103. data/tcl/BWidget-1.8.0/images/bold.gif +0 -0
  104. data/tcl/BWidget-1.8.0/images/copy.gif +0 -0
  105. data/tcl/BWidget-1.8.0/images/cut.gif +0 -0
  106. data/tcl/BWidget-1.8.0/images/dragfile.gif +0 -0
  107. data/tcl/BWidget-1.8.0/images/dragicon.gif +0 -0
  108. data/tcl/BWidget-1.8.0/images/error.gif +0 -0
  109. data/tcl/BWidget-1.8.0/images/file.gif +0 -0
  110. data/tcl/BWidget-1.8.0/images/folder.gif +0 -0
  111. data/tcl/BWidget-1.8.0/images/hourglass.gif +0 -0
  112. data/tcl/BWidget-1.8.0/images/info.gif +0 -0
  113. data/tcl/BWidget-1.8.0/images/italic.gif +0 -0
  114. data/tcl/BWidget-1.8.0/images/minus.xbm +5 -0
  115. data/tcl/BWidget-1.8.0/images/new.gif +0 -0
  116. data/tcl/BWidget-1.8.0/images/opcopy.xbm +5 -0
  117. data/tcl/BWidget-1.8.0/images/open.gif +0 -0
  118. data/tcl/BWidget-1.8.0/images/openfold.gif +0 -0
  119. data/tcl/BWidget-1.8.0/images/oplink.xbm +5 -0
  120. data/tcl/BWidget-1.8.0/images/opmove.xbm +5 -0
  121. data/tcl/BWidget-1.8.0/images/overstrike.gif +0 -0
  122. data/tcl/BWidget-1.8.0/images/palette.gif +0 -0
  123. data/tcl/BWidget-1.8.0/images/passwd.gif +0 -0
  124. data/tcl/BWidget-1.8.0/images/paste.gif +0 -0
  125. data/tcl/BWidget-1.8.0/images/plus.xbm +5 -0
  126. data/tcl/BWidget-1.8.0/images/print.gif +0 -0
  127. data/tcl/BWidget-1.8.0/images/question.gif +0 -0
  128. data/tcl/BWidget-1.8.0/images/redo.gif +0 -0
  129. data/tcl/BWidget-1.8.0/images/save.gif +0 -0
  130. data/tcl/BWidget-1.8.0/images/target.xbm +9 -0
  131. data/tcl/BWidget-1.8.0/images/underline.gif +0 -0
  132. data/tcl/BWidget-1.8.0/images/undo.gif +0 -0
  133. data/tcl/BWidget-1.8.0/images/warning.gif +0 -0
  134. data/tcl/BWidget-1.8.0/init.tcl +40 -0
  135. data/tcl/BWidget-1.8.0/label.tcl +271 -0
  136. data/tcl/BWidget-1.8.0/labelentry.tcl +100 -0
  137. data/tcl/BWidget-1.8.0/labelframe.tcl +160 -0
  138. data/tcl/BWidget-1.8.0/lang/da.rc +52 -0
  139. data/tcl/BWidget-1.8.0/lang/de.rc +52 -0
  140. data/tcl/BWidget-1.8.0/lang/en.rc +52 -0
  141. data/tcl/BWidget-1.8.0/lang/es.rc +53 -0
  142. data/tcl/BWidget-1.8.0/lang/fr.rc +52 -0
  143. data/tcl/BWidget-1.8.0/listbox.tcl +1638 -0
  144. data/tcl/BWidget-1.8.0/mainframe.tcl +711 -0
  145. data/tcl/BWidget-1.8.0/messagedlg.tcl +128 -0
  146. data/tcl/BWidget-1.8.0/notebook.tcl +1164 -0
  147. data/tcl/BWidget-1.8.0/pagesmgr.tcl +294 -0
  148. data/tcl/BWidget-1.8.0/panedw.tcl +381 -0
  149. data/tcl/BWidget-1.8.0/panelframe.tcl +246 -0
  150. data/tcl/BWidget-1.8.0/passwddlg.tcl +178 -0
  151. data/tcl/BWidget-1.8.0/pkgIndex.tcl +47 -0
  152. data/tcl/BWidget-1.8.0/progressbar.tcl +208 -0
  153. data/tcl/BWidget-1.8.0/progressdlg.tcl +87 -0
  154. data/tcl/BWidget-1.8.0/scrollframe.tcl +226 -0
  155. data/tcl/BWidget-1.8.0/scrollview.tcl +254 -0
  156. data/tcl/BWidget-1.8.0/scrollw.tcl +280 -0
  157. data/tcl/BWidget-1.8.0/separator.tcl +75 -0
  158. data/tcl/BWidget-1.8.0/spinbox.tcl +331 -0
  159. data/tcl/BWidget-1.8.0/statusbar.tcl +422 -0
  160. data/tcl/BWidget-1.8.0/tests/entry.test +173 -0
  161. data/tcl/BWidget-1.8.0/titleframe.tcl +170 -0
  162. data/tcl/BWidget-1.8.0/tree.tcl +2228 -0
  163. data/tcl/BWidget-1.8.0/utils.tcl +645 -0
  164. data/tcl/BWidget-1.8.0/widget.tcl +1576 -0
  165. data/tcl/BWidget-1.8.0/wizard.tcl +1028 -0
  166. data/tcl/BWidget-1.8.0/xpm2image.tcl +115 -0
  167. metadata +141 -5
data/README CHANGED
@@ -1,123 +1,126 @@
1
- Arcadia Ruby Ide
2
- version 0.1.1
3
-
4
- by Antonio Galeone
5
- on Mar 31, 2007
6
-
7
- "Thank you for consider this project"
8
-
9
- About
10
- =====
11
- Arcadia is a Integrated Development Environment (IDE) for Ruby language
12
- written in Ruby using the classic tcl/tk GUI toolkit.
13
-
14
- Some of Arcadia ruby ide project features include:
15
- -Editor with source browsing and syntax highlighting
16
- -Supporting RAD gui building
17
- -Generation of widget-wrapper-independent ruby code
18
- -Working on any platform where ruby and tcl-tk work.
19
- -Highly extensibility architecture.
20
-
21
- This release
22
- ============
23
- -[fixed] Bugs fixed
24
- -[new] Added completion code support (Ctrl-space) based upon rcodetools package (must be installed)
25
- -[modified] in file config the <OPERATING SYSTEM IDENTIFY> separator modified from <:> to <::>
26
-
27
- Short User guide
28
- ================
29
- I hope that you perceive Arcadia gui enough user frindly.
30
- As you can see the application is splitted in vertical
31
- and horizontal resizing frames. Clicking on vertical splitter
32
- appear two button for left or right one shot frame close.
33
- The horizontal splitter has two little button for the same reason
34
- (perhaps i will conform them to the vertical style).
35
- Every frame has a title and a button to expand or resizing it.
36
- In this beta release there are very essential feature:
37
-
38
- < Toolbar >
39
- The toolbar button are in order:
40
- -new, open, save
41
- (relatively to editor extension)
42
- -run current, run last
43
- (for execute the raised file in the editor or the last file executed)
44
- -debug current, debug last, stop debug
45
- (for the debug extension that is in very unstable state)
46
- -quit (to exit from arcadia)
47
-
48
- < Editor >
49
- Editor use the notebook metaphor. Same command are on the popup menu
50
- that is raised on "Button-3" click event fundamentalally for closing the tab
51
- under the mouse pointer.
52
- These are same editor short-cut:
53
- Ctrl-c => copy selected text
54
- Ctrl-v => paste copied text
55
- Ctrl-x => cut selected text
56
- Ctrl-z => undo
57
- Ctrl-f => copy the selected text on input combobox of find bar and moves focus
58
- Ctrl-s => save
59
- Ctrl-space => completion code
60
- Ctrl-shift-i => indent the selected block
61
- Ctrl-shift-u => unindent the selected block
62
- Ctrl-shift-c => comment/uncomment the selected code block
63
- F5 => execute the file
64
- F3 => find/ find next
65
-
66
- Double-Click on line number set or unset a debug breckpoint
67
-
68
- < File history >
69
- The last used files are organizing in tree so you can reopen them or there
70
- directory by clicking on the tree node.
71
-
72
- < Palette >
73
- It contain the wrapper components for the tk gui building.
74
- It is in very unstabled and incomplete state.
75
- The first component is a TkTopLevel wrapper, when you click on it a new form is created and a
76
- Object inspector appears.
77
- The other components must be first selected and then created by clicking on container widget.
78
- The so created widgets has a popup menu for deleting them or in the toplevel case to switch
79
- to a code view.
80
- On the palette there are also two button, one for deselect and other for copy from the selected
81
- created widget. The copy action copy also the code into the clipboard, so you can copy the
82
- code rapresenting the gui into the embedded editor or into external editor.
83
-
84
- < Object Inspector >
85
- It is for modify the widget property at runtime
86
-
87
- < Debug >
88
- It is created when a debug session init.
89
- The debug button are: Step Next, Step Into, Step Over, Resume.
90
- The debug frame show the local, instance and global variables for each
91
- step. (you must have patience!)
92
-
93
- <Configuration>
94
- Same Arcadia properties are locally configurabled by editing the file arcadia.conf
95
- under ~/.arcadia directory. The format of property definition are:
96
- <OPERATING SYSTEM IDENTIFY::>PROPERTY_NAME=PROPERTY_VALUE
97
-
98
-
99
- Requirement
100
- ===========
101
- I include into distribution also the BWidget lib (under tcl directory) so
102
- are require realy only the standard tcl tk lib (tested on tcl tk 8.4).
103
- I have tested arcadia with ruby 1.8.4, 1.8.5, 1.8.6 on FreeBsd6 and windows 2000/XP os. If you
104
- will test arcadia on other operating system sends me an e-mail.
105
-
106
- Developers information
107
- =====================
108
- Soon i will write samething about the arcadia software architecture (when it is more stable)
109
- in order to allow extensions writing and collaborations.
110
-
111
-
112
-
113
- License
114
- =======
115
- Arcadia is released under the Ruby License
116
-
117
- Contacts
118
- ========
119
- For questions:
120
- antonio-galeone@rubyforge.org
121
- For bugs, support request, feature request https://rubyforge.org/projects/arcadia:
122
-
123
- Bye
1
+ Arcadia Ruby Ide
2
+ version 0.1.2
3
+
4
+ by Antonio Galeone
5
+ on May 8, 2007
6
+
7
+ "Thank you for consider this project"
8
+
9
+ About
10
+ =====
11
+ Arcadia is a Integrated Development Environment (IDE) for Ruby language
12
+ written in Ruby using the classic tcl/tk GUI toolkit.
13
+
14
+ Some of Arcadia ruby ide project features include:
15
+ -Editor with source browsing, syntax highlighting, code completion
16
+ -Contextual ruby documentation
17
+ -Supporting RAD gui building
18
+ -Generation of widget-wrapper-independent ruby code
19
+ -Working on any platform where ruby and tcl-tk work.
20
+ -Highly extensibility architecture.
21
+
22
+ This release
23
+ ============
24
+ -[fixed] Bugs fixed and general restyling
25
+ -[new] Added integration with ri--Ruby (F1) for display contextual ruby documentation
26
+ -[new] Enhanced find/replace dialog
27
+
28
+ Short User guide
29
+ ================
30
+ I hope that you perceive Arcadia gui enough user frindly.
31
+ As you can see the application is splitted in vertical
32
+ and horizontal resizing frames. Clicking on vertical splitter
33
+ appear two button for left or right one shot frame close.
34
+ The horizontal splitter has two little button for the same reason
35
+ (perhaps i will conform them to the vertical style).
36
+ Every frame has a title and a button to expand or resizing it.
37
+ In this beta release there are very essential feature:
38
+
39
+ < Toolbar >
40
+ The toolbar button are in order:
41
+ -new, open, save
42
+ (relatively to editor extension)
43
+ -run current, run last
44
+ (for execute the raised file in the editor or the last file executed)
45
+ -debug current, debug last, stop debug
46
+ (for the debug extension that is in very unstable state)
47
+ -quit (to exit from arcadia)
48
+
49
+ < Editor >
50
+ Editor use the notebook metaphor. Same command are on the popup menu
51
+ that is raised on "Button-3" click event fundamentalally for closing the tab
52
+ under the mouse pointer.
53
+ These are same editor short-cut:
54
+ Ctrl-c => copy selected text
55
+ Ctrl-v => paste copied text
56
+ Ctrl-x => cut selected text
57
+ Ctrl-z => undo
58
+ Ctrl-f => copy the selected text on input combobox of find dialog and moves focus
59
+ Ctrl-s => save
60
+ Ctrl-space => completion code
61
+ Ctrl-shift-i => indent the selected block
62
+ Ctrl-shift-u => unindent the selected block
63
+ Ctrl-shift-c => comment/uncomment the selected code block
64
+ F5 => execute the file
65
+ F3 => find/ find next
66
+ F1 => contextual ruby documentation (called from editor or from code completion item, if
67
+ no corrispondation is founded a doc tree is build in left side)
68
+
69
+ Double-Click on line number set or unset a debug breckpoint
70
+
71
+ < File history >
72
+ The last used files are organizing in tree so you can reopen them or there
73
+ directory by clicking on the tree node.
74
+
75
+ < Palette >
76
+ It contain the wrapper components for the tk gui building.
77
+ It is in very unstabled and incomplete state.
78
+ The first component is a TkTopLevel wrapper, when you click on it a new form is created and a
79
+ Object inspector appears.
80
+ The other components must be first selected and then created by clicking on container widget.
81
+ The so created widgets has a popup menu for deleting them or in the toplevel case to switch
82
+ to a code view.
83
+ On the palette there are also two button, one for deselect and other for copy from the selected
84
+ created widget. The copy action copy also the code into the clipboard, so you can copy the
85
+ code rapresenting the gui into the embedded editor or into external editor.
86
+
87
+ < Object Inspector >
88
+ It is for modify the widget property at runtime
89
+
90
+ < Debug >
91
+ It is created when a debug session init.
92
+ The debug button are: Step Next, Step Into, Step Over, Resume.
93
+ The debug frame show the local, instance and global variables for each
94
+ step. (you must have patience!)
95
+
96
+ <Configuration>
97
+ Same Arcadia properties are locally configurabled by editing the file arcadia.conf
98
+ under ~/.arcadia directory. The format of property definition are:
99
+ <OPERATING SYSTEM IDENTIFY::>PROPERTY_NAME=PROPERTY_VALUE
100
+
101
+
102
+ Requirement
103
+ ===========
104
+ I include into distribution also the BWidget lib (under tcl directory) so
105
+ are require realy only the standard tcl tk lib (tested on tcl tk 8.4).
106
+ I have tested arcadia with ruby 1.8.4, 1.8.5, 1.8.6 on FreeBsd6, Vector linux and windows 2000/XP os. If you
107
+ will test arcadia on other operating system sends me an e-mail.
108
+
109
+ Developers information
110
+ =====================
111
+ Soon i will write samething about the arcadia software architecture (when it is more stable)
112
+ in order to allow extensions writing and collaborations.
113
+
114
+
115
+
116
+ License
117
+ =======
118
+ Arcadia is released under the Ruby License
119
+
120
+ Contacts
121
+ ========
122
+ For questions:
123
+ antonio-galeone@rubyforge.org
124
+ For bugs, support request, feature request https://rubyforge.org/projects/arcadia:
125
+
126
+ Bye
data/arcadia.rb CHANGED
@@ -1,756 +1,770 @@
1
- #
2
- # arcadia.rb - Arcadia Ruby ide
3
- # by Antonio Galeone <antonio-galeone@rubyforge.org>
4
- #
5
-
6
- Dir.chdir(File.dirname(__FILE__))
7
- if FileTest.exist?('conf/arcadia.init.rb')
8
- require 'conf/arcadia.init'
9
- end
10
- require "conf/arcadia.res"
11
- require 'tkextlib/bwidget'
12
- require "base/a-utils"
13
- require "base/a-ext"
14
- require "base/a-contracts"
15
- require "observer"
16
-
17
- class Arcadia < TkApplication
18
- include Observable
19
- attr_reader :layout
20
- attr_reader :libs
21
- #attr_reader :main_contract
22
- def initialize
23
- super(
24
- ApplicationParams.new(
25
- 'arcadia',
26
- '0.1.1',
27
- 'conf/arcadia.conf',
28
- 'conf/arcadia.pers'
29
- )
30
- )
31
- self.load_local_config(false)
32
- ObjectSpace.define_finalizer($arcadia, self.class.method(:finalize).to_proc)
33
- publish('action.on_exit', proc{do_exit})
34
- _title = "Arcadia Ruby ide :: [Platform = "+RUBY_PLATFORM+'] [Ruby version = ' + RUBY_VERSION+']'
35
- @root = TkRoot.new{
36
- title _title
37
- withdraw
38
- protocol( "WM_DELETE_WINDOW", $arcadia['action.on_exit'])
39
- }
40
- @on_event = Hash.new
41
- @main_menu = TkMenubar.new.pack('fill'=>'x')
42
- @mf_root = Tk::BWidget::MainFrame.new(@root){
43
- menu @main_menu
44
- }.pack(
45
- 'anchor'=> 'center',
46
- 'fill'=> 'both',
47
- 'expand'=> 1
48
- )
49
-
50
- #.place('x'=>0,'y'=>0,'relwidth'=>1,'relheight'=>1)
51
- @mf_root.show_statusbar('none')
52
- @toolbar = @mf_root.add_toolbar
53
- @mf_root.show_toolbar(1,true)
54
- @splash = ArcadiaAboutSplash.new('... initialize')
55
- @splash.set_progress(50)
56
- @splash.deiconify
57
- Tk.update
58
- sleep(1)
59
- @splash.next_step('..prepare')
60
- prepare
61
- @splash.last_step('..load finish')
62
- geometry = (TkWinfo.screenwidth(@root)-4).to_s+'x'+
63
- (TkWinfo.screenheight(@root)-20).to_s+'+0+0'
64
- @root.deiconify
65
- @root.raise
66
- @root.focus(true)
67
- @root.geometry(geometry)
68
- Tk.update_idletasks
69
- sleep(1)
70
- @splash.destroy
71
- if @first_run
72
- EditorContract.instance.open_file(EditorContract::TEditorObj.new(self, 'file'=>'README'))
73
- end
74
- end
75
-
76
- def Arcadia.finalize(id)
77
- puts "\nArcadia #{id} dying at #{Time.new}"
78
- end
79
-
80
- def load_libs
81
- @libs = ArcadiaLibs.new(self)
82
- libs = self['conf']['libraries'].split(',')
83
- libs.each{|lib|
84
- if lib
85
- @splash.next_step('... loading library '+lib)
86
- begin
87
- require self['conf']['libraries.'+lib+'.source']
88
- @libs.add_lib(
89
- ArcadiaLibs::ArcadiaLibParams.new(
90
- self['conf']['libraries.'+lib+'.name'],
91
- self['conf']['libraries.'+lib+'.source'],
92
- self['conf']['libraries.'+lib+'.require'],
93
- eval(self['conf']['libraries.'+lib+'.collection.class']))
94
- )
95
- rescue Exception
96
- msg = "Loading lib "+'"'+lib+'"'+" ("+$!.class.to_s+") "+" : "+$! + " at : "+$@.to_s
97
- if Tk.messageBox('icon' => 'error', 'type' => 'okcancel',
98
- 'title' => '(Arcadia) Libs', 'parent' => @root,
99
- 'message' => msg) == 'cancel'
100
- raise
101
- exit
102
- else
103
- Tk.update
104
- end
105
- end
106
- end
107
- }
108
- end
109
-
110
- def load_toolbar_buttons
111
- suf = 'toolbar_buttons'
112
- @buttons = Hash.new
113
- toolbar_buttons = self['conf'][suf].split(',')
114
- toolbar_buttons.each{|groups|
115
- if groups
116
- suf1 = suf+'.'+groups
117
- @splash.next_step('... loading '+suf1)
118
- begin
119
- buttons = self['conf'][suf1].split(',')
120
- buttons.each{|button|
121
- suf2 = suf1+'.'+button
122
- name = self['conf'][suf2+'.name']
123
- text = self['conf'][suf2+'.text']
124
- image = self['conf'][suf2+'.image']
125
- font = self['conf'][suf2+'.font']
126
- background = self['conf'][suf2+'.background']
127
- foreground = self['conf'][suf2+'.foreground']
128
- hint = self['conf'][suf2+'.hint']
129
- action = self['conf'][suf2+'.action']
130
- actions = action.split('->') if action
131
- if actions && actions.length>1
132
- _command = proc{
133
- action_obj = $arcadia[actions[0]]
134
- 1.upto(actions.length-2) do |x|
135
- action_obj = action_obj.send(actions[x])
136
- end
137
- action_obj.send(actions[actions.length-1])
138
- }
139
- elsif action
140
- _command = proc{$arcadia[action].call}
141
- end
142
- @buttons[name] = Tk::BWidget::Button.new(@toolbar){
143
- image TkPhotoImage.new('data' => eval(image)) if image
144
- borderwidth 1
145
- font font if font
146
- background background if background
147
- foreground foreground if foreground
148
- command _command if action
149
- relief 'flat'
150
- helptext hint if hint
151
- text text if text
152
- pack('side' =>'left', :padx=>2, :pady=>2)
153
- }
154
- }
155
- rescue Exception
156
- msg = 'Loading '+groups+'" -> '+buttons.to_s+ '" (' + $!.class.to_s + ") : " + $!.to_s + " at : "+$@.to_s
157
- if Tk.messageBox('icon' => 'error', 'type' => 'okcancel',
158
- 'title' => '(Arcadia) Toolbar', 'parent' => @root,
159
- 'message' => msg) == 'cancel'
160
- raise
161
- exit
162
- else
163
- Tk.update
164
- end
165
- end
166
- end
167
- Tk::BWidget::Separator.new(@toolbar, :orient=>'vertical').pack('side' =>'left', :padx=>2, :pady=>2, :fill=>'y',:anchor=> 'w')
168
- }
169
- end
170
-
171
- def ext_active?(_name)
172
- return (self['conf'][_name+'.active'] != nil && self['conf'][_name+'.active']=='yes')||
173
- (self['conf'][_name+'.active'] == nil)
174
- end
175
-
176
- def load_exts_conf
177
- @exts = Array.new
178
- dirs = Array.new
179
- files = Dir['ext/*'].concat(Dir[ENV["HOME"]+'/.arcadia/ext/*'])
180
- files.each{|f|
181
- dirs << f if File.stat(f).directory? && FileTest.exist?(f+'/'+File.basename(f)+'.conf')
182
- }
183
- dirs.each{|ext_dir|
184
- conf_hash = self.config_file2hash(ext_dir+'/'+File.basename(ext_dir)+'.conf')
185
- conf_hash2 = Hash.new
186
- name = conf_hash['name']
187
- conf_hash.each{|key, value|
188
- var_plat = key.split(':')
189
- if var_plat.length > 1
190
- new_key = var_plat[0] + ':' + name + '.' + var_plat[1]
191
- else
192
- new_key = name+'.'+key
193
- end
194
- conf_hash2[new_key]= value
195
- }
196
- @exts << name
197
- self['conf'].update(conf_hash2)
198
- }
199
- end
200
-
201
- def load_exts
202
-
203
- # create extensions
204
- @exts.each{|extension|
205
- if extension && ext_active?(extension)
206
- @splash.next_step('... creating '+extension)
207
- ext_create(extension)
208
- end
209
- }
210
-
211
- # before_build extensions
212
- @exts.each{|extension|
213
- if extension && ext_active?(extension)
214
- @splash.next_step('... before building '+extension)
215
- ext_method(extension, :before_build)
216
- MainContract.instance.extension_before_build(MainContract::TMainObj.new(self, 'obj'=>self[extension]))
217
- end
218
- }
219
-
220
- # build extensions
221
- @exts.each{|extension|
222
- if extension && ext_active?(extension)
223
- @splash.next_step('... building '+extension)
224
- ext_method(extension, :build)
225
- _tobj = MainContract::TMainObj.new(self)
226
- _tobj.obj = self[extension]
227
- MainContract.instance.extension_build(_tobj)
228
- end
229
- }
230
-
231
- # after build extensions
232
- @exts.each{|extension|
233
- if extension && ext_active?(extension)
234
- @splash.next_step('... after building '+extension)
235
- ext_method(extension, :after_build)
236
- _tobj = MainContract::TMainObj.new(self)
237
- _tobj.obj = self[extension]
238
- MainContract.instance.extension_after_build(_tobj)
239
- end
240
- }
241
-
242
- end
243
-
244
- def ext_create(_extension)
245
- begin
246
- source = self['conf'][_extension+'.require']
247
- class_name = self['conf'][_extension+'.class']
248
- if source.strip.length > 0
249
- #p source
250
- eval('require ' + "'" + source + "'")
251
- end
252
- if class_name.strip.length > 0
253
- publish(_extension, eval(class_name).new(self, _extension))
254
- end
255
- rescue Exception
256
- raise
257
- msg = "Loading "+'"'+extension+'"'+" ("+$!.class.to_s+") "+" : "+$! + " at : "+$@.to_s
258
- ans = Tk.messageBox('icon' => 'error', 'type' => 'abortretryignore',
259
- 'title' => '(Arcadia) Extensions', 'parent' => @root,
260
- 'message' => msg)
261
- if ans == 'abort'
262
- raise
263
- exit
264
- elsif ans == 'retry'
265
- retry
266
- else
267
- Tk.update
268
- end
269
- end
270
- end
271
-
272
- def ext_method(_extension, _method)
273
- begin
274
- self[_extension].send(_method)
275
- rescue Exception
276
- msg = _method.to_s+' "'+_extension.to_s+'"'+" ("+$!.class.to_s+") "+" : "+$! + "\n at : "+$@.to_s
277
- ans = Tk.messageBox('icon' => 'warning', 'type' => 'abortretryignore',
278
- 'title' => '(Arcadia) Extensions', 'parent' => @root,
279
- 'message' => msg)
280
- if ans == 'abort'
281
- raise
282
- exit
283
- elsif ans == 'retry'
284
- retry
285
- else
286
- Tk.update
287
- end
288
- end
289
- end
290
-
291
-
292
- def prepare
293
- super
294
- @splash.next_step('...initialize')
295
- @layout = ArcadiaLayout.new(self, @mf_root.get_frame)
296
-
297
- @layout.add_cols(0,0,225)
298
- @layout.add_rows(0,0,180)
299
- # @layout.add_rows(0,1,500)
300
- @layout.add_rows_perc(0,1,70)
301
-
302
-
303
- @layout.add_headers
304
- @splash.next_step
305
- self.load_libs
306
- @splash.next_step
307
- @splash.next_step('... load extensions')
308
- self.load_exts_conf
309
- self.load_local_config
310
- self.load_exts
311
- publish('buffers.code.in_memory',Hash.new)
312
- publish('action.load_code_from_buffers', proc{TkBuffersChoise.new})
313
- publish('output.action.run_last', proc{$arcadia['output'].run_last})
314
- publish('main.action.open_file', proc{self['editor'].open_file(Tk.getOpenFile)})
315
- @splash.next_step('... load obj controller')
316
- @splash.next_step('... load editor')
317
- publish('main.action.new_file',proc{$arcadia['editor'].open_buffer()})
318
- publish('main.action.edit_cut',proc{$arcadia['editor'].raised.text.text_cut()})
319
- publish('main.action.edit_copy',proc{$arcadia['editor'].raised.text.text_copy()})
320
- publish('main.action.edit_paste',proc{$arcadia['editor'].raised.text.text_paste()})
321
- @splash.next_step('... load actions')
322
- publish('action.test.keys', proc{KetTest.new})
323
- publish('action.get.font', proc{Tk::BWidget::SelectFont::Dialog.new.create})
324
- @splash.next_step
325
- publish('action.show_about', proc{ArcadiaAboutSplash.new.deiconify})
326
- publish('main.menu', AMainMenu.new(@main_menu))
327
- @splash.next_step
328
- publish('objic.action.raise_active_obj',
329
- proc{
330
- InspectorContract.instance.raise_active_toplevel(InspectorContract::TInspectorObj.new(self))
331
- # if $arcadia['objic'].active
332
- # agobj = $arcadia['objic'].active.active_object
333
- # while agobj.ag_parent
334
- # agobj = agobj.ag_parent
335
- # end
336
- # agobj.obj.raise
337
- # end
338
- }
339
- )
340
- #@root.bind("Button-1", $arcadia['objic.action.raise_active_obj'] )
341
- load_toolbar_buttons
342
- end
343
-
344
- def do_exit
345
- q1 = (Tk.messageBox('icon' => 'question', 'type' => 'yesno',
346
- 'title' => '(Arcadia) Exit', 'parent' => @root,
347
- 'message' => "Do you want exit?")=='yes')
348
- if q1 && can_exit?
349
- do_finalize
350
- @root.destroy
351
- end
352
- end
353
-
354
- def can_exit?
355
- _can_exit = true
356
- @exts.each{|extension|
357
- if ext_active?(extension) && !self[extension].can_exit_query
358
- _can_exit = false
359
- break
360
- end
361
- }
362
- return _can_exit
363
- end
364
-
365
- def do_finalize
366
- @exts.each{|extension|
367
- self[extension].finalize if ext_active?(extension)
368
- }
369
- self.write_persist
370
- end
371
- end
372
-
373
- class AMainMenu < TkMenubar
374
-
375
- def initialize(menu)
376
- # create main menu
377
- @menu = menu
378
- build
379
- menu.foreground('grey40')
380
- menu.activeforeground('red')
381
- menu.relief('flat')
382
- menu.font($arcadia['conf']['main.mainmenu.font'])
383
- end
384
-
385
- def build
386
- menu_spec_file = [
387
- ['File', 0],
388
- ['Open', $arcadia['main.action.open_file'], 0],
389
- ['New', $arcadia['main.action.new_file'], 0],
390
- '---',
391
- ['Quit', $arcadia['action.on_exit'], 0]]
392
- menu_spec_edit = [['Edit', 0],
393
- ['Cut', $arcadia['main.action.edit_cut'], 2],
394
- ['Copy', $arcadia['main.action.edit_copy'], 0],
395
- ['Paste', $arcadia['main.action.edit_paste'], 0]]
396
- menu_spec_view = [['View', 0],'---']
397
- menu_spec_tools = [['Utils', 0],
398
- ['Keys-test', $arcadia['action.test.keys'], 2],
399
- ['Load code from buffer', $arcadia['action.load_code_from_buffers'], 2]
400
- ]
401
- menu_spec_help = [['Help', 0],
402
- ['About', $arcadia['action.show_about'], 2],]
403
- @menu.add_menu(menu_spec_file)
404
- @menu.add_menu(menu_spec_edit)
405
- #@menu.add_menu(menu_spec_view)
406
- @menu.add_menu(menu_spec_tools)
407
- @menu.add_menu(menu_spec_help)
408
- end
409
-
410
- end
411
-
412
- class ArcadiaAboutSplash < TkToplevel
413
- attr :progress
414
-
415
- def initialize(_txt=nil)
416
- #_bgcolor = '#B83333'
417
- _bgcolor = '#000000'
418
- super()
419
- relief 'flat'
420
- background _bgcolor
421
- highlightbackground _bgcolor
422
- highlightthickness 6
423
- borderwidth 1
424
- withdraw
425
- overrideredirect(true)
426
-
427
- @tkLabel3 = TkLabel.new(self){
428
- image TkPhotoImage.new('format'=>'GIF','data' =>A_LOGO_GIF)
429
- background _bgcolor
430
- place('x'=> 20,'y' => 20)
431
- }
432
- @tkLabel1 = TkLabel.new(self){
433
- text 'Arcadia'
434
- background _bgcolor
435
- foreground '#ffffff'
436
- font Arcadia.instance['conf']['splash.title.font']
437
- justify 'left'
438
- place('width' => '190','x' => 120,'y' => 10,'height' => 25)
439
- }
440
- @tkLabelRuby = TkLabel.new(self){
441
- image TkPhotoImage.new('data' =>RUBY_DOCUMENT_GIF)
442
- background _bgcolor
443
- place('x'=> 150,'y' => 40)
444
- }
445
- @tkLabel2 = TkLabel.new(self){
446
- text 'Ruby ide'
447
- background _bgcolor
448
- foreground '#ffffff'
449
- font Arcadia.instance['conf']['splash.subtitle.font']
450
- justify 'left'
451
- place('width' => '90','x' => 170,'y' => 40,'height' => 19)
452
- }
453
- @tkLabelVersion = TkLabel.new(self){
454
- text 'version: '+$arcadia['applicationParams'].version
455
- background _bgcolor
456
- foreground '#ffffff'
457
- font Arcadia.instance['conf']['splash.version.font']
458
- justify 'left'
459
- place('width' => '100','x' => 150,'y' => 60,'height' => 19)
460
- }
461
- @tkLabelStep = TkLabel.new(self){
462
- text _txt
463
- background _bgcolor
464
- foreground 'yellow'
465
- font Arcadia.instance['conf']['splash.banner.font']
466
- justify 'left'
467
- anchor 'w'
468
- place('width'=>-5,'relwidth' => 1,'x' => 5,'y' => 175,'height' => 19)
469
- }
470
- @tkLabel21 = TkLabel.new(self){
471
- text 'by Antonio Galeone - 2007'
472
- background _bgcolor
473
- foreground '#ffffff'
474
- font Arcadia.instance['conf']['splash.credits.font']
475
- justify 'left'
476
- place('width' => '190','x' => 130,'y' => 146,'height' => 19)
477
- }
478
- @progress = TkVariable.new
479
- reset
480
- _width = 340
481
- _height = 210
482
- #_width = 0;_height = 0
483
- _x = TkWinfo.screenwidth(self)/2 - _width / 2
484
- _y = TkWinfo.screenheight(self)/2 - _height / 2
485
- geometry = _width.to_s+'x'+_height.to_s+'+'+_x.to_s+'+'+_y.to_s
486
- Tk.tk_call('wm', 'geometry', self, geometry )
487
- bind("Double-Button-1", proc{self.destroy})
488
- end
489
-
490
- def set_progress(_max=10)
491
- @max = _max
492
- Tk::BWidget::ProgressBar.new(self, :width=>150, :height=>10,
493
- :background=>'black',
494
- :foreground=>'yellow',
495
- :variable=>@progress,
496
- :borderwidth=>0,
497
- :relief=>'flat',
498
- :maximum=>_max).place('width' => '150','x' => 145,'y' => 95,'height' => 15)
499
- end
500
-
501
- def reset
502
- @progress.value = -1
503
- end
504
-
505
- def next_step(_txt = nil)
506
- @progress.numeric += 1
507
- labelStep(_txt) if _txt
508
- end
509
-
510
- def labelStep(_txt)
511
- @tkLabelStep.text = _txt
512
- Tk.update
513
- end
514
-
515
- def last_step(_txt = nil)
516
- @progress.numeric = @max
517
- labelStep(_txt) if _txt
518
- end
519
-
520
- end
521
-
522
- class TkBuffersChoiseView < TkToplevel
523
-
524
- def initialize
525
- super
526
- Tk.tk_call('wm', 'title', self, '...hello' )
527
- Tk.tk_call('wm', 'geometry', self, '150x217+339+198' )
528
- @lb = TkListbox.new(self){
529
- background '#fedbd7'
530
- relief 'groove'
531
- place('relwidth' => '1','relx' => 0,'x' => '0','y' => '0','relheight' => '1','rely' => 0,'height' => '0','bordermode' => 'inside','width' => '0')
532
- }
533
- end
534
-
535
- end
536
-
537
- class TkBuffersChoise < TkBuffersChoiseView
538
-
539
- def initialize
540
- super
541
- @lb.value= $arcadia['buffers.code.in_memory'].keys
542
- @lb.bind("Double-ButtonPress-1",proc{
543
- _sel = @lb.get('active')
544
- Revparsel.new($arcadia['buffers.code.in_memory'][_sel])
545
- @lb.delete('active')
546
- $arcadia['buffers.code.in_memory'].delete(_sel)
547
- destroy
548
- })
549
- raise
550
- end
551
-
552
- end
553
-
554
- class ArcadiaLayout
555
- include Observable
556
- ArcadiaPanelInfo = Struct.new( "ArcadiaPanelInfo",
557
- :name,
558
- :title,
559
- :frame
560
- )
561
-
562
- def initialize(_arcadia, _frame, _autotab=true)
563
- @arcadia = _arcadia
564
- @frames = Array.new
565
- @frames[0] = Array.new
566
- @frames[0][0] = _frame
567
- @domains = Array.new
568
- @domains[0] = Array.new
569
- @domains[0][0] = '_domain_root_'
570
- @panels = Hash.new
571
- @panels['_domain_root_']= Hash.new
572
- @panels['_domain_root_']['root']= _frame
573
- @panels['_domain_root_']['sons'] = Hash.new
574
- @autotab = _autotab
575
- @headed = false
576
- ArcadiaContractListener.new(self, MainContract, :do_main_event)
577
- end
578
-
579
- def do_main_event(_event)
580
- case _event.signature
581
- when MainContract::RAISE_EXTENSION
582
- p = @panels[_event.context.domain]
583
- if p && p['notebook'] != nil && _event.channel == '0'
584
- p['notebook'].raise(_event.context.extension)
585
- end
586
- end
587
- end
588
-
589
- def _prepare_rows(_row,_col, _height, _perc=false, _top_name=nil, _bottom_name=nil)
590
- if (@frames[_row][_col] != nil)
591
- _h = AGTkOSplittedFrames.new(@frames[_row][_col],_height, _perc)
592
- if @frames[_row + 1] == nil
593
- @frames[_row + 1] = Array.new
594
- @domains[_row + 1] = Array.new
595
- end
596
- @frames[_row][_col] = _h.top_frame
597
- @frames[_row + 1][_col] = _h.bottom_frame
598
-
599
- _top_name = _row.to_s+'.'+_col.to_s if _top_name == nil
600
- @panels[_top_name] = Hash.new
601
- @panels[_top_name]['root'] = @frames[_row][_col]
602
- @panels[_top_name]['sons'] = Hash.new
603
- @domains[_row][_col] = _top_name
604
-
605
- _bottom_name = (_row+1).to_s+'.'+_col.to_s if _bottom_name == nil
606
- @panels[_bottom_name] = Hash.new
607
- @panels[_bottom_name]['root'] = @frames[_row + 1][_col]
608
- @panels[_bottom_name]['sons'] = Hash.new
609
- @domains[_row + 1][_col] = _bottom_name
610
- end
611
- end
612
- private :_prepare_rows
613
-
614
- def add_rows(_row,_col, _height, _top_name=nil, _bottom_name=nil)
615
- _prepare_rows(_row,_col, _height, false, _top_name, _bottom_name)
616
- end
617
-
618
- def add_rows_perc(_row,_col, _height, _top_name=nil, _bottom_name=nil)
619
- _prepare_rows(_row,_col, _height, true, _top_name, _bottom_name)
620
- end
621
-
622
-
623
- def add_cols(_row,_col, _width, _left_name=nil, _right_name=nil)
624
- if (@frames[_row][_col] != nil)
625
- _w = AGTkVSplittedFrames.new(@frames[_row][_col],_width)
626
- @frames[_row][_col] = _w.left_frame
627
- @frames[_row][_col + 1] = _w.right_frame
628
-
629
- _left_name = _row.to_s+'.'+_col.to_s if _left_name == nil
630
- @panels[_left_name] = Hash.new
631
- @panels[_left_name]['root'] = @frames[_row][_col]
632
- @panels[_left_name]['sons'] = Hash.new
633
- @domains[_row][_col] = _left_name
634
-
635
- _right_name = _row.to_s+'.'+(_col+1).to_s if _right_name == nil
636
- @panels[_right_name] = Hash.new
637
- @panels[_right_name]['root'] = @frames[_row][_col + 1]
638
- @panels[_right_name]['sons'] = Hash.new
639
- @domains[_row][_col + 1] = _right_name
640
- end
641
- end
642
-
643
- def add_headers
644
- @domains.each{|row|
645
- row.each{|domain|
646
- @panels[domain]['root']= TkTitledFrame.new(@panels[domain]['root'], '...').place('x'=>0, 'y'=>0,'relheight'=>1, 'relwidth'=>1) if @panels[domain]
647
- }
648
- }
649
- @headed = true
650
- end
651
-
652
- def headed?
653
- @headed
654
- end
655
-
656
- def autotab?
657
- @autotab
658
- end
659
-
660
- def registed?(_domain_name, _name)
661
- @panels[_domain_name]['sons'][_name] != nil
662
- end
663
-
664
- def register_panel(_domain_name, _name, _title)
665
- p = @panels[_domain_name]
666
- if p!=nil
667
- num = p['sons'].length
668
- if @headed
669
- p['root'].title(_title)
670
- root_frame = p['root'].frame
671
- else
672
- root_frame = p['root']
673
- end
674
- if (num == 0 && @autotab)
675
- api = ArcadiaPanelInfo.new(_name,_title,nil)
676
- api.frame = TkFrame.new(root_frame).place('x'=>0, 'y'=>0, 'relwidth'=>1, 'relheight'=>1)
677
- p['sons'][_name] = api
678
- return api.frame
679
- else
680
- if num == 1 && @autotab && p['notebook'] == nil
681
- p['notebook'] = Tk::BWidget::NoteBook.new(root_frame){
682
- tabbevelsize 0
683
- internalborderwidth 0
684
- pack('fill'=>'both', :padx=>0, :pady=>0, :expand => 'yes')
685
- }
686
- api = p['sons'].values[0]
687
- api_tab_frame = p['notebook'].insert('end',
688
- api.name,
689
- 'text'=>api.title,
690
- 'raisecmd'=>proc{
691
- p['root'].title(api.title)
692
- p['root'].top_text('')
693
- changed
694
- notify_observers('RAISE', api.name)
695
- }
696
- )
697
- api.frame.place('in'=>api_tab_frame, 'x'=>0, 'y'=>0, 'relwidth'=>1, 'relheight'=>1)
698
- api.frame.raise
699
- elsif (num==0 && !@autotab)
700
- p['notebook'] = Tk::BWidget::NoteBook.new(root_frame){
701
- tabbevelsize 0
702
- internalborderwidth 0
703
- pack('fill'=>'both', :padx=>0, :pady=>0, :expand => 'yes')
704
- }
705
- end
706
- _panel = p['notebook'].insert('end',_name ,
707
- 'text'=>_title,
708
- #'background'=>_tab_bg,
709
- 'raisecmd'=>proc{
710
- p['root'].title(_title)
711
- changed
712
- notify_observers('RAISE', _name)
713
- }
714
- )
715
-
716
- # if _tab_bg
717
- # _panel = p['notebook'].insert('end',_name , 'text'=>_title, 'background'=>_tab_bg)
718
- # else
719
- # _panel = p['notebook'].insert('end',_name , 'text'=>_title)
720
- # end
721
- p['sons'][_name] = ArcadiaPanelInfo.new(_name,_title,_panel)
722
- p['notebook'].raise(_name)
723
- return _panel
724
- end
725
- end
726
- end
727
-
728
- def unregister_panel(_domain_name, _name)
729
- @panels[_domain_name]['sons'].delete(_name)
730
- @panels[_domain_name]['notebook'].delete(_name)
731
- new_raise_key = @panels[_domain_name]['sons'].keys[@panels[_domain_name]['sons'].length-1]
732
- @panels[_domain_name]['notebook'].raise(new_raise_key)
733
- end
734
-
735
- def raise_panel(_domain_name, _name)
736
- @panels[_domain_name]['notebook'].raise(_name) if @panels[_domain_name] && @panels[_domain_name]['notebook']
737
- end
738
-
739
- def [](_row, _col)
740
- @frames[_row][_col]
741
- end
742
-
743
- def frame(_domain_name, _name)
744
- @panels[_domain_name]['sons'][_name].frame
745
- end
746
-
747
- def domain(_domain_name)
748
- @panels[_domain_name]
749
- end
750
-
751
- def domain_root_frame(_domain_name)
752
- @panels[_domain_name]['root'].frame
753
- end
754
- end
755
-
756
- Arcadia.new.run
1
+ #
2
+ # arcadia.rb - Arcadia Ruby ide
3
+ # by Antonio Galeone <antonio-galeone@rubyforge.org>
4
+ #
5
+
6
+ Dir.chdir(File.dirname(__FILE__))
7
+ if FileTest.exist?('conf/arcadia.init.rb')
8
+ require 'conf/arcadia.init'
9
+ end
10
+ require "conf/arcadia.res"
11
+ require 'tkextlib/bwidget'
12
+ require "base/a-utils"
13
+ require "base/a-ext"
14
+ require "base/a-contracts"
15
+ require "observer"
16
+
17
+ class Arcadia < TkApplication
18
+ include Observable
19
+ attr_reader :layout
20
+ attr_reader :libs
21
+ #attr_reader :main_contract
22
+ def initialize
23
+ super(
24
+ ApplicationParams.new(
25
+ 'arcadia',
26
+ '0.1.2',
27
+ 'conf/arcadia.conf',
28
+ 'conf/arcadia.pers'
29
+ )
30
+ )
31
+ self.load_local_config(false)
32
+ ObjectSpace.define_finalizer($arcadia, self.class.method(:finalize).to_proc)
33
+ publish('action.on_exit', proc{do_exit})
34
+ _title = "Arcadia Ruby ide :: [Platform = "+RUBY_PLATFORM+'] [Ruby version = ' + RUBY_VERSION+']'
35
+ @root = TkRoot.new{
36
+ title _title
37
+ withdraw
38
+ protocol( "WM_DELETE_WINDOW", $arcadia['action.on_exit'])
39
+ }
40
+ @on_event = Hash.new
41
+ @main_menu = TkMenubar.new.pack('fill'=>'x')
42
+ @mf_root = Tk::BWidget::MainFrame.new(@root){
43
+ menu @main_menu
44
+ }.pack(
45
+ 'anchor'=> 'center',
46
+ 'fill'=> 'both',
47
+ 'expand'=> 1
48
+ )
49
+
50
+ #.place('x'=>0,'y'=>0,'relwidth'=>1,'relheight'=>1)
51
+ @mf_root.show_statusbar('none')
52
+ @toolbar = @mf_root.add_toolbar
53
+ @is_toolbar_show=self['conf']['toolbar_show']=='yes'
54
+ @mf_root.show_toolbar(0,@is_toolbar_show)
55
+ @splash = ArcadiaAboutSplash.new('... initialize')
56
+ @splash.set_progress(50)
57
+ @splash.deiconify
58
+ Tk.update
59
+ sleep(1)
60
+ @splash.next_step('..prepare')
61
+ prepare
62
+ @splash.last_step('..load finish')
63
+ geometry = (TkWinfo.screenwidth(@root)-4).to_s+'x'+
64
+ (TkWinfo.screenheight(@root)-20).to_s+'+0+0'
65
+ @root.deiconify
66
+ @root.raise
67
+ @root.focus(true)
68
+ @root.geometry(geometry)
69
+ Tk.update_idletasks
70
+ sleep(1)
71
+ @splash.destroy
72
+ if @first_run
73
+ EditorContract.instance.open_file(self, 'file'=>'README')
74
+ end
75
+ end
76
+
77
+ def show_hide_toolbar
78
+ if @is_toolbar_show
79
+ @mf_root.show_toolbar(0,false)
80
+ @is_toolbar_show = false
81
+ else
82
+ @mf_root.show_toolbar(0,true)
83
+ Tk.update
84
+ @is_toolbar_show = true
85
+ end
86
+
87
+ end
88
+
89
+
90
+ def Arcadia.finalize(id)
91
+ puts "\nArcadia #{id} dying at #{Time.new}"
92
+ end
93
+
94
+ def load_libs
95
+ @libs = ArcadiaLibs.new(self)
96
+ libs = self['conf']['libraries'].split(',')
97
+ libs.each{|lib|
98
+ if lib
99
+ @splash.next_step('... loading library '+lib)
100
+ begin
101
+ require self['conf']['libraries.'+lib+'.source']
102
+ @libs.add_lib(
103
+ ArcadiaLibs::ArcadiaLibParams.new(
104
+ self['conf']['libraries.'+lib+'.name'],
105
+ self['conf']['libraries.'+lib+'.source'],
106
+ self['conf']['libraries.'+lib+'.require'],
107
+ eval(self['conf']['libraries.'+lib+'.collection.class']))
108
+ )
109
+ rescue Exception
110
+ msg = "Loading lib "+'"'+lib+'"'+" ("+$!.class.to_s+") "+" : "+$! + " at : "+$@.to_s
111
+ if Tk.messageBox('icon' => 'error', 'type' => 'okcancel',
112
+ 'title' => '(Arcadia) Libs', 'parent' => @root,
113
+ 'message' => msg) == 'cancel'
114
+ raise
115
+ exit
116
+ else
117
+ Tk.update
118
+ end
119
+ end
120
+ end
121
+ }
122
+ end
123
+
124
+ def load_toolbar_buttons
125
+ suf = 'toolbar_buttons'
126
+ @buttons = Hash.new
127
+ toolbar_buttons = self['conf'][suf].split(',')
128
+ toolbar_buttons.each{|groups|
129
+ if groups
130
+ suf1 = suf+'.'+groups
131
+ @splash.next_step('... loading '+suf1)
132
+ begin
133
+ buttons = self['conf'][suf1].split(',')
134
+ buttons.each{|button|
135
+ suf2 = suf1+'.'+button
136
+ name = self['conf'][suf2+'.name']
137
+ text = self['conf'][suf2+'.text']
138
+ image = self['conf'][suf2+'.image']
139
+ font = self['conf'][suf2+'.font']
140
+ background = self['conf'][suf2+'.background']
141
+ foreground = self['conf'][suf2+'.foreground']
142
+ hint = self['conf'][suf2+'.hint']
143
+ action = self['conf'][suf2+'.action']
144
+ actions = action.split('->') if action
145
+ if actions && actions.length>1
146
+ _command = proc{
147
+ action_obj = $arcadia[actions[0]]
148
+ 1.upto(actions.length-2) do |x|
149
+ action_obj = action_obj.send(actions[x])
150
+ end
151
+ action_obj.send(actions[actions.length-1])
152
+ }
153
+ elsif action
154
+ _command = proc{$arcadia[action].call}
155
+ end
156
+ @buttons[name] = Tk::BWidget::Button.new(@toolbar){
157
+ image TkPhotoImage.new('data' => eval(image)) if image
158
+ borderwidth 1
159
+ font font if font
160
+ background background if background
161
+ foreground foreground if foreground
162
+ command _command if action
163
+ relief 'flat'
164
+ helptext hint if hint
165
+ text text if text
166
+ pack('side' =>'left', :padx=>2, :pady=>2)
167
+ }
168
+ }
169
+ rescue Exception
170
+ msg = 'Loading '+groups+'" -> '+buttons.to_s+ '" (' + $!.class.to_s + ") : " + $!.to_s + " at : "+$@.to_s
171
+ if Tk.messageBox('icon' => 'error', 'type' => 'okcancel',
172
+ 'title' => '(Arcadia) Toolbar', 'parent' => @root,
173
+ 'message' => msg) == 'cancel'
174
+ raise
175
+ exit
176
+ else
177
+ Tk.update
178
+ end
179
+ end
180
+ end
181
+ Tk::BWidget::Separator.new(@toolbar, :orient=>'vertical').pack('side' =>'left', :padx=>2, :pady=>2, :fill=>'y',:anchor=> 'w')
182
+ }
183
+ end
184
+
185
+ def ext_active?(_name)
186
+ return (self['conf'][_name+'.active'] != nil && self['conf'][_name+'.active']=='yes')||
187
+ (self['conf'][_name+'.active'] == nil)
188
+ end
189
+
190
+ def load_exts_conf
191
+ @exts = Array.new
192
+ dirs = Array.new
193
+ files = Dir['ext/*'].concat(Dir[ENV["HOME"]+'/.arcadia/ext/*'])
194
+ files.each{|f|
195
+ dirs << f if File.stat(f).directory? && FileTest.exist?(f+'/'+File.basename(f)+'.conf')
196
+ }
197
+ dirs.each{|ext_dir|
198
+ conf_hash = self.config_file2hash(ext_dir+'/'+File.basename(ext_dir)+'.conf')
199
+ conf_hash2 = Hash.new
200
+ name = conf_hash['name']
201
+ conf_hash.each{|key, value|
202
+ var_plat = key.split(':')
203
+ if var_plat.length > 1
204
+ new_key = var_plat[0] + ':' + name + '.' + var_plat[1]
205
+ else
206
+ new_key = name+'.'+key
207
+ end
208
+ conf_hash2[new_key]= value
209
+ }
210
+ @exts << name
211
+ self['conf'].update(conf_hash2)
212
+ }
213
+ end
214
+
215
+ def load_exts
216
+
217
+ # create extensions
218
+ @exts.each{|extension|
219
+ if extension && ext_active?(extension)
220
+ @splash.next_step('... creating '+extension)
221
+ ext_create(extension)
222
+ end
223
+ }
224
+
225
+ # before_build extensions
226
+ @exts.each{|extension|
227
+ if extension && ext_active?(extension)
228
+ @splash.next_step('... before building '+extension)
229
+ ext_method(extension, :before_build)
230
+ MainContract.instance.extension_before_build(self, 'obj'=>self[extension])
231
+ end
232
+ }
233
+
234
+ # build extensions
235
+ @exts.each{|extension|
236
+ if extension && ext_active?(extension)
237
+ @splash.next_step('... building '+extension)
238
+ ext_method(extension, :build)
239
+ MainContract.instance.extension_build(self, 'obj'=>self[extension])
240
+ end
241
+ }
242
+
243
+ # after build extensions
244
+ @exts.each{|extension|
245
+ if extension && ext_active?(extension)
246
+ @splash.next_step('... after building '+extension)
247
+ ext_method(extension, :after_build)
248
+ MainContract.instance.extension_after_build(self, 'obj'=>self[extension])
249
+ end
250
+ }
251
+
252
+ end
253
+
254
+ def ext_create(_extension)
255
+ begin
256
+ source = self['conf'][_extension+'.require']
257
+ class_name = self['conf'][_extension+'.class']
258
+ if source.strip.length > 0
259
+ #p source
260
+ eval('require ' + "'" + source + "'")
261
+ end
262
+ if class_name.strip.length > 0
263
+ publish(_extension, eval(class_name).new(self, _extension))
264
+ end
265
+ rescue Exception
266
+ raise
267
+ msg = "Loading "+'"'+extension+'"'+" ("+$!.class.to_s+") "+" : "+$! + " at : "+$@.to_s
268
+ ans = Tk.messageBox('icon' => 'error', 'type' => 'abortretryignore',
269
+ 'title' => '(Arcadia) Extensions', 'parent' => @root,
270
+ 'message' => msg)
271
+ if ans == 'abort'
272
+ raise
273
+ exit
274
+ elsif ans == 'retry'
275
+ retry
276
+ else
277
+ Tk.update
278
+ end
279
+ end
280
+ end
281
+
282
+ def ext_method(_extension, _method)
283
+ begin
284
+ self[_extension].send(_method)
285
+ rescue Exception
286
+ msg = _method.to_s+' "'+_extension.to_s+'"'+" ("+$!.class.to_s+") "+" : "+$! + "\n at : "+$@.to_s
287
+ ans = Tk.messageBox('icon' => 'warning', 'type' => 'abortretryignore',
288
+ 'title' => '(Arcadia) Extensions', 'parent' => @root,
289
+ 'message' => msg)
290
+ if ans == 'abort'
291
+ raise
292
+ exit
293
+ elsif ans == 'retry'
294
+ retry
295
+ else
296
+ Tk.update
297
+ end
298
+ end
299
+ end
300
+
301
+
302
+ def prepare
303
+ super
304
+ @splash.next_step('...initialize')
305
+ @layout = ArcadiaLayout.new(self, @mf_root.get_frame)
306
+
307
+ @layout.add_cols(0,0,225)
308
+ @layout.add_rows(0,0,180)
309
+ # @layout.add_rows(0,1,500)
310
+ @layout.add_rows_perc(0,1,70)
311
+
312
+
313
+ @layout.add_headers
314
+ @splash.next_step
315
+ self.load_libs
316
+ @splash.next_step
317
+ @splash.next_step('... load extensions')
318
+ self.load_exts_conf
319
+ self.load_local_config
320
+ self.load_exts
321
+ publish('buffers.code.in_memory',Hash.new)
322
+ publish('action.load_code_from_buffers', proc{TkBuffersChoise.new})
323
+ publish('output.action.run_last', proc{$arcadia['output'].run_last})
324
+ publish('main.action.open_file', proc{self['editor'].open_file(Tk.getOpenFile)})
325
+ @splash.next_step('... load obj controller')
326
+ @splash.next_step('... load editor')
327
+ publish('main.action.new_file',proc{$arcadia['editor'].open_buffer()})
328
+ publish('main.action.edit_cut',proc{$arcadia['editor'].raised.text.text_cut()})
329
+ publish('main.action.edit_copy',proc{$arcadia['editor'].raised.text.text_copy()})
330
+ publish('main.action.edit_paste',proc{$arcadia['editor'].raised.text.text_paste()})
331
+ @splash.next_step('... load actions')
332
+ publish('action.test.keys', proc{KetTest.new})
333
+ publish('action.get.font', proc{Tk::BWidget::SelectFont::Dialog.new.create})
334
+ @splash.next_step
335
+ publish('action.show_about', proc{ArcadiaAboutSplash.new.deiconify})
336
+ # publish('main.menu', @main_menu)
337
+ publish('main.menu', AMainMenu.new(@main_menu))
338
+ @splash.next_step
339
+ publish('objic.action.raise_active_obj',
340
+ proc{
341
+ InspectorContract.instance.raise_active_toplevel(self)
342
+ }
343
+ )
344
+ load_toolbar_buttons
345
+ end
346
+
347
+ def do_exit
348
+ q1 = (Tk.messageBox('icon' => 'question', 'type' => 'yesno',
349
+ 'title' => '(Arcadia) Exit', 'parent' => @root,
350
+ 'message' => "Do you want exit?")=='yes')
351
+ if q1 && can_exit?
352
+ do_finalize
353
+ @root.destroy
354
+ end
355
+ end
356
+
357
+ def can_exit?
358
+ _can_exit = true
359
+ @exts.each{|extension|
360
+ if ext_active?(extension) && !self[extension].can_exit_query
361
+ _can_exit = false
362
+ break
363
+ end
364
+ }
365
+ return _can_exit
366
+ end
367
+
368
+ def do_finalize
369
+ @exts.each{|extension|
370
+ self[extension].finalize if ext_active?(extension)
371
+ }
372
+ self.write_persist
373
+ end
374
+ end
375
+
376
+
377
+ class AMainMenu < TkMenubar
378
+
379
+ def initialize(menu)
380
+ # create main menu
381
+ @menu = menu
382
+ build
383
+ menu.foreground('grey40')
384
+ menu.activeforeground('red')
385
+ menu.relief('groove')
386
+ menu.borderwidth(0)
387
+ menu.font($arcadia['conf']['main.mainmenu.font'])
388
+ end
389
+
390
+ def build
391
+ menu_spec_file = [
392
+ ['File', 0],
393
+ ['Open', $arcadia['main.action.open_file'], 0],
394
+ ['New', $arcadia['main.action.new_file'], 0],
395
+ ['Save', proc{EditorContract.instance.save_file_raised(self)},0],
396
+ ['Save as ...', proc{EditorContract.instance.save_as_file_raised(self)},0],
397
+ '---',
398
+ ['Quit', $arcadia['action.on_exit'], 0]]
399
+ menu_spec_edit = [['Edit', 0],
400
+ ['Cut', $arcadia['main.action.edit_cut'], 2],
401
+ ['Copy', $arcadia['main.action.edit_copy'], 0],
402
+ ['Paste', $arcadia['main.action.edit_paste'], 0]]
403
+ menu_spec_search = [['Search', 0],
404
+ ['Find ...', proc{EditorContract.instance.show_search_dialog(self)}, 2],
405
+ ['Go to line ...', proc{EditorContract.instance.show_goto_line_dialog(self)}, 2]]
406
+ menu_spec_view = [['View', 0],['Show/Hide Toolbar', proc{$arcadia.show_hide_toolbar}, 2]]
407
+ menu_spec_tools = [['Utils', 0],
408
+ ['Keys-test', $arcadia['action.test.keys'], 2],
409
+ ['Load code from buffer', $arcadia['action.load_code_from_buffers'], 2]
410
+ ]
411
+ menu_spec_help = [['Help', 0],
412
+ ['About', $arcadia['action.show_about'], 2],]
413
+ @menu.add_menu(menu_spec_file)
414
+ @menu.add_menu(menu_spec_edit)
415
+ @menu.add_menu(menu_spec_search)
416
+ @menu.add_menu(menu_spec_view)
417
+ @menu.add_menu(menu_spec_tools)
418
+ @menu.add_menu(menu_spec_help)
419
+ end
420
+
421
+ end
422
+
423
+
424
+ class ArcadiaAboutSplash < TkToplevel
425
+ attr :progress
426
+
427
+ def initialize(_txt=nil)
428
+ #_bgcolor = '#B83333'
429
+ _bgcolor = '#000000'
430
+ super()
431
+ relief 'flat'
432
+ background _bgcolor
433
+ highlightbackground _bgcolor
434
+ highlightthickness 6
435
+ borderwidth 1
436
+ withdraw
437
+ overrideredirect(true)
438
+
439
+ @tkLabel3 = TkLabel.new(self){
440
+ image TkPhotoImage.new('format'=>'GIF','data' =>A_LOGO_GIF)
441
+ background _bgcolor
442
+ place('x'=> 20,'y' => 20)
443
+ }
444
+ @tkLabel1 = TkLabel.new(self){
445
+ text 'Arcadia'
446
+ background _bgcolor
447
+ foreground '#ffffff'
448
+ font Arcadia.instance['conf']['splash.title.font']
449
+ justify 'left'
450
+ place('width' => '190','x' => 120,'y' => 10,'height' => 25)
451
+ }
452
+ @tkLabelRuby = TkLabel.new(self){
453
+ image TkPhotoImage.new('data' =>RUBY_DOCUMENT_GIF)
454
+ background _bgcolor
455
+ place('x'=> 150,'y' => 40)
456
+ }
457
+ @tkLabel2 = TkLabel.new(self){
458
+ text 'Ruby ide'
459
+ background _bgcolor
460
+ foreground '#ffffff'
461
+ font Arcadia.instance['conf']['splash.subtitle.font']
462
+ justify 'left'
463
+ place('width' => '90','x' => 170,'y' => 40,'height' => 19)
464
+ }
465
+ @tkLabelVersion = TkLabel.new(self){
466
+ text 'version: '+$arcadia['applicationParams'].version
467
+ background _bgcolor
468
+ foreground '#ffffff'
469
+ font Arcadia.instance['conf']['splash.version.font']
470
+ justify 'left'
471
+ place('width' => '100','x' => 150,'y' => 60,'height' => 19)
472
+ }
473
+ @tkLabelStep = TkLabel.new(self){
474
+ text _txt
475
+ background _bgcolor
476
+ foreground 'yellow'
477
+ font Arcadia.instance['conf']['splash.banner.font']
478
+ justify 'left'
479
+ anchor 'w'
480
+ place('width'=>-5,'relwidth' => 1,'x' => 5,'y' => 175,'height' => 19)
481
+ }
482
+ @tkLabel21 = TkLabel.new(self){
483
+ text 'by Antonio Galeone - 2007'
484
+ background _bgcolor
485
+ foreground '#ffffff'
486
+ font Arcadia.instance['conf']['splash.credits.font']
487
+ justify 'left'
488
+ place('width' => '190','x' => 130,'y' => 146,'height' => 19)
489
+ }
490
+ @progress = TkVariable.new
491
+ reset
492
+ _width = 340
493
+ _height = 210
494
+ #_width = 0;_height = 0
495
+ _x = TkWinfo.screenwidth(self)/2 - _width / 2
496
+ _y = TkWinfo.screenheight(self)/2 - _height / 2
497
+ geometry = _width.to_s+'x'+_height.to_s+'+'+_x.to_s+'+'+_y.to_s
498
+ Tk.tk_call('wm', 'geometry', self, geometry )
499
+ bind("Double-Button-1", proc{self.destroy})
500
+ end
501
+
502
+ def set_progress(_max=10)
503
+ @max = _max
504
+ Tk::BWidget::ProgressBar.new(self, :width=>150, :height=>10,
505
+ :background=>'black',
506
+ :foreground=>'yellow',
507
+ :variable=>@progress,
508
+ :borderwidth=>0,
509
+ :relief=>'flat',
510
+ :maximum=>_max).place('width' => '150','x' => 145,'y' => 95,'height' => 15)
511
+ end
512
+
513
+ def reset
514
+ @progress.value = -1
515
+ end
516
+
517
+ def next_step(_txt = nil)
518
+ @progress.numeric += 1
519
+ labelStep(_txt) if _txt
520
+ end
521
+
522
+ def labelStep(_txt)
523
+ @tkLabelStep.text = _txt
524
+ Tk.update
525
+ end
526
+
527
+ def last_step(_txt = nil)
528
+ @progress.numeric = @max
529
+ labelStep(_txt) if _txt
530
+ end
531
+
532
+ end
533
+
534
+ class TkBuffersChoiseView < TkToplevel
535
+
536
+ def initialize
537
+ super
538
+ Tk.tk_call('wm', 'title', self, '...hello' )
539
+ Tk.tk_call('wm', 'geometry', self, '150x217+339+198' )
540
+ @lb = TkListbox.new(self){
541
+ background '#fedbd7'
542
+ relief 'groove'
543
+ place('relwidth' => '1','relx' => 0,'x' => '0','y' => '0','relheight' => '1','rely' => 0,'height' => '0','bordermode' => 'inside','width' => '0')
544
+ }
545
+ end
546
+
547
+ end
548
+
549
+ class TkBuffersChoise < TkBuffersChoiseView
550
+
551
+ def initialize
552
+ super
553
+ @lb.value= $arcadia['buffers.code.in_memory'].keys
554
+ @lb.bind("Double-ButtonPress-1",proc{
555
+ _sel = @lb.get('active')
556
+ Revparsel.new($arcadia['buffers.code.in_memory'][_sel])
557
+ @lb.delete('active')
558
+ $arcadia['buffers.code.in_memory'].delete(_sel)
559
+ destroy
560
+ })
561
+ raise
562
+ end
563
+
564
+ end
565
+
566
+ class ArcadiaLayout
567
+ include Observable
568
+ ArcadiaPanelInfo = Struct.new( "ArcadiaPanelInfo",
569
+ :name,
570
+ :title,
571
+ :frame
572
+ )
573
+
574
+ def initialize(_arcadia, _frame, _autotab=true)
575
+ @arcadia = _arcadia
576
+ @frames = Array.new
577
+ @frames[0] = Array.new
578
+ @frames[0][0] = _frame
579
+ @domains = Array.new
580
+ @domains[0] = Array.new
581
+ @domains[0][0] = '_domain_root_'
582
+ @panels = Hash.new
583
+ @panels['_domain_root_']= Hash.new
584
+ @panels['_domain_root_']['root']= _frame
585
+ @panels['_domain_root_']['sons'] = Hash.new
586
+ @autotab = _autotab
587
+ @headed = false
588
+ ArcadiaContractListener.new(self, MainContract, :do_main_event)
589
+ end
590
+ def root
591
+ @panels['_domain_root_']['root']
592
+ end
593
+ def do_main_event(_event)
594
+ case _event.signature
595
+ when MainContract::RAISE_EXTENSION
596
+ p = @panels[_event.context.domain]
597
+ if p && p['notebook'] != nil && _event.channel == '0'
598
+ p['notebook'].raise(_event.context.extension)
599
+ end
600
+ end
601
+ end
602
+
603
+ def _prepare_rows(_row,_col, _height, _perc=false, _top_name=nil, _bottom_name=nil)
604
+ if (@frames[_row][_col] != nil)
605
+ _h = AGTkOSplittedFrames.new(@frames[_row][_col],_height, _perc)
606
+ if @frames[_row + 1] == nil
607
+ @frames[_row + 1] = Array.new
608
+ @domains[_row + 1] = Array.new
609
+ end
610
+ @frames[_row][_col] = _h.top_frame
611
+ @frames[_row + 1][_col] = _h.bottom_frame
612
+
613
+ _top_name = _row.to_s+'.'+_col.to_s if _top_name == nil
614
+ @panels[_top_name] = Hash.new
615
+ @panels[_top_name]['root'] = @frames[_row][_col]
616
+ @panels[_top_name]['sons'] = Hash.new
617
+ @domains[_row][_col] = _top_name
618
+
619
+ _bottom_name = (_row+1).to_s+'.'+_col.to_s if _bottom_name == nil
620
+ @panels[_bottom_name] = Hash.new
621
+ @panels[_bottom_name]['root'] = @frames[_row + 1][_col]
622
+ @panels[_bottom_name]['sons'] = Hash.new
623
+ @domains[_row + 1][_col] = _bottom_name
624
+ end
625
+ end
626
+ private :_prepare_rows
627
+
628
+ def add_rows(_row,_col, _height, _top_name=nil, _bottom_name=nil)
629
+ _prepare_rows(_row,_col, _height, false, _top_name, _bottom_name)
630
+ end
631
+
632
+ def add_rows_perc(_row,_col, _height, _top_name=nil, _bottom_name=nil)
633
+ _prepare_rows(_row,_col, _height, true, _top_name, _bottom_name)
634
+ end
635
+
636
+
637
+ def add_cols(_row,_col, _width, _left_name=nil, _right_name=nil)
638
+ if (@frames[_row][_col] != nil)
639
+ _w = AGTkVSplittedFrames.new(@frames[_row][_col],_width)
640
+ @frames[_row][_col] = _w.left_frame
641
+ @frames[_row][_col + 1] = _w.right_frame
642
+
643
+ _left_name = _row.to_s+'.'+_col.to_s if _left_name == nil
644
+ @panels[_left_name] = Hash.new
645
+ @panels[_left_name]['root'] = @frames[_row][_col]
646
+ @panels[_left_name]['sons'] = Hash.new
647
+ @domains[_row][_col] = _left_name
648
+
649
+ _right_name = _row.to_s+'.'+(_col+1).to_s if _right_name == nil
650
+ @panels[_right_name] = Hash.new
651
+ @panels[_right_name]['root'] = @frames[_row][_col + 1]
652
+ @panels[_right_name]['sons'] = Hash.new
653
+ @domains[_row][_col + 1] = _right_name
654
+ end
655
+ end
656
+
657
+ def add_headers
658
+ @domains.each{|row|
659
+ row.each{|domain|
660
+ @panels[domain]['root']= TkTitledFrame.new(@panels[domain]['root'], '...').place('x'=>0, 'y'=>0,'relheight'=>1, 'relwidth'=>1) if @panels[domain]
661
+ }
662
+ }
663
+ @headed = true
664
+ end
665
+
666
+ def headed?
667
+ @headed
668
+ end
669
+
670
+ def autotab?
671
+ @autotab
672
+ end
673
+
674
+ def registed?(_domain_name, _name)
675
+ @panels[_domain_name]['sons'][_name] != nil
676
+ end
677
+
678
+ def register_panel(_domain_name, _name, _title)
679
+ p = @panels[_domain_name]
680
+ if p!=nil
681
+ num = p['sons'].length
682
+ if @headed
683
+ p['root'].title(_title)
684
+ root_frame = p['root'].frame
685
+ else
686
+ root_frame = p['root']
687
+ end
688
+ if (num == 0 && @autotab)
689
+ api = ArcadiaPanelInfo.new(_name,_title,nil)
690
+ api.frame = TkFrame.new(root_frame).place('x'=>0, 'y'=>0, 'relwidth'=>1, 'relheight'=>1)
691
+ p['sons'][_name] = api
692
+ return api.frame
693
+ else
694
+ if num == 1 && @autotab && p['notebook'] == nil
695
+ p['notebook'] = Tk::BWidget::NoteBook.new(root_frame){
696
+ tabbevelsize 0
697
+ internalborderwidth 0
698
+ pack('fill'=>'both', :padx=>0, :pady=>0, :expand => 'yes')
699
+ }
700
+ api = p['sons'].values[0]
701
+ api_tab_frame = p['notebook'].insert('end',
702
+ api.name,
703
+ 'text'=>api.title,
704
+ 'raisecmd'=>proc{
705
+ p['root'].title(api.title)
706
+ p['root'].top_text('')
707
+ changed
708
+ notify_observers('RAISE', api.name)
709
+ }
710
+ )
711
+ api.frame.place('in'=>api_tab_frame, 'x'=>0, 'y'=>0, 'relwidth'=>1, 'relheight'=>1)
712
+ api.frame.raise
713
+ elsif (num==0 && !@autotab)
714
+ p['notebook'] = Tk::BWidget::NoteBook.new(root_frame){
715
+ tabbevelsize 0
716
+ internalborderwidth 0
717
+ pack('fill'=>'both', :padx=>0, :pady=>0, :expand => 'yes')
718
+ }
719
+ end
720
+ _panel = p['notebook'].insert('end',_name ,
721
+ 'text'=>_title,
722
+ #'background'=>_tab_bg,
723
+ 'raisecmd'=>proc{
724
+ p['root'].title(_title)
725
+ changed
726
+ notify_observers('RAISE', _name)
727
+ }
728
+ )
729
+
730
+ # if _tab_bg
731
+ # _panel = p['notebook'].insert('end',_name , 'text'=>_title, 'background'=>_tab_bg)
732
+ # else
733
+ # _panel = p['notebook'].insert('end',_name , 'text'=>_title)
734
+ # end
735
+ p['sons'][_name] = ArcadiaPanelInfo.new(_name,_title,_panel)
736
+ p['notebook'].raise(_name)
737
+ return _panel
738
+ end
739
+ end
740
+ end
741
+
742
+ def unregister_panel(_domain_name, _name)
743
+ @panels[_domain_name]['sons'].delete(_name)
744
+ @panels[_domain_name]['notebook'].delete(_name)
745
+ new_raise_key = @panels[_domain_name]['sons'].keys[@panels[_domain_name]['sons'].length-1]
746
+ @panels[_domain_name]['notebook'].raise(new_raise_key)
747
+ end
748
+
749
+ def raise_panel(_domain_name, _name)
750
+ @panels[_domain_name]['notebook'].raise(_name) if @panels[_domain_name] && @panels[_domain_name]['notebook']
751
+ end
752
+
753
+ def [](_row, _col)
754
+ @frames[_row][_col]
755
+ end
756
+
757
+ def frame(_domain_name, _name)
758
+ @panels[_domain_name]['sons'][_name].frame
759
+ end
760
+
761
+ def domain(_domain_name)
762
+ @panels[_domain_name]
763
+ end
764
+
765
+ def domain_root_frame(_domain_name)
766
+ @panels[_domain_name]['root'].frame
767
+ end
768
+ end
769
+
770
+ Arcadia.new.run