Skip to content
Cecil edited this page Dec 11, 2017 · 1 revision

Shoes as we know it is a little graphical toolkit but combined with some wits can seamlessly manage hundreds of elements and events.

Abstract definition

Without further ado here are 2 snippets with the minimum code you need to create simple event management.

Approach 1

Shoes.app do
   stack do
      image "#{DIR}/static/shoes-icon.png"
      click do
         if @clickable
            para "hey"
         end
      end
   end

   button "enable" do
      @clickable = true
   end

   button "disable" do
      @clickable = false
   end

   start do
      @clickable = true
   end
end

Approach 2

Shoes.app do
   @b = proc do
      para "hey"
   end

   @s = stack do
      image "#{DIR}/static/shoes-icon.png"
      click &@b
   end

   button "enable" do
      @s.click &@b
   end

   button "disable" do
      @s.click do; end
   end
end

Practical example

Define the task

Create an application with numerous items that trigger events.
Events interaction can be disabled on demand for one or many groups of objects.

Begin with something small

There are a bunch of pictures in a slot that the user wants to trigger click event drawing a text that specifies the group the pictures are in and its order in the group.

Shoes.app do
	
	@box = edit_box "", left: 50, top: 400, width: 200, height: 50
	@groups = stack left: 0, top: 0, width: 100, height: 300 do
		background green
		image "#{DIR}/static/shoes-icon.png", width: 70 do
			click do 
				@box.text = "Green group, picture 1"
			end				
		end
		image "#{DIR}/static/shoes-icon-blue.png", width: 70 do
			click do 
				@box.text = "Green group, picture 2"
			end
		end
		image "#{DIR}/static/shoes-icon-federales.png", width: 70 do
			click do
				@box.text = "Green group, picture 3"
			end
		end
		image "#{DIR}/static/shoes-icon-red.png", width: 70 do
			click do 
				@box.text = "Green group, picture 4"
			end
		end
	end

end

Try the app. Notice how clicking on each picture change the text in the edit box. The code is a bit repetitive isn't it? Use loop.

Shoes.app do
	
	@box = edit_box "", left: 50, top: 400, width: 200, height: 50
	@group = stack left: 0, top: 0, width: 100, height: 300 do
		background green
		image "#{DIR}/static/shoes-icon.png", width: 70
		image "#{DIR}/static/shoes-icon-blue.png", width: 70
		image "#{DIR}/static/shoes-icon-federales.png", width: 70
		image "#{DIR}/static/shoes-icon-red.png", width: 70
	end
	
	@group.contents[1..-1].each_with_index do |c, i|
		c.click do
			@box.text = "Green group, picture #{i+1}"
		end
	end
	
end

Same simple example, just increase the scale

Same result, easy to read code. Make a second group of similar elements this time with yellow background.

Shoes.app do
	@groups = []
	@box = edit_box "", left: 50, top: 400, width: 200, height: 50
	
	@groups << (stack left: 0, top: 0, width: 100, height: 300 do
		background green
		image "#{DIR}/static/shoes-icon.png", width: 70
		image "#{DIR}/static/shoes-icon-blue.png", width: 70
		image "#{DIR}/static/shoes-icon-federales.png", width: 70
		image "#{DIR}/static/shoes-icon-red.png", width: 70
	end)
	
	@groups << (stack left: 270, top: 0, width: 100, height: 300 do
		background yellow
		image "#{DIR}/static/shoes-icon.png", width: 70
		image "#{DIR}/static/shoes-icon-blue.png", width: 70
		image "#{DIR}/static/shoes-icon-federales.png", width: 70
		image "#{DIR}/static/shoes-icon-red.png", width: 70
	end)
	
	@groups[0].contents[1..-1].each_with_index do |c, i|
		c.click do
			@box.text = "Group Green, picture #{i+1}"
		end
	end
	
	@groups[1].contents[1..-1].each_with_index do |c, i|
		c.click do
			@box.text = " group Yellow, picture #{i+1}"
		end
	end
	
end

It becomes a bit repetitive again. Move the group creating process into a method and loop it. Use a container (@groups) to save the newly created groups. Use similar technique to call them back and set click event. Now we can create as much groups as we want.

Shoes.app do
	@groups = []
	@box = edit_box "", left: 50, top: 400, width: 200, height: 50
	
	def set_group colour, i 
		group = stack left:0 + 120*i, top: 0, width: 100, height: 300 do
			background colour
			image "#{DIR}/static/shoes-icon.png", width: 70
			image "#{DIR}/static/shoes-icon-blue.png", width: 70
			image "#{DIR}/static/shoes-icon-federales.png", width: 70
			image "#{DIR}/static/shoes-icon-red.png", width: 70
		end
		return group
	end
	
	colours = [green, yellow, red, orange ]
	colour_names = ["green", "yellow", "red", "orange" ]
	
	colours.each_with_index do |clr, i|
		@groups << (set_group clr, i)
	end
	
	@groups.each_with_index do |g, i|
		g.contents[1..-1].each_with_index do |c, ii|
		    c.click do
				@box.text = "Group #{colour_names[i]}, picture #{ii+1}"
		    end
		end
	end
	
end

Where the magic lies - The hash gateway

When certain circumstances yellow and red groups elements events should be disabled. For this particular example the circumstances will be a button click.

  1. Create a gate keeper - This is an instance variable hash (event handler) that serves as a switch for group events.

  2. Setting gate keeper keys and values - For the purpose of this event colours will be used as a group names. Hash will consist of group names for keys which will be equal to true (events enabled) and false ( events disabled ). Set values to true for all hash elements.

  3. Add a gatekeeper condition when event is triggered - Next in the click event we add a condition that says only if particular hash value is set to true trigger the event.

  4. Set the open/close gate switch - Create a button that, when activated, sets Yellow and Red groups hash values to False.

Open the app and test click events on all groups. Use the button and test again - red and yellow pictures will not trigger events.

Shoes.app do
	@groups = []
	@box = edit_box "", left: 150, top: 400, width: 200, height: 50
	
	def set_group colour, i 
		group = stack left:0 + 120*i, top: 0, width: 100, height: 300 do
			background colour
			image "#{DIR}/static/shoes-icon.png", width: 70
			image "#{DIR}/static/shoes-icon-blue.png", width: 70
			image "#{DIR}/static/shoes-icon-federales.png", width: 70
			image "#{DIR}/static/shoes-icon-red.png", width: 70
		end
		return group
	end
	
	colours = [green, yellow, red, orange ]
	colour_names = ["green", "yellow", "red", "orange" ]
	@event_handler = { "green" => true,
	                    "yellow" => true,
					    "red" => true,
					    "orange" => true }
					   
	colours.each_with_index do |clr, i|
		@groups << (set_group clr, i)
	end
	
	@groups.each_with_index do |g, i|
		g.contents[1..-1].each_with_index do |c, ii|
		    c.click do
				if @event_handler[colour_names[i]] == true then
					@box.text = "Group #{colour_names[i]}, picture #{ii+1}"
				end
		    end
		end
	end
	
	button "Disable Red and Yellow groups events", left: 80, top: 350 do
		@event_handler["red"] = false
		@event_handler["yellow"] = false
	end
	
end

=============================================================================== Credits: @Backorder, @dredknight

Clone this wiki locally