Exemplo n.º 1
0
C4StartupMainDlg::C4StartupMainDlg() : C4StartupDlg(NULL) // create w/o title; it is drawn in custom draw proc
{
	// ctor
	fFirstShown = true;
	// screen calculations
	int iButtonPadding = 2;
	int iButtonHeight = C4GUI_BigButtonHgt;
	C4GUI::ComponentAligner caMain(rcBounds, 0,0,true);
	C4GUI::ComponentAligner caRightPanel(caMain.GetFromLeft(rcBounds.Wdt*2/5), rcBounds.Wdt/26, 40+rcBounds.Hgt/5);
	C4GUI::ComponentAligner caButtons(caRightPanel.GetAll(), 0, iButtonPadding);
	// main menu buttons
	C4GUI::CallbackButton<C4StartupMainDlg> *btn;
	AddElement(btn = new C4GUI::CallbackButton<C4StartupMainDlg>(LoadResStr("IDS_BTN_LOCALGAME"), caButtons.GetFromTop(iButtonHeight), &C4StartupMainDlg::OnStartBtn));
	btn->SetToolTip(LoadResStr("IDS_DLGTIP_STARTGAME"));
	btn->SetCustomGraphics(&C4Startup::Get()->Graphics.barMainButtons, &C4Startup::Get()->Graphics.barMainButtonsDown);
	pStartButton = btn;
	AddElement(btn = new C4GUI::CallbackButton<C4StartupMainDlg>(LoadResStr("IDS_BTN_NETWORKGAME"), caButtons.GetFromTop(iButtonHeight), &C4StartupMainDlg::OnNetJoinBtn));
	btn->SetToolTip(LoadResStr("IDS_DLGTIP_NETWORKGAME"));
	btn->SetCustomGraphics(&C4Startup::Get()->Graphics.barMainButtons, &C4Startup::Get()->Graphics.barMainButtonsDown);
	AddElement(btn = new C4GUI::CallbackButton<C4StartupMainDlg>(LoadResStr("IDS_DLG_PLAYERSELECTION"), caButtons.GetFromTop(iButtonHeight), &C4StartupMainDlg::OnPlayerSelectionBtn));
	btn->SetToolTip(LoadResStr("IDS_DLGTIP_PLAYERSELECTION"));
	btn->SetCustomGraphics(&C4Startup::Get()->Graphics.barMainButtons, &C4Startup::Get()->Graphics.barMainButtonsDown);
	AddElement(btn = new C4GUI::CallbackButton<C4StartupMainDlg>(LoadResStr("IDS_DLG_OPTIONS"), caButtons.GetFromTop(iButtonHeight), &C4StartupMainDlg::OnOptionsBtn));
	btn->SetToolTip(LoadResStr("IDS_DLGTIP_OPTIONS"));
	btn->SetCustomGraphics(&C4Startup::Get()->Graphics.barMainButtons, &C4Startup::Get()->Graphics.barMainButtonsDown);
	AddElement(btn = new C4GUI::CallbackButton<C4StartupMainDlg>(LoadResStr("IDS_DLG_ABOUT"), caButtons.GetFromTop(iButtonHeight), &C4StartupMainDlg::OnAboutBtn));
	btn->SetToolTip(LoadResStr("IDS_DLGTIP_ABOUT"));
	btn->SetCustomGraphics(&C4Startup::Get()->Graphics.barMainButtons, &C4Startup::Get()->Graphics.barMainButtonsDown);
	AddElement(btn = new C4GUI::CallbackButton<C4StartupMainDlg>(LoadResStr("IDS_DLG_EXIT"), caButtons.GetFromTop(iButtonHeight), &C4StartupMainDlg::OnExitBtn));
	btn->SetToolTip(LoadResStr("IDS_DLGTIP_EXIT"));
	btn->SetCustomGraphics(&C4Startup::Get()->Graphics.barMainButtons, &C4Startup::Get()->Graphics.barMainButtonsDown);
	// list of selected players
	AddElement(pParticipantsLbl = new C4GUI::Label("test", GetClientRect().Wdt*39/40, GetClientRect().Hgt*9/10, ARight, 0xffffffff, &::GraphicsResource.TitleFont, false));
	pParticipantsLbl->SetToolTip(LoadResStr("IDS_DLGTIP_SELECTEDPLAYERS"));
	// player selection shortcut - to be made optional
	UpdateParticipants();
	pParticipantsLbl->SetContextHandler(new C4GUI::CBContextHandler<C4StartupMainDlg>(this, &C4StartupMainDlg::OnPlayerSelContext));
	// key bindings
	C4CustomKey::CodeList keys;
	keys.push_back(C4KeyCodeEx(K_DOWN)); keys.push_back(C4KeyCodeEx(K_RIGHT));
	if (Config.Controls.GamepadGuiControl)
	{
		keys.push_back(C4KeyCodeEx(KEY_Gamepad(0, KEY_JOY_Down))); // right will be done by Dialog already
	}
	pKeyDown = new C4KeyBinding(keys, "StartupMainCtrlNext", KEYSCOPE_Gui,
	                            new C4GUI::DlgKeyCBEx<C4StartupMainDlg, bool>(*this, false, &C4StartupMainDlg::KeyAdvanceFocus), C4CustomKey::PRIO_CtrlOverride);
	keys.clear(); keys.push_back(C4KeyCodeEx(K_UP)); keys.push_back(C4KeyCodeEx(K_LEFT));
	if (Config.Controls.GamepadGuiControl)
	{
		keys.push_back(C4KeyCodeEx(KEY_Gamepad(0, KEY_JOY_Up))); // left will be done by Dialog already
	}
	pKeyUp = new C4KeyBinding(keys, "StartupMainCtrlPrev", KEYSCOPE_Gui,
	                          new C4GUI::DlgKeyCBEx<C4StartupMainDlg, bool>(*this, true, &C4StartupMainDlg::KeyAdvanceFocus), C4CustomKey::PRIO_CtrlOverride);
	keys.clear(); keys.push_back(C4KeyCodeEx(K_RETURN));
	pKeyEnter = new C4KeyBinding(keys, "StartupMainOK", KEYSCOPE_Gui,
	                             new C4GUI::DlgKeyCB<C4StartupMainDlg>(*this, &C4StartupMainDlg::KeyEnterDown, &C4StartupMainDlg::KeyEnterUp), C4CustomKey::PRIO_CtrlOverride);
}
Exemplo n.º 2
0
void C4GamePadControl::FeedEvent(const SDL_Event& event, int feed)
{
	switch (event.type)
	{
	case SDL_CONTROLLERAXISMOTION:
	{
		C4KeyCode minCode = KEY_Gamepad(KEY_CONTROLLER_Axis(event.caxis.axis, false));
		C4KeyCode maxCode = KEY_Gamepad(KEY_CONTROLLER_Axis(event.caxis.axis, true));
		int32_t value = abs_strength(event.caxis.value);
		uint8_t which = event.caxis.which;
		C4KeyCode keyCode = event.caxis.value >= 0 ? maxCode : minCode;

		auto doInput = [&](C4KeyEventType event, int32_t strength)
		{
			Game.DoKeyboardInput(
			  C4KeyCodeEx(KEY_Gamepad(keyCode), KEYS_None, false, which),
			  event, NULL, false, strength);
		};

		if (feed & FEED_BUTTONS)
		{
			// Also emulate button presses.
			if (PressedAxis.count(keyCode) && value <= deadZone)
			{
				PressedAxis.erase(keyCode);
				doInput(KEYEV_Up, -1);
			}
			else if (!PressedAxis.count(keyCode) && value > deadZone)
			{
				PressedAxis.insert(keyCode);
				doInput(KEYEV_Down, -1);
			}
		}
		if (feed & FEED_MOVED)
			doInput(KEYEV_Moved, value);

		AxisEvents[keyCode] = event;

		break;
	}
	case SDL_CONTROLLERBUTTONDOWN:
		if (feed & FEED_BUTTONS)
			Game.DoKeyboardInput(
			  C4KeyCodeEx(KEY_Gamepad(KEY_CONTROLLER_Button(event.cbutton.button)), KEYS_None, false, event.cbutton.which),
			  KEYEV_Down);
		break;
	case SDL_CONTROLLERBUTTONUP:
		if (feed & FEED_BUTTONS)
			Game.DoKeyboardInput(
			  C4KeyCodeEx(KEY_Gamepad(KEY_CONTROLLER_Button(event.cbutton.button)), KEYS_None, false, event.cbutton.which),
			  KEYEV_Up);
		break;
	}
}
Exemplo n.º 3
0
	Button::Button(const char *szBtnText, const C4Rect &rtBounds)
			: Control(rtBounds), pCustomGfx(NULL), pCustomGfxDown(NULL), fDown(false), fMouseOver(false), fEnabled(true),
			  dwCustomFontClr(0), pCustomFont(NULL)
	{
		// key callbacks
		C4CustomKey::CodeList keys;
		keys.push_back(C4KeyCodeEx(K_SPACE));
		keys.push_back(C4KeyCodeEx(K_RETURN));
		if (Config.Controls.GamepadGuiControl)
			keys.push_back(C4KeyCodeEx(KEY_Gamepad(0, KEY_JOY_AnyLowButton)));
		pKeyButton = new C4KeyBinding(keys, "GUIButtonPress", KEYSCOPE_Gui,
		                              new ControlKeyCB<Button>(*this, &Button::KeyButtonDown, &Button::KeyButtonUp), C4CustomKey::PRIO_Ctrl);
		sText = "";
		// set new button text
		SetText(szBtnText);
	}
