File:  [Isaki's NoNo m68k/m88k emulator] / nono / wx / wxsoftkey.h
Revision 1.1.1.16 (vendor branch): download - view: text, annotated - select for diffs
Wed Apr 29 17:05:48 2026 UTC (3 months ago) by root
Branches: MAIN, Isaki
CVS tags: v027, v026, v025, HEAD
nono 1.5.0

//
// nono
// Copyright (C) 2020 nono project
// Licensed under nono-license.txt
//

//
// ソフトウェアキーボード
//

#pragma once

#include "wxsubwindow.h"
#include "wxtextpanel.h"
#include "keyboard.h"
#include "mainapp.h"
#include <array>
#include <map>
#include <vector>

class Keyboard;

// キー描画用のデータ構造体
struct keydata_t
{
	// フォントサイズの切り替えに対応するため、座標系の単位はピクセルでは
	// ない点に注意。フォントサイズ(高さ)の 1/4 を 1 と表現する。つまり
	// どのフォントサイズでも半角1文字は 2 x 4。
	int x;	// このキー枠の左上点
	int y;	// このキー枠の左上点
	int w;	// このキー枠の幅
	int h;	// このキー枠の高さ

	// 色種別
	// LUNA の場合はキートップ色の区別に使う。1=濃い, 0=通常。
	// X68k では使用しない。
	int coltype;

	int led;			// -1ならLEDなし、0以上なら LED 番号
	uint keycode;		// キーコード (keyboard.h の KC_*)

	// 刻印
	// [0]: 通常
	// [1]: SHIFT時 (NULL なら通常のまま)
	const char *disp[2];

	int right() const { return x + w; }		// このキー枠の右
	int bottom() const { return y + h; }	// このキー枠の下
};

// ソフトウェアキーボード (パネル) 共通部分
class WXSoftKeyPanel : public WXTextPanel
{
	using inherited = WXTextPanel;
 protected:
	// 色の集合(パレット)
	struct ColorPalette {
		Color Background;		// 背景というかガワの部分の色
		Color Text;				// 文字色
		Color Keytop[2][10];	// キートップ色。
								// [2]=0:通常色、1:(あれば)濃色
								// [10]=押され具合。0は押されていないとき
		Color Border;			// LED 点灯時の枠の色
		Color LED[2];			// LED。色は各機種定義 (今のところ0:赤 1:緑)
	};

	// 修飾キーの状態
	enum Modifier {
		ModNormal = 0,
		ModShift,
	};

 protected:
	WXSoftKeyPanel(wxWindow *parent, const std::vector<keydata_t>& keydata_,
		int u_width_, int u_height_);
 public:
	~WXSoftKeyPanel() override;

	// フォントサイズ変更
	void FontChanged() override;

 protected:
	void UpdateTitle();

	void InitColorKeytop(int num);
	void InitIcon();

	// LUNA-I、LUNA-88K の共通初期化
	void InitLunaCommon();

	void OnKeyChanged(wxCommandEvent& event);
	void OnTimer(wxTimerEvent& event);

	void Draw() override;
	void DrawKey(const keydata_t& key);
	void DrawKeyBox(const keydata_t&, Color bg, Color bd);
	void DrawEnterKey();
	void DrawBuzzer(const keydata_t& key);
	virtual int DrawLED(const keydata_t& key) = 0;
	const keydata_t& FindKeydata(uint) const;

	void OnLeftDown(wxMouseEvent& event);
	void DoLeftDown(uint code);
	void OnLeftUp(wxMouseEvent& event);
	void OnLeftDClick(wxMouseEvent& event);
	void OnRightDown(wxMouseEvent& event);
	void KeyDown(uint code);
	void KeyUp(uint code);

	const keydata_t *GetKeydataFromPoint(const wxPoint& pt) const;

	// 左クリック押下時のキー
	uint leftdown_key {};

	// トグル動作にするキーの集合。
	// first はキーコード、
	// second は押下ならキーコード、開放なら 0。
	std::map<uint, uint> toggle {};

	// 修飾キーの状態 (刻印を変更するため)
	Modifier modifier {};

	// フォントサイズに相対的な描画単位
	int unit {};

	// コントロールのサイズ [基準単位]
	int u_width {};
	int u_height {};

	// 初期タイトル
	wxString title {};

	// キーボードの接続状態
	bool connected {};

	// エンターキーの矩形
	Rect enter_top {};
	Rect enter_btm {};

	// アイコン
	std::unique_ptr<BitmapI1> enter_icon /*{}*/;

	// 色
	ColorPalette color {};

	// 残光処理
	// 10   : 減光しない点灯を示す (ただし色コードは 9)
	// 9..1 : 減光中 (9 がもっとも明るい)
	// 0    : 消灯中
	std::vector<uint8> persistence {};

	wxTimer timer {};

	// UTF-8 -> CP932 変換
	// Unicode の "\\" は Shift_JIS に対応する文字がないため、これを
	// Unicode から Shift_JIS に変換すると "" になり、これではキートップが
	// 刻印できなくて困る。
	// CP932 なら "\\" を変換しても "\\" ('\x5c') になってくれるので、
	// これを使う。この \x5c をバックスラッシュだと思うか円記号だと思うかは
	// こちらで決める。
	wxCSConv conv { "CP932" };

	// キー描画データ (派生クラス側から渡される)
	const std::vector<keydata_t>& keydata;

	Keyboard *keyboard {};

	// イベントテーブル
	wxDECLARE_EVENT_TABLE();
};

// LUNA-I ソフトウェアキーボード (パネル)
class WXLuna1SoftKeyPanel : public WXSoftKeyPanel
{
	using inherited = WXSoftKeyPanel;
 public:
	explicit WXLuna1SoftKeyPanel(wxWindow *parent);
	~WXLuna1SoftKeyPanel() override;

 private:
	int DrawLED(const keydata_t& key) override;

	// キー描画データ
	static std::vector<keydata_t> keydata;
};

// LUNA-88K ソフトウェアキーボード (パネル)
class WXLuna88kSoftKeyPanel : public WXSoftKeyPanel
{
	using inherited = WXSoftKeyPanel;
 public:
	explicit WXLuna88kSoftKeyPanel(wxWindow *parent);
	~WXLuna88kSoftKeyPanel() override;

 private:
	int DrawLED(const keydata_t& key) override;

	// キー描画データ
	static std::vector<keydata_t> keydata;
};

// X68k ソフトウェアキーボード (パネル)
class WXX68kSoftKeyPanel : public WXSoftKeyPanel
{
	using inherited = WXSoftKeyPanel;
 public:
	explicit WXX68kSoftKeyPanel(wxWindow *parent);
	~WXX68kSoftKeyPanel() override;

 private:
	int DrawLED(const keydata_t& key) override;

	// キー描画データ
	static std::vector<keydata_t> keydata;
};

// ソフトウェアキーボード (ウィンドウ)
class WXSoftKeyWindow : public WXSubWindow
{
	using inherited = WXSubWindow;
 public:
	WXSoftKeyWindow(wxWindow *parent, VMType vmtype);
	~WXSoftKeyWindow() override;
};

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.