Class: Ruber::Workspace

Inherits:
Qt::Widget
  • Object
show all
Defined in:
lib/ruber/main_window/workspace.rb

Overview

Widget representing the main area of Ruber’s main window. It contains the space for the main widget (that is, the tab widget where the editors are located) and the tool widgets, together with their tab bars.

To allow for several main widgets existing (but not being visible) at the same time (one main widget for each environment) the space for the main widget is given by a single Qt::StackedWidget, where the different main widgets are placed using #add_widget. #main_widget= is then used to bring one of the main widgets to the foreground; #remove_widget removes a widget from the stacked widget (to be used when a project is closed).

The workspace provides three tool widgets containers, one on each side of the main widget except above it. The container on each side is indipendent from the others. The containers have buttons for their tool widgets and a Qt::StackedWidget for the widget themselves. Each container is indipendent from the other ones

A tool widget can be in several different states:

  • raised or lowered: a tool widget is raised when it’s on the top of its container stacked widget. There can be only one raised tool widget for side. All tool widgets which aren’t raised are said to be lowered
  • visible or hidden: each tool widget container can be visible or hidden. The raised tool widget in a visible container is said to be visible. Widgets in an hidden container are said to be hidden.
  • active or inactive: the active tool widget is the one which has keyboard focus; all others are inactive. Of course there can be at most one active tool widget across the whole workspace. If the focus is not in one of the tool widgets (most likely meaning one of the editors has focus), all tool widgets will be inactive.

Defined Under Namespace

Classes: StackedWidget, ToolData

Instance Method Summary (collapse)

Signal Summary

Constructor Details

- (Workspace) initialize(parent = nil)

A new instance of Workspace

Parameters:

  • parent (Qt::Widget, nil) (defaults to: nil)

    the parent widget



129
130
131
132
133
134
135
136
137
138
139
# File 'lib/ruber/main_window/workspace.rb', line 129

def initialize parent = nil
  super parent
  @button_bars = {}
  @splitters = {}
  @stacks = {}
  @widgets = {}
  @next_id = 0
  @tool_sizes = {}
  @sizes = Ruber[:config][:workspace, :tools_sizes].dup
  create_skeleton
end

Instance Method Details

- (Object) activate_tool(tool)

Gives focus to the tool widget tool (raising and showing it if necessary). tool can be either the tool widget itself or its object_name (as either a string or symbol). If tool doesn’t represent a valid tool widget, nothing happens. If tool is a string or symbol and more than one tool widget with the same name exists, which one will obtain focus is undefined.



270
271
272
273
274
275
# File 'lib/ruber/main_window/workspace.rb', line 270

def activate_tool tool
  tool, data = tool_and_data tool
  return unless tool
  show_tool tool unless tool.visible?
  tool.set_focus
end

- (Object) active_tool

Returns the active tool widget, or nil if there’s no active tool widget.



354
355
356
357
358
359
# File 'lib/ruber/main_window/workspace.rb', line 354

def active_tool
  fw = KDE::Application.focus_widget
  if @widgets.include? fw then fw
  else @widgets.keys.find{|w| w.find_children(Qt::Widget).include? fw}
  end
end

- (nil) add_tool_widget(side, widget, icon, caption)

Adds a tool widget to the workspace

Parameters:

  • side (Symbol)

    the side where the tool widget should be put. It can be :left, :right or :bottom

  • widget (Qt::Widget)

    the widget to add

  • icon (Qt::Pixmap)

    the icon to show on the button associated with the tool widget

  • caption (String)

    the text to show on the button associated with the tool widget

Returns:

  • (nil)

Raises:

  • (ArgumentError)

    if the same tool widget had already been added to the workspace (either on the same side or on another side)



174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/ruber/main_window/workspace.rb', line 174

def add_tool_widget side, widget, icon, caption
  if @stacks.values.include? widget.parent
    Kernel.raise ArgumentError, "This widget has already been added as tool widget"
  end
  bar = @button_bars[side]
  id = @next_id
  bar.append_tab icon, id, caption
  @widgets[widget] = ToolData.new side, id
  @stacks[side].add_widget widget
  connect bar.tab(id), SIGNAL('clicked(int)'), self, SLOT('toggle_tool(int)')
  @next_id += 1
  nil
end

- (Object) add_widget(w)



141
142
143
# File 'lib/ruber/main_window/workspace.rb', line 141

def add_widget w
  @main_widget.add_widget w
end

- (Object) create_skeleton (private)

Helper method which creates the structure of the workspace (layout, button bars, splitters and tab view)



367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
# File 'lib/ruber/main_window/workspace.rb', line 367

def create_skeleton
  self.layout = Qt::GridLayout.new self
  layout.set_contents_margins 0,0,0,0
  layout.vertical_spacing = 0
  %w[left right bottom].each do |side|
    @button_bars[side.to_sym] = 
        KDE::MultiTabBar.new(KDE::MultiTabBar.const_get(side.capitalize), self) 
  end
  layout.add_widget @button_bars[:left], 0, 0
  layout.add_widget @button_bars[:right], 0, 2
  layout.add_widget @button_bars[:bottom], 1, 0, 1, -1
  v = Qt::Splitter.new Qt::Vertical, self
  h = Qt::Splitter.new Qt::Horizontal, v
  layout.add_widget v, 0,1
  @splitters[:vertical] = v
  @splitters[:horizontal] = h
  [:left, :right, :bottom].each do |s| 
    stack = StackedWidget.new{|w| w.hide}
    @stacks[s] = stack
  end
  v.add_widget h
  v.add_widget @stacks[:bottom]
  h.add_widget @stacks[:left]
  @main_widget = Qt::StackedWidget.new self
  h.add_widget @main_widget
  h.add_widget @stacks[:right]
end

- (Object) current_widget(side)



347
348
349
# File 'lib/ruber/main_window/workspace.rb', line 347

def current_widget side
  @stacks[side].current_widget
end

- (Object) hide_tool(tool)

Hides the stack containing the tool widget tool, giving focus to the active editor, if tool is raised (that is, if it is the current widget of its stack).

tool can be either the tool widget itself or its object_name (as either a string or symbol). If tool doesn’t represent a valid tool widget, nothing happens. If tool is a string or symbol and more than one tool widget with the same name exists, which one will be used is undefined.



308
309
310
311
312
313
314
315
316
317
318
319
320
# File 'lib/ruber/main_window/workspace.rb', line 308

def hide_tool tool
  tool, data = tool_and_data tool
  return unless tool
  store_tool_size tool if tool.visible?
  stack = tool.parent
  if stack.current_widget == tool
    @button_bars[data.side].set_tab data.id, false
    if stack.visible?
      stack.hide 
      Ruber[:main_window].focus_on_editor
    end
  end
end

- (Object) main_widget



149
150
151
# File 'lib/ruber/main_window/workspace.rb', line 149

def main_widget
  @main_widget.current_widget
end

- (Object) main_widget=(w)



153
154
155
156
157
158
# File 'lib/ruber/main_window/workspace.rb', line 153

def main_widget= w
  unless @main_widget.include? w
    Kernel.raise ArgumentError, "a widget which has not been added to the workspace can\'t become the main widget"
  end
  @main_widget.current_widget = w
end

- (Object) raise_tool(tool)

Raises the tool widget tool_, which can be either the tool widget itself or its objectname, either as a string or symbol. If tool is not a tool widget (or if no tool widget with that object_name exists), nothing is done. If tool is a string or symbol and more than one tool widget exist with that object_name, which one is raised is undefined.

Note: this method doesn’t make the container of tool visible if it’s hidden



218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
# File 'lib/ruber/main_window/workspace.rb', line 218

def raise_tool tool
  tool, data = tool_and_data tool
  return unless tool
  bar = @button_bars[data.side]
  stack = @stacks[data.side]
  old = stack.current_widget
  if old and old.visible?
    store_tool_size old
    old_data = @widgets[old]
    bar.set_tab old_data.id, false
  end
  bar.set_tab data.id, true
  if old != tool
    stack.current_widget = tool
    emit tool_raised(tool)
    emit tool_shown(tool) if stack.visible?
  end
  resize_tool tool
end

- (Object) remove_tool_widget(arg)

Removes a tool widget. arg can be either the widget itself or its object_name, either as a string or as a symbol. If the widget isn’t a tool widget, nothing happens.



193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/ruber/main_window/workspace.rb', line 193

def remove_tool_widget arg
  widget, data = if arg.is_a? String or arg.is_a? Symbol
    @widgets.find{|k, v| k.object_name == arg.to_s}
  else [arg, @widgets[arg]]
  end
  return unless widget and data
  emit removing_tool(widget)
  stack = @stacks[data.side]
  raised = stack.current_widget.equal?(widget)
  stack.remove_widget widget
  if stack.empty? then stack.hide
  else raise_tool stack.current_widget
  end
  @button_bars[data.side].remove_tab data.id
end

- (Object) remove_widget(w)



145
146
147
# File 'lib/ruber/main_window/workspace.rb', line 145

def remove_widget w
  @main_widget.remove_widget w
end

- (Object) resize_tool(tool) (private)

Resizes the splitter where the tool widget tool is so that the size of tool matches that of the last time it was used. The space needed to do so is taken from the editor.

If no size is recorded for tool, nothing is done.



402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
# File 'lib/ruber/main_window/workspace.rb', line 402

def resize_tool tool
  data = @widgets[tool]
  side = data.side
  caption = @button_bars[side].tab(data.id).text
  size = @sizes[caption] #|| 150
  return unless size
  case side
  when :bottom
    splitter = @splitters[:vertical]
    total = splitter.sizes.sum
    new_sizes = [[total - size, 0].max, size]
    splitter.sizes = new_sizes
  when :left
    splitter = @splitters[:horizontal]
    old_sizes = splitter.sizes
    total = old_sizes[0..1].sum
    new_sizes = [size, [total - size, 0].max, old_sizes[-1]]
    splitter.sizes = new_sizes
  when :right
    splitter = @splitters[:horizontal]
    old_sizes = splitter.sizes
    total = old_sizes[1..-1].sum
    new_sizes = [old_sizes[0], [total - size, 0].max, size]
    splitter.sizes = new_sizes
  end
end

- (Object) show_tool(tool)

Shows the tool widget tool. This means that tool will become the current widget in its stack and that the stack will become visible (if it’s not already visible). tool won’t receive focus, unless the previously current widget of its stack had focus.

tool can be either the tool widget itself or its object_name, either as string or as symbol. In the latter cases, it there’s more than one tool widget with the same object_name, it’s undefined which one will be shown.

If tool isn’t a tool widget, nothing happens.



250
251
252
253
254
255
256
257
258
259
260
261
# File 'lib/ruber/main_window/workspace.rb', line 250

def show_tool tool
  tool, data = tool_and_data tool
  return unless tool
  data = @widgets[tool]
  stack = @stacks[data.side]
  visible = tool.visible?
  give_focus = stack.find_children(Qt::Widget).any?{|w| w.has_focus}
  raise_tool tool
  stack.show unless stack.visible?
  emit tool_shown(tool) unless visible
  tool.set_focus if give_focus
end

- (Object) store_sizes

Stores the tool widgets size in the configuration manager. It reads the sizes of the splitters for the tool widgets which are visible and uses the values stored previously for the others.



328
329
330
331
332
333
334
335
# File 'lib/ruber/main_window/workspace.rb', line 328

def store_sizes
  @stacks.each_value do |s|
    w = s.current_widget
    next unless w
    store_tool_size w if w.visible?
  end
  Ruber[:config][:workspace, :tools_sizes] = @sizes
end

- (Object) store_tool_size(tool) (private)

Stores the size of the splitter slot where the tool widget tool is in the @sizes instance variable.



433
434
435
436
437
438
439
440
441
442
443
# File 'lib/ruber/main_window/workspace.rb', line 433

def store_tool_size tool
  data = @widgets[tool]
  side = data.side
  caption = @button_bars[side].tab(data.id).text
  splitter, pos = case side
  when :bottom then [@splitters[:vertical], 1]
  when :left then [@splitters[:horizontal], 0]
  when :right then [@splitters[:horizontal], 2]
  end
  @sizes[caption] = splitter.sizes[pos]
end

- (Object) toggle_tool(tool)

Slot

Activates the tool tool if it’s not visibile and hides its stack if instead it’s visible.

tool can be either the tool widget itself or its object_name (as either a string or symbol) or the id of the tab associated with the tool widget. If tool doesn’t represent a valid tool widget, nothing happens. If tool is a string or symbol and more than one tool widget with the same name exists, which one will obtain focus is undefined.

Note: the use of the id of the tab as argument is only for internal use.



291
292
293
294
295
296
297
# File 'lib/ruber/main_window/workspace.rb', line 291

def toggle_tool tool
  tool, data = tool_and_data tool
  return unless tool
  if !tool.visible? then activate_tool tool
  else hide_tool tool
  end
end

Slot Signature:

toggle_tool(int)

- (Object) tool_and_data(arg) (private)

Returns an array containing the tool widget corresponding to arg and its data (that is, the entry in the @widgets hash corresponding to the tool widget). arg can be:

  • the tool widget itself
  • a string or symbol containing the object_name of the widget
  • an Integer containing the id of the tab associated with the tool widget. If a suitable tool widget can’t be found (or if arg is of another class), nil is returned.


455
456
457
458
459
460
461
462
463
464
465
466
467
468
# File 'lib/ruber/main_window/workspace.rb', line 455

def tool_and_data arg
  case arg
  when String, Symbol
    name = arg.to_s
    @widgets.find{|w, data| w.object_name == name} 
  when Integer
    @widgets.find{|w, data| data.id == arg}
  else
    if arg.is_a? Qt::Widget 
      data = @widgets[arg]
      [arg, data] if data
    end
  end
end

- (Object) tool_widgets

Returns a hash having all the tool widgets as keys and the side each of them is (:left, :right, :bottom) as values.



341
342
343
344
345
# File 'lib/ruber/main_window/workspace.rb', line 341

def tool_widgets
  res = {}
  @widgets.each_pair{|w, data| res[w] = data.side}
  res
end

Signal Details

- tool_raised(QWidget* arg1)

:method: tool_raised(tool)

Signal

Signature: tool_raised(QWidget*)

Signal emitted when a tool widget is raised. tool is the widget which has been raised

- removing_tool(QWidget* arg1)

:method: removing_tool(tool)

Signal

Signature: removing_tool(QWidget*)

Signal emitted just before the tool widget tool is removed

- tool_shown(QWidget* arg1)

:method: tool_shown Signal: tool_shown(QWidget*)

Signal emitted when a tool widget is shown programmaticaly.