Class: RubyCurses::TabbedPane

Inherits:
Widget show all
Defined in:
lib/rbcurse/rtabbedpane.rb

Overview

extending Widget from 2009-10-08 18:45 It should extend Widget so we can pop it in a form. In fact it should be in a form,

we should not have tried to make it standalone like messagebox.
This is the main TabbedPane widget that will be slung into a form

Defined Under Namespace

Classes: Tab

Constant Summary collapse

TAB_ROW_OFFSET =

what row should tab start on (was 4 when printing subheader)

3
TAB_COL_OFFSET =

what col should tab start on (to save space, flush on left)

0

Constants included from Io

Io::ERROR_COLOR_PAIR, Io::FOOTER_COLOR_PAIR, Io::LINEONE, Io::MAIN_WINDOW_COLOR_PAIR

Instance Attribute Summary collapse

Attributes inherited from Widget

#_object_created, #col_offset, #cols_panned, #config, #curpos, #focussed, #id, #parent_component, #row_offset, #rows_panned, #state

Instance Method Summary collapse

Methods inherited from Widget

#changed, #click, #enter, #event_list, #focus, #get_preferred_size, #getvalue, #getvalue_for_paint, #height, #height=, #hide, #init_vars, #leave, #modified?, #move, #on_leave, #override_graphic, #printstring, #process_key, #remove, #repaint_all, #repaint_required, #rowcol, #set_buffer_modified, #set_buffering, #set_form, #set_form_col, #set_form_row, #set_modified, #setformrowcol, #setrowcol, #text_variable, #unbind_key, #width, #width=

Methods included from Io

#askchoice, #askyesno, #askyesnocancel, #clear_error, #clear_this, #get_string, #newaskyesno, #old_print_header, #old_print_top_right, #print_action, #print_error, #print_footer_help, #print_header, #print_headers, #print_help, #print_help_page, #print_in_middle, #print_key_labels, #print_key_labels_row, #print_screen_labels, #print_status, #print_this, #print_top_right, #rbgetstr, #warn

Methods included from Utils

#_process_key, #bind_key, #clean_string!, #get_color, #keycode_tos, #repeatm, #view, #wrap_text

Methods included from ConfigSetup

#cget, #config_setup

Methods included from EventHandler

#bind, #fire_handler, #fire_property_change

Constructor Details

#initialize(form, aconfig = {}, &block) ⇒ TabbedPane

Returns a new instance of TabbedPane.



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/rbcurse/rtabbedpane.rb', line 172

def initialize form, aconfig={}, &block
  super
  @parent = form
  @parentwin = form.window
  @visible = true
  @focusable= true
  @tabs ||= []
  @forms ||= []
  @attr = nil
  @current_form = nil
  @current_tab = nil
  @config = aconfig
  @col_offset = 2;  @row_offset = 1 # added 2010-01-10 22:54 
  @recreate_buttons = true
  install_keys
  @_events.push(*[:OPEN, :INSERT, :DELETE])
  @on_main_form = true # 2011-10-4 we need to know this i think
end

Instance Attribute Details

#current_tabObject (readonly)

Returns the value of attribute current_tab.



170
171
172
# File 'lib/rbcurse/rtabbedpane.rb', line 170

def current_tab
  @current_tab
end

#selected_indexObject (readonly)

Returns the value of attribute selected_index.



169
170
171
# File 'lib/rbcurse/rtabbedpane.rb', line 169

def selected_index
  @selected_index
end

#windowObject (readonly)

Returns the value of attribute window.



171
172
173
# File 'lib/rbcurse/rtabbedpane.rb', line 171

def window
  @window
end

Instance Method Details

#_on_enterObject



515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
# File 'lib/rbcurse/rtabbedpane.rb', line 515

def _on_enter
  # if BTAB the last comp
  if $current_key == KEY_BTAB
    # FIXME last is not focusable, then ??
    current_component = @buttons.last
    @current_tab = @form
    @old_tab = @tabs.last
    #@form.select_last_field
  else
    current_component = @buttons.first
    @current_tab = @form
    @old_tab = @tabs.first
    #@form.select_first_field
  end
  #set_form_row
  current_component.on_enter
  $log.debug " TP came to on_enter #{current_component}, #{current_component.state} "
  current_component.set_form_col # XXX 
  current_component.repaint
