Changes for Spanning View across split screens

This is intended to give a better perspective view using multiple monitors angled inwards

git-svn-id: https://svn.code.sf.net/p/speed-dreams/code/trunk@4702 30fe4595-0a0c-4342-8851-515496e4dcbd

Former-commit-id: be1e2f6b9cdb7827facbe142ecbe643193fc039e
Former-commit-id: 0fa9d8c39c31afd614111de4a1ab5972e053b8ed
This commit is contained in:
mungewell 2012-04-19 05:49:12 +00:00
parent 58938a6859
commit 714f6c6019
7 changed files with 423 additions and 36 deletions

View file

@ -96,6 +96,15 @@
#define GR_ATT_REAR_MAP2 "Rear Level Map 2" #define GR_ATT_REAR_MAP2 "Rear Level Map 2"
#define GR_ATT_REAR_MAP3 "Rear Level Map 3" #define GR_ATT_REAR_MAP3 "Rear Level Map 3"
#define GR_SCT_MONITOR "Monitor"
#define GR_ATT_MONITOR "monitor type"
#define GR_VAL_MONITOR_16BY9 "16by9"
#define GR_VAL_MONITOR_4BY3 "4by3"
#define GR_ATT_SPANSPLIT "span splits"
#define GR_VAL_YES "yes"
#define GR_VAL_NO "no"
#define GR_ATT_BEZELCOMP "bezel compensation"
#endif /* _GRAPHV1_H_ */ #endif /* _GRAPHV1_H_ */

View file

