DEV Community

Andy Maleh
Andy Maleh

Posted on

Glimmer DSL for SWT File Drag and Drop

The Hello, Drag and Drop! sample included in Glimmer DSL for SWT has been enhanced with various different types of drag and drop in v4.21.2.2, including File Drag and Drop (files coming from outside the application).

drag and drop video

# From: https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/docs/reference/GLIMMER_SAMPLES.md#hello-drag-and-drop

require 'glimmer-dsl-swt'

class Location
  attr_accessor :country

  def country_options
    %w[USA Canada Mexico Columbia UK Australia Germany Italy Spain]
  end
end

@location = Location.new

include Glimmer

shell {
  text 'Hello, Drag and Drop!'

  tab_folder {
    tab_item {
      fill_layout
      text 'List'

      list {
        selection <=> [@location, :country]

        # Option 1: Automatic Drag Data Setting
        drag_source true

        # Option 2: Manual Drag Data Setting
#         on_drag_set_data do |event|
#           drag_widget = event.widget.control
#           event.data = drag_widget.selection.first
#         end

        # Option 3: Full Customization of Drag Source (details at:  https://www.eclipse.org/articles/Article-SWT-DND/DND-in-SWT.html)
#         drag_source(:drop_copy) { # options: :drop_copy, :drop_link, :drop_move, :drop_target_move
#           transfer :text # options: :text, :file, :rtf
#
#           on_drag_start do |event|
#             drag_widget = event.widget.control.data('proxy') # obtain Glimmer widget proxy since it permits nicer syntax for setting cursor via symbol
#             drag_widget.cursor = :wait
#           end
#
#           on_drag_set_data do |event|
#             drag_widget = event.widget.control
#             event.data = drag_widget.selection.first
#           end
#
#           on_drag_finished do |event|
#             drag_widget = event.widget.control.data('proxy') # obtain Glimmer widget proxy since it permits nicer syntax for setting cursor via symbol
#             drag_widget.cursor = :arrow
#           end
#         }
      }

      list {
        # Option 1: Automatic Drop Data Consumption
        drop_target true
#         drop_target :unique # setting drop_target to :unique makes the list not add the same data twice

        # Option 2: Manual Drop Data Consumption
#         on_drop do |event|
#           drop_widget = event.widget.control
#           drop_widget.add(event.data)
#           drop_widget.select(drop_widget.items.count - 1)
#         end

        # Option 3: Full Customization of Drop Target (details at:  https://www.eclipse.org/articles/Article-SWT-DND/DND-in-SWT.html)
#         drop_target(:drop_copy) { # options: :drop_copy, :drop_link, :drop_move, :drop_target_move
#           transfer :text # options: :text, :file, :rtf
#
#           on_drag_enter do |event|
#             ### event.detail = DND::DROP_NONE # To reject a drop, you can set event.detail to DND::DROP_NONE
#             drop_widget = event.widget.control.data('proxy') # obtain Glimmer widget proxy since it permits nicer syntax for setting background via symbol
#             drop_widget.background = :red
#           end
#
#           on_drag_leave do |event|
#             drop_widget = event.widget.control.data('proxy') # obtain Glimmer widget proxy since it permits nicer syntax for setting background via symbol
#             drop_widget.background = :white
#           end
#
#           on_drop do |event|
#             drop_widget = event.widget.control.data('proxy') # obtain Glimmer widget proxy since it permits nicer syntax for setting background/cursor via symbol
#             drop_widget.background = :white
#             drop_widget.add(event.data)
#             drop_widget.select(drop_widget.items.count - 1)
#             drop_widget.cursor = :arrow
#           end
#         }
      }
    }

    tab_item {
      grid_layout 2, true
      text 'Label'

      label {
        layout_data {
          horizontal_span 2
        }
        text 'Drag text from any label and drop it unto another label'
      }

      {
        Argentina: :green,
        Brazil: :red,
        Finland: :yellow,
        Sweden: :magenta,
        Denmark: :gray,
        Iceland: :cyan
      }.each do |country, color|
        label {
          layout_data :fill, :fill, true, true
          text country
          font height: 20
          background color
          drag_source true
          drop_target true
        }
      end
    }

    tab_item {
      grid_layout 2, true
      text 'Text'

      label {
        text 'Drag'
      }

      label {
        text 'Drop To Insert'
      }

      text {
        layout_data :fill, :center, true, false
        text 'Text1'
        drag_source true
      }

      text {
        layout_data :fill, :center, true, false
        text 'Drop To Insert'
        drop_target true
      }

      label {
        text 'Drag'
      }

      label {
        text 'Drop To Replace'
      }

      text {
        layout_data :fill, :center, true, false
        text 'Text2'
        drag_source true
      }

      text {
        layout_data :fill, :center, true, false
        text 'Drop To Replace'
        drop_target :replace
      }
    }

    tab_item {
      grid_layout 2, true
      text 'Spinner'

      label {
        text 'Drag'
      }

      label {
        text 'Drop To Insert'
      }

      spinner {
        layout_data :fill, :center, true, false
        selection 30
        drag_source true
      }

      spinner {
        layout_data :fill, :center, true, false
        drop_target true
      }
    }
    tab_item {
      fill_layout
      text 'File'

      @drop_zone_label = label(:center, :wrap) {
        text 'Drop One File Or More Here'
        background :white

        rectangle  {
          foreground :black
          line_width 4
          line_style :dash
        }

        drop_target(:drop_copy) {
          transfer :file

          on_drag_enter do |event|
            drop_widget = event.widget.control.data('proxy') # obtain Glimmer widget proxy since it permits nicer syntax for setting background via symbol
            drop_widget.background = :yellow
          end

          on_drag_leave do |event|
            drop_widget = event.widget.control.data('proxy') # obtain Glimmer widget proxy since it permits nicer syntax for setting background via symbol
            drop_widget.background = :white
          end

          on_drop do |event|
            drop_widget = event.widget.control.data('proxy') # obtain Glimmer widget proxy since it permits nicer syntax for setting background/cursor via symbol
            drop_widget.background = :white
            @drop_zone_label.text = event.data.to_a.join("\n")
          end
        }
      }
    }
  }
}.open
Enter fullscreen mode Exit fullscreen mode

Happy Glimmering!

Discussion (0)