end

#_recreate_buttonsObject

recreate all buttons We call this if even one is added : adv is we can space out accordinagly if the numbers increase We could also expand the pad here. Test it out with removing tabs to. XXX have to remove buttons from the form



395
396
397
398
399
400
401
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
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
# File 'lib/rbcurse/rtabbedpane.rb', line 395

def _recreate_buttons
  $log.debug " inside recreate_buttons: #{@tabs.size} "
  r = @row
  col = @col + 1
  @buttons ||= []
  #
  # NOTE: since we remove buttons, setting any events on them is useless !
  #
  if !@buttons.empty?
    @buttons.each {|e| @form.remove_widget(e) }
  end
  @buttons = []
  button_gap = 4
  # the next line necessitates a clear on the pad
  #  button_gap = 1 if @tabs.size > 6 # quick dirty fix, we need something that checks fit
  # we may also need to truncate text to fit

  @buttonpad.wclear
  ## create a button for each tab
  $tabradio = Variable.new # so we know which is highlighted
  @tabs.each do |tab|
    text = tab.text
    $log.debug " TABS EACH #{text} "
    @buttons << RubyCurses::TabbedButton.new(@form) do
      variable $tabradio
      text text
      name text
      value text
      row r + 1
      col col
    end
    col += text.length + button_gap
    # if col exceeds pad_w then we need to expand pad
    # but here we don't know that a pad is being used
    $log.debug " button col #{col} " 
#        form = tab.form # changed 2011  2011-09-26 
    form = form(tab)
    form.set_parent_buffer(@window) if form

    b = @buttons.last
    b.display_tab_on_traversal = @display_tab_on_traversal # 2011-10-4 
    tab._button(b) # too late, user needs this when tab is created FIXME
    b.command(b, @form) { 
      $log.debug " calling tab.repaint,button_form_repaint from button press #{b.name} #{b.state} "
      # form.rep essentially sees that buttons get correct attributes
      # when triggering M-<char>. This button should get highlighted.
      tab.repaint

      # the on_leave of current button does not get fired, so it gets
      #   left in a HIGHLIGHTED state, so two can show highlighted at the same time 2011-10-5 
      #
      @form.widgets.each { |tb| @form.on_leave(tb) if tb.state == :HIGHLIGHTED }

      button_form_repaint #( b.state == :HIGHLIGHTED )
      if @display_tab_on_traversal
        # set as old tab so ONLY on going down this becomes current_tab
        @old_tab = tab
      else
        # next line means next key is IMMED  taken by the tab not main form
        @current_tab = tab
      end
      $log.debug "TAB : form #{tab.form}, #{tab.form.widgets.first} "
      c = tab.form.widgets.first
      c.set_form_row; c.set_form_col
      fire_event tab, tab.index, :OPEN
    }
  end
  @recreate_buttons = false
  # make the buttons visible now, not after next handle_key
  @form.repaint
end

#add_tab(text, component = nil, aconfig = {}, &block) ⇒ Object Also known as: add

This is a public, user called method for appending a new tab This will be called several times for one TP. when adding tabs, you may use ampersand in text to create hotkey XXX adding a tab later does not influence buttons array,



203
204
205
206
207
# File 'lib/rbcurse/rtabbedpane.rb', line 203

def add_tab text, component = nil, aconfig={}, &block
  index = @tabs.size
  tab = insert_tab text, component, index, aconfig, &block
  return tab
end

#button_form_repaint(flag = true) ⇒ Object



535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
# File 'lib/rbcurse/rtabbedpane.rb', line 535

