Search code examples
rubyshoes

Create an inline art shape in Shoes


Using Shoes I want to create something like this:
The word "Find:" followed by a pink rectangle, followed by more content.

How do I create a rect that is inline as part of a Flow? Here is what I currently have:

flow do
  @find_color = rgb(255,0,255)
  stroke "#000"
  fill @find_color
  para "Find:"
  rect(0,0,24,24,3).click do
    @find_color = ask_color "Color to Search For"
    @find_r.text = @find_color.red
    @find_g.text = @find_color.green
    @find_b.text = @find_color.blue
    @r.style fill:@find_color
  end
  para " R:"
  @find_r = edit_line(@find_color.red,   width:30, align:'right'){ create_color }
  para " G:"
  @find_g = edit_line(@find_color.blue,  width:30, align:'right'){ create_color }
  para " B:"
  @find_b = edit_line(@find_color.green, width:30, align:'right'){ create_color }
end

And here is the result, showing that the Flow is the equivalent of a position:relative element in CSS, and the rect is using position:absolute:

The word "Find:" is overlayed by the pink rectangle, and no space has been reserved for it.

I tried to create a new flow inside the flow, by wrapping the rect call in flow do … end, but that caused the content to rect show up on a new line, and the R: label to overlap it.


Solution

  • If you wrap the rect in its own flow with a specific width it will establish a new 'canvas' that takes up space:

    flow do
      @find_color = rgb(255,0,255)
      stroke "#000"
      fill @find_color
      para "Find:"
      flow width:24 do
        rect(0,0,24,24,3).click do
          # ...rect click handler here...
        end
      end
      # other in-flow content here
    end
    

    If there are other elements with height in the parent flow then you do not need to give this flow a height; otherwise, you will need to do so for the parent flow to be held as tall as the content.