AndyObtiva/glimmer-dsl-swt

View on GitHub
samples/hello/hello_refined_table.rb

Summary

Maintainability
B
4 hrs
Test Coverage
# Copyright (c) 2007-2024 Andy Maleh
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

require 'glimmer-dsl-swt'
require 'date'

class HelloRefinedTable
  BaseballTeam = Struct.new(:name, :town, :ballpark, keyword_init: true) do
    class << self
      def all
        @all ||= [
          {town: 'Chicago', name: 'White Sox', ballpark: 'Guaranteed Rate Field'},
          {town: 'Cleveland', name: 'Indians', ballpark: 'Progressive Field'},
          {town: 'Detroit', name: 'Tigers', ballpark: 'Comerica Park'},
          {town: 'Kansas City', name: 'Royals', ballpark: 'Kauffman Stadium'},
          {town: 'Minnesota', name: 'Twins', ballpark: 'Target Field'},
          {town: 'Baltimore', name: 'Orioles', ballpark: 'Oriole Park at Camden Yards'},
          {town: 'Boston', name: 'Red Sox', ballpark: 'Fenway Park'},
          {town: 'New York', name: 'Yankees', ballpark: 'Comerica Park'},
          {town: 'Tampa Bay', name: 'Rays', ballpark: 'Tropicana Field'},
          {town: 'Toronto', name: 'Blue Jays', ballpark: 'Rogers Centre'},
          {town: 'Houston', name: 'Astros', ballpark: 'Minute Maid Park'},
          {town: 'Los Angeles', name: 'Angels', ballpark: 'Angel Stadium'},
          {town: 'Oakland', name: 'Athletics', ballpark: 'RingCentral Coliseum'},
          {town: 'Seattle', name: 'Mariners', ballpark: 'T-Mobile Park'},
          {town: 'Texas', name: 'Rangers', ballpark: 'Globe Life Field'},
          {town: 'Chicago', name: 'Cubs', ballpark: 'Wrigley Field'},
          {town: 'Cincinnati', name: 'Reds', ballpark: 'Great American Ball Park'},
          {town: 'Milwaukee', name: 'Brewers', ballpark: 'American Family Field'},
          {town: 'Pittsburgh', name: 'Pirates', ballpark: 'PNC Park'},
          {town: 'St. Louis', name: 'Cardinals', ballpark: 'Busch Stadium'},
          {town: 'Atlanta', name: 'Braves', ballpark: 'Truist Park'},
          {town: 'Miami', name: 'Marlins', ballpark: 'LoanDepot Park'},
          {town: 'New York', name: 'Mets', ballpark: 'Citi Field'},
          {town: 'Philadelphia', name: 'Phillies', ballpark: 'Citizens Bank Park'},
          {town: 'Washington', name: 'Nationals', ballpark: 'Nationals Park'},
          {town: 'Arizona', name: 'Diamondbacks', ballpark: 'Chase Field'},
          {town: 'Colorado', name: 'Rockies', ballpark: 'Coors Field'},
          {town: 'Los Angeles', name: 'Dodgers', ballpark: 'Dodger Stadium'},
          {town: 'San Diego', name: 'Padres', ballpark: 'Petco Park'},
          {town: 'San Francisco', name: 'Giants', ballpark: 'Oracle Park'},
        ].map {|team_kwargs| new(team_kwargs)}
      end
      
      def all_team_names
        @all_team_names ||= BaseballTeam.all.map {|t| t[:name]}
      end
    end
    
    def complete_name
      "#{town} #{name}"
    end
  end
    
  BaseballGame = Struct.new(:date, :home_team, :away_team, keyword_init: true) do
    def home_team_name
      home_team.complete_name
    end
    
    def home_team_name=(new_name)
      new_home_team = BaseballTeam.all.find {|t| t[:name] == new_name}
      self.home_team = new_home_team if new_home_team
    end
    
    def home_team_name_options
      BaseballTeam.all_team_names
    end
    
    def away_team_name
      away_team.complete_name
    end
    
    def away_team_name=(new_name)
      new_away_team = BaseballTeam.all.find {|t| t[:name] == new_name}
      self.away_team = new_away_team if new_away_team
    end
    
    def away_team_name_options
      BaseballTeam.all_team_names
    end
    
    def ballpark
      home_team.ballpark
    end
    
    def date=(new_date)
      self['date'] = new_date.respond_to?(:to_date) ? new_date.to_date : new_date
    end
    
    def to_s
      "#{home_team_name} vs #{away_team_name} at #{ballpark}"
    end
  end
  
  BaseballSeason = Struct.new(:year) do
    attr_accessor :selected_game
    attr_writer :games
  
    def games
      if @games.nil?
        @games = []
        baseball_team_combinations = BaseballTeam.all.combination(2).to_a
        current_day = first_day
        day_offset = 0
        begin
          if (day_offset % 7 != 6)
            day_games = []
            half_teams_count = BaseballTeam.all.count / 2
            while day_games.uniq.count < half_teams_count
              baseball_team_pair = baseball_team_combinations.sample
              teams_played_so_far = day_games.map {|game| [game.home_team, game.away_team]}.flatten
              unless teams_played_so_far.include?(baseball_team_pair.first) || teams_played_so_far.include?(baseball_team_pair.last)
                baseball_game = BaseballGame.new(
                  date: current_day,
                  home_team: baseball_team_pair.first,
                  away_team: baseball_team_pair.last,
                )
                day_games << baseball_game
                @games << baseball_game
              end
            end
          end
          day_offset += 1
          current_day += 1
        end while current_day != first_day_of_playoffs
      end
      @games
    end
    
    def first_day
      @first_day ||= Date.new(year, 04, 01)
    end
    
    def first_day_of_playoffs
      @last_day ||= Date.new(year, 10, 01)
    end
  end
  
  include Glimmer::UI::Application
  
  before_body do
    @baseball_season = BaseballSeason.new(Time.now.year)
  end

  body {
    shell {
      text 'Hello, Refined Table!'
    
      refined_table(:editable, :border, per_page: 20) { # also `page: 1` by default
        table_column {
          width 100
          text 'Date'
          editor :date_drop_down
        }
        table_column {
          width 200
          text 'Ballpark'
          editor :none
        }
        table_column {
          width 150
          text 'Home Team'
          editor :combo, :read_only # read_only is simply an SWT style passed to combo widget
        }
        table_column {
          width 150
          text 'Away Team'
          editor :combo, :read_only # read_only is simply an SWT style passed to combo widget
        }
        
        menu {
          menu_item {
            text 'Book'
            
            on_widget_selected do
              message_box {
                text 'Game Booked!'
                message "The game \"#{@baseball_season.selected_game}\" has been booked!"
              }.open
            end
          }
        }
        
        model_array <=> [@baseball_season, :games, column_attributes: {'Home Team' => :home_team_name, 'Away Team' => :away_team_name}]
        selection <=> [@baseball_season, :selected_game]
      }
    }
  }

end

HelloRefinedTable.launch