def button_form_repaint flag = true
  $log.debug " INSIDE button_form_repaint #{flag} "
  #if flag
    #@form.repaint if flag  #  This paints the outer form not inner
    #@buttonpad.mvwaddch(2, 0, Ncurses::ACS_LTEE) # beautify the corner 2010-02-06 19:35 
    #@buttonpad.mvwaddch(2, @width-1, Ncurses::ACS_RTEE)
  #end
  #ret = @buttonpad.prefresh(0,0, @row+0, @col+0, @row+@height, @col+@width)
  #$log.debug " prefresh error buttonpad 2 " if ret < 0
  #@buttonpad.modified = false
  if flag
    # repaint form and refresh pad
    @form.repaint
  else
    # only refresh pad 
    # - 2011-09-19 I don't think this is called, prolly give an error
    @form.prefresh
  end
end

#center_column(textlen) ⇒ Object



756
757
758
759
# File 'lib/rbcurse/rtabbedpane.rb', line 756

def center_column textlen
  width = @layout[:width]
  return (width-textlen)/2
end

#change_labelObject

prompts for a new label for a tab - taking care of mnemonics if ampersand present Currently, mapped to ‘C’ and ‘cw’ when cursor is on a label Perhaps some of this kind of utility stuff needs to go into a util class.



275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
# File 'lib/rbcurse/rtabbedpane.rb', line 275

def change_label
  ix = highlighted_tab_index
  return if ix < 0
  prompt = "Enter new label: "
  label = @buttons[ix].text
  config = {}
  config[:default] = label.dup
  maxlen = 10
  ret, str = rbgetstr(@graphic, $error_message_row, $error_message_col, prompt, maxlen, config)
  if ret == 0 and str != "" and str != label
    @tabs[ix].text = str
    @buttons[ix].text(str)
    @recreate_buttons = true
  end
end

#configure(*val, &block) ⇒ Object

private



364
365
366
367
368
369
370
371
372
373
# File 'lib/rbcurse/rtabbedpane.rb', line 364

def configure(*val , &block)
  case val.size
  when 1
    return @config[val[0]]
  when 2
    @config[val[0]] = val[1]
    variable_set(val[0], val[1]) 
  end
  instance_eval &block if block_given?
end

#configure_component(component) ⇒ Object

return a form for use by program - if you want to put multiple items Otherwise just use add_component private - can’t use externally



318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
# File 'lib/rbcurse/rtabbedpane.rb', line 318

def configure_component component
    #component.set_form @parent <<--- definitely NOT
    #component.form = @parent # changed on 2011-10-2 
    component.rows_panned = component.cols_panned = 0
    component.parent_component = self # added 2010-02-27  so offsets can go down ?

    $log.debug "XXX: TABBED #{@row} #{@col} #{@height} #{@width} "
    component.row ||= 0 # 2011-10-3 @row + TAB_ROW_OFFSET # 2
    component.col ||= 0 #@col + TAB_COL_OFFSET
    component.width  ||= @width #@col + TAB_COL_OFFSET
    component.height  ||= @height - 2 #@col + TAB_COL_OFFSET
    $log.debug "XXX: TABBED #{component.row} #{component.col} #{component.height} #{component.width} "

    # current_form likely to be nil XXX
    scr_top = component.row # for Pad, if Pad passed as in SplitPane
    scr_left = component.col # for Pad, if Pad passed as in SplitPane
    ho = TAB_ROW_OFFSET + 2 # 5
    component.set_buffering(:target_window => @target_window || @parentwin, :form => @current_form, :bottom => @height-ho, :right => @width-2, :screen_top => scr_top, :screen_left => scr_left)
    # if left nil, then we expand the comp
    component.height ||= @height - (ho - 1) # 1 keeps lower border inside by 1
    component.width ||= @width - 0 # 0 keeps it flush on right border


end

#create_buttonsObject



712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
# File 'lib/rbcurse/rtabbedpane.rb', line 712

def create_buttons
  case @button_type.to_s.downcase
  when "ok"
    make_buttons ["&OK"]
  when "ok_cancel" #, "input", "list", "field_list"
    make_buttons %w[&OK &Cancel]
  when "yes_no"
    make_buttons %w[&Yes &No]
  when "yes_no_cancel"
    make_buttons ["&Yes", "&No", "&Cancel"]
  when "custom"
    raise "Blank list of buttons passed to custom" if @buttons.nil? or @buttons.size == 0
    make_buttons @buttons
  else
    $log.debug "No buttontype passed for creating tabbedpane. Using default (OK)"
    make_buttons ["&OK"]
  end
