Question

Is it possible to add a background color to a bounding_box in Prawn?

 bounding_box([100, cursor], width: 80, height: 20) do
    pad_top(7) { text "THIS IS TEXT", size: 8, align: :center }
    stroke_bounds
 end 

Ive tried adding this to the bounding_box block

     background_color: "CCCCCC"

Ive tried adding this inside the block

    fill_color "CCCCCC"
    background_color "CCCCCC"

Nothing seems to work with a bounding_box

Était-ce utile?

La solution

Here the code

    bounding_box([200,cursor], :width => 350, :height => 80) do
        stroke_color 'FFFFFF'
        stroke_bounds
        stroke do
            stroke_color 'FFFF00'
            fill_color '36DA5C'
            fill_and_stroke_rounded_rectangle [cursor-80,cursor], 350, 80, 10
            fill_color '000000'
        end
    end

Autres conseils

This was discussed 2008 [1] (apparently didn't lead anywhere though), i don't see it mentioned anywhere in the manual [2] either.

As to how it's done: After putting all content into your bounding box, you can obtain the resulting width and height from the bounding box. With that information you can use primitve rectangle drawing to fill it. Afterwards you will have to redraw the content, because by now you will have painted right over it with your rectangle fill.

Hopefully (probably?) there's a better way too, one where you don't need to draw your actual content twice; Make sure to share it with everyone when you come across it!

All the stuff I mentioned in the quick how-to above is beautifully documented in the manual [2]; Good luck!

[1] https://groups.google.com/forum/#!msg/prawn-ruby/6XW54cGy0GA/RdXwL0Zo_Z8J

[2] http://prawn.majesticseacreature.com/manual.pdf

EDITTED Completely Still needs some work but try this out

module Prawn
  module Graphics
    def fill_and_stroke_bounding_box(options={},&block)
      current_settings = {fill_color: fill_color, 
                      stroke_color: stroke_color, 
                      line_width: self.line_width }
      fill_color options[:fill_color] || fill_color
      stroke_color options[:stroke][:color] || stroke_color if options[:stroke]
      self.line_width  options[:stroke][:width] || self.line_width if options[:stroke]
      rectangle options[:position], options[:width], options[:height]
      options[:stroke] ? fill_and_stroke : fill
      box_options = convert_box_options(options)
      options[:revert_before_block] ?  revert(current_settings) : check_fill_visiblity(options[:text_color])
      fill_color options[:text_color] || fill_color 
      bounding_box(box_options[:position],box_options[:options]) do 
        if block_given?
          block.call
        end
      end
      revert(current_settings) unless options[:skip_revert]
    end

    def revert(settings={})
      fill_color settings[:fill_color]
      stroke_color settings[:stroke_color]
      self.line_width settings[:line_width]
    end

    def convert_box_options(options={})
      converted_options =  {position: options.delete(:position)}
      if options.delete(:stroke)
        resize_box(options)
        reposition_box(converted_options)
      end
      converted_options.merge({options: options})
    end

    def resize_box(options ={})
      [:width,:height].each do |param|
        options[param] -= (self.line_width * 2)
      end
    end

    def reposition_box(options)
      options[:position][0] += self.line_width
      options[:position][1] -= self.line_width
    end

    def check_fill_visiblity(text_color)
      text_color ||= fill_color
      warn "[WARNING] Text Will Not be visible without text_color set or revert_before_block" if text_color == fill_color
    end 

  end
end

Then you can call it like this

fill_and_stroke_bounding_box(position:[0,cursor],
                            stroke:{color: "7CFC00",width: 2.mm},
                            text_color: "668B8B"
                            fill_color:"FFFFFF", 
                            width: 19.cm, height: 100
                            ) do 

The only options that are required are position,height, and width (bounding_box does not require a height but since you are placing it inside a rectangle you must specify a height.

Although it is recommended the text_color or revert_before_block are also set otherwise the text inside the block will be invisible.

options includes all bounding_box options including use of a block as well as the following new options stroke:{:color,:width} which lets you set the outside stroke for the rectangle. fill_color: set the color of the rectangle. text_color the color of the text inside the block. revert_before_block will set the colors back before it executes the block because fill_color controls the text_color in Prawn. You can use this option in place of text_color if the correct color is already set.skip_revert this will discard the options of fill_color,stroke_color, and self.line_width that were set prior to calling this method. This extension will also warn if the text_color is the same as the fill_color.

Hope this helps someone out.

Here's how I did it.

bounding_box([0, y_position], width: 200, height: 50) do
  fill_color 'CCCCCC'
  fill { rectangle [0, 50], 200, 50 }
  text 'Hello', align: :center, valign: :center
end

Just to add another option to Willing's answer...should somebody find this and want to use it with grid.

def widget
  grid([2,2], [3,2]).bounding_box do
    stroke do
      fill_color '36DA5C'
      fill_and_stroke_rounded_rectangle [cursor-bounds.height,cursor], bounds.width, bounds.height, 5
      fill_color '000000'
    end

    text "This is text inside the box"
  end
end
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top