In WPF, is there a way to detect that the actual render size (measured in screen units) changed?
I have elements which contain a rendered bitmap. If these elements are placed inside a Viewbox (or some other control that deals with RenderTransforms), I want to render the bitmap in the actual size on screen, so that no interpolation is done.
The main idea is that I want to place some complex parts of the UI in bitmaps as these would otherwise (when drawed in retained mode) reduce the render framerate and UI responsivity, making the application a pain to use. As a side effect, I would like to draw the lines inside these controls with constant thickness, even if scaled.
One way would be to check the size on screen with every render pass (or in some given time interval), and if it changed redraw the bitmap. However, I would like to know if there is maybe a built-in way to achieve this.
Related
I'm trying to understand animation loops in WebGl, along with React.
Basically, does the browser repaint specific elements without repainting the whole screen? Does a a reflow always refresh the whole screen? What exactly is the difference between what happens when you manually refresh the window with a refresh button, verses what reflow or repaint? I know this technology has been around awhile, but I never really dove into it much before.
I'm just trying to to understand how a webGL code animates on a canvas element and how React changes elements on a screen, without the whole screen reloading. I've read about requestAnimationFrame, and about how React bundles and diffs virtual dom changes, reducing the number of requests for rerender, but my question is more about the entire window reloading, verses rerendering individual components only. Im building a site with gatsby/react and babylonjs, and just trying to wrap my head around the underlying concepts. Thanks.
What the browser does is somewhat undefined. You give it HTML elements, it somehow draws them on the screen. How it optimizes that process is undefined, all that's defined is what the results are kind of supposed to be like. I say "kind of" because even a simple element like <p>Hello world</p> will be rendered differently on different browsers and differently on the same browser on different OSes or in the same browser on the same OS but with different OS settings etc..
In general the browser builds a tree of nodes (the elements and their contents) called the DOM. It then walks that tree and builds whatever it needs to apply the CSS and then render those elements. Most browsers would try to cache data at various points in that process so that if something changes on the page they don't have to compute everything from scratch. Example might include they generate a glyph (The pixel for a letter), store those pixels somewhere, next time they need to draw the letter at the same size they can just use the pixels they already generated instead having to rasterize that letter from the font definition.
does the browser repaint specific elements without repainting the whole screen?
That's up to the browser.
Does a a reflow always refresh the whole screen?
That's up to the browser. If the browser has way to figure out it only has to compute a partial reflow of some branch of the tree then it might not have to refresh the whole screen.
What exactly is the difference between what happens when you manually refresh the window with a refresh button, verses what reflow or repaint?
Refreshing a window is like killing a program and re-running it from scratch. All the data has to be reloaded either from the network or from the cache, the text gets parsed into elements, etc..
Reflow is computing where all the elements belong, where words or elements wrap, what size they are.
Repaint is drawing the elements. You can repaint without reflow.
how a webGL code animates on a canvas element
A canvas is just a rectangle of pixels, similar to an <img>. The difference is you can get one of several APIs to affect those pixels ("2d", "webgl", "webgl2", "webgpu", ...)
When you change those pixels the browser knows that <canvas> element needs to be re-drawn. How it re-draws it is up to the browser but at does have to at least follow the rules of the spec so for example a <canvas> like pretty much all elements, has CSS applied (it could have border, a background image/color/pattern, rounded corners, etc....). Elements are composited on top of each other so you might have elements in front of the canvas, you might have elements behind the canvas.
Like I said above, what the browser does to draw the elements is undefined but you can certainly imagine that if it can figure out the only thing that changed is the canvas's content, and there are no elements in front of the canvas, and there is nothing behind the canvas, and the canvas is opaque, then it could, potentially, just re-draw the canvas area only.
That situation is rare though. For example, most three.js examples have text at the top positioned over the canvas (the title of the example). Many also have an FPS meter. Some have a drop down UI. All of that is drawn over the canvas so at a minimum, the new contents of the canvas have to be drawn into the window and then those other elements have to rendered on top of that.
Again, how that, happens is up to the browser. It could use software rendering to draw those elements pixel by pixel, or it's possible it has stored the contents of those elements in textures and draws them as quads on top using the GPU.
how React changes elements on a screen, without the whole screen reloading
I'm not sure what you mean by reloading. React keeps its own "virtual DOM". It then tries to apply the changes in the virtual DOM to the actual browser DOM. If there are no changes needed to some elements those elements will not be affected.
From the POV of the browser, nothing is different. All the browser sees is the DOM. If you make changes to the DOM (using React or anything else), then, once your current event exits, the browser will schedule a task to walk the DOM and re-draw the page (using optimizations to re-compute/re-draw less is up to the browser).
I'm using the SpanLabel Component, but on the screen the text content does not occupying the full width when text size is lower
Someone can help please?
This can happen if the width isn't deterministic. The SpanLabel won't be able to reflow and at best will cause only its own Container to resize. There are two solutions:
Deterministic hierarchy - this is generally best but not always possible
Use TextArea - sometimes this works around the issue by reducing the hierarchy depth.
Deterministic layout means that the size of the elements is determined in a clear way by the hierarchy. E.g. BoxLayout.Y is deterministic on the X axis as it gives the components on the X axis all available space. FlowLayout isn't deterministic as it gives components their preferred size.
Some layouts can go back and forth and vary in determinism based on their axis.
This is important because when we layout the components we go from top down. So we go through the Form to its children asking each for their preferred size. If at this point the SpanLabel doesn't know its size it can give the wrong value and we can't really fix that later as we don't reflow the UI. Reflow would create a potential infinite loop and a performance problem at best.
We try to workaround some of this behavior by making a revalidate() call within TextArea but that has its limits. If the hierarchy is too deep the preferred size is already set and won't adapt. SpanLabel is just a Container with a TextArea and a Label (for the icon). So by only using a TextArea you'd slightly simplify the hierarchy and it sometimes might be enough. E.g.
TextArea t = new TextArea(myText);
t.setEditable(false);
t.setFocusable(false);
t.setUIID("Label");
I am new to silver light and would like to understand a bit more from the pros. Let me tell you what I am trying to do. I am into photography and my goal is to create a web site that allows users to view their images and be able to rotate, zoom, crop, special effect etc. I have developed the web site that allows users to order pictures but now I want to start working on the actual picture/image manipulation. So for testing i put a canvas and a rectangle( with an image). Placed a slider and was able to link the slider to the rectangle. As i increase the slider the image gets larger. But I was kind of hoping as the image gets larger it does not surpass the boundries of the canvas. I assumed that is what it means by being a child of a canvas. Am i mistaken? If so how do you suggest me doing this? Remember I am very new to this and may be going about this very wrong.
Thanks!
Your are right. In Silverlight (like in WPF, WinForms etc.) gui-elements form a hierarchy of elements wherein controls can act either as parents or as children.
The reason why your rectangle surpasses the boundaries of it's container lies in the way controls are getting aligned. This depends on what kind of container you want to place your child into.
In a canvas for example you position the children with absolute measurements (left, top, height, width). In a self-organizing container like the StackPanel you choose an horizontal alignment (Left, HCenter, HStretch, Right) or a vertical alignment (Top, VCenter, VStretch, Bottom) which determines the childs behavior when you place it inside the parent. Furthermore you can specify the dimension of the child (Width, Height) and an optional margin which determines the gap between the Top, Right, Bottom and Left bound of your child to its enclosing parent.
But what ever container you choose it's inherent to it that you can let its children surpass its boundaries e.g. with a margin that is negative or greater than the container boundaries or simply by an child that is bigger in dimension that its container as you described the situation with your rectangle.
In your case I would consider working with the idea of clipping. Clipping simply means to
(1) define an geometrical area (in Silverlight and WPF it is a Path object) which lies over some graphical context (some section of your ui or your control etc).
(2) what lies inside the boundaries of this clipping area remains visible and everything else remains invisible.
So you can think of a clipping area as a window onto your screen which you use to look through.
When you are using Microsoft Blend this is easy to realize:
(1) Just use a geometrical shape like a Rectangle, a Circle or a custom Path.
(2) Place it somewhere upon your UI
(3) Right-click the shape, select "Path" and then "Make clipping Path"
(4) and voulĂ , you've just defined a clipping area which you can modify as you are used to modify controls.
Hope this gave you an idea how to deal with your problem.
cheers.
Say I have some grid that you need to scroll down to see all of its lines, and I'm interested in saving some lines that are not currently visible as a bitmap. Is it feasible, or do I have to actually scroll down, "take a snapshot", and then scroll up again?
This is a feasibility question, and thus I don't have code to share.
Yes. You can render any UIElement (and its children) to a writeable bitmap.
When you do that you also specify a transform. That means you can display any part of the UIElement (if you do not want it all).
Whether it is "visible" on screen is completely irrelevant to bitmap rendering. It does not work like a screen grab.
The output cropping is solely down to the size of the target bitmap and the render transform provided.
As an example Silverlight Rotate & Scale a bitmap image to fit within rectangle without cropping uses UIElements that are never part of the visual tree to create a bitmap that is then rendered.
Given a WPF Application running full screen, a fair amount of controls some of which will animate from off screen to center. I was wondering if there are any special ways to save on the amount of time required to optimize an application for different screen resolutions?
For example, using Blend I've setup some text, which is originally off screen to scroll into view. Now in design mode the start positions are static. If resolution changes the start positions will obviously not be correct.
So I guess to correct this, during app startup. I need to
Check resolution
Move the text box to the desired start location
Adjust the storyboard as required, so the frames all have correct co-ordinates depending on the res of the screen.
I don't mind doing all of this, but if there is an easier way please share!
Thanks
In WPF layout of controls should be made in such way, that when size of window or content changes, controls automaticaly resize/reposition themselves to reflect this change.
This is highly affected how your layout is made, especialy by using specific panels, that do layout of their child elements.
This is also made obvious by using device-independent units for sizes, margins and sometimes positions of controls. And also allows different kind of zooming and scaling of whole UI without any need to redesign the whole thing.
If you are trying to position your controls absolutely, either by using Canvas panel or margins, your are doing it totaly wrong.
In WPF, scene is measured in abstract units, not pixels, and controls are freely scaled. There should be no problems to center something, or what?