beeware / toga

A Python native, OS native GUI toolkit.
https://toga.readthedocs.io/en/latest/
BSD 3-Clause "New" or "Revised" License
4.34k stars 669 forks source link

Border support on toga #849

Open saroad2 opened 4 years ago

saroad2 commented 4 years ago

Hey, I came across the need to add a border to a Box element on my GUI application and found out that toga doesn't support borders yet. At first, I thought it is a problem only in Windows since many features haven't been implemented there yet, but now I see it is relevant for all platforms.

Is it on purpose? Or maybe you just haven't got the time to implement it yet?

I need 4 abilities that would really help me:

  1. Border existence (hide/display)
  2. Border size
  3. Border color
  4. Border style (dashed, dotted, etc.)

I work with python 3.7 on windows, on the latest toga version.

freakboy3742 commented 4 years ago

Borders of this kind haven't been entirely ignored on purpose.

The real question I would ask is "what are you trying to do"? I'm hesitant to "just add borders", as I'm not completely sure what purpose they would fill from UI design perspective. One of the goals of Toga is to expose an API that makes it easy to "do the right thing"; an API that lets you drop a arbitrary size, color, and dash-style box into your GUI doesn't inherently sound like (a) the right UI decision for most platform style guides, or (b) the easiest API to control and use.

That said, I can definitely see a use case for "frames" that allows grouping of widgets (e.g. in the gtk.Frame) sense. That sort of layout requires a lot less customization - it results in a GUI that is padded appropriately, with lines that have accents and highlights that match the platform styleguides.

Is that what you're trying to do? Or have you got some other purpose in mind?

saroad2 commented 4 years ago

I must say that I don't fully understand the difference between a Box and a Frame. In my point of view, Box is a rectangle space in the window that elements can be placed and ordered in. And Frame is...?

As for why borders are needed, It's a stylistic choice. I want to enclose a section of the window with a dashed line so people would know it's a separate section. It is not necessary in the sense that I won't manage without it, but it's a UX feature that I think is useful.

freakboy3742 commented 4 years ago

Ok - so it sounds like your use case for a border on a box is very close to what I'm describing as the use case for a frame.

The difference between the two is a bit subtle; but there are two major differences in my mind between a "box with a border" and a "frame":

  1. The appearance of a frame is something that is OS-standardized. There are no options to pick colors, line style, or even padding; it's a standardized element for organizing a GUI layout.
  2. A frame can (and probably should) have a label that is a built-in part of the widget

Here's a quick macOS-based visual demo I've thrown together:

Screen Shot 2020-04-19 at 8 01 21 am

On the left is a "frame". The right is "box with a border". The Frame looks like it belongs in a macOS app. The box with a border looks like someone got the job done, but hasn't actually used macOS, and so they don't know what "feels" like macOS.

The box could be any color, might have rounded corners, might have a drop shadow.... It's somewhat of a mystery that Apple even allows most of these options, as they're mostly a violation of their UI guidelines.

The frame, on the other hand has a very specific look, mandated by the platform style guide. In the case of macOS, there's no border at all - the content of the frame is inset, and there's a title in a smaller font. However, that specific style is something that only exists in recent versions of macOS. Earlier versions used a gray border with the text label inset into the border, similar to the appearance of the GTK widget I linked in my previous post.

This leads to another critical distinction: if macOS updates their style guide again, every frame will change; however, boxes with a border won't.

The added irony here is that on macOS, a "Frame" is a box with very specific styling options - but that's an implementation detail. Conceptually, the two are separate; and on other platforms (like GTK), they are separate.

Another way to explain would be by analogy to the difference between "separator" and "line". A Separator is a widget that is standardized by the OS; it's always the same color, width, emphasis, etc, with limited orientation options; whereas a line could be drawn anywhere, in any color, in any direction. Toga should have a separator, but shouldn't have an arbitrary "put a line in my GUI" widget (outside of the context of a drawing canvas).

Does that explanation make any more sense?

saroad2 commented 4 years ago

It does make more sense, but I don't feel at the moment that I understand it enough to implement it on Windows, especially when your direction is toward iOS styled apps. Furthermore, I think windows doesn't have this concept inherently.

I suggest you change this issue to implement Frame for Mac and/or GTK and once those would work, I'll try to adjust it to Windows.

freakboy3742 commented 4 years ago

I've done a quick looks, at I think the Winforms widget you'd be looking for is GroupBox, setting Text for a caption.

From the perspective of Toga, toga.Frame would be a widget that contains a single child content widget, and has a title that is a text property.