简体   繁体   中英

Painting over wxPanel or add many wxControls?

I have form with space where have to be hexagon map. First what goes to mind - to place there wxPanel and paint over it everything what I want.

But really all hexagons are the same (there will be less then 10 types of them, different by color, maybe). And I read it is possible to create my own wxControls. What if I will create wxHexagon - control I need, and place them over wxPanel or over any other Layout?

That may be much easier to use: if user will Click in hex, I will not need to count coordinates and understand to which hex he clicked to select it, I will just need to set events for each hexagon control, isn't it?

Is that possible (main problem for me is to set such control size, because it have to be hexagon, not rectangle, and to place them over some layout in right positions.

What is better?

No need to create your own control. wxButton can display a bitmap. You might also use wxBitmapButton

to count coordinates and understand to which hex he clicked

Actually, this is the way I would do it, instead of mucking about with numerous identical controls one for each hex. It is almost trivial, if all your hexes are the same size. When user clicks on panel, divide x and y co-ords of click by hex size to find the row and column, multiply row by row count and add column and you immediately have the index of the hex clicked.

Creating custom controls in wxWidgets is pretty straightforward, this is not something reserved for the grand masters only. Basically, just derive a new C++ class (from wxWindow , you don't need wxPanel for a custom control like this, so why derive from it needlessly?), bind to the events you're interested in (at least wxEVT_PAINT , quite often wxEVT_CHAR and mouse events) and implement their handlers and, the only non-obvious part, perhaps, override DoGetBestClientSize() base class virtual if your control has a natural best size.

And that's it. So it doesn't take more code to create a custom control than to implement its functionality in an existing window. And because of this, you should make your choice solely from the point of view of design of your code, ie does it make sense to have a single such control or will they always be invariably used in groups? Could it ever make sense to reuse it? Could you need similar controls (which could be implemented as derived classes to reuse the implementation) in the future? And so on.

Not an answer, but too lengthy for a comment.

Without definite stated goals, which is best seems likely to be entirely subjective and a matter of personal preference.

That said, I guess which implementation ultimately comes down to a number of factors. As a minimum:

  1. Do you think it likely that you'll want hexagon-shaped controls in the future
  2. How close will they be to one-another

    • Implementing them as a new control would certainly make re-use at a later date very quick and easy
    • If they are to touch each other (like a honeycomb), I'd imagine it to be cleaner to handle hit-testing yourself, rather than rely on the (rectangular?) hit-testing employed by regular buttons.

I wanted an LCD control to mimic 1602 LCDs (1 bit ASCII), so I implemented it as a new control that inherited from wxWindow. At a later time, I simply inherited from my control and made it function as a 16bit 160x128 color graphics lcd. It was very quick to adapt. Since it was a control of it's own, I simply included the necessary files and re-implemented the required member functions. There was no need to hack parts out of an old project.

As for the hit-testing - when arranged against each other, using a square bounding-box for hit-testing will mean that you have overlapping bounding boxes. I think you'd have to subclass a wxBitmapButton or wxButton in order to handle this situation correctly. Since the hexagon size would be determined by an image, rather than with variables, I can see this getting really messy, really quickly.

Perhaps I'm being pessimistic about the task of using a wxButton or wxBitmapButton and simultaneously being overly optimistic about implementing a custom-control. In any case, I'd still be inclined to make each hexagon a control of some description, so they they can each handle hit-testing and click-event generation for you - putting this and the layout logic in the main program would not be my preference.

I'd probably use the diameter of a circle that they would fit in as the size, rather than a side-length measurement, though each would be easy enough and have situations they were better suited to. You could quite quickly and easily work out the ratio between each.

As a rough guide: 1 unit circle could hold a hexagon that was 1 unit from corner to the opposite corner, 0.89 units from one side to the opposite one and 0.48 units along each side.

In summary, the easiest to use would be a custom-control. The easiest/quickest/smallest-code to implement may well be a wxButton or wxImageButton. The best functionality would come from a custom control. I'd be interested to see how rotation would be handled using a standard button class..

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM