Class: Flammarion::Engraving

Inherits:
Object
  • Object
show all
Includes:
Revelator, Writeable
Defined in:
lib/flammarion/engraving.rb

Overview

Note:

Right now, there is no persistence of Engravings. Once it is closed, everything is erased, and you'll need to set it up all over again.

Note:

If you try to display something to a closed window, it will open a new blank window, and then display that thing.

The engraving class represents a window. It contains everything you need to display on the screen and interacts with a user. An Engraving contains one or more panes, which are containers for writeable areas. Most of the power of the panes comes from the Writeable module, which is also included in Engraving (operating on the default pane) for convenience.

See Also:

Constant Summary

Constants included from Revelator

Revelator::CHROME_PATH

Instance Attribute Summary collapse

Attributes included from Writeable

#engraving

Instance Method Summary collapse

Methods included from Writeable

#break, #button, #button_box, #callback_link, #checkbox, #clear, #dropdown, #embedded_button, #emoji, #gets, #hide, #highlight, #html, #icon, #image, #input, #js, #live_reload_template, #map, #markdown, #pane, #plot, #puts, #replace, #script, #script_src, #search, #send, #show, #status, #style, #subpane, #table, #template

Methods included from Revelator

#open_a_window, #wait_for_a_connection

Constructor Details

#initialize(options = {}) ⇒ Engraving

Creates a new Engraving (i.e., a new display window)

Parameters:

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • :on_connect (Proc)

    Called when the display window is connected (i.e., displayed)

  • :on_disconnect (Proc)

    Called when the display windows is disconnected (i.e., closed)

  • :on_callback_exception (Proc)

    Called when there is an exception executing a provided callback. (e.g., so you can log it) If no handler is provided, Flammarion will attempt to pass the exception back to the original calling thread.

  • :exit_on_disconnect (Boolean) — default: false

    Will call exit when the widow is closed if this option is true.

  • :close_on_exit (Boolean) — default: false

    Will close the window when the process exits if this is true. Otherwise, it will just stay around, but not actually be interactive.

  • :title (String)

    The initial title of the engraving. If empty, a random title will be generated.

Raises:

  • (SetupError)

    if neither chrome nor electron is set up correctly and and Flammarion is unable to display the engraving.



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/flammarion/engraving.rb', line 37

def initialize(options = {})
  options = {:title => options} if options.is_a?(String)
  @chrome = OpenStruct.new
  @sockets = []
  @actions = {}
  @engraving = self
  @pane_name = "default"
  @on_connect = options[:on_connect]
  @on_disconnect = options[:on_disconnect]
  @on_callback_exception = options[:on_callback_exception]
  @exit_on_disconnect = options.fetch(:exit_on_disconnect, false)

  start_server
  @window_id = @@server.register_window(self)
  open_a_window(options) unless options[:no_window]
  @callbacks = {}
  wait_for_a_connection unless options[:no_wait]

  at_exit {close if window_open?} if options.fetch(:close_on_exit, true)

  title options[:title] if options[:title]
end

Instance Attribute Details

#actionsObject

Returns the value of attribute actions



15
16
17
# File 'lib/flammarion/engraving.rb', line 15

def actions
  @actions
end

#callbacksObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



16
17
18
# File 'lib/flammarion/engraving.rb', line 16

def callbacks
  @callbacks
end

#on_callback_exceptionObject

Returns the value of attribute on_callback_exception



15
16
17
# File 'lib/flammarion/engraving.rb', line 15

def on_callback_exception
  @on_callback_exception
end

#on_connectObject

Returns the value of attribute on_connect



15
16
17
# File 'lib/flammarion/engraving.rb', line 15

def on_connect
  @on_connect
end

#on_disconnectObject

Returns the value of attribute on_disconnect



15
16
17
# File 'lib/flammarion/engraving.rb', line 15

def on_disconnect
  @on_disconnect
end

#socketsObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



16
17
18
# File 'lib/flammarion/engraving.rb', line 16

def sockets
  @sockets
end

Instance Method Details

#alert(text) ⇒ Object

Pops up an alert message containing text.



72
73
74
# File 'lib/flammarion/engraving.rb', line 72

def alert(text)
  send_json(action:'alert', text:text)
end

#closeObject

Attempts to close the window.



90
91
92
# File 'lib/flammarion/engraving.rb', line 90

def close
  send_json({action:'close'})
end

#disconnect(ws) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



133
134
135
136
137
# File 'lib/flammarion/engraving.rb', line 133

