Skip to content

Commit

Permalink
Merge branch 'master' of github.com:shoes/shoes4 into right_and_bottom
Browse files Browse the repository at this point in the history
  • Loading branch information
PragTob committed Apr 13, 2014
2 parents 7f30acc + b00fcfa commit 552169e
Show file tree
Hide file tree
Showing 34 changed files with 866 additions and 326 deletions.
3 changes: 2 additions & 1 deletion lib/shoes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ def gem(name)
require 'shoes/check_button'
require 'shoes/dsl'
require 'shoes/text'
require 'shoes/span'
require 'shoes/input_box'

# please keep this list tidy and alphabetically sorted
Expand All @@ -101,6 +102,7 @@ def gem(name)
require 'shoes/key_event'
require 'shoes/line'
require 'shoes/link'
require 'shoes/link_hover'
require 'shoes/list_box'
require 'shoes/logger'
require 'shoes/manual'
Expand All @@ -112,7 +114,6 @@ def gem(name)
require 'shoes/shape'
require 'shoes/slot_contents'
require 'shoes/slot'
require 'shoes/span'
require 'shoes/star'
require 'shoes/sound'
require 'shoes/text_block'
Expand Down
73 changes: 56 additions & 17 deletions lib/shoes/download.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
class Shoes
class Download

attr_reader :progress, :content_length, :gui
attr_reader :progress, :response, :content_length, :gui, :transferred, :length #length is preserved for Shoes3 compatibility
UPDATE_STEPS = 100

def initialize app, parent, url, args, &blk
def initialize(app, parent, url, opts = {}, &blk)
@opts = opts
@blk = blk
@gui = Shoes.configuration.backend_for(self)
start_download args, url
@finished = false
@transferred = 0
start_download url
end

def started?
Expand All @@ -16,41 +20,76 @@ def started?
def finished?
@finished
end

#join_thread is needed for the specs
def join_thread
@thread.join
end

def percent
@transferred * 100 / @content_length
end

def abort
@thread.exit if @thread
end

private
def start_download args, url
def start_download(url)
require 'open-uri'
@thread = Thread.new do
options = {content_length_proc: lambda { |length| download_started(length) },
progress_proc: lambda { |size| @progress = size }}
open url, options do |download|
uri_opts = {}
uri_opts[:content_length_proc] = content_length_proc
uri_opts[:progress_proc] = progress_proc if @opts[:progress]

open url, uri_opts do |download|
download_data = download.read
save_to_file(args[:save], download_data) if args[:save]
save_to_file(@opts[:save], download_data) if @opts[:save]
finish_download download_data
end
end
end

def content_length_proc
lambda do |content_length|
download_started(content_length)
eval_block(@opts[:progress], self) if @opts[:progress]
end
end

def progress_proc
lambda do |size|
if (size - self.transferred) > (content_length / UPDATE_STEPS) && !@gui.busy?
@gui.busy = true
eval_block(@opts[:progress], self)
@transferred = size
end
end
end

def finish_download download_data
def finish_download(download_data)
@finished = true
result = StringIO.new(download_data)
eval_block(result) if @blk
@response = StringIO.new(download_data)

#In case final asyncEvent didn't catch the 100%
@transferred = @content_length
eval_block(@opts[:progress], self) if @opts[:progress]

#:finish and block are the same
eval_block(@blk, self) if @blk
eval_block(@opts[:finish], self) if @opts[:finish]
end

def eval_block(result)
@gui.eval_block(result, @blk)
def eval_block(blk, result)
@gui.eval_block(blk, result)
end

def save_to_file file_path, download_data
def save_to_file(file_path, download_data)
open(file_path, 'wb') { |fw| fw.print download_data }
end

def download_started(length)
@content_length = length
def download_started(content_length)
@length = content_length
@content_length = content_length
@started = true
end
end
Expand Down
13 changes: 10 additions & 3 deletions lib/shoes/dsl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ def style_for_element(klass, styles = {})
@__app__.element_styles.fetch(klass, {}).merge(styles)
end

def normalize_style_for_element(clazz, texts)
style = style_normalizer.normalize(pop_style(texts))
style_for_element(clazz, style)
end

def create(element, *args, &blk)
element.new(@__app__, @__app__.current_slot, *args, &blk)
end
Expand Down Expand Up @@ -389,11 +394,13 @@ def bg(*texts, color)
end

def link(*texts, &blk)
Shoes::Link.new texts, &blk
opts = normalize_style_for_element(Shoes::Link, texts)
create Shoes::Link, texts, opts, &blk
end

def span(*texts)
Shoes::Span.new texts, style_normalizer.normalize(pop_style(texts))
opts = normalize_style_for_element(Shoes::Span, texts)
Shoes::Span.new texts, opts
end

def mouse
Expand All @@ -403,7 +410,7 @@ def mouse
def motion(&blk)
@__app__.mouse_motion << blk
end

def resize(&blk)
@__app__.add_resize_callback blk
end
Expand Down
39 changes: 30 additions & 9 deletions lib/shoes/link.rb
Original file line number Diff line number Diff line change
@@ -1,16 +1,37 @@
class Shoes
class Link < Text
def initialize texts, color=nil, &blk
class Link < Span
attr_reader :app, :parent, :gui

DEFAULT_OPTS = { underline: true, fg: ::Shoes::COLORS[:blue] }

