/** * @brief Is called every time one clicks on a window/screen. Then checks if anything needs to be executed in the area of the click * (e.g. button-commands, inventory-handling, geoscape-stuff, etc...) * @sa UI_ExecuteEventActions * @sa UI_RightClick * @sa Key_Message */ static void UI_LeftClick (int x, int y) { if (UI_IsMouseInvalidate()) return; /* send it to the captured mouse node */ if (capturedNode) { UI_Node_LeftClick(capturedNode, x, y); return; } /* if we click outside a dropdown window, we close it */ /** @todo need to refactoring it with the focus code (cleaner) */ /** @todo at least should be moved on the mouse down event (when the focus should change) */ /** @todo this code must be on mouse down */ if (!pressedNode && ui_global.windowStackPos != 0) { uiNode_t* window = ui_global.windowStack[ui_global.windowStackPos - 1]; if (UI_WindowIsDropDown(window)) { UI_PopWindow(); } } const bool disabled = (pressedNode == nullptr) || (pressedNode->disabled) || (pressedNode->parent && pressedNode->parent->disabled); if (!disabled) { UI_Node_LeftClick(pressedNode, x, y); } }
/** * @brief Console function to pop a window from the window stack * @sa UI_PopWindow */ static void UI_PopWindow_f (void) { if (Cmd_Argc() > 1) { Com_Printf("Usage: %s\n", Cmd_Argv(0)); return; } UI_PopWindow(false); }
static void UI_MaterialEditorStart_f (void) { /* material editor only makes sense in battlescape mode */ #ifndef ANYIMAGES if (cls.state != ca_active) { Com_Printf("Material editor is only usable in battlescape mode\n"); UI_PopWindow(); return; } #endif }
/** * @brief Starts an aircraft or stops the current mission and let the aircraft idle around. */ static void AIM_AircraftStart_f (void) { aircraft_t *aircraft; base_t *base = B_GetCurrentSelectedBase(); if (!base) return; if (!base->aircraftCurrent) { Com_DPrintf(DEBUG_CLIENT, "Error - there is no current aircraft in this base\n"); return; } /* Aircraft cannot start without Command Centre operational. */ if (!B_GetBuildingStatus(base, B_COMMAND)) { CP_Popup(_("Notice"), _("No operational Command Centre in this base.\n\nAircraft can not start.\n")); return; } aircraft = base->aircraftCurrent; /* Aircraft cannot start without a pilot. */ if (!AIR_GetPilot(aircraft)) { CP_Popup(_("Notice"), _("There is no pilot assigned to this aircraft.\n\nAircraft can not start.\n")); return; } if (AIR_IsAircraftInBase(aircraft)) { /* reload its ammunition */ AII_ReloadAircraftWeapons(aircraft); } MS_AddNewMessage(_("Notice"), _("Aircraft started"), qfalse, MSG_STANDARD, NULL); aircraft->status = AIR_IDLE; MAP_SelectAircraft(aircraft); /* Return to geoscape. */ UI_PopWindow(qfalse); UI_PopWindow(qfalse); }
/** * @brief Loads the last saved game * @note At saving the archive cvar cl_lastsave was set to the latest savegame * @sa SAV_GameLoad */ static void SAV_GameContinue_f (void) { const char *error = NULL; if (cgi->CL_OnBattlescape()) { UI_PopWindow(qfalse); return; } if (!CP_IsRunning()) { /* try to load the last saved campaign */ if (!SAV_GameLoad(cl_lastsave->string, &error)) { Cbuf_Execute(); /* wipe outstanding campaign commands */ Com_sprintf(popupText, sizeof(popupText), "%s\n%s", _("Error loading game."), error ? error : ""); UI_Popup(_("Error"), popupText); Cmd_ExecuteString("game_exit"); } } else { /* just continue the current running game */ UI_PopWindow(qfalse); } }
void UI_PopWindowWithEscKey (void) { const uiNode_t *window = ui_global.windowStack[ui_global.windowStackPos - 1]; /* nothing if stack is empty */ if (ui_global.windowStackPos == 0) return; /* some window can prevent escape */ if (WINDOWEXTRADATACONST(window).preventTypingEscape) return; UI_PopWindow(false); }
/** * @brief Init the stack to start with a window, and have an alternative window with ESC * @param[in] activeWindow The first active window of the stack, else NULL * @param[in] mainWindow The alternative window, else NULL if nothing * @param[in] popAll If true, clean up the stack first * @param[in] pushActive If true, push the active window into the stack * @todo remove Cvar_Set we have direct access to the cvar * @todo check why activeWindow can be NULL. It should never be NULL: a stack must not be empty * @todo We should only call it a very few time. When we switch from/to this different par of the game: main-option-interface / geoscape-and-base / battlescape * @todo Update the code: popAll should be every time true * @todo Update the code: pushActive should be every time true * @todo Illustration about when/how we should use UI_InitStack http://ufoai.org/wiki/index.php/Image:UI_InitStack.jpg */ void UI_InitStack (const char* activeWindow, const char* mainWindow, bool popAll, bool pushActive) { UI_FinishInit(); if (popAll) UI_PopWindow(true); if (activeWindow) { Cvar_Set("ui_sys_active", activeWindow); /* prevent calls before UI script initialization */ if (ui_global.numWindows != 0) { if (pushActive) UI_PushWindow(activeWindow); } } if (mainWindow) Cvar_Set("ui_sys_main", mainWindow); }
/** * @brief User select a base in the popup_homebase * change homebase to selected base. */ static void CL_PopupChangeHomebase_f (void) { linkedList_t* data = popupListData; /**< Use this so we do not change the original popupListData pointer. */ int selectedPopupIndex; int i; base_t *base; int baseIdx; aircraft_t *aircraft = MAP_GetSelectedAircraft(); /* If popup is opened, that means an aircraft is selected */ if (!aircraft) { Com_Printf("CL_PopupChangeHomebase_f: An aircraft must be selected\n"); return; } if (Cmd_Argc() < 2) { Com_Printf("Usage: %s <popupIndex>\tpopupIndex=num in base list\n", Cmd_Argv(0)); return; } /* read and range check */ selectedPopupIndex = atoi(Cmd_Argv(1)); Com_DPrintf(DEBUG_CLIENT, "CL_PopupHomebaseClick_f (popupNum %i, selectedPopupIndex %i)\n", popupNum, selectedPopupIndex); if (selectedPopupIndex < 0 || selectedPopupIndex >= popupNum) return; /* Convert list index to base idx */ baseIdx = INVALID_BASE; for (i = 0; data; data = data->next, i++) { if (i == selectedPopupIndex) { baseIdx = *(int*)data->data; break; } } base = B_GetFoundedBaseByIDX(baseIdx); if (base == NULL) return; AIR_MoveAircraftIntoNewHomebase(aircraft, base); UI_PopWindow(qfalse); CL_DisplayHomebasePopup(aircraft, qtrue); }
/** * @brief Draws a base. */ static void UI_BaseMapNodeDraw (uiNode_t * node) { int width, height, row, col; const building_t *building; const base_t *base = B_GetCurrentSelectedBase(); qboolean used[MAX_BUILDINGS]; if (!base) { UI_PopWindow(qfalse); return; } /* reset the used flag */ OBJZERO(used); width = node->size[0] / BASE_SIZE; height = node->size[1] / BASE_SIZE + BASE_IMAGE_OVERLAY; for (row = 0; row < BASE_SIZE; row++) { const char *image = NULL; for (col = 0; col < BASE_SIZE; col++) { vec2_t pos; UI_GetNodeAbsPos(node, pos); pos[0] += col * width; pos[1] += row * (height - BASE_IMAGE_OVERLAY); /* base tile */ if (B_IsTileBlocked(base, col, row)) { building = NULL; image = "base/invalid"; } else if (B_GetBuildingAt(base, col, row) == NULL) { building = NULL; image = "base/grid"; } else { building = B_GetBuildingAt(base, col, row); assert(building); if (building->image) image = building->image; /* some buildings are drawn with two tiles - e.g. the hangar is no square map tile. * These buildings have the needs parameter set to the second building part which has * its own image set, too. We are searching for this second building part here. */ if (B_BuildingGetUsed(used, building->idx)) continue; B_BuildingSetUsed(used, building->idx); } /* draw tile */ if (image != NULL) UI_DrawNormImageByName(qfalse, pos[0], pos[1], width * (building ? building->size[0] : 1), height * (building ? building->size[1] : 1), 0, 0, 0, 0, image); if (building) { switch (building->buildingStatus) { case B_STATUS_DOWN: case B_STATUS_CONSTRUCTION_FINISHED: break; case B_STATUS_UNDER_CONSTRUCTION: { const float time = max(0.0, B_GetConstructionTimeRemain(building)); UI_DrawString("f_small", ALIGN_UL, pos[0] + 10, pos[1] + 10, pos[0] + 10, node->size[0], 0, va(ngettext("%3.1f day left", "%3.1f days left", time), time), 0, 0, NULL, qfalse, 0); break; } default: break; } } } } if (!node->state) return; UI_BaseMapGetCellAtPos(node, mousePosX, mousePosY, &col, &row); if (col == -1) return; /* if we are building */ if (ccs.baseAction == BA_NEWBUILDING) { int y, x; int xCoord, yCoord, widthRect, heigthRect; vec2_t pos; assert(base->buildingCurrent); for (y = row; y < row + base->buildingCurrent->size[1]; y++) { for (x = col; x < col + base->buildingCurrent->size[0]; x++) { if (!B_MapIsCellFree(base, x, y)) return; } } UI_GetNodeAbsPos(node, pos); xCoord = pos[0] + col * width; yCoord = pos[1] + row * (height - BASE_IMAGE_OVERLAY); widthRect = base->buildingCurrent->size[0] * width; heigthRect = base->buildingCurrent->size[1] * (height - BASE_IMAGE_OVERLAY); R_DrawRect(xCoord, yCoord, widthRect, heigthRect, white, 3, 1); } }