📄 gd06-02.cpp
字号:
// ============================================================================
// GD06-02.cpp
// Doubly Linked List Graphical Demonstration
// ============================================================================
#include "SDLGUI.h"
#include "DLinkedList.h"
#include <stdlib.h>
#include <time.h>
// ============================================================================
// Global Constants
// ============================================================================
const char PROGRAM_NAME[] = "Doubly Linked List Graphical Demonstration";
const int WIDTH = 800;
const int HEIGHT = 600;
const int ITEMS = 32;
const int ARIAL = 0;
const int BIGARIAL = 1;
// ============================================================================
// Demo States
// ============================================================================
enum LinkedListState
{
// nothing happening.
NOSTATE,
// insert after:
INSERTMOVE, // the nodes are moving apart
INSERTNEWNODE, // new node is displayed
INSERTPOINT, // pointer is re-arranged
INSERTDONE,
// insert before:
BINSERTMOVE, // the nodes are moving apart
BINSERTNEWNODE, // new node is displayed
BINSERTPOINT, // pointer is re-arranged
BINSERTDONE,
// remove:
REMOVEMOVEDOWN, // move the node down
REMOVEPOINT, // change the pointers
REMOVEMOVE, // delete the node and move the nodes together.
REMOVEDONE
};
// ============================================================================
// Global Variables
// ============================================================================
SDLGUI* g_gui;
// the state
LinkedListState g_state = NOSTATE;
// holds the last marked time.
Uint32 g_time;
// Circles
SDL_Surface* g_blackcircle;
SDL_Surface* g_redcircle;
DLinkedList<int> g_list;
DListIterator<int> g_itr;
int g_current = 0;
// ============================================================================
// Draw Algorithms
// ============================================================================
void DrawNode( int p_value,
int p_x,
int p_y,
bool p_current )
{
static SDL_Surface* text;
static char number[] = "00";
// draw the contents of the circle.
if( p_value < 0 || p_value > 99 )
{
text = TTF_RenderText_Shaded( g_gui->GetFont(ARIAL), "x", RED, WHITE );
}
else
{
sprintf( number, "%d", p_value );
text = TTF_RenderText_Shaded( g_gui->GetFont(ARIAL), number, BLACK, WHITE );
}
g_gui->Blit( text, (g_blackcircle->w - text->w) / 2 + p_x,
(g_blackcircle->h - text->h) / 2 + p_y );
SDL_FreeSurface( text );
// draw the circle
if( !p_current )
g_gui->Blit( g_blackcircle, p_x, p_y );
else
g_gui->Blit( g_redcircle, p_x, p_y );
}
void DrawList( DLinkedList<int>& p_list, // the list to draw
int p_x, // x and y coords.
int p_y,
int p_current ) // the current index.
{
DListIterator<int> itr = p_list.GetIterator();
int index;
int y;
int lastx = -1,
lasty = -1;
// draw the list.
for( index = 0; index < p_list.Size(); index++, itr.Forth() )
{
if( g_state == INSERTMOVE && index == (p_current + 1) )
{
// skip over the node that was inserted, we don't want to draw it yet.
p_x += ( (SDL_GetTicks() - g_time) * g_blackcircle->w * 2 ) / 1000;
}
else if( g_state == INSERTNEWNODE && index == (p_current + 1) )
{
DrawNode( itr.Item(), p_x, p_y + 64, false );
// draw an arrow to the next node if it exists.
if( index < (p_list.Size() - 1) )
{
g_gui->ArrowLine( p_x + (g_blackcircle->w / 2),
p_y + (g_blackcircle->h / 2) + 64,
p_x + (g_blackcircle->w * 2) + (g_blackcircle->w / 2),
p_y + (g_blackcircle->h / 2),
(g_blackcircle->w / 2),
(g_blackcircle->w / 2),
false, true, BLACK );
}
// draw an arrow to the previous node if it exists.
if( index > 0 )
{
g_gui->ArrowLine( p_x + (g_blackcircle->w / 2),
p_y + (g_blackcircle->h / 2) + 64,
p_x - (g_blackcircle->w * 2) + (g_blackcircle->w / 2),
p_y + (g_blackcircle->h / 2),
(g_blackcircle->w / 2),
(g_blackcircle->w / 2),
false, true, BLACK );
}
p_x += (g_blackcircle->w * 2);
}
else if( g_state == INSERTPOINT && index == (p_current + 1) )
{
// calculate the current y position.
y = ( (SDL_GetTicks() - g_time) * 64 ) / 1000;
y = 64 - y;
DrawNode( itr.Item(), p_x, p_y + y, false );
// draw an arrow to the last node.
g_gui->ArrowLine( p_x + (g_blackcircle->w / 2),
p_y + (g_blackcircle->h / 2) + y,
lastx, lasty,
(g_blackcircle->w / 2),
(g_blackcircle->w / 2),
true, true, BLACK );
lastx = p_x + (g_blackcircle->w / 2);
lasty = p_y + (g_blackcircle->h / 2) + y;
p_x += (g_blackcircle->w * 2);
}
else if( g_state == BINSERTMOVE && index == (p_current - 1) )
{
// skip over the node that was inserted, we don't want to draw it yet.
p_x += ( (SDL_GetTicks() - g_time) * g_blackcircle->w * 2 ) / 1000;
}
else if( g_state == BINSERTNEWNODE && index == (p_current - 1) )
{
DrawNode( itr.Item(), p_x, p_y + 64, false );
// draw an arrow to the next node if it exists.
if( index < (p_list.Size() - 1) )
{
g_gui->ArrowLine( p_x + (g_blackcircle->w / 2),
p_y + (g_blackcircle->h / 2) + 64,
p_x + (g_blackcircle->w * 2) + (g_blackcircle->w / 2),
p_y + (g_blackcircle->h / 2),
(g_blackcircle->w / 2),
(g_blackcircle->w / 2),
false, true, BLACK );
}
// draw an arrow to the previous node if it exists.
if( index > 0 )
{
g_gui->ArrowLine( p_x + (g_blackcircle->w / 2),
p_y + (g_blackcircle->h / 2) + 64,
p_x - (g_blackcircle->w * 2) + (g_blackcircle->w / 2),
p_y + (g_blackcircle->h / 2),
(g_blackcircle->w / 2),
(g_blackcircle->w / 2),
false, true, BLACK );
}
p_x += (g_blackcircle->w * 2);
}
else if( g_state == BINSERTPOINT && index == (p_current - 1) )
{
// calculate the current y position.
y = ( (SDL_GetTicks() - g_time) * 64 ) / 1000;
y = 64 - y;
DrawNode( itr.Item(), p_x, p_y + y, false );
// draw an arrow to the last node if it exists.
if( index != 0 )
{
g_gui->ArrowLine( p_x + (g_blackcircle->w / 2),
p_y + (g_blackcircle->h / 2) + y,
lastx, lasty,
(g_blackcircle->w / 2),
(g_blackcircle->w / 2),
true, true, BLACK );
}
lastx = p_x + (g_blackcircle->w / 2);
lasty = p_y + (g_blackcircle->h / 2) + y;
p_x += (g_blackcircle->w * 2);
}
else if( g_state == REMOVEMOVEDOWN && index == p_current )
{
// calculate the current y position.
y = ( (SDL_GetTicks() - g_time) * 64 ) / 1000;
DrawNode( itr.Item(), p_x, p_y + y, false );
// draw an arrow to the last node if it exists.
if( index != 0 )
{
g_gui->ArrowLine( p_x + (g_blackcircle->w / 2),
p_y + (g_blackcircle->h / 2) + y,
lastx, lasty,
(g_blackcircle->w / 2),
(g_blackcircle->w / 2),
true, true, BLACK );
}
lastx = p_x + (g_blackcircle->w / 2);
lasty = p_y + (g_blackcircle->h / 2) + y;
p_x += (g_blackcircle->w * 2);
}
else if( g_state == REMOVEPOINT && index == p_current )
{
DrawNode( itr.Item(), p_x, p_y + 64, false );
// draw an arrow to the next node if it exists.
if( index < (p_list.Size() - 1) )
{
g_gui->ArrowLine( p_x + (g_blackcircle->w / 2),
p_y + (g_blackcircle->h / 2) + 64,
p_x + (g_blackcircle->w * 2) + (g_blackcircle->w / 2),
p_y + (g_blackcircle->h / 2),
(g_blackcircle->w / 2),
(g_blackcircle->w / 2),
false, true, BLACK );
}
// draw an arrow to the previous node if it exists.
if( index > 0 )
{
g_gui->ArrowLine( p_x + (g_blackcircle->w / 2),
p_y + (g_blackcircle->h / 2) + 64,
p_x - (g_blackcircle->w * 2) + (g_blackcircle->w / 2),
p_y + (g_blackcircle->h / 2),
(g_blackcircle->w / 2),
(g_blackcircle->w / 2),
false, true, BLACK );
}
p_x += (g_blackcircle->w * 2);
}
else if( g_state == REMOVEMOVE && index == p_current )
{
// skip over the node that was inserted, we don't want to draw it yet.
p_x += ( (g_blackcircle->w * 2) -
( (SDL_GetTicks() - g_time) * g_blackcircle->w * 2 ) / 1000 );
}
else
{
// draw the current node
DrawNode( itr.Item(), p_x, p_y, g_itr == itr );
if( lastx != -1 && lasty != -1 )
{
g_gui->ArrowLine( p_x + (g_blackcircle->w / 2),
p_y + (g_blackcircle->h / 2),
lastx, lasty,
(g_blackcircle->w / 2),
(g_blackcircle->w / 2),
true, true, BLACK );
}
// keep track of the center coords of this node
// for the next iteration, so it can draw an arrow-line.
lastx = p_x + (g_blackcircle->w / 2);
lasty = p_y + (g_blackcircle->h / 2);
p_x += (g_blackcircle->w * 2);
}
}
}
// ============================================================================
// Callbacks
// ============================================================================
void Start()
{
g_itr.Start();
g_current = 0;
}
void End()
{
g_itr.End();
g_current = g_list.Size() - 1;
}
void Forth()
{
g_itr.Forth();
g_current++;
}
void Back()
{
g_itr.Back();
g_current--;
}
void InsertBefore()
{
if( g_list.Size() < 8 && g_itr.Valid() )
{
// insert new data.
g_list.InsertBefore( g_itr, rand() % 100 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -