Skip to content

Commit

Permalink
pass all views to all controllers, lookup using '<name>_view' syntax,…
Browse files Browse the repository at this point in the history
… controller registers all commands for a category to a given controller, load all files into separate source buffers, one controller per command category, SourceModel responsible for loading it's own file
  • Loading branch information
PhilT committed Oct 16, 2010
1 parent 760195b commit 78cddd5
Show file tree
Hide file tree
Showing 23 changed files with 219 additions and 85 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -1,3 +1,4 @@
.rvmrc
*.gem
images

4 changes: 2 additions & 2 deletions config/commands.yml
Expand Up @@ -40,7 +40,7 @@ file:
help: Rename or move a file. Opens panel with file path. Make any adjustments and press ENTER
key: CTRL+M

list:
switch:
help: Switch between open files. Like an ALT+TAB window switcher holding down CTRL keeps the list open while pressing TAB cycles through it.
key: CTRL+TAB

Expand Down Expand Up @@ -131,7 +131,7 @@ tools:
help: Goto to last error
key: CTRL+E

application:
main:
numbers:
help: Toggle line numbers
key: CTRL+SHIFT+L
Expand Down
2 changes: 2 additions & 0 deletions lib/merrol.rb
@@ -1,6 +1,8 @@
require 'gtk2'
require 'gtksourceview2'
require 'yaml'
require 'active_support/inflector'
require 'observer'

APP_NAME = "Merrol"
WORKING_DIR = Dir.getwd
Expand Down
18 changes: 10 additions & 8 deletions lib/merrol/application.rb
Expand Up @@ -7,16 +7,18 @@ def self.start_in working_dir, arguments
end

protected
def initialize working_dir, filepaths
@views = WidgetBuilder.build 'main', 'status_bar', 'file_status', 'file_path', 'scroll_bars', 'editor'
main = @views['main']
def initialize working_dir, paths
@views = WidgetBuilder.build :main, :status_bar, :file_status, :file_path, :scroll_bars, :edit
main_view = @views[:main]

commands = Commands.new(main)
status_bar = StatusBarController.new @views['status_bar'], @views['file_status'], @views['file_path']
MainController.new main, working_dir, commands
EditorController.new @views['editor'], status_bar, filepaths, commands
commands = Commands.new main_view
main = MainController.new commands, @views
main.working_dir = working_dir

main.show_all
edit = EditController.new commands, @views
edit.load_all paths

main_view.show_all
end

end
Expand Down
21 changes: 21 additions & 0 deletions lib/merrol/controllers/controller.rb
@@ -1,5 +1,26 @@
module Merrol
class Controller
include Observable

def initialize commands, views
@commands = commands
@views = views

@commands.register(self)
end

def method_missing(meth, *args, &block)
method = meth.to_s
if method =~ /_view$/
@views[method.gsub(/_view$/, '').to_sym]
else
super
end
end

def name
self.class.to_s.demodulize.underscore.gsub(/_controller$/, '').to_sym
end
end
end

20 changes: 20 additions & 0 deletions lib/merrol/controllers/edit_controller.rb
@@ -0,0 +1,20 @@
module Merrol
class EditController < Controller
def initialize commands, views
super commands, views
end

def switch buffer
edit_view.buffer = buffer
end

def save
end

def load_all paths
source_models = paths.map { |path| SourceModel.new(path) }
edit_view.buffer = source_models.first
end
end
end

27 changes: 0 additions & 27 deletions lib/merrol/controllers/editor_controller.rb

This file was deleted.

8 changes: 8 additions & 0 deletions lib/merrol/controllers/file_controller.rb
@@ -0,0 +1,8 @@
module Merrol
class FileController < Controller
def switch

end
end
end

6 changes: 6 additions & 0 deletions lib/merrol/controllers/help_controller.rb
@@ -0,0 +1,6 @@
module Merrol
class HelpController < Controller

end
end

22 changes: 14 additions & 8 deletions lib/merrol/controllers/main_controller.rb
@@ -1,19 +1,25 @@
module Merrol
class MainController < Controller
def initialize view, working_dir, commands
@view = view
@view.signal_connect('destroy') { Gtk.main_quit}
commands.register('application', 'quit') {quit}
def initialize commands, views
super commands, views
main_view.signal_connect('destroy') { Gtk.main_quit}
end

def working_dir= working_dir
name = File.basename(working_dir)
@view.title = "#{name} (#{working_dir[0..-name.length - 2]})"
main_view.title = "#{name} (#{working_dir[0..-name.length - 2]})"
end

def complete
false
def numbers

end

def quit
@view.destroy
main_view.destroy
end

def cancel

end

end
Expand Down
5 changes: 5 additions & 0 deletions lib/merrol/controllers/search_controller.rb
@@ -0,0 +1,5 @@
module Merrol
class SearchController < Controller
end
end

14 changes: 0 additions & 14 deletions lib/merrol/controllers/status_bar_controller.rb

This file was deleted.

28 changes: 28 additions & 0 deletions lib/merrol/controllers/tools_controller.rb
@@ -0,0 +1,28 @@
module Merrol
class ToolsController < Controller
def complete

end

def test

end

def diff

end

def snippets

end

def reload

end

def error

end
end
end

27 changes: 14 additions & 13 deletions lib/merrol/lib/commands.rb
@@ -1,25 +1,28 @@

module Merrol
class Commands
def initialize(window)
@accel_group = Gtk::AccelGroup.new
window.add_accel_group @accel_group
load_commands
load
end

def register category, command, &block
@accel_group.connect "<#{APP_NAME}>/#{category}/#{command}", &block
def register controller
@commands[controller.name.to_s].each do |command, detail|
@accel_group.connect "<#{APP_NAME}>/#{controller.name}/#{command}" do
controller.send(command)
end
end
end

private
private

def load_commands
@help = YAML.load_config 'commands'
@commands = {}
@help.each do |name, category|
category.each do |command, detail|
@commands[detail['key']] = [command, detail['help']]
def load
@commands = YAML.load_config 'commands'
@commands.each do |category, commands|
commands.each do |command, detail|
keyval, modifiers = to_keyval(detail['key'])
Gtk::AccelMap.add_entry("<#{APP_NAME}>/#{name}/#{command}", keyval, modifiers)
Gtk::AccelMap.add_entry("<#{APP_NAME}>/#{category}/#{command}", keyval, modifiers)
end
end
end
Expand All @@ -33,7 +36,5 @@ def to_keyval key
[keyval, state]
end
end


end

21 changes: 21 additions & 0 deletions lib/merrol/models/source_model.rb
@@ -0,0 +1,21 @@
module Merrol
class SourceModel < Gtk::SourceBuffer

def initialize path = nil
super(nil)
@path = path
load
end

def save
File.open(@path, 'w') {|f| f.write(self.text) }
end

def load
if @path && File.exist?(@path)
self.text = File.read(@path)
end
end
end
end

File renamed without changes.
4 changes: 2 additions & 2 deletions lib/merrol/widget_builder.rb
Expand Up @@ -3,7 +3,7 @@ class WidgetBuilder
def self.build *view_names
widgets = {}
view_names.each do |view_name|
yaml = YAML.load_view(view_name)
yaml = YAML.load_view(view_name.to_s)
widget = nil
add_to = nil
pack = {:expand => false, :fill => false, :padding => 0}
Expand All @@ -13,7 +13,7 @@ def self.build *view_names
elsif value.is_a?(Hash)
widget.send("#{key}=", constants_from(value))
elsif key == 'add_to'
add_to = widgets[value]
add_to = widgets[value.to_sym]
elsif %w(expand fill padding).include?(key)
pack[key.to_sym] = value
else
Expand Down
9 changes: 9 additions & 0 deletions spec/controllers/controller_spec.rb
@@ -0,0 +1,9 @@
require 'spec_helper'

describe Controller do
it 'gets the name without controller suffix' do
mock_view = mock Gtk::Window, :signal_connect => nil
MainController.new(mock(Commands, :register => nil), {:main => mock_view }).name.should == :main
end
end

18 changes: 18 additions & 0 deletions spec/controllers/edit_controller_spec.rb
@@ -0,0 +1,18 @@
require 'spec_helper'

describe EditController do
before(:each) do
@mock_commands = mock Commands, :register => nil
@mock_views = {:edit => mock(Gtk::SourceView)}
end

it 'creates the source models' do
mock_source_model = mock SourceModel
SourceModel.should_receive(:new).with('path1').and_return mock_source_model
SourceModel.should_receive(:new).with('path2').and_return mock_source_model
edit = EditController.new @mock_commands, @mock_views
@mock_views[:edit].should_receive(:buffer=).once.with mock_source_model
edit.load_all ['path1', 'path2']
end
end

12 changes: 12 additions & 0 deletions spec/controllers/main_controller_spec.rb
@@ -0,0 +1,12 @@
require 'spec_helper'

describe MainController do
it 'sets the title' do
mock_commands = mock Commands, :register => nil
mock_view = mock Gtk::Window, :signal_connect => nil
mock_view.should_receive(:title=).with('project (working/dir)')
main = MainController.new mock_commands, {:main => mock_view}
main.working_dir = 'working/dir/project'
end
end

11 changes: 7 additions & 4 deletions spec/lib/commands_spec.rb
Expand Up @@ -19,13 +19,16 @@
end

it 'can be registered' do
YAML.stub!(:load_config).and_return []
YAML.stub!(:load_config).and_return({'main' => {'a_command' => {'help' => '', 'key' => 'CTRL+O'}, 'another_command' => {'help' => '', 'key' => 'CTRL+T'}} })
mock_accel_group = mock Gtk::AccelGroup
mock_accel_group.should_receive(:connect).with('<Merrol>/category/command').and_yield
mock_accel_group.should_receive(:connect).with('<Merrol>/main/a_command').and_yield
mock_accel_group.should_receive(:connect).with('<Merrol>/main/another_command').and_yield
Gtk::AccelGroup.stub!(:new).and_return mock_accel_group
commands = Commands.new(mock(Gtk::Window, :add_accel_group => nil))
commands.register 'category', 'command' do
end
mock_controller = mock MainController, :class => MainController, :name => :main
mock_controller.should_receive :a_command
mock_controller.should_receive :another_command
commands.register mock_controller
end

end
Expand Down

0 comments on commit 78cddd5

Please sign in to comment.