Class: Canis::Viewer

Inherits:
Object show all
Defined in:
lib/canis/core/util/viewer.rb

Overview

a data viewer for viewing some text or filecontents view filename, :close_key => KEY_ENTER send data in an array view Array, :close_key => KEY_ENTER, :layout => [23,80,0,0] (ht, wid, top, left) when passing layout reserve 4 rows for window and border. So for 2 lines of text give 6 rows.

Class Method Summary collapse

Class Method Details

.view(what, config = {}) { ... } ⇒ Object

Parameters:

  • filename

    as string or content as array

Yields:

  • textview object for further configuration before display



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/canis/core/util/viewer.rb', line 25

def self.view what, config={}, &block  #:yield: textview
  case what
  when String # we have a path
    content = _get_contents(what)
  when Array
    content = what
  when TextDocument
    $log.debug "  setting content to textdocument #{what.options.keys} "
    content = what
    #content = what.text
    #config[:content_type] = what.content_type
  else
    raise ArgumentError, "Viewer: Expecting Filename or Contents (array), but got #{what.class} "
  end
  wt = 0 # top margin
  wl = 0 # left margin
  wh = Ncurses.LINES-wt # height, goes to bottom of screen
  ww = Ncurses.COLS-wl  # width, goes to right end
  layout = { :height => wh, :width => ww, :top => wt, :left => wl } 
  if config.has_key? :layout
    layout = config[:layout]
    case layout
    when Array
      #wt, wl, wh, ww = layout
      # 2014-04-27 - 11:22 changed to the same order as window, otherwise confusion and errors
      wh, ww, wt, wl = layout
      layout = { :height => wh, :width => ww, :top => wt, :left => wl } 
    when Hash
      # okay
    end
  end

  fp = config[:title] || ""
  pf = config.fetch(:print_footer, true)
  ta = config.fetch(:title_attrib, 'bold')
  fa = config.fetch(:footer_attrib, 'bold')
  wbg = config.fetch(:window_bgcolor, nil)
  b_ah = config[:app_header]
  type = config[:content_type]

  v_window = Canis::Window.new(layout)
  v_form = Canis::Form.new v_window
  v_window.name = "WINDOW::Viewer"
  if wbg
    v_window.wbkgd(Ncurses.COLOR_PAIR(wbg)); #  does not work on xterm-256color
  end
  # I am placing this in globals since an alert on top will refresh the lower windows and this is quite large.
  $global_windows << v_window
  colors = Ncurses.COLORS
  back = :blue
  back = 235 if colors >= 256
  blue_white = get_color($datacolor, :white, back)

  tprow = 0
  ah = nil
  if b_ah
    ah = ApplicationHeader.new v_form, "", :text_center => fp
    tprow += 1
  end

  #blue_white = Canis::Utils.get_color($datacolor, :white, 235)
  textview = TextPad.new v_form do
    name   "Viewer" 
    row  tprow
    col  0
    width ww
    height wh-tprow # earlier 2 but seems to be leaving space.
    title fp
    title_attrib ta
    print_footer pf
    footer_attrib fa
    #border_attrib :reverse
    border_color blue_white
  end
  # why multibuffers  -- since used in help
  require 'canis/core/include/multibuffer'
  textview.extend(Canis::MultiBuffers)

  t = textview
  t.bind_key(Ncurses::KEY_F5, 'maximize window '){ f = t.form.window; 
    f.resize_with([FFI::NCurses.LINES-0, Ncurses.COLS, 0,0]); 
    #f.resize_with([0,0, 0,0]); 
    t.height = Ncurses.LINES - t.row - 0
  }
  t.bind_key(Ncurses::KEY_F6, 'restore window ', layout){ |l,m, n| 
    # l was DefaultKeyHandler, m was string, n was Hash
    f = t.form.window; 
    #$log.debug "  F6 ARG is #{m}, #{n}"
    f.hide; # need to hide since earlier window was larger.
    f.resize_with(n);
    #f.resize_with([0,0, 0,0]); 
    t.height =  f.height - t.row - 0
    f.show
  }
  t.bind_key(?\C-\], "open file under cursor") { 
    eve = t.text_action_event
    file = eve.word_under_cursor.strip
    if File.exists? file
      t.add_content file
      t.buffer_last
    end
  }

=begin
  # just for fun -- seeing how we can move window around
  # these are working, but can cause a padrefresh error. we should check for bounds or something.
  #
  t.bind_key('<', 'move window left'){ f = t.form.window; c = f.left - 1; f.hide; f.mvwin(f.top, c); f.show;
    f.set_layout([f.height, f.width, f.top, c]); 
  }
  t.bind_key('>', 'move window right'){ f = t.form.window; c = f.left + 1; f.hide; f.mvwin(f.top, c); 
    f.set_layout([f.height, f.width, f.top, c]); f.show;
  }
  t.bind_key('^', 'move window up'){ f = t.form.window; c = f.top - 1 ; f.hide; f.mvwin(c, f.left); 
    f.set_layout([f.height, f.width, c, f.left]) ; f.show;
  }
  t.bind_key('V', 'move window down'){ f = t.form.window; c = f.top + 1 ; f.hide; f.mvwin(c, f.left); 
    f.set_layout([f.height, f.width, c, f.left]); f.show;
  }
=end
  items = {:header => ah}
  close_keys = [ config[:close_key] , 3 , ?q.getbyte(0), 27 , 2727 ]
  begin
    # the next can also be used to use formatted_text(text, :ansi)
    # yielding textview so you may further configure or bind keys or events
    if block_given?
      if block.arity > 0
        yield textview, items
      else
        textview.instance_eval(&block)
      end
    end
    # multibuffer requires add_co after set_co
    # We are using in help, therefore we need multibuffers.
    #textview.set_content content, :content_type => type #, :stylesheet => t.stylesheet
    # i need to do this so it is available when moving around
    # buffers
    #  but this means that pressing next will again show the same
    #  buffer.
    textview.add_content content, :content_type => type #, :stylesheet => t.stylesheet
    textview.buffer_last
  #yield textview if block_given? 
  v_form.repaint
  v_window.wrefresh
  Ncurses::Panel.update_panels
  retval = ""
  # allow closing using q and Ctrl-q in addition to any key specified
  #  user should not need to specify key, since that becomes inconsistent across usages
  #  NOTE: 2727 is no longer operational, so putting just ESC
    while((ch = v_window.getchar()) != ?\C-q.getbyte(0) )
      $log.debug "  VIEWER got key #{ch} , close key is #{config[:close_key]} "
      retval = textview.current_value() if ch == config[:close_key] 
      break if close_keys.include? ch
      # if you've asked for ENTER then i also check for 10 and 13
      retval = textview.current_value() if (ch == 10 || ch == 13) && config[:close_key] == KEY_ENTER
      break if (ch == 10 || ch == 13) && config[:close_key] == KEY_ENTER
      $log.debug "  1 VIEWER got key #{ch} "
      v_form.handle_key ch
      v_form.repaint
    end
  rescue => err
      $log.error " VIEWER ERROR #{err} "
      $log.debug(err.backtrace.join("\n"))
      alert "#{err}"
      #textdialog ["Error in viewer: #{err} ", *err.backtrace], :title => "Exception"
  ensure
    v_window.destroy if !v_window.nil?
  end
  return retval
end