AndyObtiva/glimmer-dsl-tk

View on GitHub
lib/glimmer/tk/scrollbar_frame_proxy.rb

Summary

Maintainability
B
4 hrs
Test Coverage
# Copyright (c) 2020-2022 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/tk/widget_proxy'

module Glimmer
  module Tk
    # Scrolledframe (#scrolledframe_tk attribute)
    # Nested widgets go into the child site (#tk attribute or @scrolledframe_tk.child_site)
    class ScrollbarFrameProxy < WidgetProxy
      attr_reader :original_parent_proxy, :container_frame_proxy, :canvas_proxy, :yscrollbar_proxy, :xscrollbar_proxy
      
      def post_add_content
        @tk.bind('Configure') {
          @canvas_proxy.tk.scrollregion(@canvas_proxy.tk.bbox("all"))
        }
        @canvas_proxy.tk.yscrollcommand {|*args| @yscrollbar_proxy&.set(*args)}
        @canvas_proxy.tk.xscrollcommand {|*args| @xscrollbar_proxy&.set(*args)}
      end
      
      def has_attribute?(attribute, *args)
        case attribute.to_s
        when 'yscrollbar', 'xscrollbar'
          true
        else
          container_frame_proxy.has_attribute?(attribute, *args)
        end
      end
      
      def set_attribute(attribute, *args)
        case attribute.to_s
        when 'yscrollbar'
          @yscrollbar = args.first
          if @yscrollbar == true
            build_yscrollbar unless @yscrollbar_proxy
          elsif @yscrollbar.is_a?(Glimmer::Tk::WidgetProxy)
            @yscrollbar_proxy.destroy
            build_yscrollbar(@yscrollbar)
          else
            @yscrollbar_proxy.destroy
            @yscrollbar_proxy = nil
          end
        when 'xscrollbar'
          @xscrollbar = args.first
          if @xscrollbar == true
            build_xscrollbar unless @xscrollbar_proxy
          elsif @xscrollbar.is_a?(Glimmer::Tk::WidgetProxy)
            @xscrollbar_proxy.destroy
            build_xscrollbar(@xscrollbar)
          else
            @xscrollbar_proxy.destroy
            @xscrollbar_proxy = nil
          end
        else
          container_frame_proxy.set_attribute(attribute, *args)
        end
      end
      
      def get_attribute(attribute, *args)
        case attribute.to_s
        when 'show_yscrollbar'
          @yscrollbar
        when 'show_xscrollbar'
          @xscrollbar
        else
          container_frame_proxy.get_attribute(attribute, *args)
        end
      end
      
      private
      
      def griddable_parent_proxy
        @original_parent_proxy
      end
      
      def griddable_proxy
        @container_frame_proxy
      end

      def build_widget
        @original_parent_proxy = @parent_proxy
        @container_frame_proxy = WidgetProxy.new('frame', @parent_proxy, @args)
        @parent_proxy = @canvas_proxy = WidgetProxy.new('canvas', @container_frame_proxy, [{width: 300, height: 300}])
        @canvas_proxy.grid(row: 0, column: 0, row_weight: 1, column_weight: 1)
        build_yscrollbar
        build_xscrollbar
        tk_widget_class = self.class.tk_widget_class_for('frame')
        @tk = tk_widget_class.new(@canvas_proxy.tk, *args).tap {|tk| tk.singleton_class.include(Glimmer::Tk::Widget); tk.proxy = self}
        TkcWindow.new(@canvas_proxy.tk, 0, 0, :anchor => "nw", :window => @tk)
      end
      
      def build_yscrollbar(scrollbar_widget_proxy = nil)
        @yscrollbar_proxy = scrollbar_widget_proxy || WidgetProxy.new('scrollbar', @container_frame_proxy, [])
        @yscrollbar_proxy.orient = 'vertical'
        @yscrollbar_proxy.grid(row: 0, column: 1) unless scrollbar_widget_proxy
        @yscrollbar_proxy.command {|*args| @canvas_proxy.tk.yview(*args)}
      end
      
      def build_xscrollbar(scrollbar_widget_proxy = nil)
        @xscrollbar_proxy = scrollbar_widget_proxy || WidgetProxy.new('scrollbar', @container_frame_proxy, [])
        @xscrollbar_proxy.orient = 'horizontal'
        @xscrollbar_proxy.grid(row: 1, column: 0, column_span: 2, row_weight: 0) unless scrollbar_widget_proxy
        @xscrollbar_proxy.command {|*args| @canvas_proxy.tk.xview(*args)}
      end
      
      def initialize_defaults
        options = {}
        options[:sticky] = 'nsew'
        options[:column_weight] = 1 if @original_parent_proxy.children.count == 1
        options[:row_weight] = 1 if @original_parent_proxy.children.count == 1
        grid(options)
      end
    end
  end
end