def initialize(app, parent, texts, opts={}, &blk)
@app = app
@parent = parent
setup_block(blk, opts)

opts = DEFAULT_OPTS.merge(opts)
@gui = Shoes.backend_for(self, opts)

super texts, opts
end

def setup_block(blk, opts)
if blk
@blk = blk
elsif opts.include?(:click)
# Slightly awkward, but we need App, not InternalApp, to call visit
@blk = Proc.new { app.app.visit(opts[:click]) }
end
end

def click(&blk)
@blk = blk
super texts, color
self
end
attr_reader :blk
attr_accessor :click_listener, :line_height, :start_x, :start_y,
:end_x, :end_y, :clickabled,
:parent

def in_bounds?(x, y)
(start_x..end_x).include?(x) and (start_y..end_y).include?(y)
def execute_link
@blk.call
end

end
end
5 changes: 5 additions & 0 deletions lib/shoes/link_hover.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class Shoes
class LinkHover
# Just a placeholder for now until we get this implemented
end
end
1 change: 1 addition & 0 deletions lib/shoes/mock.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
require 'shoes/mock/keypress'
require 'shoes/mock/keyrelease'
require 'shoes/mock/line'
require 'shoes/mock/link'
require 'shoes/mock/list_box'
require 'shoes/mock/oval'
require 'shoes/mock/progress'
Expand Down
11 changes: 11 additions & 0 deletions lib/shoes/mock/link.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class Shoes
module Mock
class Link
include Shoes::Mock::CommonMethods

def initialize(dsl, app, opts = {})
end
end
end
end

2 changes: 1 addition & 1 deletion lib/shoes/span.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ class Shoes
class Span < Text
def initialize(texts, options={})
@opts = options
super texts
super texts, options.delete(:color)
end

def opts
Expand Down
9 changes: 8 additions & 1 deletion lib/shoes/swt.rb
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ def self.display
require 'shoes/swt/key_event'
require 'shoes/swt/key_listener'
require 'shoes/swt/line'
require 'shoes/swt/link'
require 'shoes/swt/list_box'
require 'shoes/swt/mouse_move_listener'
require 'shoes/swt/oval'
Expand All @@ -100,8 +101,14 @@ def self.display
require 'shoes/swt/star'
require 'shoes/swt/sound'
require 'shoes/swt/text_block'
require 'shoes/swt/text_block_fitter'
require 'shoes/swt/timer'

require 'shoes/swt/fitted_text_layout'
require 'shoes/swt/fitted_text_layout_collection'
require 'shoes/swt/text_block_cursor_painter'
require 'shoes/swt/text_block_fitter'
require 'shoes/swt/text_font_factory'
require 'shoes/swt/text_style_factory'

# redrawing aspect needs to know all the classes
require 'shoes/swt/redrawing_aspect'
24 changes: 20 additions & 4 deletions lib/shoes/swt/app.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,13 @@ def quit
def app
self
end

def width
@shell.getVerticalBar.getVisible ? (@shell.client_area.width + @shell.getVerticalBar.getSize.x) : @shell.client_area.width
if overlay_scrollbars?
@shell.client_area.width
else
width_adjusted_for_scrollbars
end
end

def height
Expand All @@ -69,7 +73,7 @@ def redraw(left=nil, top=nil, width=nil, height=nil, all=true)
def main_app?
::Shoes::Swt.main_app.equal? self
end

def flush
if @dsl.top_slot
@real.layout
Expand All @@ -79,7 +83,7 @@ def flush
def scroll_top
@real.getLocation.y
end

def scroll_top=(n)
@real.setLocation 0, -n
@shell.getVerticalBar.setSelection n
Expand Down Expand Up @@ -204,6 +208,18 @@ def attach_real_event_listeners
@real.addMouseListener MouseListener.new(self)
end

def overlay_scrollbars?
@shell.scrollbars_mode == ::Swt::SWT::SCROLLBAR_OVERLAY
end

def width_adjusted_for_scrollbars
if @shell.getVerticalBar.getVisible
@shell.client_area.width + @shell.getVerticalBar.getSize.x
else
@shell.client_area.width
end
end

end

class ShellControlListener
Expand Down
11 changes: 3 additions & 8 deletions lib/shoes/swt/common/clickable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,16 @@ def clickable(object = self, block)
def click(&block)
add_listener_for ::Swt::SWT::MouseDown, block
end

def release(&block)
add_listener_for ::Swt::SWT::MouseUp, block
end

private
def add_listener_for(object = self, event, block)
if object.respond_to? :dsl
dsl_object = object.dsl
else
dsl_object = object
end
listener = ClickListener.new(dsl_object, block)
listener = ClickListener.new(object, block)
object.click_listener = listener
app.add_clickable_element dsl_object
app.add_clickable_element object
app.add_listener event, listener
end

Expand Down
10 changes: 8 additions & 2 deletions lib/shoes/swt/download.rb
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
class Shoes
module Swt
class Download


attr_accessor :busy
def initialize(_dsl)
@busy = false
end

# This exists to guarantee the callback block for download completion
# executes on the main UI thread. Without it we get thread access errors.
def eval_block(result, blk)
def eval_block(blk, result)
::Swt.display.asyncExec do
blk.call result
@busy = false
end
end

def busy?
@busy
end
end
end
end

0 comments on commit 552169e

Please sign in to comment.