Stroke bounds method?
Hi all,
One of the things I love about Prawn is that you can solve positioning problems with a stroke_axis method and a stroke_bounds method.
These methods help you see what you're doing and precisely where things end up. stroke_axis puts down a coordinate system on the document, and stroke bounds draws a 1 pixel wide square around bounding boxes.
The only thing is, the maintainers didn't want to have to support stroke_axis as an official part of their API (something we can relate to!). So they didn't!
OK, so enough about Prawn, why am I talking about prawn?
Because I'd like to have a convenience method or two for helping us debug all these positioning / dimensions issues!
We don't have to support them in the API, but we could put them somewhere convenient (analogous to the swt/tooling stuff) for our use.
In the past, I've just used
flow do
background orange
end
to see the boundary of the flow. But what if background is malfunctioning? (It is)
OK, so that's a lot of backstory, but here's some suggestions:
show boundary
Let's have elements take a :show_boundary option in their opts/style hash that shows the element's position, dimensions, and margins by outlining them with boxes or something like that. Again, it doesn't have to become part of the API, but it could help us see why an element is getting drawn where it is.
rect 10, 10, 100, 100, show_boundary: true
#or
para "Hi", show_boundary: [:margin_top, :margin_bottom ]
#or
para "Hi", show_boundary: {margins: blue}
# or something like that, I'm just brain storming here :-)
draw grid
Shoes.app do
draw_grid every: 10, horizontal: true, vertical: true
end
draw a grid every 10 pixels horizontally and vertically, with the lines (1px wide) representing pixel 1, 11, 21 etc with numbers to be clear. The grid could take stroke since it's just a bunch of lines.
debug mode
Firefox has amazing debugging tools that can help you see how each element comes from the source code, how it's layed out and why. I know this would be a pretty big project in itself, but wouldn't it be cool if shoes had something similar? :smiley:
Conclusion
I know that this might not be high priority right now, but building tools like these is something I'd really like to do both for my own app development, and shoes development. Plus I think it'd help me learn a lot more about the nitty gritty of positioning/dimensions in shoes.
So I just wanted to hear you guys' feedback. Do these sound useful? Do you have ideas of related but simpler tools that might be useful? Or does this stuff seem too pie in the sky to even talk about right now :)
It does sound useful.
The thing about official/unofficial is... the moment you expose something people WILL use it and then you have to maintain it. Background right now might be off, but so might every other implementation we'll write - as debugging tools can also have bugs. :-)
As for show_boundary I wouldn't want to provide stuff like margin_top/margin_bottom. Either I draw you a boundary or not. There should be two types of boundaries though, one that takes margins into account and one that doesn't. Maybe outline_element_position or outline_absolute_position (according to the Dimension names). I would make it like: outline_element_position: color to specify a color or just true for a random color. It should also be possible to set globally.
So yeah, I like the idea but for now it's rather low priority for me (hence 4.1.0 as a milestone which is our "future stuff goodie bag").
I'm with @PragTob about the 4.1, but I think all three of those are great ideas. I've had the "firebug" thought before about Shoes too. Definitely a big undertaking, but super useful.
Hadn't considered the debugging grid before, but I can see where that would have use outside of just those building Shoes itself--helping Cora position stuff in our programs, a grid would be awesome for helping her visualize the distances we're talking about.
Good ideas @KCErb!
Good stuff!
Well I may end up writing some kind of simple method of my own right now for debugging and if I find it's very useful I'll share it and tinker with it until we want to do something more official. Thanks for the discussion!
I'm just getting started looking into Shoes & I saw this post, so noobie or not I'll put in my thoughts...
Since you want this to be debug feature it seems like it could be a switch thrown at a low level in the code- down near the SWT layer, where the bounds of an element being drawn are known. Then the drawing code does an extra step of drawing a bounding box too. It seems more straight forward than add an attribute to every item in your drawing.
If the capability were added correctly you could set the switch for individual types like oval, line, image, etc. The switch could be thrown on the fly from code or from UI element and only exposed in developer environments, not in deployed apps. My 25c worth. Thanks for bearing with my undoubtedly naive take on this.
Hi there!
Thanks for your input! :-)
The great thing about shoes and the style system is, that this is already possible with the style system. My syntax might be wrong but you could do:
style show_boundary: true # all the elements
style Oval, show_boundary: true # just oval
Might be wrong but that should work as is with the style method, right @KCErb ?
Yes, you could implement this on every element that includes the style module by just adding show_boundary to the common_styles array here since all elements in the module include common_styles. The only thing left to do after that would be to implement either a front or back-end method that checks for this attribute and does the work.
The ability to turn on boundary for all or just a single sub-type is nice. I'm drilling down into the code and would the draw routines in the swt/xxx.rb fore each sub-type be a place to do this? Would it make a difference if the boundary is drawn before or after the object (not sure about layering yet). e.g. in swt/oval.rb:
def draw(graphics_context)
sw = graphics_context.get_line_width
# draw boundary here?
graphics_context.draw_oval(@obj.element_left+sw/2, @obj.element_top+sw/2,
@obj.element_width-sw, @obj.element_height-sw)
# or draw boundary here?
end
Sorry @BoskyO, I'm not much with the SWT side and can't answer your question and the other guys are getting back from BaRuCo still.
But thanks for drilling into this! I'm hoping to get time to start debugging issues that need this kind of tool. So maybe after I've played with hacking my own together I'll be more helpful.
@BoskyO For the art elements where we have a painter and a draw method, I think that's absolutely the sort of place that we'd want to do the boundary drawing.
There are lots of element types, though (button, text box, etc.) which don't necessarily have their own explicit drawing step--we rely on the SWT widgets to handle themselves. Those might need a bit more thinking about the right spot to hook into it.
That said, I don't feel like we need to solve for all element types to make something valuable to get started on, so if you wanted to take a shot at the types where it's pretty straight-forward and call that a mergeable piece of work, feel free to!
Hi everyone,
please remind me to do a more thorough answer here later. But imo we could just iterate over all elements and draw a rectangle over them according to their Dimension - we weould then ahve to make sure that we don't draw rectangles around rectangles.. but hey we can do that. Gotta run, more later or please ping... thanks =D