So I am trying to get a vc with 4 mfds. The buttons and mfd work but the labels only appear on the first one?
dimension of mfd button clickable area
Code was made by Lilias.

Code:
#include "ClassicMfdCST.h"
#include "CST100VCMESH.h"
ClassicMfd::ClassicMfd(int const mfdQtd,
HFONT const labelFont, DWORD const labelColor, HBRUSH const buttonBrush, HBRUSH const buttonLabelBrush,
DIMENSION const * const buttonFnDim, RECT const buttonFnRect[],
DIMENSION const * const buttonSysDim, RECT const buttonSysRect[])
: mfdQtd(mfdQtd),
labelFont(labelFont), buttonBrush(buttonBrush), buttonLabelBrush(buttonLabelBrush), labelColor(labelColor),
buttonFnDim(buttonFnDim), buttonFnRect(buttonFnRect), buttonSysDim(buttonSysDim), buttonSysRect(buttonSysRect)
{
}
ClassicMfd::~ClassicMfd() {}
void ClassicMfd::HandleLoadMesh(UINT const meshi, MESHHANDLE const meshhg)
{
meshi_VC = meshi;
meshhg_VC = meshhg;
}
bool ClassicMfd::HandleLoadVC(UINT const vcId)
{
this->vcId = vcId;
DefineMfds();
DefineMfdsButtons();
return true;
}
bool ClassicMfd::HandleRedrawEvent(int const aid, int const event, SURFHANDLE const surf)
{
switch (aid) {
case AID_PILOT_MFD_LEFT_BTNS_FN:
RedrawMFDButtons(surf, MFD_PILOT_LEFT);
return true;
case AID_PILOT_MFD_RIGHT_BTNS_FN:
RedrawMFDButtons(surf, MFD_PILOT_RIGHT);
return true;
case AID_COPILOT_MFD_LEFT_BTNS_FN:
RedrawMFDButtons(surf, MFD_COPILOT_LEFT);
return true;
case AID_COPILOT_MFD_RIGHT_BTNS_FN:
RedrawMFDButtons(surf, MFD_COPILOT_RIGHT);
return true;
}
return false;
}
bool ClassicMfd::HandleMouseEvent(int const aid, int const event, VECTOR3 const &p)
{
switch (aid) {
case AID_PILOT_MFD_LEFT_BTNS_FN:
return ProcessMfdFnButton(MFD_PILOT_LEFT, event, p);
case AID_PILOT_MFD_LEFT_BTNS_SYS:
return ProcessMfdSysButton(MFD_PILOT_LEFT, event, p);
case AID_PILOT_MFD_RIGHT_BTNS_FN:
return ProcessMfdFnButton(MFD_PILOT_RIGHT, event, p);
case AID_PILOT_MFD_RIGHT_BTNS_SYS:
return ProcessMfdSysButton(MFD_PILOT_RIGHT, event, p);
case AID_COPILOT_MFD_LEFT_BTNS_FN:
return ProcessMfdFnButton(MFD_COPILOT_LEFT, event, p);
case AID_COPILOT_MFD_LEFT_BTNS_SYS:
return ProcessMfdSysButton(MFD_COPILOT_LEFT, event, p);
case AID_COPILOT_MFD_RIGHT_BTNS_FN:
return ProcessMfdFnButton(MFD_COPILOT_RIGHT, event, p);
case AID_COPILOT_MFD_RIGHT_BTNS_SYS:
return ProcessMfdSysButton(MFD_COPILOT_RIGHT, event, p);
}
return false;
}
bool ClassicMfd::ProcessMfdFnButton(int const mfd, int const event, VECTOR3 const &p)
{
if (p.x > 0.07 && p.x < 0.93) return false;
int index = (int)(p.y * 11);
if (index == 0 || index / 2 != (index - 1) / 2) {
index /= 2;
if (p.x > 0.5) index += 6;
oapiProcessMFDButton(mfd, index, event);
return true;
}
return false;
}
bool ClassicMfd::ProcessMfdSysButton(int const mfd, int const event, VECTOR3 const &p)
{
if (event & PANEL_MOUSE_LBDOWN) {
if (p.x < 0.1) {
oapiToggleMFD_on(mfd);
return true;
}
else if (p.x > 0.9) {
oapiSendMFDKey(mfd, OAPI_KEY_GRAVE);
return true;
}
else if (p.x > 0.8) {
oapiSendMFDKey(mfd, OAPI_KEY_F1);
return true;
}
}
return false;
}
void ClassicMfd::HandleMFDMode(int const mfd, int const mode)
{
switch (mfd) {
case MFD_PILOT_LEFT:
oapiVCTriggerRedrawArea(-1, AID_PILOT_MFD_LEFT_BTNS_FN);
break;
case MFD_PILOT_RIGHT:
oapiVCTriggerRedrawArea(-1, AID_PILOT_MFD_RIGHT_BTNS_FN);
break;
case MFD_COPILOT_LEFT:
oapiVCTriggerRedrawArea(-1, AID_COPILOT_MFD_LEFT_BTNS_FN);
break;
case MFD_COPILOT_RIGHT:
oapiVCTriggerRedrawArea(-1, AID_COPILOT_MFD_RIGHT_BTNS_FN);
break;
}
}
void ClassicMfd::DefineMfds()
{
DefineMfd(MFD_PILOT_LEFT, GRP_CST100NEWPANELB_MFDVC1);
DefineMfd(MFD_COPILOT_LEFT, GRP_CST100NEWPANELB_MFDVC2);
DefineMfd(MFD_PILOT_RIGHT, GRP_CST100NEWPANELB_MFDVC3);
DefineMfd(MFD_COPILOT_RIGHT, GRP_CST100NEWPANELB_MFDVC4);
}
void ClassicMfd::DefineMfd(UINT const mfdId, UINT const screenGroupId)
{
VCMFDSPEC mfds;
mfds.nmesh = meshi_VC;
mfds.ngroup = screenGroupId;
oapiVCRegisterMFD(mfdId, &mfds);
}
void ClassicMfd::DefineMfdsButtons()
{
// Pilot Left
DefineMfdButtons(
TEX_CST100NEWPANELB_MFD_DYNAMIC_05,
AID_PILOT_MFD_LEFT_BTNS_FN, GRP_CST100NEWPANELB_PILOT_MFD_LEFT_BTNS_FN, buttonFnRect[MFD_PILOT_LEFT],
AID_PILOT_MFD_LEFT_BTNS_SYS, GRP_CST100NEWPANELB_PILOT_MFD_LEFT_BTNS_SYS
);
//PILOT RIGHT
DefineMfdButtons(
TEX_CST100NEWPANELB_MFD_DYNAMIC_05,
AID_PILOT_MFD_RIGHT_BTNS_FN, GRP_CST100NEWPANELB_PILOT_MFD_RIGHT_BTNS_FN, buttonFnRect[MFD_PILOT_RIGHT],
AID_PILOT_MFD_RIGHT_BTNS_SYS, GRP_CST100NEWPANELB_PILOT_MFD_RIGHT_BTNS_SYS
);
DefineMfdButtons(
TEX_CST100NEWPANELB_MFD_DYNAMIC_05,
AID_COPILOT_MFD_LEFT_BTNS_FN, GRP_CST100NEWPANELB_COPILOT_MFD_LEFT_BTNS_FN, buttonFnRect[MFD_COPILOT_LEFT],
AID_COPILOT_MFD_LEFT_BTNS_SYS, GRP_CST100NEWPANELB_COPILOT_MFD_LEFT_BTNS_SYS
);
//PILOT RIGHT
DefineMfdButtons(
TEX_CST100NEWPANELB_MFD_DYNAMIC_05,
AID_COPILOT_MFD_RIGHT_BTNS_FN, GRP_CST100NEWPANELB_COPILOT_MFD_RIGHT_BTNS_FN, buttonFnRect[MFD_COPILOT_RIGHT],
AID_COPILOT_MFD_RIGHT_BTNS_SYS, GRP_CST100NEWPANELB_COPILOT_MFD_RIGHT_BTNS_SYS
);
}
void ClassicMfd::DefineMfdButtons(
UINT const texId,
UINT const fuctionAreaId, UINT const functionGroupId, RECT const functionRect,
UINT const sysAreaId, UINT const sysGroupId
)
{
SURFHANDLE const texDyn = oapiGetTextureHandle(meshhg_VC, texId);
oapiVCRegisterArea(fuctionAreaId, functionRect, PANEL_REDRAW_USER, PANEL_MOUSE_LBDOWN | PANEL_MOUSE_LBPRESSED | PANEL_MOUSE_ONREPLAY, PANEL_MAP_NONE, texDyn);
DefineStaticClickArea(oapiMeshGroup(meshhg_VC, functionGroupId), fuctionAreaId, true);
oapiVCRegisterArea(sysAreaId, PANEL_REDRAW_NEVER, PANEL_MOUSE_LBDOWN | PANEL_MOUSE_ONREPLAY);
DefineStaticClickArea(oapiMeshGroup(meshhg_VC, sysGroupId), sysAreaId, true);
}
static int get_font_height(HDC const hDC)
{
TEXTMETRIC tm;
if (GetTextMetrics(hDC, &tm))
{
return abs(tm.tmAscent);
}
return 5; // Wild, crazy guessing
}
void ClassicMfd::RedrawMFDButtons(SURFHANDLE const surf, int const mfd)
{
int const btnWidth = buttonFnDim->width;
int const btnHeight = buttonFnDim->height;
// RECT const draw_area = _R(buttonFnRect[mfd].right - buttonFnRect[mfd].left, buttonFnRect[mfd].bottom - buttonFnRect[mfd].top);(SURFHANDLE surf, int mfd, int side)
const RECT &draw_area = buttonFnRect[mfd];
HDC const hDC = oapiGetDC(surf);
SelectObject(hDC, buttonBrush);
SetBkMode(hDC, OPAQUE);
Rectangle(hDC, draw_area.left, draw_area.top, draw_area.right, draw_area.bottom);
HFONT pFont = (HFONT)SelectObject(hDC, labelFont);
SetTextColor(hDC, labelColor);
SetTextAlign(hDC, TA_CENTER);
int const half_font_height = get_font_height(hDC) / 2;
char const * label;
int const label_x_offset = (btnWidth / 2);
int const label_y_offset = (btnHeight / 2) - buttonFnDim->marginHeight - half_font_height;
for (int i = 0; i < 12; i++) {
int const x = i / 6;
int const y = i % 6;
if (label = oapiMFDButtonLabel(mfd, i)) {
int const xwidth = (x * btnWidth);
int const yheight = (y * btnHeight);
SelectObject(hDC, buttonLabelBrush);
SetBkMode(hDC, OPAQUE);
Rectangle(hDC,
draw_area.left + xwidth + buttonFnDim->marginWidth,
draw_area.top + yheight + buttonFnDim->marginHeight,
draw_area.left + xwidth + btnWidth - buttonFnDim->marginWidth,
draw_area.top + yheight + btnHeight - buttonFnDim->marginHeight
);
SetBkMode(hDC, TRANSPARENT);
TextOut(hDC, draw_area.left + xwidth + label_x_offset, draw_area.top + yheight + label_y_offset, label, strlen(label));
}
else break;
}
SelectObject(hDC, pFont);
oapiReleaseDC(surf, hDC);
}
void ClassicMfd::DefineStaticClickArea(MESHGROUP const * const gr, int const id, bool const rect, const VECTOR3& revert, const VECTOR3& maxShift)
{
float minX, maxX, minY, maxY, minZ, maxZ, x, y, z;
minX = minY = minZ = 1000.0f;
maxX = maxY = maxZ = -1000.0f;
for (DWORD i = 0; i < gr->nVtx; i++) {
x = gr->Vtx[i].x;
y = gr->Vtx[i].y;
z = gr->Vtx[i].z;
if (x < minX) minX = x;
if (y < minY) minY = y;
if (z < minZ) minZ = z;
if (x > maxX) maxX = x + (float)maxShift.x;
if (y > maxY) maxY = y + (float)maxShift.y;
if (z > maxZ) maxZ = z + (float)maxShift.z;
}
if (rect) {
VECTOR3 p1 = _V(revert.x > 0 ? maxX : minX, revert.y > 0 ? minY : maxY, revert.z > 0 ? minZ : maxZ);
VECTOR3 p2 = _V(revert.x > 0 ? minX : maxX, revert.y > 0 ? minY : maxY, revert.z > 0 ? minZ : maxZ);
VECTOR3 p3 = _V(revert.x > 0 ? maxX : minX, revert.y > 0 ? maxY : minY, revert.z > 0 ? maxZ : minZ);
VECTOR3 p4 = _V(revert.x > 0 ? minX : maxX, revert.y > 0 ? maxY : minY, revert.z > 0 ? maxZ : minZ);
oapiVCSetAreaClickmode_Quadrilateral(id, p1, p2, p3, p4);
}
else {
double distX = Distance(minX, maxX);
double distY = Distance(minY, maxY);
double distZ = Distance(minZ, maxZ);
VECTOR3 center = _V(minX + distX / 2.0f, minY + distY / 2.0f, minZ + distZ / 2.0f);
double rad = max(distX, max(distY, distZ)) / 2.0;
oapiVCSetAreaClickmode_Spherical(id, center, rad);
}
}
Code:
#pragma once
#include <OrbiterAPI.h>
#include <VesselAPI.h>
#include "AreaIds.h"
#define MFD_PILOT_LEFT (MFD_LEFT)
#define MFD_PILOT_RIGHT (MFD_RIGHT)
#define MFD_COPILOT_LEFT (MFD_USER1)
#define MFD_COPILOT_RIGHT (MFD_USER2)
typedef struct structDIMENSION
{
int width;
int height;
int marginWidth;
int marginHeight;
} DIMENSION;
inline DIMENSION _D(int width, int height, int marginWidth, int marginHeight)
{
DIMENSION d = { width, height, marginWidth, marginHeight }; return d;
}
class ClassicMfd {
public:
ClassicMfd::ClassicMfd(int const mfdQtd,
HFONT const labelFont, DWORD const labelColor, HBRUSH const buttonBrush, HBRUSH const buttonLabelBrush,
DIMENSION const * const buttonFnDim, RECT const buttonFnRect[],
DIMENSION const * const buttonSysDim, RECT const buttonSysRect[]);
~ClassicMfd();
void HandleSetClassCaps();
void HandleLoadMesh(UINT const meshi, MESHHANDLE const meshhg);
bool HandleLoadVC(UINT const vcId);
bool HandleRedrawEvent(int const id, int const event, SURFHANDLE const surf);
bool HandleMouseEvent(int const id, int const event, VECTOR3 const &p);
void HandleMFDMode(int const mfd, int const mode);
private:
HFONT const labelFont;
HBRUSH const buttonBrush, buttonLabelBrush;
DWORD const labelColor;
RECT const * const buttonFnRect;
DIMENSION const * const buttonFnDim;
RECT const * const buttonSysRect;
DIMENSION const * const buttonSysDim;
int const mfdQtd;
MESHHANDLE meshhg_VC;
UINT meshi_VC;
UINT vcId;
void DefineMfds();
void DefineMfd(UINT const mfdId, UINT const screenGroupId);
void DefineMfdsButtons();
void ClassicMfd::DefineMfdButtons(
UINT const texId,
UINT const fuctionAreaId, UINT const functionGroupId, RECT const functionRect,
UINT const sysAreaId, UINT const sysGroupId
);
void DefineStaticClickArea(MESHGROUP const * const gr, int const id, bool const rect = true, const VECTOR3& revert = _V(0, 0, 0), const VECTOR3& maxShift = _V(0, 0, 0));
//void RedrawPanel_MFDButton(SURFHANDLE surf, int mfd, int side);
void RedrawMFDButtons(SURFHANDLE const surf, int const mfd);
bool ProcessMfdFnButton(int const mfd, int const event, VECTOR3 const &p);
bool ProcessMfdSysButton(int const mfd, int const event, VECTOR3 const &p);
inline double Distance(double const d1, double const d2) {
return max(d1, d2) - min(d1, d2);
}
};
Code:
static DIMENSION const MFD_BUTTONS_FN_DIM = _D(50, 28, 2, 2);
static RECT const MFD_BUTTONS_FN_RECT[] = { _R(000, 000, 100, 168), _R(100, 000, 200, 168), _R(200, 000, 300, 168), _R(300, 000, 400, 168) };
static DIMENSION const MFD_BUTTONS_SYS_DIM = _D(30, 30, 0, 0);
static RECT const MFD_BUTTONS_SYS_RECT[] = { _R(230, 272, 260, 302), _R(230, 272, 260, 302), _R(230, 272, 260, 302), _R(230, 272, 260, 302) };
Code:
mfdController = new ClassicMfd(4, g_Param.hFont[0], g_Param.col[0], g_Param.hBrush[0], g_Param.hBrush[1], &MFD_BUTTONS_FN_DIM, MFD_BUTTONS_FN_RECT, &MFD_BUTTONS_SYS_DIM, MFD_BUTTONS_SYS_RECT);
Code:
#pragma once
#define AID_FIRST_ID 0
#define AID_PILOT_MFD_LEFT_BTNS_FN 1
#define AID_PILOT_MFD_LEFT_BTNS_SYS 2
#define AID_PILOT_MFD_RIGHT_BTNS_FN 3
#define AID_PILOT_MFD_RIGHT_BTNS_SYS 4
#define AID_COPILOT_MFD_LEFT_BTNS_FN 5
#define AID_COPILOT_MFD_LEFT_BTNS_SYS 6
#define AID_COPILOT_MFD_RIGHT_BTNS_FN 7
#define AID_COPILOT_MFD_RIGHT_BTNS_SYS 8
Last edited: