Gtk Drawing graphic items - gtk

I want to create a gtk (with pygobject) application for drawing graphic items as rectangles, circles, lines, and also more complex ones as UML components.
Each graphic item should be able to be moved around, resized, etc...
I see two possible approaches:
Define simple class with a draw method and appropiate attribues for each item type.
Then draw the shapes in a Gtk.DrawingArea .
Make all the items Gtk widgets. And put the widgets in a Gtk.Layout or Gtk.Fixed
For this approach I don't know which widget should I subclass. Maybe DrawingArea ?
Which of the two approaches is best?

Related

How to draw line between two views in Swift

I want to Draw lines from one object to another object. Like a Matching object game. I want Swift language with UIKit Use. Here I attach the Sample Screenshot.
Does anyone have experience with this? then please help me.
You have a couple of choices.
You can create a custom subclass of UIView that implements the draw(_:) function to draw custom content. That view would need to big enough to enclose all of your custom drawing. You'd fill most of the view with clear, and then draw the lines you want using Core Graphics.
The other option is to use Core Animation layers. You could add a CAShapeLayer to your view's layer, set up the shape layer with the desired line thickness and color, and add a path to the layer containing the lines you want to draw. (Note that if you use CAShapeLayers, all the lines drawn in a single shape layer will be the same color. You'll need multiple shape layers in order to draw in multiple colors.)
Both approaches will require some research. Shape layers are more efficient and take better advantage of the graphics hardware on iOS devices, but using them has a fairly steep learning curve.
You should be able to google examples of both approaches. Try search phrases like "Custom drawing in a UIView" and "drawing with CAShapeLayer". I wrote a little demo app called OvalView that demonstrates how to create a UIView subclass that manages a shape layer.
Edit:
I adapted the code from my sample app into a demo called LinesBetweenViews. The new demo has a custom UIView that draws lines between any pairs of subviews you put into it.
Here is a screenshot of the demo:
If you answer my questions I can upload the demo app to Github so you can look at it.
Edit #2
See this Github repo for a sample project that draws lines between pairs of subviews.

How to bend / crook a Flutter widget? (non-affine widget render transform)

Let's say you have some flutter widget, for example, a TabBar. It is rendered in a rectangular box. I need it to be rendered in an arc so that the text and the underline follow part of a circle (or better still, a bezier curve).
How can that be achieved?
This illustrates what I am trying to achieve - bent TabBar widget:
Please note that in this case, the TabBar bends following and an arc (edge of a circle). This is what I need immediately. However, in the future, I might need bending that follows the edge of an eclipse so a solution that allows it would be preferable.
Also, a solution that works for different widgets is preferred.
IMPORTANT: I do NOT want to clip a curved shape of the widget. The entire area of the widget should stay visible. Instead, I need to bend the content of the widget (=bend its render image).
Apologies for the bold font but without it, people will keep posting answers about how to clip a widget which is trivial in comparison and useless for my problem.
An answer "this is currently not supported by Flutter" from authority (e.g. high reputation in Flutter tag or Flutter a team member) will also be accepted.
One approach: Use a CustomPaint to draw lines/areas/etc freely
You can use a CustomPaint to draw whatever curved lines, areas, etc freely. Therefore, you can definitely achieve your goal - since they are nothing but curved lines, areas with curved edges, rotated texts, etc.
That will take a bit of work, but if you encapsulate it well enough, it is not that hard to implement. For example, draw a Path with filled red area, then draw a white arc, then draw several texts with calculated rotations, etc. Sounds like you can do that within maybe hundreds of lines. If you find difficulty implementing this please comment and I will explain.
Another approach: Hack Canvas such that the call to drawLine becomes indeed calls to drawPath, etc.
You may do the following to allow bend/crook for any widget (and their combination, of course), but this may need a bit of engineering. You can make your own Canvas, say, class BendCanvas implements Canvas {}. The BendCanvas.drawLine, for example, has an implementation of Canvas.drawPath with a curved path cooresponding to the input "line". Similar things hold for drawing rectangles, etc. Then you need to hack Flutter's painting logic, such that it takes in your own BendCanvas instead of the original canvas. This is a universal solution, and it is much more efficient (less code) if you plan to have a lot of bend UI; but if only on bend TabBar, maybe use the first approach.
As for the bend text
In the two approaches above, we have mainly described how you draw the bended rectangle (i.e. draw an arbitrary shaped widget). As for bending text, see: https://github.com/flutter/flutter/issues/16477 , which is still an open issue.
Remarks
It is not possible using transformations. As explained in the comments, you already see Transform does not work - it is affine or perspective, which, by definition, will not bend. Then what about other transforms? After some research there seems to be none. Then, what about looking under the scene. We know Flutter uses Skia under it to draw the UI with high performance, then let us search through Skia. However, it does not provide any transformations like bending. So there seems no use.
P.S. I am not that high reputation in Flutter tag, but I did answer >100 Flutter questions (including some dig-into-source-code style ones), and have developed >100k lines of Flutter code in the production app.

flutter: Make layers of CustomPaint drawing complement each other instead of blending into each other

I'm painting two layers of graphs on one CustomPaint. The first will occlude over half of the second layer.
Problem
Currently I just paint the first data and then second data using two Paints, with their blendMode set.
This creates an overlay of two data, which blends. But I don't need the blend, just the area of difference to be painted using the second Paint, i.e., a complementary composite view.
On the performance side, I don't know if blending would have internal optimization to avoid drawing the occluded part.
Reference image
Notice that all these data graphs blend but I just need them to occlude each other, while the overlapped parts don't draw at all for performance.
Attempts
I could use a new path to only draw the difference, but I'm not sure this is the easiest way.
I checked RepaintBoundary but it's a widget that handles infrequent data changes, not exactly what I need here.
Similarly Overlay seems a standalone widget, so I don't know how to fit it into CustomPaint.
Question
Is there a standard way to achieve the occlusion I need?

Drawing graphs on iOS: Use layers or override drawRect?

Reading through the documentation, it's not clear to me if overriding a UIView's drawRect or using layers is appropriate.
I am going to be rendering two kinds of graphs. A line graph and a single-bar bar graph. Both will have ticks along the axis and text aligned with the ticks. Below I only show four ticks per axis, but there could be more.
What is the better way of drawing the ticks? Should I use an individual layer for each tick, or render them all at once on a separate view using drawRect?
Is there another way to render the text other than using a separate UILabel for each?
For the bar graph, I am using a CAGradientLayer for the bar. For the line graph, is it even possible to render this using layers?
Sample Graph
In the end, I used a combination of overriding drawRect and CALayer/CAShapeLayer. Having now been through the process of implementing it all from scratch, I would go with shapes and layers.
The shapes and layers approach is plenty performant, and is a more robust solution. In the end it takes less code if you are doing things like animation.

How are these two iPhone UI pieces accomplished?

This might be trivial for some of you, but I have two screenshots from the Lose It! app in which I'm curious how two different screens were put together.
The first:
That middle graph which shows the statistics chart. Is that a custom image being drawn on top of with Core Graphics / Quartz to achieve the desired numbers? Is the yellow line that's being dynamically allocated all the work of Quartz?
And second:
This one might be a bit easier, but the whole bar which looks like a native UIKit widget, which contains [Budget, Food, Exercise, Net, Under]. There appears to be a drop shadow above it. Are they doing a drop shadow on the UINavigationBar? Is the menu below it just a UIImage that a designer was able to craft to look like the UINavigationBar?
If there's a blog out there which teaches UI tricks such as these, I'd love to read more.
1) Yes, it's likely a view that uses the chart as a background and then uses core graphics to render the line,
2) This could be a single view divided into four sections. Each section has two lines of text drawn with different colors. It's possible that each section may be a view that encapsulates this behavior.
I'm not aware of any blog that teaches these "tricks". It's really a case of understanding what functionality is available and then using it creatively to develop your UI.
For example we know it's possible to;
Draw images at different sizes/positions.
Draw text in different fonts, sizes, colors, alignment
Draw primitives
Really, when you have those you can create pretty much anything.
I think there's an SDK sample that demonstrates using custom views to create a fancy timezone style applications. That might be one worth checking out.
Update: found it, it's here.