end

#create_tab_form(tab) ⇒ Object

This creates a form for the tab, in case we wish to put many components in it. Else just pass single components in add_tab.

Returns:

  • form - a pad based form



559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
# File 'lib/rbcurse/rtabbedpane.rb', line 559

def create_tab_form tab
    mtop = 0
    mleft = 0
    bottom_offset = 2 # 0 will overwrite bottom line, 1 will make another line for inner form
  layout = { :height => @height-(mtop+bottom_offset), :width => @width, :top => mtop, :left => mleft } 
  # create a pad but it must behave like a window at all times 2009-10-25 12:25 
  window = VER::Pad.create_with_layout(layout)

  form = RubyCurses::Form.new window
  $log.debug " pad created in TP create_tab_form: #{window.name} , form #{form.name}  "
  $log.debug " hwtl: #{layout[:height]} #{layout[:width]} #{layout[:top]} #{layout[:left]} "
  ## added 2010-01-21 15:46 to pass cursor up
  form.parent_form = @parent
  form.navigation_policy = :NON_CYCLICAL
  window.bkgd(Ncurses.COLOR_PAIR($datacolor));
  window.box( 0, 0);
  window.mvwaddch(0, 0, Ncurses::ACS_LTEE) # beautify the corner 2010-02-06 19:35 
  window.mvwaddch(0, @width-1, Ncurses::ACS_RTEE)

  # XXX TODO this wastes space we should ditch it.
  ## this prints the tab name on top left
  window.mvprintw(1,1, tab.text.tr('&', '')) if @print_subheader
  window.name = "Tab::TAB-#{tab.text}" # 2010-02-02 19:59 
  form.name = "Form::TAB-#{tab.text}" # 2010-02-02 19:59 
  form.add_cols=@col + 0
  form.add_rows=@row + 2 # 2011-10-3  position cursor correctly
  return form
end

#create_windowObject

This form is for the tabbed buttons on top



467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
# File 'lib/rbcurse/rtabbedpane.rb', line 467

def create_window
  set_buffer_modified() # required still ??
  # first create the main top window with the tab buttons on it.
  $log.debug " TPane create_buff Top #{@row}, Left #{@col} H #{@height} W #{@width} "
  #$log.debug " parentwin #{@parentwin.left} #{@parentwin.top} "

  r = @row
  c = @col
  @form = ScrollForm.new(@parentwin)
  @form.set_layout(1, @width, @row+1, @col+1)
  @form.display_h = 1
  @form.display_w = @width-3
  @buttonpad = @form.create_pad


  ## We will use the parent window, and not a pad. We will write absolute coordinates.
  @window = @parentwin
  color = $datacolor
  # border around button bar. should this not be in scrollform as a border ? XXX
  @window.print_border @row, @col, 2, @width, color #, Ncurses::A_REVERSE
  @buttonpad.name = "Window::TPTOPPAD" # 2010-02-02 20:01 
  @form.name = "Form::TPTOPFORM"
  $log.debug("TP WINDOW TOP ? PAD MAIN FORM W:#{@window.name},  F:#{@form.name} ")
  @form.parent_form = @parent ## 2010-01-21 15:55 TRYING OUT BUFFERED
  @form.navigation_policy = :NON_CYCLICAL
  
  Ncurses::Panel.update_panels
  _recreate_buttons
 
  @old_tab = @tabs.first
  @old_tab.repaint if @old_tab
  button_form_repaint true
  @window.wrefresh ## ADDED  2009-11-02 23:29 
  #@buttons.first().fire unless @buttons.empty? # make the first form active to start with.
  #@current_tab = nil # 2011-10-3 otherwise keys go to this form in the beginning
  @current_tab = @form # 2011-10-4 buttons form should be first
end

#destroyObject

ensure that the pads are being destroyed, although we’ve not found a way.



708
709
710
711
# File 'lib/rbcurse/rtabbedpane.rb', line 708

def destroy
  @window.destroy
  @forms.each { |f| w = f.window; w.destroy unless w.nil? }
end

#fire_event(tab, index, event) ⇒ Object



760
761
762
763
764
765
766
767
768
769
# File 'lib/rbcurse/rtabbedpane.rb', line 760

def fire_event tab, index, event
  # experimenting with structs, earlier we've used classes
  if @tabbedpane_event.nil?
    @tabbedpane_event = Event.new
  end
  @tabbedpane_event.tab = tab
  @tabbedpane_event.index = index
  @tabbedpane_event.event = event
  fire_handler event, @tabbedpane_event
end

#form(tab) ⇒ Object

create a form for tab, if multiple components are to be placed inside tab.

Tabbedpane has no control over placement and width etc of what's inside a form


344
345
346
347
348
349
350
# File 'lib/rbcurse/rtabbedpane.rb', line 344

def form tab
  if !tab.has_form?
    @forms << create_tab_form(tab)
    tab.form = @forms.last
  end
  return tab.form
end

#handle_key(ch) ⇒ Object

added 2009-10-08 19:39 so it can be placed in a form XXX stop this nonsense about current_form and current_tab TP should only be concerned with tabs. what happens inside is none of its business



592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
# File 'lib/rbcurse/rtabbedpane.rb', line 592

def handle_key(ch) # tabbed pane TP


  if @current_tab == @form         # on main form
    return :UNHANDLED if ch == ?\M-\C-i.getbyte(0) # alt-tab to exit
    ret = @form.handle_key ch
    $log.debug "TP HNDLE KEY got ret #{ret}, ch #{ch} "
    ret ||= :UNHANDLED
    if ret == :UNHANDLED
      $log.warn "unhandled key in TP main #{ch} "
      case ch
      when KEY_RIGHT, KEY_LEFT, KEY_TAB, KEY_BTAB
      when KEY_UP
      when KEY_DOWN
      when KEY_TAB
      when KEY_BTAB
      end
    elsif ret == :NO_NEXT_FIELD
      case ch
      when KEY_TAB
        return :UNHANDLED
      when KEY_RIGHT, KEY_DOWN, ?j.getbyte(0)

        @current_tab = @old_tab 
        if @current_tab
          @current_tab.set_focus :FIRST
        else
          alert "Need to press enter on button"
          if @current_tab.nil? ##or @current_tab.is_a?  Form
            w = @form.widgets.first
            w.fire if w.respond_to? :fire
          end
        end
        return 0
      when KEY_UP
      when KEY_BTAB
      end
      return ret
    elsif ret == :NO_PREV_FIELD
      case ch
      when KEY_LEFT, KEY_BTAB, ?k.getbyte(0)
        $log.debug "LEFT BTAB when no previous field"
        return :UNHANDLED
      end
      return ret
    end
    return 0
  end
  
    $log.debug " handle_key in tabbed pane got : #{ch},  #{@current_tab}, f: #{@form}  "
  @current_tab ||= @form # first we cycle buttons
    $log.debug " handle_key in tabbed pane got : #{ch}, giving to #{@current_tab} "
  # needs to go to component
  ret = @current_tab.handle_key(ch)
    $log.debug " -- form.handle_key in tabbed pane got ret : #{ret} , #{@current_tab} , #{ch} "

  # components will usually return UNHANDLED for a tab or btab
  # We need to convert it so the main form can use it
  if @current_tab != @form
      if ret == :UNHANDLED
        if ch == KEY_TAB #or ch == KEY_DOWN
          ret = :NO_NEXT_FIELD
        elsif ch == KEY_BTAB or ch == ?k.getbyte(0) #or ch == KEY_UP # btab
          ret = :NO_PREV_FIELD
        end
      end
      else
        # key down pressed in top form, go to tab
        if ch == KEY_DOWN
          ret = :NO_NEXT_FIELD
        end
      end

    case ret
    when :NO_NEXT_FIELD
      #alert "came to no nex field" # CLEAN
      if @current_tab != @form
        #alert "case 1 no next field req first" # changed on 2011-10-2  # 2011-10-04 16:12:34
        ## if no next field on a subform go to first button of main form
        @old_tab = @current_tab
        @current_tab = @form
        @form.req_first_field
     
      else
        # on top button panel - no more buttons, go to tabs first field
        if @old_tab # in case of empty tabbed pane old_tab was nil
        #alert "case 2 no next field set focus" # CLEANUP # 2011-10-04 16:12:46
          @current_tab = @old_tab
          @current_tab.set_focus :FIRST
        end
      end
    when :NO_PREV_FIELD
      if @current_tab != @form
        $log.debug "TP 1 no prev field - going to last button "
        @old_tab = @current_tab
        @current_tab = @form
        @form.req_last_field
      else
        # on top button panel - no prev buttons, go to tabs last field
        if @old_tab # in case of one tab
          @current_tab = @old_tab
          @current_tab.set_focus :LAST
        end
      end
    when :UNHANDLED
      $log.debug " unhandled in tabbed pane #{ch}"
      ret = @form.process_key ch, self # field

      return ret if ret == :UNHANDLED
    end
    if @buttonpad.modified
      button_form_repaint
    end
