Coder Social home page Coder Social logo

Feature questions about owlkettle HOT 13 CLOSED

can-lehmann avatar can-lehmann commented on May 20, 2024
Feature questions

from owlkettle.

Comments (13)

can-lehmann avatar can-lehmann commented on May 20, 2024 1

Text Wrapping: I added the line_wrap field to the Label widget, which can be used to wrap text. There is also an example for how to use it.

Text Styles: Font size, outline and icon size options seem like something which should be controlled by a theme (= CSS stylesheet). It is currently not possible to set a stylesheet for an app, but I will probably add this feature at some point. Changing the size of icons is already possible using the pixel_size field, the unit of this value is pixels however.

Menus: Since I find traditional menu bars quite cumbersome, I personally do not have interest in supporting menus (i.e. I will probably not implement this). I do however recognize that CSDs look weird in DEs that do not use them. The ideal solution would be to have a unified API which automatically detects the users preferred menu style (e.g. based on the used desktop environment) and creates the corresponding menu/header bar/popover from a single specification. Since such an API is not trivial to design, a simpler solution would be to create an extension (separate module, e.g. owlkettle/ext/menus) for building non-CSD menus.

Tray Icons: The GTK API for creating system tray icons seems to be deprecated. So a separate library might be a better solution here.

from owlkettle.

can-lehmann avatar can-lehmann commented on May 20, 2024 1

Since my reasoning for not automatically creating boxes does not apply to ListBoxRow and FlowBoxChild, I decided to make ListBoxRow and FlowBoxChild optional.

from owlkettle.

insomniacUNDERSCORElemon avatar insomniacUNDERSCORElemon commented on May 20, 2024

Thank you for the quick textwrap addition.

Font size, outline and icon size options seem like something which should be controlled by a theme

Well, as I've said the issue for me is that that buttons (and other elements) scale but their contents don't. It looks weird having a bigger button with text/icon staying the same.

Though for any sort of text-based app it'd be useful for a user to just quickly change size. Outline (aside from aesthetic) is more useful when your text isn't on a set background (games or some other kind of HUD).

Menus

Not sure if it's what you meant by cumbersome, but my setup is ultra-minimal (12px titlebar) and maximized windows hide their titlebar (XFCE tweak). GNOME-style takes up more space.

I don't think hamburger menus are always terrible, but I don't think it's suited for really complex applications. For instance I'm sure most people who use any kind of design application (Krita, Inkscape, Blender etc) would definitely not want a hamburger menu there.

from owlkettle.

can-lehmann avatar can-lehmann commented on May 20, 2024

Scaling

In most user interfaces I am aware of, buttons only scale/expand in at most one direction. Its content just stays at a constant size. This can be accomplished in owlkettle by setting the expand attribute:

Box:
  Button {.expand: false.}:
    icon = "list-add-symbolic"

Do you have a specific example where a button needs to expand in both directions?

Menus

What I mean by cumbersome is that it is very hard to find the items you are looking for in a large menu. Look at GIMPs menu for example: It contains a lot of different items, submenus and even submenus of submenus. Finding a specific filter you want to apply is therefore quite time consuming (e.g. try to find the "difference clouds" filter).

Hamburger Menus do not solve these problems. But because of their inherent simplicity, they require the application designer to find better solutions to the design problems at hand (instead of a filter menu, you might have a "Apply Filter" tool which allows you to search a single list of filters).

Blender is actually also an interesting case study here, since it does not have a large global menu (and the still existing global menu could just as easily be a hamburger menu + a header bar). The individual panes actually have something quite similar to a HeaderBar. E.g. the HeaderBar of the 3d view contains buttons to switch the rendering mode, dropdowns for configuring snapping and a "Popover" for configuring viewport overlays. Although I am not a frequent Blender user, at least from what I have seen, this design was received quite well by the community.

Hamburger Menus can of course also be used incorrectly. This might happen when they are used as a direct replacement for traditional menus. Just moving all of the complexity into another submenu just makes the user experience worse.

Please keep in mind, that I am not a user interface designer. I just happen to have a few strong opinions about how user interfaces should work ;)
As I have said before, I am not opposed to support menus in owlkettle, but I just do not have a personal interest in implementing them (and the necessary free time). My use for owlkettle is to develop applications which target the GNOME desktop environment where the use of menus is discouraged.

from owlkettle.

insomniacUNDERSCORElemon avatar insomniacUNDERSCORElemon commented on May 20, 2024

Do you have a specific example where a button needs to expand in both directions?

The most specific would just be having buttons that end up really small and thus could use the extra space for readability. Otherwise, it just seems like a waste of space and is aesthetically ugly.

EDIT: Some unicode characters aren't very readable at default size (and I'm not sure how much that could improve with the standard button height). 🕵

Seems like it'd be nice to have more control here similar to x/y alignment (assuming I understand that correctly). Define what % the buttons can grow, and also define what % their contents can grow. I'd probably go with 50% (maybe less depending on original button size) and 75% respectively.


More:

  1. I have a scrolledwindow with a lot of text in it now, when the application is ran it is scrolled to the bottom already. Is there a way to configure this, or is it a bug?

  2. I haven't done much yet, but I already find it annoying needing to use boxes just to get multiple widgets even before organizing things. Particularly due to spacing (and I'm using single spaces!). Window(box(label, scrolledwindow(box(label, box(row of buttons)))))

EDIT: The spacing might be a bit of a nitpick/preference (until really complex stuff at least), but it really would be significantly neater if multi-widget was more available even if it were with OrientY assumed/locked for said widgets.

from owlkettle.

can-lehmann avatar can-lehmann commented on May 20, 2024

I have added support for custom stylesheets, which allow you to modify the theme of your application. This example shows how to include a stylesheet. I am not sure if GTK's CSS dialect allows you to scale font sizes proportionally to the parent element however (it seems like this is not possible with standard CSS). The example results in the following app:

css

You can also set the font style for individual labels/parts of labels using the Label.use_markup field. This example shows how you can use it. A full documentation of the available text style attributes can be found here.

Regarding 1: This just seems to be the default GTK behavior. I think that it happens, because GTK will try to show the selected/focused widget to the user. So when you have a button below a large label in a scrolled window, the button is the first focusable widget in the window and GTK scrolls down to show it. I have tried to manually set the initial scroll position to 0, but GTK ignores this and scrolls down anyways. Making the first label in the scrolled window focusable does not work either, because it messes up keyboard navigation. So I am currently not sure how to "fix" this.

Regarding 2: Currently owlkettles widgets map (nearly) directly to GTK widgets. Since GtkWindow, GtkScrolledWindow, ... (→ GtkBin) cannot have multiple child widgets, owlkettle's Window, ScrolledWindow, ... widgets also only allow a single child widget. Automatically generating a GtkBox when adding multiple children to a widget is theoretically possible, but would be quite complex to maintain. There is also the issue of not being able to specify the attributes/fields of this implicit Box widget.

If you notice that your view code becomes to complex, it is always possible to split it into multiple components as shown in this example. In your example, you might want to refactor the box(label, box(row of buttons)) into a new widget.

from owlkettle.

insomniacUNDERSCORElemon avatar insomniacUNDERSCORElemon commented on May 20, 2024

Making the first label in the scrolled window focusable does not work either, because it messes up keyboard navigation. So I am currently not sure how to "fix" this.

It's still a silly work-around, but it does work simply to put a button either at the top of the scrolledwindow or even above it.

CSS and markup

That's cool and helpful for what I was trying, but yeah still not seeing the scaling I wanted.

I am not too knowledgeable with CSS but I looked it up and did see vw and vh for scaling based on viewport size... however this setup does not support that and instead will not run at all. Error: unhandled exception: style.css:43:21'vw' is not a valid unit. [IOError]

Also, another useful option would be calc, for instance one example I found: font-size: calc(4vw + 4vh + 2vmin); with quote: "Using calc in combination with vw and vh units for font-size to create text that always fills the viewport. No matter what ratio." (though personally testing on a wysiwyg editor, I'd go with 2vw and 2vh respectively)

Not sure how literal viewport is here, though given buttons scale this way (if enabled) it does seem like what I'm looking for.

Sidenote about your CSS example: you should set your font colors, too. On my system I have tweaked theme colors (dark theme), so the default color is inverted and thus the label text is unreadable.

EDIT: Also not sure if you can fix it with CSS or if it's just a system setup thing, but the example does not have the rounded borders on my end

EDIT2: Nevermind, this is just because I have compositing turned off. Which is a bit odd that it needs partial transparency to achieve (at least XFWM4 themes don't need it to have round-edged titlebars).

Regarding 2: Currently owlkettles widgets map (nearly) directly to GTK widgets

That's unfortunate... one idea I had for making things cleaner (more declarative?) would be if you split box into vbox and hbox (or maybe x_box and y_box / box_x and box_y). Though that doesn't help by much when it comes to needing to use boxes over and over again for a simple vertical arrangement.

There is also the issue of not being able to specify the attributes/fields of this implicit Box widget

Maybe you could set the orientation (and maybe some of the other attributes) globally (though I'm not sure why you'd want/need to design an entire application horizontally) or a use-last(/inherit) system that still takes an orientation input. Though I still think vertical default makes the most sense.

In your example, you might want to refactor ... into a new widget

Yeah... still seems a bit clunky though, even just from a usage standpoint.

from owlkettle.

can-lehmann avatar can-lehmann commented on May 20, 2024

I fixed the colors in the css example, it should now render correctly on systems which use a dark theme.

I am sadly unable to change the feature set of the CSS dialect, since it is implemented by GTK. If calc, vw and vh are not supported, I therefore cannot add them. At this point it looks like the best way to achieve what you want to is to render the text using a DrawingArea. I will however have to add a few features to the cairo wrapper before this is possible.

Regarding the Box: I have decided against implementing something like this for now, but while exploring how an implementation would look like, it occured to me, that you can actually just add this behavior yourself if you need it. Adding the following lines to the top of your program should enable you to add multiple children to Bin widgets:

const
  DEFAULT_SPACING* = 6
  DEFAULT_ORIENTATION* = OrientY

proc add(bin: Bin, child: Widget) =
  if bin.has_child:
    if not (bin.val_child of Box):
      let box = Box(
        has_spacing: true,
        val_spacing: DEFAULT_SPACING,
        has_orient: true,
        val_orient: DEFAULT_ORIENTATION,
      )
      box.add(bin.val_child)
      bin.val_child = box
    Box(bin.val_child).add(child)
  else:
    bin.has_child = true
    bin.val_child = child

This solution is a bit hacky, but it seems to work for the cases I tried.

from owlkettle.

insomniacUNDERSCORElemon avatar insomniacUNDERSCORElemon commented on May 20, 2024

@can-lehmann forgive me if overstepping, but for CSS have you looked into contributing upstream? (though I can absolutely understand management/communication issues making that unlikely)

Also as far as actual programming goes I feel as if I'm trying to learn on grass and thus cannot do more than fall over. But I am trusting that this works. Can you integrate you hack here as an option like easytree or some other 1-line plus an external module(exported function)? Also adding the node differentiation, as if you know vboxes are automatically used it'd make sense for the user to manually add hboxes explicitly.

Forgive me if you've thought about that or if you don't really feel comfortable without a userbase to poll on the opinion.

from owlkettle.

can-lehmann avatar can-lehmann commented on May 20, 2024

To be honest, I have next to no idea how GTK actually works internally (especially all the gobject stuff. They have a custom class system for doing OOP in C for example). I have only ever used the public GTK API. This makes it very unlikely that I will find the time to contribute to GTK directly any time soon.

I do not think that this solution actually works when you put it into a separate module (because it relies on the fact, that the overload priority of add is higher when it is defined in the same module; this is also why I call this solution hacky), but I will see what I can do. I have outlined my reasoning for not including it by default before.

HBox and VBox is currently difficult to implement (without resorting to hacks), because owlkettle uses a somewhat custom OOP system which does not allow setting property defaults of parent classes. This might be added in the future.

from owlkettle.

insomniacUNDERSCORElemon avatar insomniacUNDERSCORElemon commented on May 20, 2024

Another feature question/suggestion: is there a way to get a dynamic grid of based on available space and best fit?

For instance if I have 4 groups (each 1 button+1 label) I may want 4x1, 1x4, 2x2, or 3+1/1+3, 1+1+2 etc depending on the available width and how much room content takes up.

from owlkettle.

can-lehmann avatar can-lehmann commented on May 20, 2024

This sounds very similar to GTK's FlowBox. Since I wanted to add support for this widget anyway, I just implemented it and you can try it out yourself to see to what extent it fulfills your requirements. The documentation can be found here.

from owlkettle.

insomniacUNDERSCORElemon avatar insomniacUNDERSCORElemon commented on May 20, 2024

Flowbox

Given that simply changing a box to a flowbox doesn't seem to work, I'm not quite sure how I'm supposed to use this. I looked into using seq but am still not sure how that works with child nodes.

If I have to also use a seq for every box that I'm using or create them dynamically that's pretty annoying.

EDIT: Alright FlowBoxChild works, but this is another step past the same annoyance as I have with needing boxes.

from owlkettle.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.