@ -28,7 +28,10 @@
#include "grutil.h" //grGetHOT #include "grutil.h" //grGetHOT
static char path[1024]; static char path[1024];
static float allfovy;
static int spansplit;
static float spanfovy;
static float bezelcomp;
// Utilities ================================================================ // Utilities ================================================================
@ -157,7 +160,11 @@ float cGrPerspCamera::getLODFactor(float x, float y, float z) {
void cGrPerspCamera::setViewOffset(float newOffset) void cGrPerspCamera::setViewOffset(float newOffset)
{ {
viewOffset = newOffset; if (spansplit && newOffset) {
viewOffset = newOffset;
spanfovy = fovy;
} else
viewOffset = 0;
} }
void cGrPerspCamera::setZoom(int cmd) void cGrPerspCamera::setZoom(int cmd)
@ -197,7 +204,9 @@ void cGrPerspCamera::setZoom(int cmd)
} }
limitFov(); limitFov();
allfovy = fovy;
if (spansplit && viewOffset)
spanfovy = fovy;
sprintf(buf, "%s-%d-%d", GR_ATT_FOVY, screen->getCurCamHead(), getId()); sprintf(buf, "%s-%d-%d", GR_ATT_FOVY, screen->getCurCamHead(), getId());
sprintf(path, "%s/%d", GR_SCT_DISPMODE, screen->getId()); sprintf(path, "%s/%d", GR_SCT_DISPMODE, screen->getId());
@ -283,7 +292,7 @@ class cGrCarCamInsideDriverEye : public cGrPerspCamera
void update(tCarElt *car, tSituation *s) { void update(tCarElt *car, tSituation *s) {
sgVec3 P, p; sgVec3 P, p;
float offset; float offset = 0;
p[0] = car->_drvPos_x; p[0] = car->_drvPos_x;
p[1] = car->_drvPos_y; p[1] = car->_drvPos_y;
@ -294,9 +303,11 @@ class cGrCarCamInsideDriverEye : public cGrPerspCamera
eye[1] = p[1]; eye[1] = p[1];
eye[2] = p[2]; eye[2] = p[2];
// Compute offset angle (fudged in bezel compensation) // Compute offset angle and bezel compensation)
offset = viewOffset * 1.10 * atan(screen->getViewRatio() * tan(allfovy * M_PI / 360.0)) * 2; if (spansplit && viewOffset) {
fovy = allfovy; offset += (viewOffset - 10) * bezelcomp / 100 * atan(screen->getViewRatio() * tan(spanfovy * M_PI / 360.0)) * 2;
fovy = spanfovy;
}
P[0] = car->_bonnetPos_x + 30.0 * cos(car->_glance + offset); P[0] = car->_bonnetPos_x + 30.0 * cos(car->_glance + offset);
P[1] = car->_bonnetPos_y - 30.0 * sin(car->_glance + offset); P[1] = car->_bonnetPos_y - 30.0 * sin(car->_glance + offset);
@ -561,6 +572,7 @@ class cGrCarCamInsideFixedCar : public cGrPerspCamera
void update(tCarElt *car, tSituation *s) { void update(tCarElt *car, tSituation *s) {
sgVec3 P, p; sgVec3 P, p;
float offset = 0;
p[0] = car->_bonnetPos_x; p[0] = car->_bonnetPos_x;
p[1] = car->_bonnetPos_y; p[1] = car->_bonnetPos_y;
@ -570,9 +582,15 @@ class cGrCarCamInsideFixedCar : public cGrPerspCamera
eye[0] = p[0]; eye[0] = p[0];
eye[1] = p[1]; eye[1] = p[1];
eye[2] = p[2]; eye[2] = p[2];
// Compute offset angle and bezel compensation)
if (spansplit && viewOffset) {
offset += (viewOffset - 10) * bezelcomp / 100 * atan(screen->getViewRatio() * tan(spanfovy * M_PI / 360.0)) * 2;
fovy = spanfovy;
}
P[0] = car->_bonnetPos_x + 30.0 * cos(car->_glance); P[0] = car->_bonnetPos_x + 30.0 * cos(car->_glance + offset);
P[1] = car->_bonnetPos_y - 30.0 * sin(car->_glance); P[1] = car->_bonnetPos_y - 30.0 * sin(car->_glance + offset);
P[2] = car->_bonnetPos_z; P[2] = car->_bonnetPos_z;
sgXformPnt3(P, car->_posMat); sgXformPnt3(P, car->_posMat);
@ -609,6 +627,7 @@ class cGrCarCamBehindFixedCar : public cGrPerspCamera
void update(tCarElt *car, tSituation *s) void update(tCarElt *car, tSituation *s)
{ {
sgVec3 P, p; sgVec3 P, p;
float offset = 0;
p[0] = car->_bonnetPos_x - 6.0f; p[0] = car->_bonnetPos_x - 6.0f;
p[1] = car->_bonnetPos_y; p[1] = car->_bonnetPos_y;
@ -619,8 +638,14 @@ class cGrCarCamBehindFixedCar : public cGrPerspCamera
eye[1] = p[1]; eye[1] = p[1];
eye[2] = p[2]; eye[2] = p[2];
P[0] = car->_bonnetPos_x + 30.0; // Compute offset angle and bezel compensation)
P[1] = car->_bonnetPos_y; if (spansplit && viewOffset) {
offset += (viewOffset - 10) * bezelcomp / 100 * atan(screen->getViewRatio() * tan(spanfovy * M_PI / 360.0)) * 2;
fovy = spanfovy;
}
P[0] = car->_bonnetPos_x + 30.0 * cos(offset);
P[1] = car->_bonnetPos_y - 30.0 * sin(offset);
P[2] = car->_bonnetPos_z; P[2] = car->_bonnetPos_z;
sgXformPnt3(P, car->_posMat); sgXformPnt3(P, car->_posMat);
@ -673,6 +698,7 @@ class cGrCarCamBehindReverse : public cGrPerspCamera
void update(tCarElt *car, tSituation *s) void update(tCarElt *car, tSituation *s)
{ {
sgVec3 P, p; sgVec3 P, p;
float offset = 0;
p[0] = car->_bonnetPos_x - (car->_dimension_x/2); p[0] = car->_bonnetPos_x - (car->_dimension_x/2);
p[1] = car->_bonnetPos_y; p[1] = car->_bonnetPos_y;
@ -682,9 +708,15 @@ class cGrCarCamBehindReverse : public cGrPerspCamera
eye[0] = p[0]; eye[0] = p[0];
eye[1] = p[1]; eye[1] = p[1];
eye[2] = p[2]; eye[2] = p[2];
// Compute offset angle and bezel compensation)
if (spansplit && viewOffset) {
offset += (viewOffset - 10) * bezelcomp / 100 * atan(screen->getViewRatio() * tan(spanfovy * M_PI / 360.0)) * 2;
fovy = spanfovy;
}
P[0] = car->_bonnetPos_x; P[0] = car->_bonnetPos_x + 30.0 * cos(offset);
P[1] = car->_bonnetPos_y; P[1] = car->_bonnetPos_y - 30.0 * sin(offset);
P[2] = car->_bonnetPos_z; P[2] = car->_bonnetPos_z;
sgXformPnt3(P, car->_posMat); sgXformPnt3(P, car->_posMat);
@ -1560,6 +1592,13 @@ grCamCreateSceneCameraList(class cGrScreen *myscreen, tGrCamHead *cams,
int c; int c;
class cGrCamera *cam; class cGrCamera *cam;
/* Check whether view should be spanned across vertical splits */
const char *pszSpanSplit =
GfParmGetStr(grHandle, GR_SCT_MONITOR, GR_ATT_SPANSPLIT, GR_VAL_NO);
spansplit = strcmp(pszSpanSplit, GR_VAL_YES) ? 0 : 1;
bezelcomp = (float)GfParmGetNum(grHandle, GR_SCT_MONITOR, GR_ATT_BEZELCOMP, NULL, 120);
/* Scene Cameras */ /* Scene Cameras */
c = 0; c = 0;

View file

@ -138,8 +138,8 @@ grAdaptScreenSize(void)
grNbArrangeScreens = 0; grNbArrangeScreens = 0;
case 0: case 0:
// Left & Right half of the window // Left & Right half of the window
grScreens[0]->activate(grWinx, grWiny, grWinw / 2, grWinh, -0.5); grScreens[0]->activate(grWinx, grWiny, grWinw / 2, grWinh, -0.5 + 10);
grScreens[1]->activate(grWinx + grWinw / 2, grWiny, grWinw / 2, grWinh, 0.5); grScreens[1]->activate(grWinx + grWinw / 2, grWiny, grWinw / 2, grWinh, 0.5 + 10);
break; break;
case 1: case 1:
// Top & Bottom half of the window // Top & Bottom half of the window
@ -167,9 +167,9 @@ grAdaptScreenSize(void)
grNbArrangeScreens = 0; grNbArrangeScreens = 0;
case 0: case 0:
// All side by side // All side by side
grScreens[0]->activate(grWinx, grWiny, grWinw / 3, grWinh, -1); grScreens[0]->activate(grWinx, grWiny, grWinw / 3, grWinh, -1 + 10);
grScreens[1]->activate(grWinx + grWinw / 3, grWiny, grWinw / 3, grWinh, 0.0); grScreens[1]->activate(grWinx + grWinw / 3, grWiny, grWinw / 3, grWinh, 0.0 + 10);
grScreens[2]->activate(grWinx + grWinw * 2/3, grWiny, grWinw / 3, grWinh, 1); grScreens[2]->activate(grWinx + grWinw * 2/3, grWiny, grWinw / 3, grWinh, 1 + 10);
break; break;
case 1: case 1:
// Left/Right above wide // Left/Right above wide
@ -217,10 +217,10 @@ grAdaptScreenSize(void)
grNbArrangeScreens = 0; grNbArrangeScreens = 0;
case 0: case 0:
// All side by side // All side by side
grScreens[0]->activate(grWinx, grWiny, grWinw / 4, grWinh, -1.5); grScreens[0]->activate(grWinx, grWiny, grWinw / 4, grWinh, -1.5 + 10);
grScreens[1]->activate(grWinx + grWinw / 4, grWiny, grWinw / 4, grWinh, -0.5); grScreens[1]->activate(grWinx + grWinw / 4, grWiny, grWinw / 4, grWinh, -0.5 + 10);
grScreens[2]->activate(grWinx + grWinw * 2/4, grWiny, grWinw / 4, grWinh, 0.5); grScreens[2]->activate(grWinx + grWinw * 2/4, grWiny, grWinw / 4, grWinh, 0.5 + 10);
grScreens[3]->activate(grWinx + grWinw * 3/4, grWiny, grWinw / 4, grWinh, 1.5); grScreens[3]->activate(grWinx + grWinw * 3/4, grWiny, grWinw / 4, grWinh, 1.5 + 10);
break; break;
case 1: case 1:
// Top/Bottom Left/Rigth Quarters // Top/Bottom Left/Rigth Quarters
@ -281,11 +281,11 @@ grAdaptScreenSize(void)
grNbArrangeScreens = 0; grNbArrangeScreens = 0;
case 0: case 0:
// All side by side // All side by side
grScreens[0]->activate(grWinx, grWiny, grWinw / 5, grWinh, -2.0); grScreens[0]->activate(grWinx, grWiny, grWinw / 5, grWinh, -2.0 + 10);
grScreens[1]->activate(grWinx + grWinw / 5, grWiny, grWinw / 5, grWinh, -1.0); grScreens[1]->activate(grWinx + grWinw / 5, grWiny, grWinw / 5, grWinh, -1.0 + 10);
grScreens[2]->activate(grWinx + grWinw * 2/5, grWiny, grWinw / 5, grWinh, 0.0); grScreens[2]->activate(grWinx + grWinw * 2/5, grWiny, grWinw / 5, grWinh, 0.0 + 10);
grScreens[3]->activate(grWinx + grWinw * 3/5, grWiny, grWinw / 5, grWinh, 1.0); grScreens[3]->activate(grWinx + grWinw * 3/5, grWiny, grWinw / 5, grWinh, 1.0 + 10);
grScreens[4]->activate(grWinx + grWinw * 4/5, grWiny, grWinw / 5, grWinh, 2.0); grScreens[4]->activate(grWinx + grWinw * 4/5, grWiny, grWinw / 5, grWinh, 2.0 + 10);
break; break;
} }
for (i=5; i < GR_NB_MAX_SCREEN; i++) for (i=5; i < GR_NB_MAX_SCREEN; i++)
@ -297,12 +297,12 @@ grAdaptScreenSize(void)
grNbArrangeScreens = 0; grNbArrangeScreens = 0;
case 0: case 0:
// All side by side // All side by side
grScreens[0]->activate(grWinx, grWiny, grWinw / 6, grWinh, -2.5); grScreens[0]->activate(grWinx, grWiny, grWinw / 6, grWinh, -2.5 + 10);
grScreens[1]->activate(grWinx + grWinw / 6, grWiny, grWinw / 6, grWinh, -1.5); grScreens[1]->activate(grWinx + grWinw / 6, grWiny, grWinw / 6, grWinh, -1.5 + 10);
grScreens[2]->activate(grWinx + grWinw * 2/6, grWiny, grWinw / 6, grWinh, -0.5); grScreens[2]->activate(grWinx + grWinw * 2/6, grWiny, grWinw / 6, grWinh, -0.5 + 10);
grScreens[3]->activate(grWinx + grWinw * 3/6, grWiny, grWinw / 6, grWinh, 0.5); grScreens[3]->activate(grWinx + grWinw * 3/6, grWiny, grWinw / 6, grWinh, 0.5 + 10);
grScreens[4]->activate(grWinx + grWinw * 4/6, grWiny, grWinw / 6, grWinh, 1.5); grScreens[4]->activate(grWinx + grWinw * 4/6, grWiny, grWinw / 6, grWinh, 1.5 + 10);
grScreens[5]->activate(grWinx + grWinw * 5/6, grWiny, grWinw / 6, grWinh, 2.5); grScreens[5]->activate(grWinx + grWinw * 5/6, grWiny, grWinw / 6, grWinh, 2.5 + 10);
break; break;
case 1: case 1:
// Top/Bottom Left/Middle/Rigth Matrix // Top/Bottom Left/Middle/Rigth Matrix

View file

@ -60,7 +60,6 @@ cGrScreen::cGrScreen(int myid)
scry = 0; scry = 0;
scrw = 800; scrw = 800;
scrh = 600; scrh = 600;
viewOffset = 0;
} }
cGrScreen::~cGrScreen() cGrScreen::~cGrScreen()
@ -120,7 +119,6 @@ void cGrScreen::activate(int x, int y, int w, int h, float v)
scry = y; scry = y;
scrw = w; scrw = w;
scrh = h; scrh = h;
viewOffset = v;
if (boardCam) delete boardCam; if (boardCam) delete boardCam;
@ -142,6 +140,7 @@ void cGrScreen::activate(int x, int y, int w, int h, float v)
if (curCam) { if (curCam) {
curCam->limitFov (); curCam->limitFov ();
curCam->setZoom (GR_ZOOM_DFLT); curCam->setZoom (GR_ZOOM_DFLT);
curCam->setViewOffset(v);
} }
active = true; active = true;
} }
@ -354,7 +353,6 @@ void cGrScreen::update(tSituation *s, const cGrFrameInfo* frameInfo)
glEnable(GL_SCISSOR_TEST); glEnable(GL_SCISSOR_TEST);
glViewport(scrx, scry, scrw, scrh); glViewport(scrx, scry, scrw, scrh);
glScissor(scrx, scry, scrw, scrh); glScissor(scrx, scry, scrw, scrh);
curCam->setViewOffset(viewOffset);
dispCam = curCam; dispCam = curCam;
camDraw(s); camDraw(s);
glDisable(GL_SCISSOR_TEST); glDisable(GL_SCISSOR_TEST);

View file

@ -17,6 +17,7 @@ SET(CONFSCREENS_SOURCES ${CS}/playerconfig.cpp ${CS}/controlconfig.cpp
${CS}/joystickconfig.cpp ${CS}/mouseconfig.cpp ${CS}/joystickconfig.cpp ${CS}/mouseconfig.cpp
${CS}/joy2butconfig.cpp ${CS}/joy2butconfig.cpp
${CS}/displayconfig.cpp ${CS}/graphconfig.cpp ${CS}/openglconfig.cpp ${CS}/displayconfig.cpp ${CS}/graphconfig.cpp ${CS}/openglconfig.cpp
${CS}/monitorconfig.cpp
${CS}/simuconfig.cpp ${CS}/soundconfig.cpp ${CS}/aiconfig.cpp ${CS}/simuconfig.cpp ${CS}/soundconfig.cpp ${CS}/aiconfig.cpp
${CS}/carsettingsmenu.cpp ${CS}/hostsettingsmenu.cpp ${CS}/carsettingsmenu.cpp ${CS}/hostsettingsmenu.cpp
${CS}/confscreens.h ${CS}/confscreens.h

View file

@ -0,0 +1,270 @@
/***************************************************************************
file : monitorconfig.cpp
created : October 2010
copyright : (C) 2010 Jean-Philippe Meuret
web : speed-dreams.sourceforge.net
version : $Id$
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
/* Display configuration menu */
#include <sstream>
#include <tgfclient.h>
#include "legacymenu.h"
#include "monitorconfig.h"
#include "graphic.h"
// Some consts.
static const char* AMonitorTypes[MonitorMenu::nMonitorTypes] = { "4:3", "16:9" };
static const char* ASpanSplits[MonitorMenu::nSpanSplits] = { "Disabled", "Enabled" };
static float _nBezelComp;
static int nBezelCompID;
// The unique MonitorMenu instance.
static MonitorMenu* PMonitorMenu = 0;
// Call-backs ================================================================
void MonitorMenu::onActivate(void *pMonitorMenu)
{
// Get the MonitorMenu instance.
MonitorMenu* pMenu = static_cast<MonitorMenu*>(pMonitorMenu);
// Load settings from XML file.
pMenu->loadSettings();
// Initialize GUI from loaded values.
pMenu->updateControls();
}
void MonitorMenu::onChangeMonitorType(tComboBoxInfo *pInfo)
{
// Get the MonitorMenu instance from call-back user data.
MonitorMenu* pMenu = static_cast<MonitorMenu*>(pInfo->userData);
pMenu->setMonitorType((EMonitorType)pInfo->nPos);
}
void MonitorMenu::onChangeSpanSplit(tComboBoxInfo *pInfo)
{
// Get the MonitorMenu instance from call-back user data.
MonitorMenu* pMenu = static_cast<MonitorMenu*>(pInfo->userData);
pMenu->setSpanSplit((ESpanSplit)pInfo->nPos);
}
void MonitorMenu::onChangeBezelComp(void *)
{
char* val = GfuiEditboxGetString(PMonitorMenu->getMenuHandle(), nBezelCompID);
sscanf(val, "%g", &_nBezelComp);
if (_nBezelComp > 120.0f)
_nBezelComp = 100.0f;
else if (_nBezelComp < 80.0f)
_nBezelComp = 80.0f;
char buf[32];
sprintf(buf, "%g", _nBezelComp);
GfuiEditboxSetString(PMonitorMenu->getMenuHandle(), nBezelCompID, buf);
#if 0
// Get the MonitorMenu instance from call-back user data.
MonitorMenu* pMenu = static_cast<MonitorMenu*>(pInfo->userData);
pMenu->setBezelComp((float)pInfo->nPos);
#endif
}
// Re-init screen to take new graphical settings into account (implies process restart).
void MonitorMenu::onAccept(void *pMonitorMenu)
{
// Get the MonitorMenu instance from call-back user data.
MonitorMenu* pMenu = static_cast<MonitorMenu*>(pMonitorMenu);
// Force current control to loose focus (if one had it) and update associated variable.
GfuiUnSelectCurrent();
// Save display settings.
pMenu->storeSettings();
// Back to previous screen.
GfuiScreenActivate(pMenu->getPreviousMenuHandle());
}
void MonitorMenu::onCancel(void *pMonitorMenu)
{
// Get the MonitorMenu instance from call-back user data.
const MonitorMenu* pMenu = static_cast<MonitorMenu*>(pMonitorMenu);
// Back to previous screen.
GfuiScreenActivate(pMenu->getPreviousMenuHandle());
}
void MonitorMenu::updateControls()
{
int nControlId = getDynamicControlId("MonitorCombo");
GfuiComboboxSetSelectedIndex(getMenuHandle(), nControlId, _eMonitorType);
nControlId = getDynamicControlId("SpanSplitCombo");
GfuiComboboxSetSelectedIndex(getMenuHandle(), nControlId, _eSpanSplit);
nControlId = getDynamicControlId("BezelCompCombo");
GfuiComboboxSetSelectedIndex(getMenuHandle(), nControlId, _nBezelComp);
}
void MonitorMenu::loadSettings()
{
std::ostringstream ossConfFile;
ossConfFile << GfLocalDir() << GR_PARAM_FILE;
void* grHandle =
GfParmReadFile(ossConfFile.str().c_str(), GFPARM_RMODE_STD | GFPARM_RMODE_CREAT);
// Monitor Type : 4:3 or 16:9
const char *pszMonitorType =
GfParmGetStr(grHandle, GR_SCT_MONITOR, GR_ATT_MONITOR, GR_VAL_MONITOR_16BY9);
_eMonitorType = strcmp(pszMonitorType, GR_VAL_MONITOR_16BY9) ? e4by3: e16by9;
// Span Split Screens
const char *pszSpanSplit =
GfParmGetStr(grHandle, GR_SCT_MONITOR, GR_ATT_SPANSPLIT, GR_VAL_NO);
_eSpanSplit = strcmp(pszSpanSplit, GR_VAL_YES) ? eDisabled : eEnabled;
// Bezel Compensation
_nBezelComp = (float)GfParmGetNum(grHandle, GR_SCT_MONITOR, GR_ATT_BEZELCOMP, NULL, 100);
if (_nBezelComp > 120.0f)
_nBezelComp = 100.0f;
else if (_nBezelComp < 80.0f)
_nBezelComp = 80.0f;
char buf[32];
sprintf(buf, "%g", _nBezelComp);
GfuiEditboxSetString(PMonitorMenu->getMenuHandle(), nBezelCompID, buf);
// Release screen config params file.
GfParmReleaseHandle(grHandle);
}
// Save graphical settings to XML file.
void MonitorMenu::storeSettings() const
{
std::ostringstream ossConfFile;
ossConfFile << GfLocalDir() << GR_PARAM_FILE;
void* grHandle =
GfParmReadFile(ossConfFile.str().c_str(), GFPARM_RMODE_STD | GFPARM_RMODE_CREAT);
const char* pszMonitorType =
(_eMonitorType == e16by9) ? GR_VAL_MONITOR_16BY9 : GR_VAL_MONITOR_4BY3;
GfParmSetStr(grHandle, GR_SCT_MONITOR, GR_ATT_MONITOR, pszMonitorType);
const char* pszSpanSplit =
(_eSpanSplit == eEnabled) ? GR_VAL_YES : GR_VAL_NO;
GfParmSetStr(grHandle, GR_SCT_MONITOR, GR_ATT_SPANSPLIT, pszSpanSplit);
GfParmSetNum(grHandle, GR_SCT_MONITOR, GR_ATT_BEZELCOMP, (char*)NULL, _nBezelComp);
// Write and release screen config params file.
GfParmWriteFile(NULL, grHandle, "Screen");
GfParmReleaseHandle(grHandle);
}
void MonitorMenu::setMonitorType(EMonitorType eMode)
{
_eMonitorType = eMode;
}
void MonitorMenu::setSpanSplit(ESpanSplit eMode)
{
_eSpanSplit = eMode;
}
void MonitorMenu::setBezelComp(float value)
{
_nBezelComp = value;
}
MonitorMenu::MonitorMenu()
: GfuiMenuScreen("monitorconfigmenu.xml")
{
_eMonitorType = e16by9;
_eSpanSplit = eDisabled;
_nBezelComp = 1.0;
}
bool MonitorMenu::initialize(void *pPreviousMenu)
{
// Save the menu to return to.
setPreviousMenuHandle(pPreviousMenu);
// Create the menu and all its controls.
createMenu(NULL, this, onActivate, NULL, (tfuiCallback)NULL, 1);
void *param = GfuiMenuLoad("monitorconfigmenu.xml");
openXMLDescriptor();
createStaticControls();
const int nMonitorTypeComboId =
createComboboxControl("MonitorTypeCombo", this, onChangeMonitorType);
const int nSpanSplitComboId =
createComboboxControl("SpanSplitCombo", this, onChangeSpanSplit);
nBezelCompID = GfuiMenuCreateEditControl(getMenuHandle(), param, "BezelCompEdit", (void*)1, NULL, onChangeBezelComp);
// createComboboxControl("BezelCompEdit", this, onChangeBezelComp);
createButtonControl("ApplyButton", this, onAccept);
createButtonControl("CancelButton", this, onCancel);
addShortcut(GFUIK_RETURN, "Apply", this, onAccept, 0);
addShortcut(GFUIK_ESCAPE, "Cancel", this, onCancel, 0);
// TODO Keyboard shortcuts: Add support for shortcuts in GfuiCombobox ?
//addShortcut(GFUIK_LEFT, "Previous Resolution", this, onChangeScreenSize, 0);
//addShortcut(GFUIK_RIGHT, "Next Resolution", this, onChangeScreenSize, 0);
addShortcut(GFUIK_F1, "Help", getMenuHandle(), GfuiHelpScreen, 0);
addShortcut(GFUIK_F12, "Screen-Shot", 0, GfuiScreenShot, 0);
closeXMLDescriptor();
// Load constant value lists in combo-boxes.
// 1) Monitor Type
for (int nMonitorTypeInd = 0; nMonitorTypeInd < nMonitorTypes; nMonitorTypeInd++)
GfuiComboboxAddText(getMenuHandle(), nMonitorTypeComboId, AMonitorTypes[nMonitorTypeInd]);
// 2) Span Split Screens - for wide displays
for (int nSpanSplitInd = 0; nSpanSplitInd < nSpanSplits; nSpanSplitInd++)
GfuiComboboxAddText(getMenuHandle(), nSpanSplitComboId, ASpanSplits[nSpanSplitInd]);
return true;
}
/** Create and activate the monitor options menu screen.
@ingroup screen
@param precMenu previous menu to return to
*/
void* MonitorMenuInit(void *pPreviousMenu)
{
if (!PMonitorMenu)
{
PMonitorMenu = new MonitorMenu;
PMonitorMenu->initialize(pPreviousMenu);
}
return PMonitorMenu->getMenuHandle();
}

View file

@ -0,0 +1,70 @@
/***************************************************************************
file : displayconfig.h
created : October 2010
copyright : (C) 2010 Jean-Philippe Meuret
web : speed-dreams.sourceforge.net
version : $Id$
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef _MONITORCONFIG_H_
#define _MONITORCONFIG_H_
#include <tgfclient.h>
#include "confscreens.h"
class MonitorMenu : public GfuiMenuScreen
{
public:
MonitorMenu();
bool initialize(void* pPreviousMenu);
enum EMonitorType { e4by3 = 0, e16by9 = 1, nMonitorTypes };
enum ESpanSplit { eDisabled = 0, eEnabled = 1, nSpanSplits };
void setMonitorType(EMonitorType eMode);
void setSpanSplit(ESpanSplit eMode);
void setBezelComp(float value);
void storeSettings() const;
void loadSettings();
void updateControls();
protected:
// Control callback functions (must be static).
static void onActivate(void *pMonitorMenu);
static void onChangeMonitorType(tComboBoxInfo *pInfo);
static void onChangeSpanSplit(tComboBoxInfo *pInfo);
static void onChangeBezelComp(void *);
static void onAccept(void *pMonitorMenu);
static void onCancel(void *pMonitorMenu);
private:
//! Current Setting for Monitor Type
EMonitorType _eMonitorType;
//! Current Setting for Span Splits
ESpanSplit _eSpanSplit;
};
extern void* MonitorMenuInit(void* pPreviousMenu);
#endif //_MONITORCONFIG_H_