end

#highlighted_tab_index0..

returns the index of the tab cursor is on (not the one that is selected)

Returns:

  • (0..)

    index, or -1 if some error



293
294
295
296
297
298
# File 'lib/rbcurse/rtabbedpane.rb', line 293

def highlighted_tab_index
  @form.widgets.each_with_index{ |w, ix| 
    return ix if w.state == :HIGHLIGHTED
  }
  return -1
end

#insert_tab(text, component, index, aconfig = {}, &block) ⇒ Object

insert a component at given index index cannnot be greater than size of tab count



212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'lib/rbcurse/rtabbedpane.rb', line 212

def insert_tab text, component, index, aconfig={}, &block
  $log.debug " TAB insert #{text} at #{index} "
  @tabs[index] = Tab.new(text, self, aconfig, &block)
  tab = @tabs[index]

  # trying out setting current tab when created  2011-10-4 
  #  This situation happens when someone externally is setting data
  #  in a tab and calling its repaint. When user presses DOWN from button
  #  it was crashing. Old tab is the tab you see below. current_tab takes on 
  #  either form or old_tab to distinguish whether we are on top buttons or
  #  inside a tab.
  @old_tab = tab

  tform = form(tab) # this could go inside Tab constructor now 2011-10-4 
  #tab.component = component unless component.nil? # changed on 2011-10-3  CLEAN
  #component.form = tform unless component.nil? # changed on 2011-10-3  CLEAN
  component.set_form( tform) unless component.nil? # changed on 2011-10-3 
  configure_component component unless component.nil?
  tab.index = index # so i can undelete !!!
  fire_event tab, index, :INSERT
  @recreate_buttons = true
  return tab
end

#install_keysObject



190
191
192
193
194
195
196
197
# File 'lib/rbcurse/rtabbedpane.rb', line 190

def install_keys
  @form.bind_key([?d, ?d]) { ix = highlighted_tab_index; repeatm { remove_tab(ix) } }
  @form.bind_key(?u) { undelete_tab; }
  @form.bind_key(?p) { paste_tab 0; } # paste before or at position
  @form.bind_key(?P) { paste_tab 1; } # paste deleted tab after this one
  @form.bind_key([?c, ?w]) { change_label }
  @form.bind_key(?C) { change_label }
end

#make_buttons(names) ⇒ Object



730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
# File 'lib/rbcurse/rtabbedpane.rb', line 730

def make_buttons names
  total = names.inject(0) {|total, item| total + item.length + 4}
  bcol = center_column total

  brow = @layout[:height]-2
  button_ct=0
  names.each_with_index do |bname, ix|
    text = bname
    #underline = @underlines[ix] if [email protected]?

    button = Button.new @form do
      text text
      name bname
      row brow
      col bcol
      #underline underline
      highlight_background $reversecolor 
      color $datacolor
      bgcolor $datacolor
    end
    index = button_ct
    button.command { |form| @selected_index = index; @stop = true; $log.debug "Pressed Button #{bname}";}
    button_ct += 1
    bcol += text.length+6
  end
