bsnes/higan/phoenix/core/layout/vertical-layout.cpp

143 lines
4.3 KiB
C++
Raw Normal View History

void VerticalLayout::append(Sizable &sizable, const Size &size, unsigned spacing) {
for(auto &child : children) if(child.sizable == &sizable) return;
children.append({ &sizable, size.width, size.height, spacing });
synchronizeLayout();
if(window()) window()->synchronizeLayout();
}
void VerticalLayout::append(Sizable &sizable) {
for(auto &child : children) if(child.sizable == &sizable) return;
Layout::append(sizable);
if(window()) window()->synchronizeLayout();
}
bool VerticalLayout::enabled() {
if(layout()) return state.enabled && layout()->enabled();
return state.enabled;
Update to v075r08 release. byuu says: Eleven hours of work. Window is now a base type (inherits from Object, not Widget), same for Layout. FixedLayout still inherits from Layout. Added HorizontalLayout and VerticalLayout types, that can append each other to themselves to create box layouts. Layout margins are supported, spacing is specified inline (I find this a much better way to fine-grain spacing than Qt's single setSpacing function), and alignment is handled strictly via padding widgets (insert a zero-sized label and it will automatically grow to consume all extra space.) Overall, my box packing model is slightly less powerful than Qt's, but it is a good deal simpler and and easier to use in 90% of cases. The one limitation I hit was with my input settings window, I'm not currently able to embed two different layouts and toggle one on and the other off to show only either { mouse x-axis, y-axis } or { mouse left, middle, right }, so they instead just space out differently and I had to grow the input window width a bit to compensate. Resizing works great, pretty cool seeing that this is the first time I've ever written my own resizer. I had to fight with Qt for several hours to the point of potentially developing an aneurysm, but I finally got it to properly handle geometry and sizing stuff. Some weird issue with the bsnes viewport widget, I tell it to resize and for some reason it doesn't. Cheap hack, I just make it constantly resize every video refresh and it eventually takes. Wish I knew what was up with that. All of bsnes now uses dynamic layouts sans the main window, so you can resize them however you like. This is still all Qt-only, I'm afraid. The other two ports are in-progress.
2011-02-07 09:15:43 +00:00
}
Geometry VerticalLayout::minimumGeometry() {
unsigned width = 0, height = 0;
for(auto &child : children) {
if(child.width == MinimumSize || child.width == MaximumSize) {
width = max(width, child.sizable->minimumGeometry().width);
continue;
}
width = max(width, child.width);
}
for(auto &child : children) {
height += child.spacing;
if(child.height == MinimumSize || child.height == MaximumSize) {
height += child.sizable->minimumGeometry().height;
continue;
}
height += child.height;
}
return { 0, 0, state.margin * 2 + width, state.margin * 2 + height };
}
void VerticalLayout::remove(Sizable &sizable) {
for(unsigned n = 0; n < children.size(); n++) {
if(children[n].sizable == &sizable) {
if(dynamic_cast<Layout*>(children[n].sizable)) {
Layout *layout = (Layout*)children[n].sizable;
layout->reset();
}
children.remove(n);
Layout::remove(sizable);
if(window()) window()->synchronizeLayout();
break;
}
}
}
Update to v075r09 release. byuu says: Ported phoenix/Windows and phoenix/GTK+ over to the new system. There are some problems that need to be addressed: - Windows ComboBox height setting needs widget creation height to properly scale itself (make Widget::setGeometry virtual and override ComboBox::setGeometry) - Windows Canvas is completely broken - GTK+ Canvas is slow as shit compared to Qt Canvas, probably nothing I can do about it, have to do a very costly conversion because GTK+ is stupid and uses BGR like Nintendo - GTK+ listboxes are fucking insanely complicated to set up. Currently I just split the second-half of creation to the setHeaderText call, but when you don't call that, things explode - I'm probably going to have to completely destroy and recreate listboxes when changing the header text / column count - Qt resize code is still impossible to get right, it's not letting me size a window > 2/3rds of the screen size (it's in their docs) - I swear, Qt is the most painful API in the world to move/size windows with - now that Window is separate, it really needs geometry() and frameGeometry() as the two are quite different - I need a way to toggle window resizability for fixed layouts, Qt is once again going to be a nightmare as it lacks a way to do this other than fixed layouts - GTK+ currently explodes on bsnes, millions of console messages, wonderful - plenty more I'm forgetting One bit of really cool/good news though: I made Fixed/Horizontal/Vertical layouts external to phoenix itself. The code is included for all targets so that it's always there and compiled into one object, but the great news is that you can easily write your own layout widgets and they'll work on all toolkits instantly. That resize issue with bsnes was so simple it's annoying: my FixedLayout container was repositioning on geometry updates. Made it only do it once at creation like it should. bsnes now has a fancy resize, grow the window and get black borders, shrink it and the video shrinks with it. I plan to make it fancier with constraint settings (center, scale, stretch). Basically I want to turn the fullscreen setting into a general setting that also applies to windowed scaling. I will probably turn the video scale X sizes into regular items instead of radio boxes, so you can easily reset to a fixed size whenever you want. Update bsnes to remember width,height geometry as well and it should be quite nice.
2011-02-07 09:18:01 +00:00
void VerticalLayout::reset() {
for(auto &child : children) {
Update to v082r18 release. byuu says: There we go, the GUI is nearly feature-complete once again. All cores now output their native video format (NES={emphasis}{palette}, SNES=BGR555, GameBoy={ bright, normal, darker, darkest }), and are transformed to RGB555 data that is passed to the video renderer. The video renderer then uses its internal palette to apply brightness/contrast/gamma/ramp adjustments and outputs in RGB888 color space. This does add in another rendering pass, unfortunately, but it's a necessary one for universal support. The plan is to adapt all filters to take RGB555 input, and output RGB555 data as well. By doing this, it will be possible to stack filters. However, it's a bit complicated: I need to plan how the stacking should occur (eg we never want to apply scanlines before HQ2x, etc.) Added input frequency adjustments for all three systems. I can easily get perfect video/audio sync on all three now, hooray. Long-term, it seems like we only really need one, and we can do a video/audio delta to get an adjusted value. But for now, this gets the job done. Added audio volume adjust. I left out the balance for now, since it's obviously impossible to balance the NES' single channel audio (I can duplicate the channel, and do twice the filtering work, but ... why?) I replaced NTSC/PAL TV mode selection with an "Enable Overscan" checkbox. On, you get 240 lines on NES+SNES. Off, you get 224 lines on NES+SNES. Also added aspect correction box back. I don't do that gross PAL distortion shit anymore, sorry PAL people. I just scale up the 54/47*(240/224) aspect correction for overscan off mode. All memory is loaded and saved now, for all three systems (hooray, now you can actually play Zelda 1&2.) Added all of the old bsnes hotkeys, with the exception of capture screenshot. May add again later. May come up with something a bit different for extra features. Re-added the NSS DIP switch setting window. Since geometry is saved, I didn't want to auto-hide rows, so now you'll see all eight possible DIPs, and the ones not used are grayed out. Ultimately, nobody will notice since we only have DIPs for ActRaiser NSS, and nobody's probably even using the XML file for that anyway. Whatever, it's nice to have anyway. Took FitzRoy's advice and single-item combo boxes on the input selection are disabled, so the user doesn't waste time checking them. I wanted to leave text so that you know there's not a problem. Qt disabled radio box items look almost exactly like enabled ones. Fixed lots of issues in phoenix and extended it a bit. But I was still having trouble with radio box grouping, so I said fuck it and made the panels show/hide based instead of append/remove based. That's all for stuff off the checklist, I did a bunch of other things I don't recall. So yeah, I'd say the GUI is 100% usable now. This is my opinion on how multi-platform GUIs should be done =) Oh, I figure I should mention, but the NES core is GPLv3, and all future SNES+GB releases will be as well. It's a move against Microsoft's Metro store.
2011-09-20 14:04:43 +00:00
if(window() && dynamic_cast<Layout*>(child.sizable)) ((Layout*)child.sizable)->reset();
if(window() && dynamic_cast<Widget*>(child.sizable)) window()->remove((Widget&)*child.sizable);
}
}
Update to v075r08 release. byuu says: Eleven hours of work. Window is now a base type (inherits from Object, not Widget), same for Layout. FixedLayout still inherits from Layout. Added HorizontalLayout and VerticalLayout types, that can append each other to themselves to create box layouts. Layout margins are supported, spacing is specified inline (I find this a much better way to fine-grain spacing than Qt's single setSpacing function), and alignment is handled strictly via padding widgets (insert a zero-sized label and it will automatically grow to consume all extra space.) Overall, my box packing model is slightly less powerful than Qt's, but it is a good deal simpler and and easier to use in 90% of cases. The one limitation I hit was with my input settings window, I'm not currently able to embed two different layouts and toggle one on and the other off to show only either { mouse x-axis, y-axis } or { mouse left, middle, right }, so they instead just space out differently and I had to grow the input window width a bit to compensate. Resizing works great, pretty cool seeing that this is the first time I've ever written my own resizer. I had to fight with Qt for several hours to the point of potentially developing an aneurysm, but I finally got it to properly handle geometry and sizing stuff. Some weird issue with the bsnes viewport widget, I tell it to resize and for some reason it doesn't. Cheap hack, I just make it constantly resize every video refresh and it eventually takes. Wish I knew what was up with that. All of bsnes now uses dynamic layouts sans the main window, so you can resize them however you like. This is still all Qt-only, I'm afraid. The other two ports are in-progress.
2011-02-07 09:15:43 +00:00
void VerticalLayout::setAlignment(double alignment) {
state.alignment = max(0.0, min(1.0, alignment));
}
void VerticalLayout::setEnabled(bool enabled) {
state.enabled = enabled;
for(auto &child : children) {
child.sizable->setEnabled(dynamic_cast<Widget*>(child.sizable) ? child.sizable->enabled() : enabled);
}
}
void VerticalLayout::setGeometry(const Geometry &containerGeometry) {
auto children = this->children;
for(auto &child : children) {
if(child.width == MinimumSize) child.width = child.sizable->minimumGeometry().width;
if(child.height == MinimumSize) child.height = child.sizable->minimumGeometry().height;
}
Update to v075r08 release. byuu says: Eleven hours of work. Window is now a base type (inherits from Object, not Widget), same for Layout. FixedLayout still inherits from Layout. Added HorizontalLayout and VerticalLayout types, that can append each other to themselves to create box layouts. Layout margins are supported, spacing is specified inline (I find this a much better way to fine-grain spacing than Qt's single setSpacing function), and alignment is handled strictly via padding widgets (insert a zero-sized label and it will automatically grow to consume all extra space.) Overall, my box packing model is slightly less powerful than Qt's, but it is a good deal simpler and and easier to use in 90% of cases. The one limitation I hit was with my input settings window, I'm not currently able to embed two different layouts and toggle one on and the other off to show only either { mouse x-axis, y-axis } or { mouse left, middle, right }, so they instead just space out differently and I had to grow the input window width a bit to compensate. Resizing works great, pretty cool seeing that this is the first time I've ever written my own resizer. I had to fight with Qt for several hours to the point of potentially developing an aneurysm, but I finally got it to properly handle geometry and sizing stuff. Some weird issue with the bsnes viewport widget, I tell it to resize and for some reason it doesn't. Cheap hack, I just make it constantly resize every video refresh and it eventually takes. Wish I knew what was up with that. All of bsnes now uses dynamic layouts sans the main window, so you can resize them however you like. This is still all Qt-only, I'm afraid. The other two ports are in-progress.
2011-02-07 09:15:43 +00:00
Geometry geometry = containerGeometry;
geometry.x += state.margin;
geometry.y += state.margin;
geometry.width -= state.margin * 2;
geometry.height -= state.margin * 2;
unsigned minimumHeight = 0, maximumHeightCounter = 0;
for(auto &child : children) {
if(child.height == MaximumSize) maximumHeightCounter++;
if(child.height != MaximumSize) minimumHeight += child.height;
minimumHeight += child.spacing;
Update to v075r08 release. byuu says: Eleven hours of work. Window is now a base type (inherits from Object, not Widget), same for Layout. FixedLayout still inherits from Layout. Added HorizontalLayout and VerticalLayout types, that can append each other to themselves to create box layouts. Layout margins are supported, spacing is specified inline (I find this a much better way to fine-grain spacing than Qt's single setSpacing function), and alignment is handled strictly via padding widgets (insert a zero-sized label and it will automatically grow to consume all extra space.) Overall, my box packing model is slightly less powerful than Qt's, but it is a good deal simpler and and easier to use in 90% of cases. The one limitation I hit was with my input settings window, I'm not currently able to embed two different layouts and toggle one on and the other off to show only either { mouse x-axis, y-axis } or { mouse left, middle, right }, so they instead just space out differently and I had to grow the input window width a bit to compensate. Resizing works great, pretty cool seeing that this is the first time I've ever written my own resizer. I had to fight with Qt for several hours to the point of potentially developing an aneurysm, but I finally got it to properly handle geometry and sizing stuff. Some weird issue with the bsnes viewport widget, I tell it to resize and for some reason it doesn't. Cheap hack, I just make it constantly resize every video refresh and it eventually takes. Wish I knew what was up with that. All of bsnes now uses dynamic layouts sans the main window, so you can resize them however you like. This is still all Qt-only, I'm afraid. The other two ports are in-progress.
2011-02-07 09:15:43 +00:00
}
for(auto &child : children) {
if(child.width == MaximumSize) child.width = geometry.width;
if(child.height == MaximumSize) child.height = (geometry.height - minimumHeight) / maximumHeightCounter;
Update to v075r08 release. byuu says: Eleven hours of work. Window is now a base type (inherits from Object, not Widget), same for Layout. FixedLayout still inherits from Layout. Added HorizontalLayout and VerticalLayout types, that can append each other to themselves to create box layouts. Layout margins are supported, spacing is specified inline (I find this a much better way to fine-grain spacing than Qt's single setSpacing function), and alignment is handled strictly via padding widgets (insert a zero-sized label and it will automatically grow to consume all extra space.) Overall, my box packing model is slightly less powerful than Qt's, but it is a good deal simpler and and easier to use in 90% of cases. The one limitation I hit was with my input settings window, I'm not currently able to embed two different layouts and toggle one on and the other off to show only either { mouse x-axis, y-axis } or { mouse left, middle, right }, so they instead just space out differently and I had to grow the input window width a bit to compensate. Resizing works great, pretty cool seeing that this is the first time I've ever written my own resizer. I had to fight with Qt for several hours to the point of potentially developing an aneurysm, but I finally got it to properly handle geometry and sizing stuff. Some weird issue with the bsnes viewport widget, I tell it to resize and for some reason it doesn't. Cheap hack, I just make it constantly resize every video refresh and it eventually takes. Wish I knew what was up with that. All of bsnes now uses dynamic layouts sans the main window, so you can resize them however you like. This is still all Qt-only, I'm afraid. The other two ports are in-progress.
2011-02-07 09:15:43 +00:00
}
unsigned maximumWidth = 0;
for(auto &child : children) maximumWidth = max(maximumWidth, child.width);
for(auto &child : children) {
unsigned pivot = (maximumWidth - child.width) * state.alignment;
Geometry childGeometry = { geometry.x + pivot, geometry.y, child.width, child.height };
child.sizable->setGeometry(childGeometry);
geometry.y += child.height + child.spacing;
geometry.height -= child.height + child.spacing;
Update to v075r08 release. byuu says: Eleven hours of work. Window is now a base type (inherits from Object, not Widget), same for Layout. FixedLayout still inherits from Layout. Added HorizontalLayout and VerticalLayout types, that can append each other to themselves to create box layouts. Layout margins are supported, spacing is specified inline (I find this a much better way to fine-grain spacing than Qt's single setSpacing function), and alignment is handled strictly via padding widgets (insert a zero-sized label and it will automatically grow to consume all extra space.) Overall, my box packing model is slightly less powerful than Qt's, but it is a good deal simpler and and easier to use in 90% of cases. The one limitation I hit was with my input settings window, I'm not currently able to embed two different layouts and toggle one on and the other off to show only either { mouse x-axis, y-axis } or { mouse left, middle, right }, so they instead just space out differently and I had to grow the input window width a bit to compensate. Resizing works great, pretty cool seeing that this is the first time I've ever written my own resizer. I had to fight with Qt for several hours to the point of potentially developing an aneurysm, but I finally got it to properly handle geometry and sizing stuff. Some weird issue with the bsnes viewport widget, I tell it to resize and for some reason it doesn't. Cheap hack, I just make it constantly resize every video refresh and it eventually takes. Wish I knew what was up with that. All of bsnes now uses dynamic layouts sans the main window, so you can resize them however you like. This is still all Qt-only, I'm afraid. The other two ports are in-progress.
2011-02-07 09:15:43 +00:00
}
}
Update to v075r08 release. byuu says: Eleven hours of work. Window is now a base type (inherits from Object, not Widget), same for Layout. FixedLayout still inherits from Layout. Added HorizontalLayout and VerticalLayout types, that can append each other to themselves to create box layouts. Layout margins are supported, spacing is specified inline (I find this a much better way to fine-grain spacing than Qt's single setSpacing function), and alignment is handled strictly via padding widgets (insert a zero-sized label and it will automatically grow to consume all extra space.) Overall, my box packing model is slightly less powerful than Qt's, but it is a good deal simpler and and easier to use in 90% of cases. The one limitation I hit was with my input settings window, I'm not currently able to embed two different layouts and toggle one on and the other off to show only either { mouse x-axis, y-axis } or { mouse left, middle, right }, so they instead just space out differently and I had to grow the input window width a bit to compensate. Resizing works great, pretty cool seeing that this is the first time I've ever written my own resizer. I had to fight with Qt for several hours to the point of potentially developing an aneurysm, but I finally got it to properly handle geometry and sizing stuff. Some weird issue with the bsnes viewport widget, I tell it to resize and for some reason it doesn't. Cheap hack, I just make it constantly resize every video refresh and it eventually takes. Wish I knew what was up with that. All of bsnes now uses dynamic layouts sans the main window, so you can resize them however you like. This is still all Qt-only, I'm afraid. The other two ports are in-progress.
2011-02-07 09:15:43 +00:00
void VerticalLayout::setMargin(unsigned margin) {
state.margin = margin;
Update to v075r11 release. byuu says: Rewrote the way menus are attached, they act like layouts/widgets now. All three phoenix targets once again work with both radio menu items and radio widgets. Both GTK+ and Qt have built-in group controls right inside the widgets, so I don't have to keep my own groups around anymore. They do act screwy at widget creation though, have to jump through some hoops to get it to work right. All I can say is, definitely set all child widgets to the parent before trying to check any of them. My long-term goal for the main window is to honor the fullscreen video setting as a generic setting, and let the window scale auto-fit the best possible size that matches your scale preference into the output window, centered just like fullscreen. For now, I've just set it to a fixed window size until I finish working on phoenix. The scale X settings will just be to snap the window to an exact size in case you don't want any black borders, they won't be radio items and the bsnes-geometry.cfg file will save width/height information as well. Simplified the sizing requirements for creating layouts and updated all bsnes windows to support the new system. Layouts also expose their minimum width/height values, which I use to create perfectly sized windows on all three platforms. This will fix cut-off heights on the last Windows WIP. Qt is being annoying though and forcing a minimum window size of 300,100 despite me telling it to use a smaller window size. Always have to fight with Qt, I swear to god.
2011-02-10 10:08:12 +00:00
}
void VerticalLayout::setVisible(bool visible) {
state.visible = visible;
for(auto &child : children) {
child.sizable->setVisible(dynamic_cast<Widget*>(child.sizable) ? child.sizable->visible() : visible);
}
}
void VerticalLayout::synchronizeLayout() {
for(auto &child : children) Layout::append(*child.sizable);
}
bool VerticalLayout::visible() {
if(layout()) return state.visible && layout()->visible();
return state.visible;
}
Update to v075r08 release. byuu says: Eleven hours of work. Window is now a base type (inherits from Object, not Widget), same for Layout. FixedLayout still inherits from Layout. Added HorizontalLayout and VerticalLayout types, that can append each other to themselves to create box layouts. Layout margins are supported, spacing is specified inline (I find this a much better way to fine-grain spacing than Qt's single setSpacing function), and alignment is handled strictly via padding widgets (insert a zero-sized label and it will automatically grow to consume all extra space.) Overall, my box packing model is slightly less powerful than Qt's, but it is a good deal simpler and and easier to use in 90% of cases. The one limitation I hit was with my input settings window, I'm not currently able to embed two different layouts and toggle one on and the other off to show only either { mouse x-axis, y-axis } or { mouse left, middle, right }, so they instead just space out differently and I had to grow the input window width a bit to compensate. Resizing works great, pretty cool seeing that this is the first time I've ever written my own resizer. I had to fight with Qt for several hours to the point of potentially developing an aneurysm, but I finally got it to properly handle geometry and sizing stuff. Some weird issue with the bsnes viewport widget, I tell it to resize and for some reason it doesn't. Cheap hack, I just make it constantly resize every video refresh and it eventually takes. Wish I knew what was up with that. All of bsnes now uses dynamic layouts sans the main window, so you can resize them however you like. This is still all Qt-only, I'm afraid. The other two ports are in-progress.
2011-02-07 09:15:43 +00:00
VerticalLayout::VerticalLayout() {
state.alignment = 0.0;
state.enabled = true;
state.margin = 0;
state.visible = true;
}
VerticalLayout::~VerticalLayout() {
while(children.size()) remove(*children[0].sizable);
Update to v075r08 release. byuu says: Eleven hours of work. Window is now a base type (inherits from Object, not Widget), same for Layout. FixedLayout still inherits from Layout. Added HorizontalLayout and VerticalLayout types, that can append each other to themselves to create box layouts. Layout margins are supported, spacing is specified inline (I find this a much better way to fine-grain spacing than Qt's single setSpacing function), and alignment is handled strictly via padding widgets (insert a zero-sized label and it will automatically grow to consume all extra space.) Overall, my box packing model is slightly less powerful than Qt's, but it is a good deal simpler and and easier to use in 90% of cases. The one limitation I hit was with my input settings window, I'm not currently able to embed two different layouts and toggle one on and the other off to show only either { mouse x-axis, y-axis } or { mouse left, middle, right }, so they instead just space out differently and I had to grow the input window width a bit to compensate. Resizing works great, pretty cool seeing that this is the first time I've ever written my own resizer. I had to fight with Qt for several hours to the point of potentially developing an aneurysm, but I finally got it to properly handle geometry and sizing stuff. Some weird issue with the bsnes viewport widget, I tell it to resize and for some reason it doesn't. Cheap hack, I just make it constantly resize every video refresh and it eventually takes. Wish I knew what was up with that. All of bsnes now uses dynamic layouts sans the main window, so you can resize them however you like. This is still all Qt-only, I'm afraid. The other two ports are in-progress.
2011-02-07 09:15:43 +00:00
}