arcadia 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +122 -0
- data/arcadia.rb +748 -0
- data/base/a-contracts.rb +253 -0
- data/base/a-ext.rb +360 -0
- data/base/a-libs.rb +852 -0
- data/base/a-utils.rb +780 -0
- data/conf/arcadia.conf +198 -0
- data/conf/arcadia.init.rb +13 -0
- data/conf/arcadia.res.rb +1211 -0
- data/ext/ae-debug/ae-debug.conf +7 -0
- data/ext/ae-debug/ae-debug.rb +582 -0
- data/ext/ae-debug/debug1.57.rb +998 -0
- data/ext/ae-editor/ae-editor.conf +92 -0
- data/ext/ae-editor/ae-editor.rb +1744 -0
- data/ext/ae-event-log/ae-event-log.conf +5 -0
- data/ext/ae-event-log/ae-event-log.rb +44 -0
- data/ext/ae-file-history/ae-file-history.conf +17 -0
- data/ext/ae-file-history/ae-file-history.rb +280 -0
- data/ext/ae-inspector/ae-inspector.conf +7 -0
- data/ext/ae-inspector/ae-inspector.rb +1519 -0
- data/ext/ae-output-event/ae-output-event.conf +15 -0
- data/ext/ae-output/ae-output.conf +14 -0
- data/ext/ae-output/ae-output.rb +162 -0
- data/ext/ae-palette/ae-palette.conf +7 -0
- data/ext/ae-palette/ae-palette.rb +319 -0
- data/ext/ae-shell/ae-shell.conf +11 -0
- data/ext/ae-shell/ae-shell.rb +54 -0
- data/lib/tk/al-tk.rb +3078 -0
- data/lib/tk/al-tk.res.rb +217 -0
- data/lib/tk/al-tkarcadia.rb +26 -0
- data/lib/tk/al-tkcustom.rb +70 -0
- data/lib/tkext/al-bwidget.rb +194 -0
- data/lib/tkext/al-iwidgets.rb +25 -0
- data/lib/tkext/al-tile.rb +173 -0
- data/lib/tkext/al-tktable.rb +48 -0
- metadata +90 -0
data/README
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
Arcadia Ruby Ide
|
2
|
+
version 0.1.0
|
3
|
+
|
4
|
+
by Antonio Galeone
|
5
|
+
on Feb 25, 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
|
+
This is the first public version. A lot of things are to do
|
24
|
+
but i have decided to begin to release something. I use Arcadia
|
25
|
+
to develop Arcadia so there is something!
|
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 vertial
|
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-shift-i => indent the selected block
|
60
|
+
Ctrl-shift-u => unindent the selected block
|
61
|
+
Ctrl-shift-c => comment/uncomment the selected code block
|
62
|
+
F5 => execute the file
|
63
|
+
F3 => find/ find next
|
64
|
+
|
65
|
+
Double-Click on line number set or unset a debug breckpoint
|
66
|
+
|
67
|
+
< File history >
|
68
|
+
The last used files are organizing in tree so you can reopen them or there
|
69
|
+
directory by clicking on the tree node.
|
70
|
+
|
71
|
+
< Palette >
|
72
|
+
It containe the wrapper components for the tk gui building.
|
73
|
+
It is in very unstabled and incomplete state.
|
74
|
+
The first component is a TkTopLevel wrapper, when you click on it a new form is created and a
|
75
|
+
Object inspector appears.
|
76
|
+
The other component must be first selected and then created by clicking on container widget.
|
77
|
+
The so created widgets has a popup menu for deleting them or in the toplevel case to switch
|
78
|
+
to a code view.
|
79
|
+
On the palette there are also two button, one for deselect and other for copy from the selected
|
80
|
+
created widget. The copy action copy also the code into the clipboard, so you can copy the
|
81
|
+
code rapresenting the gui into the embedded editor or into external editor.
|
82
|
+
|
83
|
+
< Object Inspector >
|
84
|
+
It is for modify the widget property at runtime
|
85
|
+
|
86
|
+
< Debug >
|
87
|
+
It is created when a debug session init.
|
88
|
+
The debug button are: Step Next, Step Into, Step Over, Resume.
|
89
|
+
The debug frame show the local, instance and global variables for each
|
90
|
+
step. (you must have patience!)
|
91
|
+
|
92
|
+
<Configuration>
|
93
|
+
Same Arcadia properties are locally configurabled by editing the file arcadia.conf
|
94
|
+
under ~/.arcadia directory. The format of property definition are:
|
95
|
+
<OPERATING SYSTEM IDENTIFY:>PROPERTY_NAME=PROPERTY_VALUE
|
96
|
+
|
97
|
+
|
98
|
+
Requirement
|
99
|
+
===========
|
100
|
+
I include into distribution also the BWidget lib (under tcl directory) so
|
101
|
+
are require realy only the standard tcl tk lib (tested on tcl tk 8.4).
|
102
|
+
I have tested arcadia with ruby 1.8.4 and 1.8.5 on FreeBsd6 and windows 2000 os. If you
|
103
|
+
will test arcadia on other operating system sends me a e-mail.
|
104
|
+
|
105
|
+
Developers information
|
106
|
+
=====================
|
107
|
+
Soon i will write samething about the arcadia software architecture (when it is more stable)
|
108
|
+
in order to allow extensions writing and collaborations.
|
109
|
+
|
110
|
+
|
111
|
+
|
112
|
+
License
|
113
|
+
=======
|
114
|
+
Arcadia is released under the Ruby License
|
115
|
+
|
116
|
+
Contacts
|
117
|
+
========
|
118
|
+
For questions:
|
119
|
+
antonio-galeone@rubyforge.org
|
120
|
+
For bugs, support request, feature request https://rubyforge.org/projects/arcadia:
|
121
|
+
|
122
|
+
|
data/arcadia.rb
ADDED
@@ -0,0 +1,748 @@
|
|
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.0',
|
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
|
+
@toolbar = @mf_root.add_toolbar
|
50
|
+
@mf_root.show_toolbar(1,true)
|
51
|
+
@splash = ArcadiaAboutSplash.new('... initialize')
|
52
|
+
@splash.set_progress(50)
|
53
|
+
@splash.deiconify
|
54
|
+
Tk.update
|
55
|
+
sleep(1)
|
56
|
+
@splash.next_step('..prepare')
|
57
|
+
prepare
|
58
|
+
@splash.last_step('..load finish')
|
59
|
+
geometry = (TkWinfo.screenwidth(@root)-4).to_s+'x'+
|
60
|
+
(TkWinfo.screenheight(@root)-20).to_s+'+0+0'
|
61
|
+
@root.deiconify
|
62
|
+
@root.raise
|
63
|
+
@root.focus(true)
|
64
|
+
@root.geometry(geometry)
|
65
|
+
Tk.update_idletasks
|
66
|
+
sleep(1)
|
67
|
+
@splash.destroy
|
68
|
+
if @first_run
|
69
|
+
EditorContract.instance.open_file(EditorContract::TEditorObj.new(self, 'file'=>'README'))
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def Arcadia.finalize(id)
|
74
|
+
puts "\nArcadia #{id} dying at #{Time.new}"
|
75
|
+
end
|
76
|
+
|
77
|
+
def load_libs
|
78
|
+
@libs = ArcadiaLibs.new(self)
|
79
|
+
libs = self['conf']['libraries'].split(',')
|
80
|
+
libs.each{|lib|
|
81
|
+
if lib
|
82
|
+
@splash.next_step('... loading library '+lib)
|
83
|
+
begin
|
84
|
+
require self['conf']['libraries.'+lib+'.source']
|
85
|
+
@libs.add_lib(
|
86
|
+
ArcadiaLibs::ArcadiaLibParams.new(
|
87
|
+
self['conf']['libraries.'+lib+'.name'],
|
88
|
+
self['conf']['libraries.'+lib+'.source'],
|
89
|
+
self['conf']['libraries.'+lib+'.require'],
|
90
|
+
eval(self['conf']['libraries.'+lib+'.collection.class']))
|
91
|
+
)
|
92
|
+
rescue Exception
|
93
|
+
msg = "Loading lib "+'"'+lib+'"'+" ("+$!.class.to_s+") "+" : "+$! + " at : "+$@.to_s
|
94
|
+
if Tk.messageBox('icon' => 'error', 'type' => 'okcancel',
|
95
|
+
'title' => '(Arcadia) Libs', 'parent' => @root,
|
96
|
+
'message' => msg) == 'cancel'
|
97
|
+
raise
|
98
|
+
exit
|
99
|
+
else
|
100
|
+
Tk.update
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
}
|
105
|
+
end
|
106
|
+
|
107
|
+
def load_toolbar_buttons
|
108
|
+
suf = 'toolbar_buttons'
|
109
|
+
@buttons = Hash.new
|
110
|
+
toolbar_buttons = self['conf'][suf].split(',')
|
111
|
+
toolbar_buttons.each{|groups|
|
112
|
+
if groups
|
113
|
+
suf1 = suf+'.'+groups
|
114
|
+
@splash.next_step('... loading '+suf1)
|
115
|
+
begin
|
116
|
+
buttons = self['conf'][suf1].split(',')
|
117
|
+
buttons.each{|button|
|
118
|
+
suf2 = suf1+'.'+button
|
119
|
+
name = self['conf'][suf2+'.name']
|
120
|
+
text = self['conf'][suf2+'.text']
|
121
|
+
image = self['conf'][suf2+'.image']
|
122
|
+
font = self['conf'][suf2+'.font']
|
123
|
+
background = self['conf'][suf2+'.background']
|
124
|
+
foreground = self['conf'][suf2+'.foreground']
|
125
|
+
hint = self['conf'][suf2+'.hint']
|
126
|
+
action = self['conf'][suf2+'.action']
|
127
|
+
actions = action.split('->') if action
|
128
|
+
if actions && actions.length>1
|
129
|
+
_command = proc{
|
130
|
+
action_obj = $arcadia[actions[0]]
|
131
|
+
1.upto(actions.length-2) do |x|
|
132
|
+
action_obj = action_obj.send(actions[x])
|
133
|
+
end
|
134
|
+
action_obj.send(actions[actions.length-1])
|
135
|
+
}
|
136
|
+
elsif action
|
137
|
+
_command = proc{$arcadia[action].call}
|
138
|
+
end
|
139
|
+
@buttons[name] = Tk::BWidget::Button.new(@toolbar){
|
140
|
+
image TkPhotoImage.new('data' => eval(image)) if image
|
141
|
+
borderwidth 1
|
142
|
+
font font if font
|
143
|
+
background background if background
|
144
|
+
foreground foreground if foreground
|
145
|
+
command _command if action
|
146
|
+
relief 'flat'
|
147
|
+
helptext hint if hint
|
148
|
+
text text if text
|
149
|
+
pack('side' =>'left', :padx=>2, :pady=>2)
|
150
|
+
}
|
151
|
+
}
|
152
|
+
rescue Exception
|
153
|
+
msg = 'Loading '+groups+'" -> '+buttons.to_s+ '" (' + $!.class.to_s + ") : " + $!.to_s + " at : "+$@.to_s
|
154
|
+
if Tk.messageBox('icon' => 'error', 'type' => 'okcancel',
|
155
|
+
'title' => '(Arcadia) Toolbar', 'parent' => @root,
|
156
|
+
'message' => msg) == 'cancel'
|
157
|
+
raise
|
158
|
+
exit
|
159
|
+
else
|
160
|
+
Tk.update
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
Tk::BWidget::Separator.new(@toolbar, :orient=>'vertical').pack('side' =>'left', :padx=>2, :pady=>2, :fill=>'y',:anchor=> 'w')
|
165
|
+
}
|
166
|
+
end
|
167
|
+
|
168
|
+
def ext_active?(_name)
|
169
|
+
return (self['conf'][_name+'.active'] != nil && self['conf'][_name+'.active']=='yes')||
|
170
|
+
(self['conf'][_name+'.active'] == nil)
|
171
|
+
end
|
172
|
+
|
173
|
+
def load_exts_conf
|
174
|
+
@exts = Array.new
|
175
|
+
dirs = Array.new
|
176
|
+
files = Dir['ext/*'].concat(Dir[ENV["HOME"]+'/.arcadia/ext/*'])
|
177
|
+
files.each{|f|
|
178
|
+
dirs << f if File.stat(f).directory? && FileTest.exist?(f+'/'+File.basename(f)+'.conf')
|
179
|
+
}
|
180
|
+
dirs.each{|ext_dir|
|
181
|
+
conf_hash = self.config_file2hash(ext_dir+'/'+File.basename(ext_dir)+'.conf')
|
182
|
+
conf_hash2 = Hash.new
|
183
|
+
name = conf_hash['name']
|
184
|
+
conf_hash.each{|key, value|
|
185
|
+
var_plat = key.split(':')
|
186
|
+
if var_plat.length > 1
|
187
|
+
new_key = var_plat[0] + ':' + name + '.' + var_plat[1]
|
188
|
+
else
|
189
|
+
new_key = name+'.'+key
|
190
|
+
end
|
191
|
+
conf_hash2[new_key]= value
|
192
|
+
}
|
193
|
+
@exts << name
|
194
|
+
self['conf'].update(conf_hash2)
|
195
|
+
}
|
196
|
+
end
|
197
|
+
|
198
|
+
def load_exts
|
199
|
+
|
200
|
+
# create extensions
|
201
|
+
@exts.each{|extension|
|
202
|
+
if extension && ext_active?(extension)
|
203
|
+
@splash.next_step('... creating '+extension)
|
204
|
+
ext_create(extension)
|
205
|
+
end
|
206
|
+
}
|
207
|
+
|
208
|
+
# before_build extensions
|
209
|
+
@exts.each{|extension|
|
210
|
+
if extension && ext_active?(extension)
|
211
|
+
@splash.next_step('... before building '+extension)
|
212
|
+
ext_method(extension, :before_build)
|
213
|
+
MainContract.instance.extension_before_build(MainContract::TMainObj.new(self, 'obj'=>self[extension]))
|
214
|
+
end
|
215
|
+
}
|
216
|
+
|
217
|
+
# build extensions
|
218
|
+
@exts.each{|extension|
|
219
|
+
if extension && ext_active?(extension)
|
220
|
+
@splash.next_step('... building '+extension)
|
221
|
+
ext_method(extension, :build)
|
222
|
+
_tobj = MainContract::TMainObj.new(self)
|
223
|
+
_tobj.obj = self[extension]
|
224
|
+
MainContract.instance.extension_build(_tobj)
|
225
|
+
end
|
226
|
+
}
|
227
|
+
|
228
|
+
# after build extensions
|
229
|
+
@exts.each{|extension|
|
230
|
+
if extension && ext_active?(extension)
|
231
|
+
@splash.next_step('... after building '+extension)
|
232
|
+
ext_method(extension, :after_build)
|
233
|
+
_tobj = MainContract::TMainObj.new(self)
|
234
|
+
_tobj.obj = self[extension]
|
235
|
+
MainContract.instance.extension_after_build(_tobj)
|
236
|
+
end
|
237
|
+
}
|
238
|
+
|
239
|
+
end
|
240
|
+
|
241
|
+
def ext_create(_extension)
|
242
|
+
begin
|
243
|
+
source = self['conf'][_extension+'.require']
|
244
|
+
class_name = self['conf'][_extension+'.class']
|
245
|
+
if source.strip.length > 0
|
246
|
+
#p source
|
247
|
+
eval('require ' + "'" + source + "'")
|
248
|
+
end
|
249
|
+
if class_name.strip.length > 0
|
250
|
+
publish(_extension, eval(class_name).new(self, _extension))
|
251
|
+
end
|
252
|
+
rescue Exception
|
253
|
+
raise
|
254
|
+
msg = "Loading "+'"'+extension+'"'+" ("+$!.class.to_s+") "+" : "+$! + " at : "+$@.to_s
|
255
|
+
ans = Tk.messageBox('icon' => 'error', 'type' => 'abortretryignore',
|
256
|
+
'title' => '(Arcadia) Extensions', 'parent' => @root,
|
257
|
+
'message' => msg)
|
258
|
+
if ans == 'abort'
|
259
|
+
raise
|
260
|
+
exit
|
261
|
+
elsif ans == 'retry'
|
262
|
+
retry
|
263
|
+
else
|
264
|
+
Tk.update
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
def ext_method(_extension, _method)
|
270
|
+
begin
|
271
|
+
self[_extension].send(_method)
|
272
|
+
rescue Exception
|
273
|
+
msg = _method.to_s+' "'+_extension.to_s+'"'+" ("+$!.class.to_s+") "+" : "+$! + "\n at : "+$@.to_s
|
274
|
+
ans = Tk.messageBox('icon' => 'warning', 'type' => 'abortretryignore',
|
275
|
+
'title' => '(Arcadia) Extensions', 'parent' => @root,
|
276
|
+
'message' => msg)
|
277
|
+
if ans == 'abort'
|
278
|
+
raise
|
279
|
+
exit
|
280
|
+
elsif ans == 'retry'
|
281
|
+
retry
|
282
|
+
else
|
283
|
+
Tk.update
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
|
289
|
+
def prepare
|
290
|
+
super
|
291
|
+
@splash.next_step('...initialize')
|
292
|
+
@layout = ArcadiaLayout.new(self, @mf_root.get_frame)
|
293
|
+
|
294
|
+
#@layout.add_cols(0,0,230,'_mosca_','_white_street_')
|
295
|
+
#@layout.add_rows(0,1,80,'_tokyo_','_red_street_')
|
296
|
+
#@layout.add_rows(1,1,450,'_los_angeles_','_rome_')
|
297
|
+
|
298
|
+
@layout.add_cols(0,0,230)
|
299
|
+
@layout.add_rows(0,0,190)
|
300
|
+
#@layout.add_rows(0,1,80)
|
301
|
+
#@layout.add_rows(1,1,450)
|
302
|
+
@layout.add_rows(0,1,500)
|
303
|
+
|
304
|
+
|
305
|
+
@layout.add_headers
|
306
|
+
@splash.next_step
|
307
|
+
self.load_libs
|
308
|
+
@splash.next_step
|
309
|
+
@splash.next_step('... load extensions')
|
310
|
+
self.load_exts_conf
|
311
|
+
self.load_local_config
|
312
|
+
self.load_exts
|
313
|
+
publish('buffers.code.in_memory',Hash.new)
|
314
|
+
publish('action.load_code_from_buffers', proc{TkBuffersChoise.new})
|
315
|
+
publish('output.action.run_last', proc{$arcadia['output'].run_last})
|
316
|
+
publish('main.action.open_file', proc{self['editor'].open_file(Tk.getOpenFile)})
|
317
|
+
@splash.next_step('... load obj controller')
|
318
|
+
@splash.next_step('... load editor')
|
319
|
+
publish('main.action.new_file',proc{$arcadia['editor'].open_buffer()})
|
320
|
+
publish('main.action.edit_cut',proc{$arcadia['editor'].raised.text.text_cut()})
|
321
|
+
publish('main.action.edit_copy',proc{$arcadia['editor'].raised.text.text_copy()})
|
322
|
+
publish('main.action.edit_paste',proc{$arcadia['editor'].raised.text.text_paste()})
|
323
|
+
@splash.next_step('... load actions')
|
324
|
+
publish('action.test.keys', proc{KetTest.new})
|
325
|
+
publish('action.get.font', proc{Tk::BWidget::SelectFont::Dialog.new.create})
|
326
|
+
@splash.next_step
|
327
|
+
publish('action.show_about', proc{ArcadiaAboutSplash.new.deiconify})
|
328
|
+
publish('main.menu', AMainMenu.new(@main_menu))
|
329
|
+
@splash.next_step
|
330
|
+
publish('objic.action.raise_active_obj',
|
331
|
+
proc{
|
332
|
+
InspectorContract.instance.raise_active_toplevel(InspectorContract::TInspectorObj.new(self))
|
333
|
+
# if $arcadia['objic'].active
|
334
|
+
# agobj = $arcadia['objic'].active.active_object
|
335
|
+
# while agobj.ag_parent
|
336
|
+
# agobj = agobj.ag_parent
|
337
|
+
# end
|
338
|
+
# agobj.obj.raise
|
339
|
+
# end
|
340
|
+
}
|
341
|
+
)
|
342
|
+
#@root.bind("Button-1", $arcadia['objic.action.raise_active_obj'] )
|
343
|
+
load_toolbar_buttons
|
344
|
+
end
|
345
|
+
|
346
|
+
def do_exit
|
347
|
+
q1 = (Tk.messageBox('icon' => 'question', 'type' => 'yesno',
|
348
|
+
'title' => '(Arcadia) Exit', 'parent' => @root,
|
349
|
+
'message' => "Do you want exit?")=='yes')
|
350
|
+
if q1 && can_exit?
|
351
|
+
do_finalize
|
352
|
+
@root.destroy
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
def can_exit?
|
357
|
+
_can_exit = true
|
358
|
+
@exts.each{|extension|
|
359
|
+
if ext_active?(extension) && !self[extension].can_exit_query
|
360
|
+
_can_exit = false
|
361
|
+
break
|
362
|
+
end
|
363
|
+
}
|
364
|
+
return _can_exit
|
365
|
+
end
|
366
|
+
|
367
|
+
def do_finalize
|
368
|
+
@exts.each{|extension|
|
369
|
+
self[extension].finalize if ext_active?(extension)
|
370
|
+
}
|
371
|
+
self.write_persist
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
class AMainMenu < TkMenubar
|
376
|
+
|
377
|
+
def initialize(menu)
|
378
|
+
# create main menu
|
379
|
+
@menu = menu
|
380
|
+
build
|
381
|
+
menu.foreground('grey40')
|
382
|
+
menu.activeforeground('red')
|
383
|
+
menu.relief('flat')
|
384
|
+
menu.font($arcadia['conf']['main.mainmenu.font'])
|
385
|
+
end
|
386
|
+
|
387
|
+
def build
|
388
|
+
menu_spec_file = [
|
389
|
+
['File', 0],
|
390
|
+
['Open', $arcadia['main.action.open_file'], 0],
|
391
|
+
['New', $arcadia['main.action.new_file'], 0],
|
392
|
+
'---',
|
393
|
+
['Quit', $arcadia['action.on_exit'], 0]]
|
394
|
+
menu_spec_edit = [['Edit', 0],
|
395
|
+
['Cut', $arcadia['main.action.edit_cut'], 2],
|
396
|
+
['Copy', $arcadia['main.action.edit_copy'], 0],
|
397
|
+
['Paste', $arcadia['main.action.edit_paste'], 0]]
|
398
|
+
menu_spec_view = [['View', 0],'---']
|
399
|
+
menu_spec_tools = [['Utils', 0],
|
400
|
+
['Keys-test', $arcadia['action.test.keys'], 2],
|
401
|
+
['Load code from buffer', $arcadia['action.load_code_from_buffers'], 2]
|
402
|
+
]
|
403
|
+
menu_spec_help = [['Help', 0],
|
404
|
+
['About', $arcadia['action.show_about'], 2],]
|
405
|
+
@menu.add_menu(menu_spec_file)
|
406
|
+
@menu.add_menu(menu_spec_edit)
|
407
|
+
#@menu.add_menu(menu_spec_view)
|
408
|
+
@menu.add_menu(menu_spec_tools)
|
409
|
+
@menu.add_menu(menu_spec_help)
|
410
|
+
end
|
411
|
+
|
412
|
+
end
|
413
|
+
|
414
|
+
class ArcadiaAboutSplash < TkToplevel
|
415
|
+
attr :progress
|
416
|
+
|
417
|
+
def initialize(_txt=nil)
|
418
|
+
#_bgcolor = '#B83333'
|
419
|
+
_bgcolor = '#000000'
|
420
|
+
super()
|
421
|
+
relief 'flat'
|
422
|
+
background _bgcolor
|
423
|
+
highlightbackground _bgcolor
|
424
|
+
highlightthickness 6
|
425
|
+
borderwidth 1
|
426
|
+
withdraw
|
427
|
+
overrideredirect(true)
|
428
|
+
|
429
|
+
@tkLabel3 = TkLabel.new(self){
|
430
|
+
image TkPhotoImage.new('format'=>'GIF','data' =>A_LOGO_GIF)
|
431
|
+
background _bgcolor
|
432
|
+
place('x'=> 20,'y' => 20)
|
433
|
+
}
|
434
|
+
@tkLabel1 = TkLabel.new(self){
|
435
|
+
text 'Arcadia'
|
436
|
+
background _bgcolor
|
437
|
+
foreground '#ffffff'
|
438
|
+
font Arcadia.instance['conf']['splash.title.font']
|
439
|
+
justify 'left'
|
440
|
+
place('width' => '190','x' => 120,'y' => 10,'height' => 25)
|
441
|
+
}
|
442
|
+
@tkLabelRuby = TkLabel.new(self){
|
443
|
+
image TkPhotoImage.new('data' =>RUBY_DOCUMENT_GIF)
|
444
|
+
background _bgcolor
|
445
|
+
place('x'=> 150,'y' => 40)
|
446
|
+
}
|
447
|
+
@tkLabel2 = TkLabel.new(self){
|
448
|
+
text 'Ruby ide'
|
449
|
+
background _bgcolor
|
450
|
+
foreground '#ffffff'
|
451
|
+
font Arcadia.instance['conf']['splash.subtitle.font']
|
452
|
+
justify 'left'
|
453
|
+
place('width' => '90','x' => 170,'y' => 40,'height' => 19)
|
454
|
+
}
|
455
|
+
@tkLabelVersion = TkLabel.new(self){
|
456
|
+
text 'version: '+$arcadia['applicationParams'].version
|
457
|
+
background _bgcolor
|
458
|
+
foreground '#ffffff'
|
459
|
+
font Arcadia.instance['conf']['splash.version.font']
|
460
|
+
justify 'left'
|
461
|
+
place('width' => '100','x' => 150,'y' => 60,'height' => 19)
|
462
|
+
}
|
463
|
+
@tkLabelStep = TkLabel.new(self){
|
464
|
+
text _txt
|
465
|
+
background _bgcolor
|
466
|
+
foreground 'yellow'
|
467
|
+
font Arcadia.instance['conf']['splash.banner.font']
|
468
|
+
justify 'left'
|
469
|
+
anchor 'w'
|
470
|
+
place('width'=>-5,'relwidth' => 1,'x' => 5,'y' => 175,'height' => 19)
|
471
|
+
}
|
472
|
+
@tkLabel21 = TkLabel.new(self){
|
473
|
+
text 'by Antonio Galeone - 2007'
|
474
|
+
background _bgcolor
|
475
|
+
foreground '#ffffff'
|
476
|
+
font Arcadia.instance['conf']['splash.credits.font']
|
477
|
+
justify 'left'
|
478
|
+
place('width' => '190','x' => 130,'y' => 146,'height' => 19)
|
479
|
+
}
|
480
|
+
@progress = TkVariable.new
|
481
|
+
reset
|
482
|
+
_width = 340
|
483
|
+
_height = 210
|
484
|
+
#_width = 0;_height = 0
|
485
|
+
_x = TkWinfo.screenwidth(self)/2 - _width / 2
|
486
|
+
_y = TkWinfo.screenheight(self)/2 - _height / 2
|
487
|
+
geometry = _width.to_s+'x'+_height.to_s+'+'+_x.to_s+'+'+_y.to_s
|
488
|
+
Tk.tk_call('wm', 'geometry', self, geometry )
|
489
|
+
bind("Double-Button-1", proc{self.destroy})
|
490
|
+
end
|
491
|
+
|
492
|
+
def set_progress(_max=10)
|
493
|
+
@max = _max
|
494
|
+
Tk::BWidget::ProgressBar.new(self, :width=>150, :height=>10,
|
495
|
+
:background=>'black',
|
496
|
+
:foreground=>'yellow',
|
497
|
+
:variable=>@progress,
|
498
|
+
:borderwidth=>0,
|
499
|
+
:relief=>'flat',
|
500
|
+
:maximum=>_max).place('width' => '150','x' => 145,'y' => 95,'height' => 15)
|
501
|
+
end
|
502
|
+
|
503
|
+
def reset
|
504
|
+
@progress.value = -1
|
505
|
+
end
|
506
|
+
|
507
|
+
def next_step(_txt = nil)
|
508
|
+
@progress.numeric += 1
|
509
|
+
labelStep(_txt) if _txt
|
510
|
+
end
|
511
|
+
|
512
|
+
def labelStep(_txt)
|
513
|
+
@tkLabelStep.text = _txt
|
514
|
+
Tk.update
|
515
|
+
end
|
516
|
+
|
517
|
+
def last_step(_txt = nil)
|
518
|
+
@progress.numeric = @max
|
519
|
+
labelStep(_txt) if _txt
|
520
|
+
end
|
521
|
+
|
522
|
+
end
|
523
|
+
|
524
|
+
class TkBuffersChoiseView < TkToplevel
|
525
|
+
|
526
|
+
def initialize
|
527
|
+
super
|
528
|
+
Tk.tk_call('wm', 'title', self, '...hello' )
|
529
|
+
Tk.tk_call('wm', 'geometry', self, '150x217+339+198' )
|
530
|
+
@lb = TkListbox.new(self){
|
531
|
+
background '#fedbd7'
|
532
|
+
relief 'groove'
|
533
|
+
place('relwidth' => '1','relx' => 0,'x' => '0','y' => '0','relheight' => '1','rely' => 0,'height' => '0','bordermode' => 'inside','width' => '0')
|
534
|
+
}
|
535
|
+
end
|
536
|
+
|
537
|
+
end
|
538
|
+
|
539
|
+
class TkBuffersChoise < TkBuffersChoiseView
|
540
|
+
|
541
|
+
def initialize
|
542
|
+
super
|
543
|
+
@lb.value= $arcadia['buffers.code.in_memory'].keys
|
544
|
+
@lb.bind("Double-ButtonPress-1",proc{
|
545
|
+
_sel = @lb.get('active')
|
546
|
+
Revparsel.new($arcadia['buffers.code.in_memory'][_sel])
|
547
|
+
@lb.delete('active')
|
548
|
+
$arcadia['buffers.code.in_memory'].delete(_sel)
|
549
|
+
destroy
|
550
|
+
})
|
551
|
+
raise
|
552
|
+
end
|
553
|
+
|
554
|
+
end
|
555
|
+
|
556
|
+
class ArcadiaLayout
|
557
|
+
include Observable
|
558
|
+
ArcadiaPanelInfo = Struct.new( "ArcadiaPanelInfo",
|
559
|
+
:name,
|
560
|
+
:title,
|
561
|
+
:frame
|
562
|
+
)
|
563
|
+
|
564
|
+
def initialize(_arcadia, _frame, _autotab=true)
|
565
|
+
@arcadia = _arcadia
|
566
|
+
@frames = Array.new
|
567
|
+
@frames[0] = Array.new
|
568
|
+
@frames[0][0] = _frame
|
569
|
+
@domains = Array.new
|
570
|
+
@domains[0] = Array.new
|
571
|
+
@domains[0][0] = '_domain_root_'
|
572
|
+
@panels = Hash.new
|
573
|
+
@panels['_domain_root_']= Hash.new
|
574
|
+
@panels['_domain_root_']['root']= _frame
|
575
|
+
@panels['_domain_root_']['sons'] = Hash.new
|
576
|
+
@autotab = _autotab
|
577
|
+
@headed = false
|
578
|
+
ArcadiaContractListener.new(self, MainContract, :do_main_event)
|
579
|
+
end
|
580
|
+
|
581
|
+
def do_main_event(_event)
|
582
|
+
case _event.signature
|
583
|
+
when MainContract::RAISE_EXTENSION
|
584
|
+
p = @panels[_event.context.domain]
|
585
|
+
if p && p['notebook'] != nil && _event.channel == '0'
|
586
|
+
p['notebook'].raise(_event.context.extension)
|
587
|
+
end
|
588
|
+
end
|
589
|
+
end
|
590
|
+
|
591
|
+
def add_rows(_row,_col, _height, _top_name=nil, _bottom_name=nil)
|
592
|
+
if (@frames[_row][_col] != nil)
|
593
|
+
_h = AGTkOSplittedFrames.new(@frames[_row][_col],_height)
|
594
|
+
if @frames[_row + 1] == nil
|
595
|
+
@frames[_row + 1] = Array.new
|
596
|
+
@domains[_row + 1] = Array.new
|
597
|
+
end
|
598
|
+
@frames[_row][_col] = _h.top_frame
|
599
|
+
@frames[_row + 1][_col] = _h.bottom_frame
|
600
|
+
|
601
|
+
_top_name = _row.to_s+'.'+_col.to_s if _top_name == nil
|
602
|
+
@panels[_top_name] = Hash.new
|
603
|
+
@panels[_top_name]['root'] = @frames[_row][_col]
|
604
|
+
@panels[_top_name]['sons'] = Hash.new
|
605
|
+
@domains[_row][_col] = _top_name
|
606
|
+
|
607
|
+
_bottom_name = (_row+1).to_s+'.'+_col.to_s if _bottom_name == nil
|
608
|
+
@panels[_bottom_name] = Hash.new
|
609
|
+
@panels[_bottom_name]['root'] = @frames[_row + 1][_col]
|
610
|
+
@panels[_bottom_name]['sons'] = Hash.new
|
611
|
+
@domains[_row + 1][_col] = _bottom_name
|
612
|
+
end
|
613
|
+
end
|
614
|
+
|
615
|
+
def add_cols(_row,_col, _width, _left_name=nil, _right_name=nil)
|
616
|
+
if (@frames[_row][_col] != nil)
|
617
|
+
_w = AGTkVSplittedFrames.new(@frames[_row][_col],_width)
|
618
|
+
@frames[_row][_col] = _w.left_frame
|
619
|
+
@frames[_row][_col + 1] = _w.right_frame
|
620
|
+
|
621
|
+
_left_name = _row.to_s+'.'+_col.to_s if _left_name == nil
|
622
|
+
@panels[_left_name] = Hash.new
|
623
|
+
@panels[_left_name]['root'] = @frames[_row][_col]
|
624
|
+
@panels[_left_name]['sons'] = Hash.new
|
625
|
+
@domains[_row][_col] = _left_name
|
626
|
+
|
627
|
+
_right_name = _row.to_s+'.'+(_col+1).to_s if _right_name == nil
|
628
|
+
@panels[_right_name] = Hash.new
|
629
|
+
@panels[_right_name]['root'] = @frames[_row][_col + 1]
|
630
|
+
@panels[_right_name]['sons'] = Hash.new
|
631
|
+
@domains[_row][_col + 1] = _right_name
|
632
|
+
end
|
633
|
+
end
|
634
|
+
|
635
|
+
def add_headers
|
636
|
+
@domains.each{|row|
|
637
|
+
row.each{|domain|
|
638
|
+
@panels[domain]['root']= TkTitledFrame.new(@panels[domain]['root'], '...').place('x'=>0, 'y'=>0,'relheight'=>1, 'relwidth'=>1) if @panels[domain]
|
639
|
+
}
|
640
|
+
}
|
641
|
+
@headed = true
|
642
|
+
end
|
643
|
+
|
644
|
+
def headed?
|
645
|
+
@headed
|
646
|
+
end
|
647
|
+
|
648
|
+
def autotab?
|
649
|
+
@autotab
|
650
|
+
end
|
651
|
+
|
652
|
+
def registed?(_domain_name, _name)
|
653
|
+
@panels[_domain_name]['sons'][_name] != nil
|
654
|
+
end
|
655
|
+
|
656
|
+
def register_panel(_domain_name, _name, _title)
|
657
|
+
p = @panels[_domain_name]
|
658
|
+
if p!=nil
|
659
|
+
num = p['sons'].length
|
660
|
+
if @headed
|
661
|
+
p['root'].title(_title)
|
662
|
+
root_frame = p['root'].frame
|
663
|
+
else
|
664
|
+
root_frame = p['root']
|
665
|
+
end
|
666
|
+
if (num == 0 && @autotab)
|
667
|
+
api = ArcadiaPanelInfo.new(_name,_title,nil)
|
668
|
+
api.frame = TkFrame.new(root_frame).place('x'=>0, 'y'=>0, 'relwidth'=>1, 'relheight'=>1)
|
669
|
+
p['sons'][_name] = api
|
670
|
+
return api.frame
|
671
|
+
else
|
672
|
+
if num == 1 && @autotab && p['notebook'] == nil
|
673
|
+
p['notebook'] = Tk::BWidget::NoteBook.new(root_frame){
|
674
|
+
tabbevelsize 0
|
675
|
+
internalborderwidth 0
|
676
|
+
pack('fill'=>'both', :padx=>0, :pady=>0, :expand => 'yes')
|
677
|
+
}
|
678
|
+
api = p['sons'].values[0]
|
679
|
+
api_tab_frame = p['notebook'].insert('end',
|
680
|
+
api.name,
|
681
|
+
'text'=>api.title,
|
682
|
+
'raisecmd'=>proc{
|
683
|
+
p['root'].title(api.title)
|
684
|
+
p['root'].top_text('')
|
685
|
+
changed
|
686
|
+
notify_observers('RAISE', api.name)
|
687
|
+
}
|
688
|
+
)
|
689
|
+
api.frame.place('in'=>api_tab_frame, 'x'=>0, 'y'=>0, 'relwidth'=>1, 'relheight'=>1)
|
690
|
+
api.frame.raise
|
691
|
+
elsif (num==0 && !@autotab)
|
692
|
+
p['notebook'] = Tk::BWidget::NoteBook.new(root_frame){
|
693
|
+
tabbevelsize 0
|
694
|
+
internalborderwidth 0
|
695
|
+
pack('fill'=>'both', :padx=>0, :pady=>0, :expand => 'yes')
|
696
|
+
}
|
697
|
+
end
|
698
|
+
_panel = p['notebook'].insert('end',_name ,
|
699
|
+
'text'=>_title,
|
700
|
+
#'background'=>_tab_bg,
|
701
|
+
'raisecmd'=>proc{
|
702
|
+
p['root'].title(_title)
|
703
|
+
changed
|
704
|
+
notify_observers('RAISE', _name)
|
705
|
+
}
|
706
|
+
)
|
707
|
+
|
708
|
+
# if _tab_bg
|
709
|
+
# _panel = p['notebook'].insert('end',_name , 'text'=>_title, 'background'=>_tab_bg)
|
710
|
+
# else
|
711
|
+
# _panel = p['notebook'].insert('end',_name , 'text'=>_title)
|
712
|
+
# end
|
713
|
+
p['sons'][_name] = ArcadiaPanelInfo.new(_name,_title,_panel)
|
714
|
+
p['notebook'].raise(_name)
|
715
|
+
return _panel
|
716
|
+
end
|
717
|
+
end
|
718
|
+
end
|
719
|
+
|
720
|
+
def unregister_panel(_domain_name, _name)
|
721
|
+
@panels[_domain_name]['sons'].delete(_name)
|
722
|
+
@panels[_domain_name]['notebook'].delete(_name)
|
723
|
+
new_raise_key = @panels[_domain_name]['sons'].keys[@panels[_domain_name]['sons'].length-1]
|
724
|
+
@panels[_domain_name]['notebook'].raise(new_raise_key)
|
725
|
+
end
|
726
|
+
|
727
|
+
def raise_panel(_domain_name, _name)
|
728
|
+
@panels[_domain_name]['notebook'].raise(_name) if @panels[_domain_name] && @panels[_domain_name]['notebook']
|
729
|
+
end
|
730
|
+
|
731
|
+
def [](_row, _col)
|
732
|
+
@frames[_row][_col]
|
733
|
+
end
|
734
|
+
|
735
|
+
def frame(_domain_name, _name)
|
736
|
+
@panels[_domain_name]['sons'][_name].frame
|
737
|
+
end
|
738
|
+
|
739
|
+
def domain(_domain_name)
|
740
|
+
@panels[_domain_name]
|
741
|
+
end
|
742
|
+
|
743
|
+
def domain_root_frame(_domain_name)
|
744
|
+
@panels[_domain_name]['root'].frame
|
745
|
+
end
|
746
|
+
end
|
747
|
+
|
748
|
+
Arcadia.new.run
|