end

#on_enterObject

Handle placing control in first or last button. R



507
508
509
510
511
512
513
514
# File 'lib/rbcurse/rtabbedpane.rb', line 507

def on_enter
  if $current_key == KEY_BTAB
    c = @form.widgets.count-1
    @form.select_field c
  else
    @form.select_field 0
  end
end

#paste_tab(pos) ⇒ Object



258
259
260
261
262
263
264
265
266
267
268
# File 'lib/rbcurse/rtabbedpane.rb', line 258

def paste_tab pos
  return unless @deleted_tab
  ix = highlighted_tab_index
  return if ix == -1
  @recreate_buttons = true
  @deleted_tab.index = ix + pos
  @tabs.insert(@deleted_tab.index, @deleted_tab)
  fire_event @deleted_tab, @deleted_tab.index, :INSERT
  @deleted_tab = nil
  $log.debug " paste over #{@tabs.size} #{ix} + #{pos} "
end

#remove_allObject

remove all tabs



306
307
308
309
310
311
312
313
# File 'lib/rbcurse/rtabbedpane.rb', line 306

def remove_all
  if !@buttons.empty?
    @buttons.each {|e| @form.remove_widget(e) }
  end
  @buttons = []
  @tabs = []
  @recreate_buttons = true
end

#remove_tab(index) ⇒ Object

remove given tab based on index This does not unbind the key mapping, FIXME Currently, can be invoked by ‘dd’ over highlighted button XXX can append to deleted_tabs, then on insert or paste insert with splat.



239
240
241
242
243
244
245
# File 'lib/rbcurse/rtabbedpane.rb', line 239

def remove_tab index
  @recreate_buttons = true
  $log.debug " inside remove_tab with #{index}, #{@tabs.size} "
  @deleted_tab = @tabs.delete_at(index) unless @tabs.size < index
  # note this is the index it was at. 
  fire_event @deleted_tab, index, :DELETE
end

#repaintObject

this is a really wierd repaint method. First time it creates the TP window/form which contains the buttons. In future calls it really doesn’t do anything. Deos it have nothing to paint, no borders to redraw, no repaint_required ???



378
379
380
381
382
383
384
385
386
# File 'lib/rbcurse/rtabbedpane.rb', line 378

def repaint
  $log.debug " tabbedpane repaint "
  @window || create_window
  _recreate_buttons if @recreate_buttons
  $log.debug " tabbedpane repaint #{@window.name} "
  @window.show
  @window.wrefresh # trying out FFI 2011-09-19 since form not being refreshed
  #x set_buffer_modified()
end

#selected_tab_indexObject

returns the index of the current / selected tab



354
355
356
357
358
359
# File 'lib/rbcurse/rtabbedpane.rb', line 354

def selected_tab_index
  @form.widgets.each_with_index{ |w, ix| 
    return ix if w.selected?
  }
  return -1
end

#showObject

x set_buffer_modified()



387
388
389
# File 'lib/rbcurse/rtabbedpane.rb', line 387

def show
  repaint
end

#undelete_tabObject

Move this fun stuff to a util class. TODO If tab deleted accidentally, undelete it Okay, i just can stop myself from having a little fun



250
251
252
253
254
255
256
257
# File 'lib/rbcurse/rtabbedpane.rb', line 250

def undelete_tab
  return unless @deleted_tab
  @recreate_buttons = true
  @tabs.insert(@deleted_tab.index, @deleted_tab)
  fire_event @deleted_tab, @deleted_tab.index, :INSERT
  @deleted_tab = nil
  $log.debug " undelete over #{@tabs.size} "
end

#variable_set(var, val) ⇒ Object

private



359
360
361
362
# File 'lib/rbcurse/rtabbedpane.rb', line 359

def variable_set var, val
    var = "@#{var}"
    instance_variable_set(var, val) 
end