| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982 |
- /*
- ** Command & Conquer Renegade(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /***********************************************************************************************
- *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
- ***********************************************************************************************
- * *
- * Project Name : Combat *
- * *
- * $Archive:: /Commando/Code/wwui/tabctrl.cpp $*
- * *
- * Author:: Patrick Smith *
- * *
- * $Modtime:: 9/19/01 11:30a $*
- * *
- * $Revision:: 17 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- // Disable warning about exception handling not being enabled. It's used as part of STL - in a part of STL we don't use.
- #pragma warning(disable : 4530)
- #include "tabctrl.h"
- #include "assetmgr.h"
- #include "refcount.h"
- #include "mousemgr.h"
- #include "dialogmgr.h"
- #include "dialogbase.h"
- #include "stylemgr.h"
- #include "texture.h"
- #include "ww3d.h"
- #include "font3d.h"
- #include "childdialog.h"
- ////////////////////////////////////////////////////////////////
- // Local constants
- ////////////////////////////////////////////////////////////////
- static const RectClass BarUVs (1, 1, 26, 255);
- static const RectClass SelUVs (28, 1, 254, 69);
- static const RectClass UnfocusUVs (28, 236, 42, 250);
- static const RectClass FocusUVs (43, 236, 57, 250);
- static const RectClass BarTopUVs (1, 1, 26, 79);
- static const RectClass BarBottomUVs (1, 169, 26, 255);
- static const RectClass BarTileUVs (1, 80, 26, 168);
- static const float BUBBLE_OFFSET_X = 23;
- static const float BUBBLE_OFFSET_Y = 25;
- static const float BAR_OFFSET = 25;
- static const float TEXT_OFFSET = 60;
- static const float SEL_TEXT_OFFSET = 75;
- static const float TEXT_RADIUS = 40;
- static const float ANGLE_MIN = 115;
- static const float ANGLE_MAX = 245;
- static const float BLINK_DELAY = 500;
- static const float PAGE_AREA_OFFSET = 245;
- static const float PIXELS_PER_SEC = 500;
- ////////////////////////////////////////////////////////////////
- //
- // TabCtrlClass
- //
- ////////////////////////////////////////////////////////////////
- TabCtrlClass::TabCtrlClass (void) :
- CurrTabIndex (0),
- NextBlinkTime (0),
- SelectorPos (0),
- SelRect (0, 0, 0, 0),
- ScaleX (0),
- ScaleY (0),
- IsBubbleDisplayed (false)
- {
- //
- // Determine what scale to use
- //
- ScaleX = Render2DClass::Get_Screen_Resolution().Width () / 800;
- ScaleY = Render2DClass::Get_Screen_Resolution().Height () / 600;
- //
- // Assign the font to the text renderers
- //
- StyleMgrClass::Assign_Font (&TextRenderer, StyleMgrClass::FONT_HEADER);
- StyleMgrClass::Assign_Font (&GlowRenderer, StyleMgrClass::FONT_HEADER);
- StyleMgrClass::Assign_Font (&HilightRenderer, StyleMgrClass::FONT_BIG_HEADER);
- StyleMgrClass::Assign_Font (&HilightGlowRenderer, StyleMgrClass::FONT_BIG_HEADER);
- //
- // Configure the renderers
- //
- StyleMgrClass::Configure_Renderer (&ControlRenderer);
- //
- // Load the texture for the control
- //
- TextureClass *texture = WW3DAssetManager::Get_Instance ()->Get_Texture ("IF_MENUPARTS9.TGA", TextureClass::MIP_LEVELS_1);
- ControlRenderer.Set_Texture (texture);
- REF_PTR_RELEASE (texture);
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // ~TabCtrlClass
- //
- ////////////////////////////////////////////////////////////////
- TabCtrlClass::~TabCtrlClass (void)
- {
- Free_Tabs ();
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Create_Text_Renderer
- //
- ////////////////////////////////////////////////////////////////
- void
- TabCtrlClass::Create_Text_Renderer (void)
- {
- //
- // Reset the renderers
- //
- GlowRenderer.Reset ();
- TextRenderer.Reset ();
- HilightRenderer.Reset ();
- HilightGlowRenderer.Reset ();
- float text_left = ClientRect.Left + (TEXT_OFFSET * ScaleX);
- float height = ClientRect.Height ();
- float tab_height = height / max (TabList.Count (), 1);
- //
- // Setup some variables we can use to simulate a semi-circle for the text
- //
- float angle_min = DEG_TO_RADF (ANGLE_MIN);
- float angle_max = DEG_TO_RADF (ANGLE_MAX);
- float radius = TEXT_RADIUS * ScaleX;
- //
- // Render the tab names
- //
- float y_pos = ClientRect.Top;
- for (int index = 0; index < TabList.Count (); index ++) {
- //
- // Calculate a "semi-circular" x-offset for the text
- //
- float angle = angle_min + ((angle_max - angle_min) * ((float)index / float(TabList.Count()-1)));
- float x_offset = WWMath::Cos (angle) * radius;
- //
- // Calculate what rectangle to render to
- //
- RectClass text_rect;
- text_rect.Left = (int)(text_left + (radius + x_offset));
- text_rect.Top = (int)y_pos;
- text_rect.Right = (int)ClientRect.Right;
- text_rect.Bottom = int(y_pos + tab_height);
- //
- // Get the title from the child dialog
- //
- WideStringClass title;
- TabList[index]->Get_Title (&title);
- //
- // Is this the selected tab?
- //
- if (index == CurrTabIndex) {
- //
- // Move the hilighted text in a bit
- //
- text_rect.Left = SelRect.Left + (SEL_TEXT_OFFSET * ScaleX);
- //
- // Render the hilighted text and its glow
- //
- HilightRenderer.Build_Sentence (title);
- HilightGlowRenderer.Build_Sentence (title);
- //StyleMgrClass::Render_Text (title, &HilightRenderer, text_rect, true, true);
- StyleMgrClass::Render_Text (title, &HilightRenderer,
- StyleMgrClass::Get_Tab_Text_Color (),
- StyleMgrClass::Get_Text_Shadow_Color (),
- text_rect, true, true);
- /*HilightRenderer.Set_Clipping_Rect (text_rect);
- //
- // Get the extents of the text we will be drawing
- //
- Vector2 text_extent = HilightRenderer.Get_Text_Extents (title);
- //
- // Assume left justification
- //
- int x_pos = text_rect.Left + 1;
- int y_pos = int(text_rect.Top + (text_rect.Height () / 2) - (text_extent.Y / 2));
- //
- // Construct the textures needed to render the text
- //
- HilightRenderer.Build_Sentence (title);
- HilightRenderer.Set_Location (Vector2 (x_pos - 1, y_pos - 1));
- HilightRenderer.Draw_Sentence (RGB_TO_INT32 (255, 255, 255));
- HilightRenderer.Set_Location (Vector2 (x_pos + 1, y_pos + 1));
- HilightRenderer.Draw_Sentence (RGB_TO_INT32 (0, 0, 0));
- //
- // Render the text
- //
- HilightRenderer.Set_Location (Vector2 (x_pos, y_pos));
- HilightRenderer.Draw_Sentence (RGB_TO_INT32 (147, 155, 153));*/
- StyleMgrClass::Render_Glow (title, &HilightGlowRenderer, text_rect, 7, 7,
- StyleMgrClass::Get_Tab_Glow_Color ());
- } else {
-
- //
- // Render the text and its glow
- //
- TextRenderer.Build_Sentence (title);
- GlowRenderer.Build_Sentence (title);
- StyleMgrClass::Render_Text (title, &TextRenderer,
- StyleMgrClass::Get_Tab_Text_Color (),
- StyleMgrClass::Get_Text_Shadow_Color (),
- text_rect, true, true);
- /*TextRenderer.Set_Clipping_Rect (text_rect);
- //
- // Get the extents of the text we will be drawing
- //
- Vector2 text_extent = TextRenderer.Get_Text_Extents (title);
- //
- // Assume left justification
- //
- int x_pos = text_rect.Left + 1;
- int y_pos = int(text_rect.Top + (text_rect.Height () / 2) - (text_extent.Y / 2));
- //
- // Construct the textures needed to render the text
- //
- TextRenderer.Build_Sentence (title);
- TextRenderer.Set_Location (Vector2 (x_pos - 1, y_pos - 1));
- TextRenderer.Draw_Sentence (RGB_TO_INT32 (255, 255, 255));
- TextRenderer.Set_Location (Vector2 (x_pos + 1, y_pos + 1));
- TextRenderer.Draw_Sentence (RGB_TO_INT32 (0, 0, 0));
- //
- // Render the text
- //
- TextRenderer.Set_Location (Vector2 (x_pos, y_pos));
- TextRenderer.Draw_Sentence (RGB_TO_INT32 (147, 155, 153));*/
-
- StyleMgrClass::Render_Glow (title, &GlowRenderer, text_rect, 4, 4,
- StyleMgrClass::Get_Tab_Glow_Color ());
- }
- //
- // Move down to the next tab
- //
- y_pos += tab_height;
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Create_Control_Renderer
- //
- ////////////////////////////////////////////////////////////////
- void
- TabCtrlClass::Create_Control_Renderer (void)
- {
- Render2DClass &renderer = ControlRenderer;
- renderer.Reset ();
- //
- // Determine which UVs to use for the bubble
- //
- RectClass bubble_uvs = UnfocusUVs;
- if (IsBubbleDisplayed) {
- bubble_uvs = FocusUVs;
- }
- //
- // Scale the dimensions of the components
- //
- float bar_tile_height = BarTileUVs.Height () * ScaleY;
- float bar_tip_height = BarTopUVs.Height () * ScaleY;
- float bar_width = BarTileUVs.Width () * ScaleX;
- float sel_width = SelUVs.Width () * ScaleX;
- float sel_height = SelUVs.Height () * ScaleY;
- float bubble_width = bubble_uvs.Width () * ScaleX;
- float bubble_height = bubble_uvs.Height () * ScaleX;
- //
- // Setup some variables we can use to simulate a semi-circle for the text
- //
- float angle_min = DEG_TO_RADF (ANGLE_MIN);
- float angle_max = DEG_TO_RADF (ANGLE_MAX);
- float radius = TEXT_RADIUS * ScaleX;
- float min_y = Pos_From_Tab (0);
- float max_y = Pos_From_Tab (TabList.Count () - 1);
- float percent = (SelectorPos - min_y) / (max_y - min_y);
- float angle = angle_min + percent * (angle_max - angle_min);
- //float left_pos = -radius;
- float x_offset = radius + (WWMath::Cos (angle) * radius);
- //
- // Calculate the screen rectangle for the bar
- //
- RectClass bar_rect;
- bar_rect.Left = int(ClientRect.Left + x_offset + (BAR_OFFSET * ScaleX) - (bar_width / 2));
- bar_rect.Right = int(bar_rect.Left + bar_width);
- bar_rect.Top = int(ClientRect.Top - (x_offset * 1.5F));
- bar_rect.Bottom = int(ClientRect.Bottom + (x_offset * 1.5F));
- //
- // Calculate the screen rectangle for the selector
- //
- SelRect.Left = int(ClientRect.Left + x_offset);
- SelRect.Right = int(SelRect.Left + sel_width);
- SelRect.Top = int(SelectorPos - (sel_height / 2));
- SelRect.Bottom = int(SelRect.Top + sel_height);
- //
- // Calculate the screen rectangle for the bubble
- //
- RectClass bubble_rect;
- bubble_rect.Left = int(SelRect.Left + BUBBLE_OFFSET_X * ScaleX);
- bubble_rect.Right = int(bubble_rect.Left + bubble_width);
- bubble_rect.Top = int(SelRect.Top + BUBBLE_OFFSET_Y * ScaleY);
- bubble_rect.Bottom = int(bubble_rect.Top + bubble_height);
- //
- // Normalize the UVs
- //
- RectClass sel_uvs = SelUVs;
- RectClass bar_top_uvs = BarTopUVs;
- RectClass bar_bottom_uvs = BarBottomUVs;
- sel_uvs.Inverse_Scale (Vector2 (256, 256));
- bar_top_uvs.Inverse_Scale (Vector2 (256, 256));
- bar_bottom_uvs.Inverse_Scale (Vector2 (256, 256));
- bubble_uvs.Inverse_Scale (Vector2 (256, 256));
- //
- // Render the bar top and bottom
- //
- RectClass bar_top_rect;
- bar_top_rect.Left = int(bar_rect.Left);
- bar_top_rect.Right = int(bar_rect.Right);
- bar_top_rect.Top = int(bar_rect.Top);
- bar_top_rect.Bottom = int(bar_top_rect.Top + bar_tip_height);
-
- RectClass bar_bottom_rect;
- bar_bottom_rect.Left = int(bar_rect.Left);
- bar_bottom_rect.Right = int(bar_rect.Right);
- bar_bottom_rect.Top = int(bar_rect.Bottom - bar_tip_height);
- bar_bottom_rect.Bottom = int(bar_rect.Bottom);
-
- renderer.Add_Quad (bar_top_rect, bar_top_uvs);
- renderer.Add_Quad (bar_bottom_rect, bar_bottom_uvs);
- //
- // Tile the remaining pieces
- //
- float y_pos = bar_top_rect.Bottom;
- float total_height = bar_bottom_rect.Top - y_pos;
- while (total_height > 0) {
-
- float height = min (bar_tile_height, total_height);
- //
- // Setup the UV rectangle
- //
- RectClass uvs = BarTileUVs;
- uvs.Bottom = uvs.Top + height;
- uvs.Inverse_Scale (Vector2 (256, 256));
- //
- // Setup the screen rectangle
- //
- RectClass bar_tile_rect = bar_rect;
- bar_tile_rect.Top = y_pos;
- bar_tile_rect.Bottom = y_pos + height;
- //
- // Render the section
- //
- renderer.Add_Quad (bar_tile_rect, uvs);
-
- y_pos += height;
- total_height -= height;
- }
-
- //
- // Render the bar and selector
- //
- renderer.Add_Quad (SelRect, sel_uvs);
- renderer.Add_Quad (bubble_rect, bubble_uvs);
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // On_Set_Cursor
- //
- ////////////////////////////////////////////////////////////////
- void
- TabCtrlClass::On_Set_Cursor (const Vector2 &mouse_pos)
- {
- //
- // Change the mouse cursor
- //
- if (mouse_pos.X < (ClientRect.Left + PAGE_AREA_OFFSET * ScaleX)) {
- MouseMgrClass::Set_Cursor (MouseMgrClass::CURSOR_ACTION);
- } else {
- MouseMgrClass::Set_Cursor (MouseMgrClass::CURSOR_ARROW);
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Update_Client_Rect
- //
- ////////////////////////////////////////////////////////////////
- void
- TabCtrlClass::Update_Client_Rect (void)
- {
- //
- // Set the client area
- //
- ClientRect = Rect;
- Set_Dirty ();
- //
- // Resize each child dialog so it fits in the new rectangle
- //
- for (int index = 0; index < TabList.Count (); index ++) {
- RectClass rect;
- rect.Left = (int)(ClientRect.Left + PAGE_AREA_OFFSET * ScaleX);
- rect.Top = (int)ClientRect.Top;
- rect.Right = (int)ClientRect.Right;
- rect.Bottom = (int)ClientRect.Bottom;
- TabList[index]->Set_Rect (rect);
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Render
- //
- ////////////////////////////////////////////////////////////////
- void
- TabCtrlClass::Render (void)
- {
- Update_Selector ();
- Update_Bubble ();
- //
- // Recreate the renderers (if necessary)
- //
- if (IsDirty) {
- Create_Control_Renderer ();
- Create_Text_Renderer ();
- }
- //
- // Render the background and text
- //
- GlowRenderer.Render ();
- HilightGlowRenderer.Render ();
- TextRenderer.Render ();
- HilightRenderer.Render ();
- ControlRenderer.Render ();
- DialogControlClass::Render ();
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // On_LButton_Down
- //
- ////////////////////////////////////////////////////////////////
- void
- TabCtrlClass::On_LButton_Down (const Vector2 &mouse_pos)
- {
- //
- // Change tabs
- //
- if (mouse_pos.X < (ClientRect.Left + PAGE_AREA_OFFSET * ScaleX)) {
- Set_Curr_Tab (Tab_From_Pos (mouse_pos));
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // On_LButton_Up
- //
- ////////////////////////////////////////////////////////////////
- void
- TabCtrlClass::On_LButton_Up (const Vector2 &mouse_pos)
- {
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // On_Mouse_Move
- //
- ////////////////////////////////////////////////////////////////
- void
- TabCtrlClass::On_Mouse_Move (const Vector2 &mouse_pos)
- {
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // On_Set_Focus
- //
- ////////////////////////////////////////////////////////////////
- void
- TabCtrlClass::On_Set_Focus (void)
- {
- Set_Dirty ();
- DialogControlClass::On_Set_Focus ();
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // On_Kill_Focus
- //
- ////////////////////////////////////////////////////////////////
- void
- TabCtrlClass::On_Kill_Focus (DialogControlClass *focus)
- {
- Set_Dirty ();
- DialogControlClass::On_Kill_Focus (focus);
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // On_Key_Down
- //
- ////////////////////////////////////////////////////////////////
- bool
- TabCtrlClass::On_Key_Down (uint32 key_id, uint32 key_data)
- {
- bool handled = true;
- switch (key_id)
- {
- case VK_UP:
- case VK_LEFT:
- Set_Curr_Tab (CurrTabIndex - 1);
- break;
- case VK_DOWN:
- case VK_RIGHT:
- Set_Curr_Tab (CurrTabIndex + 1);
- break;
- case VK_HOME:
- Set_Curr_Tab (0);
- break;
- case VK_END:
- Set_Curr_Tab (TabList.Count () - 1);
- break;
- default:
- handled = false;
- break;
- }
- return handled;
- }
- ////////////////////////////////////////////////////////////////
- //
- // On_Create
- //
- ////////////////////////////////////////////////////////////////
- void
- TabCtrlClass::On_Create (void)
- {
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Tab_From_Pos
- //
- ////////////////////////////////////////////////////////////////
- int
- TabCtrlClass::Tab_From_Pos (const Vector2 &mouse_pos)
- {
- int retval = -1;
- float height = ClientRect.Height ();
- float tab_height = height / max (TabList.Count (), 1);
- //
- // Check each of the tabs
- //
- float y_pos = ClientRect.Top;
- for (int index = 0; index < TabList.Count (); index ++) {
- //
- // Is the mouse over this tab?
- //
- if (mouse_pos.Y >= y_pos && mouse_pos.Y <= (y_pos + tab_height)) {
- retval = index;
- break;
- }
- //
- // Move down to the next tab
- //
- y_pos += tab_height;
- }
- return retval;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Pos_From_Tab
- //
- ////////////////////////////////////////////////////////////////
- float
- TabCtrlClass::Pos_From_Tab (int index)
- {
- float height = ClientRect.Height ();
- float tab_height = height / max (TabList.Count (), 1);
- //
- // Return the centered y-position
- //
- return ClientRect.Top + (tab_height * (index + 1)) - (tab_height / 2);
- }
- ////////////////////////////////////////////////////////////////
- //
- // Set_Curr_Tab
- //
- ////////////////////////////////////////////////////////////////
- void
- TabCtrlClass::Set_Curr_Tab (int index)
- {
- //
- // Bound the index
- //
- index = min (TabList.Count () - 1, index);
- index = max (0, index);
- //
- // Did we change tabs?
- //
- if (CurrTabIndex != index) {
-
- //
- // Switch tabs visibly
- //
- TabList[CurrTabIndex]->Show (false);
- TabList[index]->Show (true);
- //
- // Change the tab and force a repaint
- //
- CurrTabIndex = index;
- Set_Dirty ();
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Update_Bubble
- //
- ////////////////////////////////////////////////////////////////
- void
- TabCtrlClass::Update_Bubble (void)
- {
- if (HasFocus) {
-
- //
- // Is it time to blink the bubble light?
- //
- int curr_time = DialogMgrClass::Get_Time ();
- if (curr_time > NextBlinkTime) {
-
- //
- // Toggle the bubble light
- //
- IsBubbleDisplayed = !IsBubbleDisplayed;
- NextBlinkTime = curr_time + BLINK_DELAY;
-
- //
- // Force a repaint
- //
- Set_Dirty ();
- }
- } else {
- IsBubbleDisplayed = false;
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Update_Selector
- //
- ////////////////////////////////////////////////////////////////
- void
- TabCtrlClass::Update_Selector (void)
- {
- //
- // Exit early if there's nothing to do
- //
- float end_pos = Pos_From_Tab (CurrTabIndex);
- if (SelectorPos == end_pos) {
- return ;
- }
- //
- // Calculate the rate the selector moves
- //
- float rate = PIXELS_PER_SEC * ScaleY;
- //
- // Calculate how far we need to move
- //
- float time = DialogMgrClass::Get_Frame_Time () / 1000.0F;
- float dist = rate * time;
- //
- // Move the selector
- //
- if (SelectorPos < end_pos) {
- SelectorPos += dist;
- SelectorPos = min (end_pos, SelectorPos);
- Set_Dirty ();
- } else if (SelectorPos > end_pos) {
- SelectorPos -= dist;
- SelectorPos = max (end_pos, SelectorPos);
- Set_Dirty ();
- }
- //
- // Bound the selector position
- //
- SelectorPos = min (Pos_From_Tab (TabList.Count () - 1), SelectorPos);
- SelectorPos = max (Pos_From_Tab (0), SelectorPos);
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Add_Tab
- //
- ////////////////////////////////////////////////////////////////
- void
- TabCtrlClass::Add_Tab (ChildDialogClass *dialog)
- {
- if (dialog == NULL) {
- return ;
- }
- //
- // Start the dialog
- //
- dialog->Show (TabList.Count () == 0);
- dialog->Start_Dialog ();
- Parent->Add_Child_Dialog (dialog);
- //
- // Size the child so it fits perfectly in the
- // page area.
- //
- RectClass rect;
- rect.Left = (int)(ClientRect.Left + PAGE_AREA_OFFSET * ScaleX);
- rect.Top = (int)ClientRect.Top;
- rect.Right = (int)ClientRect.Right;
- rect.Bottom = (int)ClientRect.Bottom;
- dialog->Set_Rect (rect);
- //
- // Add this dialog to our list
- //
- dialog->Add_Ref ();
- TabList.Add (dialog);
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Remove_Tab
- //
- ////////////////////////////////////////////////////////////////
- void
- TabCtrlClass::Remove_Tab (int index)
- {
- if (index < 0 || index >= TabList.Count ()) {
- return ;
- }
- //
- // Remove this dialog from our list
- //
- Parent->Remove_Child_Dialog (TabList[index]);
- TabList[index]->End_Dialog ();
- REF_PTR_RELEASE (TabList[index]);
- TabList.Delete (index);
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Free_Tabs
- //
- ////////////////////////////////////////////////////////////////
- void
- TabCtrlClass::Free_Tabs (void)
- {
- //
- // Release our hold on each tab
- //
- for (int index = 0; index < TabList.Count (); index ++) {
- REF_PTR_RELEASE (TabList[index]);
- }
- TabList.Delete_All ();
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // On_Mouse_Wheel
- //
- ////////////////////////////////////////////////////////////////
- void
- TabCtrlClass::On_Mouse_Wheel (int direction)
- {
- if (direction < 0) {
- Set_Curr_Tab (CurrTabIndex - 1);
- } else {
- Set_Curr_Tab (CurrTabIndex + 1);
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Apply_Changes_On_Tabs
- //
- ////////////////////////////////////////////////////////////////
- bool
- TabCtrlClass::Apply_Changes_On_Tabs (void)
- {
- bool retval = true;
- //
- // Get each tab to apply their changes
- //
- for (int index = 0; retval && index < TabList.Count (); index ++) {
- retval &= TabList[index]->On_Apply ();
- }
- return retval;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Discard_Changes_On_Tabs
- //
- ////////////////////////////////////////////////////////////////
- bool
- TabCtrlClass::Discard_Changes_On_Tabs (void)
- {
- bool retval = true;
- //
- // Get each tab to discard their changes
- //
- for (int index = 0; retval && index < TabList.Count (); index ++) {
- retval &= TabList[index]->On_Discard ();
- }
- return retval;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Reload_Tabs
- //
- ////////////////////////////////////////////////////////////////
- void
- TabCtrlClass::Reload_Tabs (void)
- {
- //
- // Get each tab to discard their changes
- //
- for (int index = 0; index < TabList.Count (); index ++) {
- TabList[index]->On_Reload ();
- }
- return ;
- }
|