SWT 캔버스 경로 DSL용 Glimmer DSL

42874 단어 guidesktoprubydsl
Glimmer DSL for SWT은 v4.18.6.0과 후속 v4.18.6.1에서 비교적 주요 릴리스를 통해 Canvas Path DSL이라는 새로운 Sub-DSL을 도입했습니다. 이를 통해 다음으로 구성된 경로를 만들 수 있습니다.
  • 포인트
  • 라인
  • 2차 베지어 곡선
  • 큐빅 베지어 곡선

  • 다른 명령형 그래프 GUI 라이브러리와 달리 Glimmer는 경로의 선언적 생성을 용이하게 합니다. 즉, move_to, curve_to 등을 명시적으로 사용할 필요가 없습니다. (SWT 을 통해 직접 가능하더라도) 대신 path , point 와 같은 명사를 통해 경로를 명확하고 간결하게 선언해야 합니다. line , quadcubic , 따라서 더 높은 코드 이해성, 유지 관리성 및 생산성을 가능하게 합니다.

    # 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 !

    좋은 웹페이지 즐겨찾기