Exemplo n.º 4
0
CheckBox::CheckBox(const C4Rect &rtBounds, const char *szCaption, bool fChecked)
: Control(rtBounds), fChecked(fChecked), fMouseOn(false), fEnabled(true), pFont(NULL)
, dwEnabledClr(C4GUI_CheckboxFontClr), dwDisabledClr(C4GUI_CheckboxDisabledFontClr), cHotkey(0)
	{
	if (szCaption)
		{
		sCaption.Copy(szCaption);
		ExpandHotkeyMarkup(sCaption, cHotkey);
		}
	// key callbacks: Check/Uncheck on space and primary joy button
	C4CustomKey::CodeList Keys;
	Keys.push_back(C4KeyCodeEx(K_SPACE));
	if (Config.Controls.GamepadGuiControl)
		{
		Keys.push_back(C4KeyCodeEx(KEY_Gamepad(0, KEY_JOY_AnyLowButton)));
		}
	pKeyCheck = new C4KeyBinding(Keys, "GUICheckboxToggle", KEYSCOPE_Gui,
		new ControlKeyCB<CheckBox>(*this, &CheckBox::KeyCheck), C4CustomKey::PRIO_Ctrl);
	pCBHandler = NULL;
	}
Exemplo n.º 5
0
bool C4KeyboardInput::DoInput(const C4KeyCodeEx &InKey, C4KeyEventType InEvent, DWORD InScope, int32_t iStrength)
{
    // store last-key-info
    LastKeyExtraData.iStrength = (iStrength >= 0) ? iStrength : ((InEvent != KEYEV_Up) * 100);
    LastKeyExtraData.game_x = LastKeyExtraData.game_y = LastKeyExtraData.vp_x = LastKeyExtraData.vp_y = C4KeyEventData::KeyPos_None;
    // check all key events generated by this key: First the keycode itself, then any more generic key events like KEY_Any
    const int32_t iKeyRangeMax = 5;
    int32_t iKeyRangeCnt=0, j;
    C4KeyCode FallbackKeys[iKeyRangeMax];
    FallbackKeys[iKeyRangeCnt++] = InKey.Key;
    if (Key_IsGamepadButton(InKey.Key))
    {
        uint8_t byGamepad = Key_GetGamepad(InKey.Key);
        uint8_t byBtnIndex = Key_GetGamepadButtonIndex(InKey.Key);
        // even/odd button events: Add even button indices as odd events, because byBtnIndex is zero-based and the event naming scheme is for one-based button indices
        if (byBtnIndex % 2) FallbackKeys[iKeyRangeCnt++] = KEY_Gamepad(byGamepad, KEY_JOY_AnyEvenButton);
        else FallbackKeys[iKeyRangeCnt++] = KEY_Gamepad(byGamepad, KEY_JOY_AnyOddButton);
        // high/low button events
        if (byBtnIndex < 4) FallbackKeys[iKeyRangeCnt++] = KEY_Gamepad(byGamepad, KEY_JOY_AnyLowButton);
        else FallbackKeys[iKeyRangeCnt++] = KEY_Gamepad(byGamepad, KEY_JOY_AnyHighButton);
        // "any gamepad button"-event
        FallbackKeys[iKeyRangeCnt++] = KEY_Gamepad(byGamepad, KEY_JOY_AnyButton);
    }
    else if (Key_IsGamepadAxis(InKey.Key))
    {
        // xy-axis-events for all even/odd axises
        uint8_t byGamepad = Key_GetGamepad(InKey.Key);
        uint8_t byAxis = Key_GetGamepadAxisIndex(InKey.Key);
        bool fHigh = Key_IsGamepadAxisHigh(InKey.Key);
        C4KeyCode keyAxisDir;
        if (byAxis % 2)
            if (fHigh) keyAxisDir = KEY_JOY_Down;
            else keyAxisDir = KEY_JOY_Up;
        else if (fHigh) keyAxisDir = KEY_JOY_Right;
        else keyAxisDir = KEY_JOY_Left;
        FallbackKeys[iKeyRangeCnt++] = KEY_Gamepad(byGamepad, (uint8_t)keyAxisDir);
    }
    if (InKey.Key != KEY_Any) FallbackKeys[iKeyRangeCnt++] = KEY_Any;
    // now get key ranges for fallback chain
    std::pair<KeyCodeMap::iterator, KeyCodeMap::iterator> KeyRanges[iKeyRangeMax];
    assert(iKeyRangeCnt <= iKeyRangeMax);
    for (int32_t i = 0; i<iKeyRangeCnt; ++i)
    {
        KeyRanges[i] = KeysByCode.equal_range(FallbackKeys[i]);
    }
    // check all assigned keys
    // exec from highest to lowest priority
    unsigned int uiLastPrio = C4CustomKey::PRIO_MoreThanMax;
    for (;;)
    {
        KeyCodeMap::const_iterator i;
        // get priority to exec
        unsigned int uiExecPrio = C4CustomKey::PRIO_None, uiCurr;
        for (j = 0; j < iKeyRangeCnt; ++j)
            for (i = KeyRanges[j].first; i != KeyRanges[j].second; ++i)
            {
                uiCurr = i->second->GetPriority();
                if (uiCurr > uiExecPrio && uiCurr < uiLastPrio) uiExecPrio = uiCurr;
            }
        // nothing with correct priority set left?
        if (uiExecPrio == C4CustomKey::PRIO_None) break;
        // exec all of this priority
        for (j = 0; j < iKeyRangeCnt; ++j)
            for (i = KeyRanges[j].first; i != KeyRanges[j].second; ++i)
            {
                C4CustomKey *pKey = i->second;
                assert(pKey);
                // check priority
                if (pKey->GetPriority() == uiExecPrio)
                    // check scope and modifier
                    // (not on release of a key that has been down, because a key release might happen with a different modifier or in different scope than its pressing!)
                    if ((InEvent == KEYEV_Up && pKey->IsDown())
                            || ((pKey->GetScope() & InScope) && pKey->IsCodeMatched(C4KeyCodeEx(FallbackKeys[j], C4KeyShiftState(InKey.dwShift)))))
                        // exec it
                        if (pKey->Execute(InEvent, InKey))
                            return true;
            }
        // nothing found in this priority: exec next
        uiLastPrio = uiExecPrio;
    }
    // no key matched or all returned false in Execute: Not processed
    return false;
}
Exemplo n.º 6
0
C4KeyCode C4KeyCodeEx::String2KeyCode(const StdStrBuf &sName)
{
    // direct key code?
    if (sName.getLength() > 2)
    {
        unsigned int dwRVal;
        if (sscanf(sName.getData(), "\\x%x", &dwRVal) == 1) return dwRVal;
        // scan code
        if (*sName.getData() == '$') return GetKeyByScanCode(sName.getData());
        // direct gamepad code
#ifdef _WIN32
        if (!strnicmp(sName.getData(), "Joy", 3))
#else
        if (!strncasecmp(sName.getData(), "Joy", 3))
#endif
        {
            int iGamepad;
            if (sscanf(sName.getData(), "Joy%d",  &iGamepad) == 1)
            {
                // skip Joy[number]
                const char *key_str = sName.getData()+4;
                while (isdigit(*key_str)) ++key_str;
                // check for button (single, uppercase letter) (e.g. Joy1A)
                if (*key_str && !key_str[1])
                {
                    char cGamepadButton = toupper(*key_str);
                    if (Inside(cGamepadButton, 'A', 'Z'))
                    {
                        cGamepadButton = cGamepadButton - 'A';
                        return KEY_Gamepad(iGamepad-1, KEY_JOY_Button(cGamepadButton));
                    }
                }
                else
                {
                    // check for standard axis (e.g. Joy1Left)
                    if (!stricmp(key_str, "Left")) return KEY_Gamepad(iGamepad-1, KEY_JOY_Left);
                    if (!stricmp(key_str, "Up")) return KEY_Gamepad(iGamepad-1, KEY_JOY_Up);
                    if (!stricmp(key_str, "Down")) return KEY_Gamepad(iGamepad-1, KEY_JOY_Down);
                    if (!stricmp(key_str, "Right")) return KEY_Gamepad(iGamepad-1, KEY_JOY_Right);
                    // check for specific axis (e.g. Joy1Axis1Min)
                    int iAxis;
                    if (sscanf(key_str, "Axis%d", &iAxis) == 1 && iAxis>0)
                    {
                        --iAxis; // axis is 0-based internally but written 1-based in config
                        key_str += 5;
                        while (isdigit(*key_str)) ++key_str;
                        if (!stricmp(key_str, "Min")) return KEY_Gamepad(iGamepad-1, KEY_JOY_Axis(iAxis, false));
                        if (!stricmp(key_str, "Max")) return KEY_Gamepad(iGamepad-1, KEY_JOY_Axis(iAxis, true));
                    }
                }
            }
        }
        bool is_mouse_key;
#ifdef _WIN32
        is_mouse_key = !strnicmp(sName.getData(), "Mouse", 5);
#else
        is_mouse_key = !strncasecmp(sName.getData(), "Mouse", 5);
#endif
        if (is_mouse_key)
        {
            // skip Mouse/GameMouse
            const char *key_str = sName.getData()+5;
            int mouse_id;
            if (sscanf(key_str, "%d",  &mouse_id) == 1)
            {
                // skip number
                while (isdigit(*key_str)) ++key_str;
                // check for known mouse events (e.g. Mouse1Move or GameMouse1Wheel)
                if (!stricmp(key_str, "Move")) return KEY_Mouse(mouse_id-1, KEY_MOUSE_Move);
                if (!stricmp(key_str, "Wheel1Up")) return KEY_Mouse(mouse_id-1, KEY_MOUSE_Wheel1Up);
                if (!stricmp(key_str, "Wheel1Down")) return KEY_Mouse(mouse_id-1, KEY_MOUSE_Wheel1Down);
                if (SEqualNoCase(key_str, "Button", 6)) // e.g. Mouse1ButtonLeft or GameMouse1ButtonRightDouble
                {
                    // check for known mouse button events
                    uint8_t mouseevent_id = 0;
                    key_str += 6;
                    if (SEqualNoCase(key_str, "Left",4)) {
                        mouseevent_id=KEY_MOUSE_ButtonLeft;
                        key_str += 4;
                    }
                    else if (SEqualNoCase(key_str, "Right",5)) {
                        mouseevent_id=KEY_MOUSE_ButtonRight;
                        key_str += 5;
                    }
                    else if (SEqualNoCase(key_str, "Middle",6)) {
                        mouseevent_id=KEY_MOUSE_ButtonMiddle;
                        key_str += 6;
                    }
                    else if (isdigit(*key_str))
                    {
                        // indexed mouse button (e.g. Mouse1Button4 or Mouse1Button4Double)
                        int button_index;
                        if (sscanf(key_str, "%d",  &button_index) == 1)
                        {
                            mouseevent_id=static_cast<uint8_t>(KEY_MOUSE_Button1+button_index-1);
                            while (isdigit(*key_str)) ++key_str;
                        }
                    }
                    if (mouseevent_id)
                    {
                        // valid event if finished or followed by "Double"
                        if (!*key_str) return KEY_Mouse(mouse_id-1, mouseevent_id);
                        if (!stricmp(key_str, "Double")) return KEY_Mouse(mouse_id-1, mouseevent_id+(KEY_MOUSE_Button1Double-KEY_MOUSE_Button1));
                        // invalid mouse key...
                    }
                }
            }
        }

    }
    // query map
    const C4KeyCodeMapEntry *pCheck = KeyCodeMap;
    while (pCheck->szName) {
        if (SEqualNoCase(sName.getData(), pCheck->szName)) {
            return(pCheck->wCode);
        }
        ++pCheck;
    }
#if defined(USE_SDL_MAINLOOP)
    SDL_Scancode s = SDL_GetScancodeFromName(sName.getData());
    if (s != SDL_SCANCODE_UNKNOWN) return s;
#endif
    return KEY_Undefined;
}