I've been looking around for awhile about how to produce buttons using Direct2D and DirectWrite with no luck. I'm comfortable with shapes, text and that jazz. However, it suddenly occurred to me I might be looking about it in the wrong way.
Take the sentence:
you draw your controls and content for your app using the Direct2D and
DirectWrite APIs, handling all the input events directly.
I'm now thinking this means that instead of being able to quickly produce a fully functional button as I would using XAML. I would draw the button, manually check the location of the mouse on click, whether it's within the button boundaries and then handle the event? Similar method for hovering without the click.
Is this the kind of method required when using Direct2D and DirectWrite?
I haven't any experience with DirectX, but in OpenGL I build my buttons from scratch. Assuming you have animated sprites implemented, your buttons are essentially sprites that play certain animations in response to being clicked, hovered over, etc., and which you can register callbacks with. In my 2D engine, I have a class called UiButton, which inherits Sprite, and listens for various UI events. It gets more complicated when you want to handle keyboard navigation (arrow keys + enter to select) as you have to think about how the buttons are connected and which of them has focus at any given moment.
Here is my implementation for reference:
Headers: https://github.com/RobJinman/dodge/tree/master/Dodge/include/dodge/ui
Source: https://github.com/RobJinman/dodge/tree/master/Dodge/src/ui
If you're not prepared to roll your own, Googling "direct2d gui framework" seems to bring up some promising results.
Sorry I can't be of more help.
Yes, to draw a UI Button with Direct2D, you need to handle everything yourself, why? Direct2D is a 2D graphics API, not controls library. you need to draw the layout of your button, and handle the message of your button(such as click, mouse hover...), you lost lots of convenient and that's time-consuming, but the most important thing is: you can control it by yourself!
Direct2D is a graphics library. UI controls like, Text-selection, Textbox, and Buttons is not a part of it. However the benefits of using Direct2D and DirectWrite is we can implement our own UI controls, and having a full control of it.
Please also see: ID2D1Geometry::FillsContainsPoint() for hit-testing task.
Related
I've got application for applications sharing (over network). I need to highlight application's window when it is in sharing state. Currently I use GtkWidget to create border around the window to show that the window is shared. However there are a lot of problems with this approach (need to hide border when application is minimized, need to resize border when application has changed it's size, etc.).
So the question is there any way to show that the window is shared (highlight it somehow or make it flickering or something like that) using xlib (or gtk) API? I didn't find any useful info in the Internet, so I had to ask it here.
Thanks.
I was looking at how sometimes when you right click, the menu goes outside of the window.
Is this implemented with a separate window? If so, how can I get this functionality. I am trying to use GLFW, but I understand if it isn't possible.
Currently I am on windows, but I like keeping my options open, which is why GLFW would be preferable.
I noticed that GLUT has such a feature. If you are confused to what I am looking at then look at that.
Thanks for any help!!
Overlapping menus (in MS Windows) have to be implemented as a new top-level window, you would have a new OpenGL rendering context and draw the menu in that space - yes, it's a fair bit of work all for the edge-case of a menu overspilling the parent window,
However this isn't often a problem in OpenGL programming because if you're working on a full-screen game then the menu will always be displayed within the main window, and even if it isn't a full-screen a game your users really won't notice them as games tend to use different UI concepts like radial-menus which wouldn't overspill the parent window.
Or if you're working on a non-game title, chances are it isn't full-screen and is going to be an OpenGL rendering area within a larger application that is rendered using a native UI toolkit (e.g. 3ds Max, AutoCAD, etc), in which case no problem: just use native menus.
You can, of course, use native menus in an OpenGL application anyway, provided you do the necessary plumbing for native window messages.
I have a general question on how to develop an image viewer plugin with Firebreath. For that, I would like to incorporate a GUI framework, like wxwidget or Qt. The GUI would be used to to fire up some dialogs, adding a toolbar on top, or to open context menus with right clicking an image.
As far as I understand I have a hwnd handle and so I can draw onto a window. I also understand that I have various events I can react on, like mouse button clicks or keyboard strokes. But it fails me how I would add graphical menus, buttons, etc. I know I could use html around the window but that's not the route I like to take.
For instance, does it makes sense to render an user interface offline (in memory) onto an image and then keep somehow track of the state internally?
Has anyone done such thing? Or can anyone give me some insight on how to accomplish adding a user interface.
Assuming you only care about windows and assuming that you don't mind using a windowed plugin, which is the easiest (but no HTML elements can float over the plugin), it should be no different than creating a GUI in any other windows application.
You are given a window that shows up with the AttachedEvent; when DetachedEvent is fired you need to stop using the window. Many people create a child window inside that parent window and use that for all their actual real code which makes it a little easier to use one of those other abstractions, but that's basically all there is to it. I don't know specifically how you'd do it with QT or wxwidget but you'd create a child window of that HWND that you are given and have the abstraction do your thing for you.
As to whether or not it would be rendering things offscreen, etc, I have no idea; that would totally depend on the window system. There is no reason that I know of that you would need to do that, and most things just draw directly to the HWND, but there are a zillion different ways you could do it. It looks to me like what you really need is to understand how drawing in Windows actually works.
I hope that helps
I have implemented my custom button inheriting from CButton and drawing it by using uxtheme.dll (DrawThemeBackground with BP_PUSHBUTTON).
Everything works fine but I have two statuses (Normal and Pressed) which Hot status is the same. It means when the user places the cursor over the button it is drawn alike regardless the button status (Pressed or not).
This is a bit confusing to the user and I would like to change the way the button is drawn in Pressed & Hot status. Does anybody know a way?
I have also thought about custumizing the whole drawing but the buttons use gradients, borders, shadows, etc. So it is not easy to achive the same look&feel drawing everything by myself. Is there a way to find the source code of the dll or know how to do it?
Thanks in advance.
Javier
Note: I think I could be able to achive what I want to do by using CMFCButton and overriding the OnDraw method. Let the control draw the button on OnDrawBorder and then drawing the inside button myself. But I need to know how the control draws the inside button when pressed. It is a gradient and I can't guess how it's done. Does anybody have a clue?
In answer to your second question, if you derive from CMFCButton instead of CButton you can override OnDraw() or OnDrawText() instead of the usual DrawItem(). That way the default button background will be drawn, and then your drawing code is executed.
The only way I know of to really tackle this is to use 'custom draw', rather than 'owner draw'. Custom draw came in with Windows 2000, but is only used by button controls with comctrl32 6.0 (so Windows XP onwards), isn't very clearly documented, and isn't something MFC goes out of its way to support.
Anyway, the good thing about custom draw is that it lets you hook in at various points in the drawing process, unlike owner draw, which makes you deal with the whole thing. Have a look in MSDN at the NM_CUSTOMDRAW notification message.
For the other part of your problem, detecting the 'hot' state, the easiest way to do this is to use WM_MOUSEMOVE messages and the TrackMouseEvent() function to track whether the mouse is over your button.
Unfortunately this is a bit of a vague answer: the amount of code you need to demonstrate a button that uses custom draw is a bit too much to type into these answer boxes! I do have a project that demonstrates such techniques, using a custom draw button (falling back to owner draw on older Windows versions) that adds a little arrow to the button. You can have a look at the source code by getting
Windows_UI_source.zip
Open it and have a look at the "DropArrowButton" class. The important bit is the OnCustomDraw() handler and its helper function DrawControl(): these get called at the various button drawing phases, and use UxTheme to draw the control appropriately.
I finally figured out how to achive what I want to do. It's pretty easy indeed.
I use two calls to DrawThemeBackground. The first one with PBS_PRESSED and the second one with state PBS_HOT. Then I make a ExcludeClipRect to avoid from drawing over the center of the button.
Something like this:
DrawThemeBackground( hTheme,
pCustomDraw->hdc,
BP_PUSHBUTTON,
PBS_PRESSED,
&pCustomDraw->rc,
NULL);
CDC *pDC = CDC::FromHandle(pCustomDraw->hdc);
CRect rectClient;
GetClientRect(rectClient);
CRect rectInternal = rectClient;
rectInternal.DeflateRect(4,4);
pDC->SelectClipRgn(NULL);
pDC->ExcludeClipRect(&rectInternal);
DrawThemeBackground( hTheme,
pCustomDraw->hdc,
BP_PUSHBUTTON,
PBS_HOT,
&pCustomDraw->rc,
NULL);
pDC->SelectClipRgn(NULL);
Of course this is not the whole code but I think is enough to make my point.
Thanks.
I would like to be able to display some dynamic text at the mouse
cursor location in a win32 app, for instance to give an X,Y coordinate that
would move with the cursor as though attached. I can do this during a
mousemove event using a TextOut() call for the window at the mouse
coordinates and invalidate a rectange around a stored last cursor position
to clear up the previous output. However this can suffer from flickering and
cause problems with other things being drawn in a window such as tracker
boxes. Is there a better way to do this, perhaps using the existing cursor
drawing/invalidating mechanism ?
You can do this via ToolTips - check out CToolTipCtrl.
If you want flicker free tracking ToolTips then you will need to derive your own classes from CToolTipCtrl that use the trackActivate messages.
You may want to consider a small transparent window that you move to follow the mouse. In particular, since Windows 2000, Layered windows seem to be the weapon of choice (confession: no personal experience there).
You can overwrite OnSetCursor to get a dynamic mouse cursor. I just found a German tutorial.
German tutorial
English translated tutorial