• ORBITER-FORUM will be temporarily closed at 2026-07-23 18:00 UTC while we complete some OF maintenance tasks. The amount of downtime is expected to take up to one hour, but probably less.

Problem vc MFD LABEL ISSUE

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
10,659
Reaction score
4,465
Points
203
Location
Dallas, TX
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?

U9FMTKW.jpg


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);
	}
};
dimension of mfd button clickable area

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
Code was made by Lilias.
 
Last edited:
Back
Top