Implement ActionList::Entry#clear.
[kaya.git] / lib / multiview.rb
blob8d23e28a29f1b1ea4c664ea06a459d9df02c82aa
1 # Copyright (c) 2009 Paolo Capriotti <p.capriotti@gmail.com>
2
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version.
8 require 'observer_utils'
10 class MultiView < KDE::TabWidget
11   attr_reader :index
12   attr_accessor :clean
13   
14   include Observable
15   include Observer
16   include Enumerable
17   
18   def initialize(parent, movelist_stack, factories)
19     super(parent)
20     @movelist_stack = movelist_stack
21     @factories = factories
22     @views = []
23     @index = -1
24     tab_bar.visible = false
25     tab_bar.tabs_closable = true
26     on(:current_changed, ["int"]) {|i| self.index = i; fire :changed }
27     tab_bar.on(:tab_close_requested) {|i| delete_at(i) }
28   end
29   
30   def index=(value)
31     if value >= 0 and value < size and value != @index
32       @index = value
33       self.current_index = value
34       @movelist_stack.current_index = value
35       on_activity(current, false)
36     end
37   end
38   
39   def activate(user, name = nil)
40     @views.each_with_index do |view, i|
41       if user == view.controller
42         self.index = i
43         set_tab_text(i, name) if name
44         break
45       end
46     end
47   end
48   
49   def find
50     @views.each_with_index do |view, i|
51       return i if yield view
52     end
53     nil
54   end
55   
56   def current
57     if @index != -1
58       @views[@index]
59     end
60   end
61   
62   def current_name
63     if @index != -1
64       tab_text(@index)
65     end
66   end
67   
68   def create(opts =  { })
69     if @clean and not opts[:force]
70       @clean = false
71       if opts[:name]
72         set_tab_text(index, opts[:name])
73         fire :changed
74       end
75       current
76     else    
77       @clean = false
78       table = @factories[:table].new(self)
79       controller = @factories[:controller].new(table)
80       movelist = @factories[:movelist].new(controller)
81       
82       v = View.new(table, controller, movelist)
83       add(v, opts)
84       v
85     end
86   end
87   
88   def add(view, opts = { })
89     view.add_observer(self)
90     @views << view
91     i = add_tab(view.main_widget, opts[:name] || "?")
92     unless i == size - 1
93       raise "[bug] inconsistent MultiView index #{size - 1}, expected #{i}"
94     end
95     @movelist_stack.insert_widget(i, view.movelist)
96     if opts[:activate] || index == -1
97       self.index = i
98     end
99     tab_bar.visible = size > 1
100     i
101   end
102   
103   def delete_at(index)
104     raise "Cannot delete last view" if size <= 1
105     if index >= 0 and index < size
106       self.index -= 1 if index <= @index
107       removeTab(index)
108       v = @views.delete_at(index)
109       @movelist_stack.remove_widget(v.movelist)
110       tab_bar.visible = size > 1
111       v.controller.close
112       v.close
113       v.delete_observer(self)
114       v
115     end
116   end
117   
118   def size
119     @views.size
120   end
121   
122   def each(&blk)
123     @views.each(&blk)
124   end
125   
126   def on_activity(view, value = true)
127     i = find { |v| v == view }
128     return unless i
129     @@base_color ||= tab_bar.tab_text_color(i)
130     
131     if i != @index && value
132       tab_bar.set_tab_text_color(i, KDE::active_color)
133     else
134       tab_bar.set_tab_text_color(i, @@base_color)
135     end
136   end
137   
138   def on_dirty(view, value = true)
139     @clean = false
140   end