SWT 캔버스 경로 DSL용 Glimmer DSL
다른 명령형 그래프 GUI 라이브러리와 달리 Glimmer는 경로의 선언적 생성을 용이하게 합니다. 즉, move_to, curve_to 등을 명시적으로 사용할 필요가 없습니다. (SWT 을 통해 직접 가능하더라도) 대신
path
, point
와 같은 명사를 통해 경로를 명확하고 간결하게 선언해야 합니다. line
, quad
및 cubic
, 따라서 더 높은 코드 이해성, 유지 관리성 및 생산성을 가능하게 합니다.# From: https://github.com/AndyObtiva/glimmer-dsl-swt/blob/development/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md#canvas-path-dsl
require 'glimmer-dsl-swt'
include Glimmer
shell {
text 'Canvas Path Example'
minimum_size 300, 300
canvas {
path {
foreground :black
250.times {|n|
cubic(n + n%30, n+ n%50, 40, 40, 70, 70, n + 20 + n%30, n%30*-1 * n%50)
}
}
}
}.open
실제로 새로운Glimmer DSL for SWT 기능을 시연하기 위해 두 개의 새로운 샘플이 Canvas Path DSL에 추가되었습니다.
Hello, Canvas Path!
# From: https://github.com/AndyObtiva/glimmer-dsl-swt/blob/development/docs/reference/GLIMMER_SAMPLES.md#hello-canvas-path
require 'glimmer-dsl-swt'
include Glimmer
shell {
text 'Hello, Canvas Path!'
minimum_size 800, 700
background :white
canvas {
background :white
text('line', 15, 200) {
foreground :red
}
@path1 = path {
antialias :on
foreground :red
}
text('quad', 15, 300) {
foreground :dark_green
}
@path2 = path {
antialias :on
foreground :dark_green
}
text('cubic', 15, 400) {
foreground :blue
}
@path3 = path {
antialias :on
foreground :blue
}
}
on_swt_show {
Thread.new {
y1 = y2 = y3 = 300
800.times.each do |x|
x += 55
x1 = x - 2
x2 = x - 1
x3 = x
y1 = y3
y2 = y1
y3 = [[y3 + (rand*24 - 12), 0].max, 700].min
@path1.content {
line(x1, y1 - 100)
}
if x % 2 == 0
@path2.content {
quad(x1, y1, x2, y2)
}
end
if x % 3 == 0
@path3.content {
cubic(x1, y1 + 100, x2, y2 + 100, x3, y3 + 100)
}
end
sleep(0.01)
end
}
}
}.open
Stock Ticker
# From: https://github.com/AndyObtiva/glimmer-dsl-swt/blob/development/docs/reference/GLIMMER_SAMPLES.md#stock-ticker
require 'glimmer-dsl-swt'
# This Sample is an Early Alpha (New Canvas Path DSL Feature)
class StockTicker
class Stock
class << self
attr_writer :stock_price_min, :stock_price_max
def stock_price_min
@stock_price_min ||= 1
end
def stock_price_max
@stock_price_max ||= 600
end
end
attr_reader :name, :stock_prices
attr_accessor :stock_price
def initialize(name, stock_price)
@name = name
@stock_price = stock_price
@stock_prices = [@stock_price]
@delta_sign = 1
start_new_trend!
end
def tick!
@tick_count = @tick_count.to_i + 1
delta = @tick_count%@trend_length
if delta == 0
@delta_sign *= -1
start_new_trend!
end
stock_prices << self.stock_price = [[@stock_price + @delta_sign*delta, Stock.stock_price_min].max, Stock.stock_price_max].min
end
def start_new_trend!
@trend_length = (rand*12).to_i + 1
end
end
include Glimmer::UI::CustomShell
before_body {
@stocks = [
Stock.new('DELL', 81),
Stock.new('AAPL', 121),
Stock.new('MSFT', 232),
Stock.new('ADBE', 459),
]
@stock_colors = [:red, :dark_green, :blue, :dark_magenta]
max_stock_name_width = 0
left_margin = 5
@tabs = ['Lines', 'Quadratic Bezier Curves', 'Cubic Bezier Curves', 'Points'].map {|title| {title: title, stock_paths: [], stock_transforms: []}}
@stocks.each_with_index do |stock, stock_index|
observe(stock, :stock_price) do |new_price|
begin
@tabs.each do |tab|
new_x = stock.stock_prices.count - 1
new_y = @tabs.first[:canvas].bounds.height - new_price - 1
max_stock_name_width = tab[:text]&.bounds&.width if tab[:text]&.bounds&.width.to_f > max_stock_name_width
if new_x > 0
case tab[:title]
when 'Cubic Bezier Curves'
if new_x%3 == 0 && stock.stock_prices[new_x] && stock.stock_prices[new_x - 1] && stock.stock_prices[new_x - 2]
tab[:stock_paths][stock_index].content {
cubic(new_x - 2, @tabs.first[:canvas].bounds.height - stock.stock_prices[new_x - 2] - 1, new_x - 1, @tabs.first[:canvas].bounds.height - stock.stock_prices[new_x - 1] - 1, new_x, new_y)
tab[:stock_transforms][stock_index] ||= transform {
translate max_stock_name_width + 5 + left_margin, tab[:text].bounds.height / 2.0
}
}
end
when 'Quadratic Bezier Curves'
if new_x%2 == 0 && stock.stock_prices[new_x] && stock.stock_prices[new_x - 1]
tab[:stock_paths][stock_index].content {
quad(new_x - 1, @tabs.first[:canvas].bounds.height - stock.stock_prices[new_x - 1] - 1, new_x, new_y)
tab[:stock_transforms][stock_index] ||= transform {
translate max_stock_name_width + 5 + left_margin, tab[:text].bounds.height / 2.0
}
}
end
when 'Lines'
tab[:stock_paths][stock_index].content {
line(new_x, new_y)
tab[:stock_transforms][stock_index] ||= transform {
translate max_stock_name_width + 5 + left_margin, tab[:text].bounds.height / 2.0
}
}
when 'Points'
tab[:stock_paths][stock_index].content {
point(new_x, new_y)
tab[:stock_transforms][stock_index] ||= transform {
translate max_stock_name_width + 5 + left_margin, tab[:text].bounds.height / 2.0
}
}
end
new_x_location = new_x + max_stock_name_width + 5 + left_margin + 5
canvas_width = tab[:canvas].bounds.width
if new_x_location > canvas_width
tab[:canvas].set_size(new_x_location, @tabs.first[:canvas].bounds.height)
tab[:canvas].cursor = :hand
tab[:scrolled_composite].set_min_size(new_x_location, @tabs.first[:canvas].bounds.height)
tab[:scrolled_composite].set_origin(tab[:scrolled_composite].origin.x + 1, tab[:scrolled_composite].origin.y) if (tab[:scrolled_composite].origin.x + tab[:scrolled_composite].client_area.width) == canvas_width
end
else
tab[:canvas].content {
tab[:text] = text(stock.name, new_x + left_margin, new_y) {
foreground @stock_colors[stock_index]
}
}
end
end
rescue => e
Glimmer::Config.logger.error {e.full_message}
end
end
end
}
after_body {
@thread = Thread.new {
loop {
@stocks.each(&:tick!)
sleep(0.01)
}
}
}
body {
shell {
fill_layout {
margin_width 15
margin_height 15
}
text 'Stock Ticker'
minimum_size 650, 650
background :white
@tab_folder = tab_folder {
@tabs.each do |tab|
tab_item {
fill_layout {
margin_width 0
margin_height 0
}
text tab[:title]
tab[:scrolled_composite] = scrolled_composite {
tab[:canvas] = canvas {
background :white
@stocks.count.times do |stock_index|
tab[:stock_paths][stock_index] = path {
antialias :on
foreground @stock_colors[stock_index]
}
end
on_mouse_down {
@drag_detected = false
}
on_drag_detected { |drag_detect_event|
@drag_detected = true
@drag_start_x = drag_detect_event.x
@drag_start_y = drag_detect_event.y
}
on_mouse_move { |mouse_event|
if @drag_detected
origin = tab[:scrolled_composite].origin
new_x = origin.x - (mouse_event.x - @drag_start_x)
new_y = origin.y - (mouse_event.y - @drag_start_y)
tab[:scrolled_composite].set_origin(new_x, new_y)
end
}
on_mouse_up { |mouse_event|
@drag_detected = false
}
}
}
}
end
}
on_swt_show {
Stock.stock_price_min = 25
Stock.stock_price_max = @tabs.first[:canvas].bounds.height - 6
# pre-initialize all tabs by selecting them so that they render content when they are later in the background
@tab_folder.items.each do |item|
@tab_folder.selection = item
end
@tab_folder.selection = @tab_folder.items.first
}
on_widget_disposed {
@thread.kill # safe to kill as data is in memory only
}
}
}
end
StockTicker.launch
크로스 플랫폼 데스크탑 응용 프로그램을 구축할 때 Glimmer DSL for SWT보다 더 생산적인 것은 없습니다! 그리고 매일 더 좋아지고 있습니다. Glimmer DSL for SWT을 읽고 개선을 위한 피드백을 보고하면서 자신만의 앱을 구축하여 오늘 학습Glimmer blog posts을 시작하십시오. 이제 Ruby 이 웹뿐만 아니라 데스크톱 개발을 위한 세계 최고의 언어가 될 때가 되었습니다.
해피Glimmering !
Reference
이 문제에 관하여(SWT 캔버스 경로 DSL용 Glimmer DSL), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/andyobtiva/glimmer-dsl-for-swt-canvas-path-dsl-3693텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)