arcadia 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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