/// <summary>
        /// Use this to create the UIFastList.
        /// Do NOT use AddUIComponent.
        /// I had to do that way because MonoBehaviors classes cannot be generic
        /// </summary>
        /// <typeparam name="T">The type of the row UI component</typeparam>
        /// <param name="parent"></param>
        /// <returns></returns>
        public static UIFastList Create <T>(UIComponent parent)
            where T : UIPanel, IUIFastListRow
        {
            UIFastList list = parent.AddUIComponent <UIFastList>();

            list.m_rowType = typeof(T);
            return(list);
        }
        /// <summary>
        /// Create the panel; we no longer use Start() as that's not sufficiently reliable (race conditions), and is no longer needed, with the new create/destroy process.
        /// </summary>
        internal void Setup()
        {
            // Generic setup.
            isVisible            = true;
            canFocus             = true;
            isInteractive        = true;
            backgroundSprite     = "UnlockingPanel";
            autoLayout           = false;
            autoSize             = false;
            width                = parent.width;
            height               = 395f;
            builtinKeyNavigation = true;
            clipChildren         = true;

            // Labels.
            floorHeightLabel   = AddVolumetricLabel(this, "RPR_CAL_VOL_FLH", RightColumn, Row1, "RPR_CAL_VOL_FLH_TIP");
            firstMinLabel      = AddVolumetricLabel(this, "RPR_CAL_VOL_FMN", RightColumn, Row2, "RPR_CAL_VOL_FMN_TIP");
            firstExtraLabel    = AddVolumetricLabel(this, "RPR_CAL_VOL_FMX", RightColumn, Row3, "RPR_CAL_VOL_FMX_TIP");
            numFloorsLabel     = AddVolumetricLabel(this, "RPR_CAL_VOL_FLR", RightColumn, Row5, "RPR_CAL_VOL_FLR_TIP");
            floorAreaLabel     = AddVolumetricLabel(this, "RPR_CAL_VOL_TFA", RightColumn, Row6, "RPR_CAL_VOL_TFA_TIP");
            totalHomesLabel    = AddVolumetricLabel(this, "RPR_CAL_VOL_HOU", RightColumn, Row7, "RPR_CAL_VOL_UTS_TIP");
            totalJobsLabel     = AddVolumetricLabel(this, "RPR_CAL_VOL_WOR", RightColumn, Row7, "RPR_CAL_VOL_UTS_TIP");
            totalStudentsLabel = AddVolumetricLabel(this, "RPR_CAL_VOL_STU", RightColumn, Row7, "RPR_CAL_VOL_UTS_TIP");
            visitCountLabel    = AddVolumetricLabel(this, "RPR_CAL_VOL_VIS", RightColumn, Row8, "RPR_CAL_VOL_VIS_TIP");
            productionLabel    = AddVolumetricLabel(this, "RPR_CAL_VOL_PRD", RightColumn, Row8, "RPR_CAL_VOL_PRD_TIP");
            unitsLabel         = AddVolumetricLabel(this, "RPR_CAL_VOL_UNI", LeftColumn, Row2, "RPR_CAL_VOL_UNI_TIP");
            emptyPercentLabel  = AddVolumetricLabel(this, "RPR_CAL_VOL_EPC", LeftColumn, Row2, "RPR_CAL_VOL_EPC_TIP");
            emptyAreaLabel     = AddVolumetricLabel(this, "RPR_CAL_VOL_EMP", LeftColumn, Row3, "RPR_CAL_VOL_EMP_TIP");
            perLabel           = AddVolumetricLabel(this, "RPR_CAL_VOL_APU", LeftColumn, Row4, "RPR_CAL_VOL_APU_TIP");
            schoolWorkerLabel  = AddVolumetricLabel(this, "RPR_CAL_SCH_WKR", LeftColumn, Row7, "RPR_CAL_SCH_WKR_TIP");
            costLabel          = AddVolumetricLabel(this, "RPR_CAL_SCH_CST", LeftColumn, Row8, "RPR_CAL_SCH_CST_TIP");

            // Intially hidden (just to avoid ugliness if no building is selected).
            totalHomesLabel.Hide();
            totalStudentsLabel.Hide();

            // Fixed population checkbox.
            fixedPopCheckBox = CalcCheckBox(this, "RPR_CAL_VOL_FXP", LeftColumn, Row1, "RPR_CAL_VOL_FXP_TIP");
            fixedPopCheckBox.isInteractive = false;
            fixedPopCheckBox.Disable();

            // Multi-floor units checkbox.
            multiFloorCheckBox = CalcCheckBox(this, "RPR_CAL_VOL_MFU", LeftColumn, Row5, "RPR_CAL_VOL_MFU_TIP");
            multiFloorCheckBox.isInteractive = false;
            multiFloorCheckBox.Disable();

            // Ignore first floor checkbox.
            ignoreFirstCheckBox = CalcCheckBox(this, "RPR_CAL_VOL_IGF", RightColumn, Row4, "RPR_CAL_VOL_IGF_TIP");
            ignoreFirstCheckBox.isInteractive = false;
            ignoreFirstCheckBox.Disable();

            // Message label.
            messageLabel = UIControls.AddLabel(this, Margin, MessageY, string.Empty);

            // Floor list - attached to root panel as scrolling and interactivity can be unreliable otherwise.
            floorsList = UIFastList.Create <UIFloorRow>(BuildingDetailsPanel.Panel);

            // Size, appearance and behaviour.
            floorsList.backgroundSprite  = "UnlockingPanel";
            floorsList.width             = this.width;
            floorsList.isInteractive     = true;
            floorsList.canSelect         = false;
            floorsList.rowHeight         = 20;
            floorsList.autoHideScrollbar = true;;
            ResetFloorListPosition();

            // Data.
            floorsList.rowsData      = new FastList <object>();
            floorsList.selectedIndex = -1;

            // Toggle floorsList visibility on this panel's visibility change (because floorsList is attached to root panel).
            this.eventVisibilityChanged += (control, isVisible) => floorsList.isVisible = isVisible;
        }