#!/usr/bin/env ruby # -*- ruby -*- # Copyright 2000, 2001 by Jim Weirich (jweirich@one.net). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. require 'gem/utils' require 'tk' module Gem # ==================================================================== class CommandObserver attr_accessor :command def initialize (&command) fail "No block given" if not block_given? @command = command end def update @command.call end end # ==================================================================== class ListingWidget def initialize (parent, title, container=nil) p = {'fill'=>'both', 'expand'=>true, 'side'=>'left'} @widget = (container ? container : TkFrame.new(parent) { pack p } ) TkLabel.new(@widget) { text title pack ( 'fill'=>'none', 'expand'=>false, 'side'=>'top', 'anchor'=>'w' ) } @list = TkListbox.new(@widget) { height 3; width 15; pack p } sb = TkScrollbar.new (@widget) sb.command (proc { |*args| @list.yview *args }) sb.pack ('fill'=>'y', 'side'=>'right') @list.yscrollcommand (proc { |a,b| sb.set(a,b) }) #TBD @select_action = proc { puts "Do Nothing" } @list.bind ("ButtonRelease-1") { index = @list.curselection[0] @model.select (index) if index.is_a?(Integer) } end def use_model (model) @model = model @model.add_observer(self) end def update top, bottom = @list.yview @list.delete (0, "end") @model.items.each {|item| @list.insert ("end", item)} @list.yview ('moveto', top) highlight (@model.selection_index) end def highlight (index) return if index < 0 @list.selection_clear (0, 'end') @list.selection_set (index) @list.see (index) end end # ==================================================================== class ClassBrowser include GemUtils def initialize finder = MethodFinder.new root = TkRoot.new { title "Gem Finder (#{REV})" } buttons = TkFrame.new { pack ( 'fill'=>'x', 'expand'=>false, 'side'=>'bottom' ) } TkButton.new(buttons) { text 'Exit' command proc { exit } pack ( 'fill'=>'x', 'expand'=>false, 'side'=>'right') } flat_button = TkCheckButton.new (buttons) { text 'Flat View' pack ( 'fill'=>'x', 'expand'=>false, 'side'=>'left') } private_button = TkCheckButton.new (buttons) { text 'Private' pack ( 'fill'=>'x', 'expand'=>false, 'side'=>'left') } cm_button = TkCheckButton.new (buttons) { text 'Class Methods' variable TkVariable.new ($checked) pack ( 'fill'=>'x', 'expand'=>false, 'side'=>'left') } sys_button = TkCheckButton.new (buttons) { text 'System' pack ( 'fill'=>'x', 'expand'=>false, 'side'=>'left') } sys_button.select labels = TkFrame.new { pack ( 'fill'=>'x', 'expand'=>false ) } class_label = TkLabel.new(labels) { text "Class: " pack ( 'fill'=>'none', 'expand'=>false, 'side'=>'left', 'anchor'=>'w') } class_label = TkLabel.new (labels) { relief 'groove' width 15 pack ( 'fill'=>'x', 'expand'=>true, 'side'=>'left', 'anchor'=>'w') } parent_label = TkButton.new (labels) { text "" width 15 pack ( 'fill'=>'x', 'expand'=>true, 'side'=>'right', 'anchor'=>'w') } TkLabel.new(labels) { text "Parent: " pack ( 'fill'=>'none', 'expand'=>false, 'side'=>'right', 'anchor'=>'w') } windows = TkFrame.new { pack ('fill'=>'both', 'expand'=>true) } browser = ClassBrowserModel.new (finder) class_list = ListingWidget.new (windows, "Classes") class_list.use_model (browser.class_model) center_frame = TkFrame.new(windows) { pack ('fill'=>'both', 'expand'=>true, 'side'=>'left') } center_top_frame = TkFrame.new (center_frame) { pack ('fill'=>'both', 'expand'=>true, 'side'=>'top') } center_bottom_frame = TkFrame.new (center_frame) { pack ('fill'=>'both', 'expand'=>true, 'side'=>'top') } child_list = ListingWidget.new (center_top_frame, "Subclasses", center_top_frame) child_list.use_model(browser.child_model) module_list = ListingWidget.new (center_bottom_frame, "Included Modules", center_bottom_frame) module_list.use_model(browser.module_model) method_list = ListingWidget.new (windows, "Methods") method_list.use_model(browser.method_model) parent_label.command proc { class_name = parent_label.text if class_name.is_a?(String) and (class_name!="") then browser.class_model.select_name(parent_label.text) end } browser.class_model.add_observer CommandObserver.new { class_label.text (browser.class_model.selection) parent_label.text (parent_name_of(browser.class_model.selection)) } cm_button.command proc { finder.use_class_methods = ! finder.use_class_methods browser.class_model.notify } flat_button.command proc { finder.flat = ! finder.flat browser.class_model.notify } private_button.command proc { finder.show_private = ! finder.show_private browser.class_model.notify } sys_button.command proc { browser.class_model.include_system = ! browser.class_model.include_system } browser.fill end end end