def disconnect(ws)
  @sockets.delete ws
  exit 0 if @exit_on_disconnect
  @on_disconnect.call if @on_disconnect
end

#get_save_pathObject

Opens a native “Save File” Dialog box, prompting the user for a file.



95
96
97
98
99
100
101
# File 'lib/flammarion/engraving.rb', line 95

def get_save_path
  if Gem.win_platform?
    `powershell "Add-Type -AssemblyName System.windows.forms|Out-Null;$f=New-Object System.Windows.Forms.SaveFileDialog;$f.InitialDirectory='%cd%';$f.Filter='All Files (*.*)|*.*';$f.showHelp=$true;$f.ShowDialog()|Out-Null;$f.FileName"`.strip
  else
    `zenity --file-selection --save --confirm-overwrite`.strip
  end
end

#layout(file) ⇒ Object

Allows you to load a custom layout file. This replaces all html in the window with a custom slim layout. You probably don't want this unless your writing a very complex application.



122
123
124
125
# File 'lib/flammarion/engraving.rb', line 122

def layout(file)
  data = Slim::Template.new(file).render
  send_json({action:'layout', data:data})
end

#live_reload_layout(file) ⇒ Object



127
128
129
130
# File 'lib/flammarion/engraving.rb', line 127

def live_reload_layout(file)
  layout(file); yield if block_given?
  FileWatcher.new(file).watch {|file| layout(file); yield if block_given? }
end

#make_idObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



171
172
173
174
175
# File 'lib/flammarion/engraving.rb', line 171

def make_id
  @id ||= 0
  @id += 1
  "i#{@id}"
end

#orientation=(orientation) ⇒ Object

Changes the orientation of the panes in this engraving. Options are

  • :horizontal

  • :vertical

Raises:

  • (ArgumentError)


79
80
81
82
# File 'lib/flammarion/engraving.rb', line 79

def orientation=(orientation)
  raise ArgumentError.new("Orientation must be :horizontal or :vertical") unless [:horizontal, :vertical].include?(orientation)
  send_json({action:'reorient', orientation:orientation})
end

#process_message(msg) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



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
# File 'lib/flammarion/engraving.rb', line 140

def process_message(msg)
  @last_msg = msg
  m = {}
  begin
    m = JSON.parse(msg)
  rescue JSON::ParserError
    log "Invalid JSON String"
    return
  end

  case m["action"]
  when 'callback'
    callback = @callbacks[m['id']]
    unless callback.nil?
      if callback.arity == 1
        callback.call(m)
      else
        callback.call
      end
    end
  end
  @actions[m["action"]].call(m) if @actions.include?(m["action"])
rescue Exception
  if @on_callback_exception then
    @on_callback_exception.call($!)
  else
    raise
  end
end

#send_json(val) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



186
187
188
189
190
191
192
193
# File 'lib/flammarion/engraving.rb', line 186

def send_json(val)
  if @sockets.empty? then
    open_a_window
    wait_for_a_connection
  end
  @sockets.each{|ws| ws.send val.to_json}
  nil
end

#serverObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



183
# File 'lib/flammarion/engraving.rb', line 183

def server; @@server; end

#snapshot(&block) ⇒ Object

Currently only works with Electron. Returns a PNG image of the Engraving



104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/flammarion/engraving.rb', line 104

def snapshot(&block)
  if block_given?
    id = make_id
    callbacks[id] = Proc.new {|d| block.call(d.fetch('data', {}).fetch('data', []).pack('c*')) }
    send_json(action:'snapshot', id: id)
  else
    return_value = nil
    snapshot {|d| return_value = d}
    Timeout.timeout(10) do
      sleep(0.01) until return_value
    end
    return return_value
  end
end

#start_serverObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



178
179
180
# File 'lib/flammarion/engraving.rb', line 178

def start_server
  @@server ||= Server.new
end

#title(str) ⇒ Object

Sets the title of the window



85
86
87
# File 'lib/flammarion/engraving.rb', line 85

def title(str)
  send_json({action:'title', title:str})
end

#wait_until_closedObject

Blocks the current thread until the window has been closed. All user interactions and callbacks will continue in other threads.



62
63
64
# File 'lib/flammarion/engraving.rb', line 62

def wait_until_closed
  sleep 1 until @sockets.empty?
end

#window_open?Boolean

Is this Engraving displayed on the screen.

Returns:

  • (Boolean)


67
68
69
# File 'lib/flammarion/engraving.rb', line 67

def window_open?
  not @sockets.empty?
end