From a4c804b49ec872b71bd5a0167c3ad45704a3cc30 Mon Sep 17 00:00:00 2001 From: adiblol Date: Thu, 8 Mar 2012 19:32:05 +0100 Subject: Initial commit, Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch --- src/list.cpp | 858 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 858 insertions(+) create mode 100644 src/list.cpp (limited to 'src/list.cpp') diff --git a/src/list.cpp b/src/list.cpp new file mode 100644 index 0000000..79a3dd6 --- /dev/null +++ b/src/list.cpp @@ -0,0 +1,858 @@ +// list.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "D3DEngine.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "button.h" +#include "scroll.h" +#include "text.h" +#include "list.h" + + + +#define MARGING 4.0f + + + +// Constructeur de l'objet. + +CList::CList(CInstanceManager* iMan) : CControl(iMan) +{ + int i; + + CControl::CControl(iMan); + + for ( i=0 ; iCreate(pos, dim, 0, EVENT_NULL); + m_eventScroll = m_scroll->RetEventMsg(); + + return MoveAdjust(); +} + +// Ajuste après un changement de dimensions. + +BOOL CList::MoveAdjust() +{ + FPOINT ipos, idim, ppos, ddim; + float marging, h; + int i; + + for ( i=0 ; iRetText()->RetHeight(m_fontSize, m_fontType)*m_expand; + + m_displayLine = (int)(idim.y/h); + if ( m_displayLine == 0 ) return FALSE; + if ( m_displayLine > LISTMAXDISPLAY ) m_displayLine = LISTMAXDISPLAY; + idim.y = h*m_displayLine; + m_dim.y = idim.y+marging*2.0f/480.f; + + ppos.x = ipos.x; + ppos.y = ipos.y+idim.y-h; + ddim.x = idim.x-SCROLL_WIDTH; + ddim.y = h; + for ( i=0 ; iCreate(ppos, ddim, -1, EVENT_NULL); + m_button[i]->SetJustif(1); + m_button[i]->SetState(STATE_SIMPLY); + m_button[i]->SetFontType(m_fontType); + m_button[i]->SetFontSize(m_fontSize); + ppos.y -= h; + + m_eventButton[i] = m_button[i]->RetEventMsg(); + } + + if ( m_scroll != 0 ) + { + ppos.x = ipos.x+idim.x-SCROLL_WIDTH; + ppos.y = ipos.y; + ddim.x = SCROLL_WIDTH; + ddim.y = idim.y; + m_scroll->SetPos(ppos); + m_scroll->SetDim(ddim); + } + + UpdateScroll(); + UpdateButton(); + return TRUE; +} + + +// Retourne le message d'un bouton. + +EventMsg CList::RetEventMsgButton(int i) +{ + if ( i < 0 || i >= m_displayLine ) return EVENT_NULL; + if ( m_button[i] == 0 ) return EVENT_NULL; + return m_button[i]->RetEventMsg(); +} + +// Retourne le message de l'ascenseur. + +EventMsg CList::RetEventMsgScroll() +{ + if ( m_scroll == 0 ) return EVENT_NULL; + return m_scroll->RetEventMsg(); +} + + +void CList::SetPos(FPOINT pos) +{ + CControl::SetPos(pos); +} + +void CList::SetDim(FPOINT dim) +{ + m_dim = dim; + MoveAdjust(); + CControl::SetDim(dim); +} + + +BOOL CList::SetState(int state, BOOL bState) +{ + int i; + + if ( state & STATE_ENABLE ) + { + for ( i=0 ; iSetState(state, bState); + } + if ( m_scroll != 0 ) m_scroll->SetState(state, bState); + } + + return CControl::SetState(state, bState); +} + +BOOL CList::SetState(int state) +{ + int i; + + if ( state & STATE_ENABLE ) + { + for ( i=0 ; iSetState(state); + } + if ( m_scroll != 0 ) m_scroll->SetState(state); + } + + return CControl::SetState(state); +} + +BOOL CList::ClearState(int state) +{ + int i; + + if ( state & STATE_ENABLE ) + { + for ( i=0 ; iClearState(state); + } + if ( m_scroll != 0 ) m_scroll->ClearState(state); + } + + return CControl::ClearState(state); +} + + +// Gestion d'un événement. + +BOOL CList::EventProcess(const Event &event) +{ + int i; + + if ( m_bBlink && // clignotte ? + event.event == EVENT_FRAME ) + { + i = m_selectLine-m_firstLine; + + if ( i >= 0 && i < 4 && + m_button[i] != 0 ) + { + m_blinkTime += event.rTime; + if ( Mod(m_blinkTime, 0.7f) < 0.3f ) + { + m_button[i]->ClearState(STATE_ENABLE); + m_button[i]->ClearState(STATE_CHECK); + } + else + { + m_button[i]->SetState(STATE_ENABLE); + m_button[i]->SetState(STATE_CHECK); + } + } + } + + if ( (m_state & STATE_VISIBLE) == 0 ) return TRUE; + if ( (m_state & STATE_ENABLE) == 0 ) return TRUE; + + if ( event.event == EVENT_KEYDOWN && + event.param == VK_WHEELUP && + Detect(event.pos) ) + { + if ( m_firstLine > 0 ) m_firstLine --; + UpdateScroll(); + UpdateButton(); + return TRUE; + } + if ( event.event == EVENT_KEYDOWN && + event.param == VK_WHEELDOWN && + Detect(event.pos) ) + { + if ( m_firstLine < m_totalLine-m_displayLine ) m_firstLine ++; + UpdateScroll(); + UpdateButton(); + return TRUE; + } + + CControl::EventProcess(event); + + if ( event.event == EVENT_MOUSEMOVE && Detect(event.pos) ) + { + m_engine->SetMouseType(D3DMOUSENORM); + for ( i=0 ; i= m_totalLine ) break; + if ( m_button[i] != 0 ) + { + m_button[i]->EventProcess(event); + } + } + } + + if ( m_bSelectCap ) + { + for ( i=0 ; i= m_totalLine ) break; + if ( m_button[i] != 0 ) + { + if ( !m_button[i]->EventProcess(event) ) return FALSE; + + if ( event.event == m_eventButton[i] ) + { + SetSelect(m_firstLine+i); + + Event newEvent = event; + newEvent.event = m_eventMsg; + m_event->AddEvent(newEvent); // ligne sélectionnée changée + } + } + } + } + + if ( m_scroll != 0 ) + { + if ( !m_scroll->EventProcess(event) ) return FALSE; + + if ( event.event == m_eventScroll ) + { + MoveScroll(); + UpdateButton(); + } + } + + return TRUE; +} + + +// Dessine la liste. + +void CList::Draw() +{ + FPOINT uv1, uv2, corner, pos, dim, ppos, ddim; + float dp; + int i, j; + char text[100]; + char *pb, *pe; + + if ( (m_state & STATE_VISIBLE) == 0 ) return; + + if ( m_state & STATE_SHADOW ) + { + DrawShadow(m_pos, m_dim); + } + + dp = 0.5f/256.0f; + + if ( m_icon != -1 ) + { + dim = m_dim; + + if ( m_icon == 0 ) + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATENORMAL); + + uv1.x = 128.0f/256.0f; + uv1.y = 64.0f/256.0f; // u-v texture + uv2.x = 160.0f/256.0f; + uv2.y = 96.0f/256.0f; + } + else + { + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATENORMAL); + + uv1.x = 132.0f/256.0f; + uv1.y = 68.0f/256.0f; // u-v texture + uv2.x = 156.0f/256.0f; + uv2.y = 92.0f/256.0f; + + if ( m_button[0] != 0 ) + { + dim = m_button[0]->RetDim(); + dim.y *= m_displayLine; // fond pile-poil derrière + } + } + + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + + corner.x = 10.0f/640.0f; + corner.y = 10.0f/480.0f; + DrawIcon(m_pos, dim, uv1, uv2, corner, 8.0f/256.0f); + } + + if ( m_totalLine < m_displayLine ) // boutons pas jusqu'en bas ? + { + i = m_totalLine; + if ( m_button[i] != 0 ) + { + pos = m_button[i]->RetPos(); + dim = m_button[i]->RetDim(); + pos.y += dim.y*1.1f; + dim.y *= 0.4f; + pos.y -= dim.y; + + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATETTw); + uv1.x = 120.0f/256.0f; + uv1.y = 64.0f/256.0f; + uv2.x = 128.0f/256.0f; + uv2.y = 48.0f/256.0f; + uv1.x += dp; + uv1.y -= dp; + uv2.x -= dp; + uv2.y += dp; + DrawIcon(pos, dim, uv1, uv2); // ch'tite ombre mignonne + } + } + + for ( i=0 ; i= m_totalLine ) break; + + if ( m_button[i] != 0 ) + { + if ( !m_bBlink && i+m_firstLine < m_totalLine ) + { + m_button[i]->SetState(STATE_ENABLE, m_enable[i+m_firstLine] && (m_state & STATE_ENABLE) ); + } + m_button[i]->Draw(); // dessine une case sans texte + + // dessine le texte dans la case + pos = m_button[i]->RetPos(); + dim = m_button[i]->RetDim(); + if ( m_tabs[0] == 0.0f ) + { + ppos.x = pos.x+dim.y*0.5f; + ppos.y = pos.y+dim.y*0.5f; + ppos.y -= m_engine->RetText()->RetHeight(m_fontSize, m_fontType)/2.0f; + ddim.x = dim.x-dim.y; + DrawCase(m_text[i+m_firstLine], ppos, ddim.x, 1); + } + else + { + ppos.x = pos.x+dim.y*0.5f; + ppos.y = pos.y+dim.y*0.5f; + ppos.y -= m_engine->RetText()->RetHeight(m_fontSize, m_fontType)/2.0f; + pb = m_text[i+m_firstLine]; + for ( j=0 ; j<10 ; j++ ) + { + pe = strchr(pb, '\t'); + if ( pe == 0 ) + { + strcpy(text, pb); + } + else + { + strncpy(text, pb, pe-pb); + text[pe-pb] = 0; + } + DrawCase(text, ppos, m_tabs[j], m_justifs[j]); + + if ( pe == 0 ) break; + ppos.x += m_tabs[j]; + pb = pe+1; + } + } + + if ( (m_state & STATE_EXTEND) && i < m_totalLine ) + { + pos = m_button[i]->RetPos(); + dim = m_button[i]->RetDim(); + pos.x += dim.x-dim.y*0.75f; + dim.x = dim.y*0.75f; + pos.x += 2.0f/640.0f; + pos.y += 2.0f/480.0f; + dim.x -= 4.0f/640.0f; + dim.y -= 4.0f/480.0f; + + if ( m_check[i+m_firstLine] ) + { + m_engine->SetTexture("button1.tga"); + m_engine->SetState(D3DSTATENORMAL); + uv1.x = 64.0f/256.0f; + uv1.y = 0.0f/256.0f; + uv2.x = 96.0f/256.0f; + uv2.y = 32.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + DrawIcon(pos, dim, uv1, uv2); // dessine carré + + m_engine->SetState(D3DSTATETTw); + uv1.x = 0.0f/256.0f; // v + uv1.y = 64.0f/256.0f; + uv2.x = 32.0f/256.0f; + uv2.y = 96.0f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + DrawIcon(pos, dim, uv1, uv2); // dessine v + } + else + { + m_engine->SetTexture("button1.tga"); + m_engine->SetState(D3DSTATETTw); + if ( i+m_firstLine == m_selectLine ) + { + uv1.x =224.0f/256.0f; // < + uv1.y =192.0f/256.0f; + uv2.x =256.0f/256.0f; + uv2.y =224.0f/256.0f; + } + else + { + uv1.x = 96.0f/256.0f; // x + uv1.y = 32.0f/256.0f; + uv2.x =128.0f/256.0f; + uv2.y = 64.0f/256.0f; + } + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + DrawIcon(pos, dim, uv1, uv2); // dessine x + } + } + } + } + + if ( m_scroll != 0 ) + { + m_scroll->Draw(); // dessine l'ascenseur + } +} + +// Affiche un texte dans une case. + +void CList::DrawCase(char *text, FPOINT pos, float width, int justif) +{ + if ( justif == 1 ) + { + m_engine->RetText()->DrawText(text, pos, width, 1, m_fontSize, m_fontStretch, m_fontType, 0); + } + else if ( justif == 0 ) + { + pos.x += width/2.0f; + m_engine->RetText()->DrawText(text, pos, width, 0, m_fontSize, m_fontStretch, m_fontType, 0); + } + else + { + pos.x += width; + m_engine->RetText()->DrawText(text, pos, width, -1, m_fontSize, m_fontStretch, m_fontType, 0); + } +} + + +// Vide complètement la liste. + +void CList::Flush() +{ + m_totalLine = 0; + m_selectLine = -1; + m_firstLine = 0; + UpdateButton(); + UpdateScroll(); +} + + +// Spécifie le nombre total de lignes. + +void CList::SetTotal(int i) +{ + m_totalLine = i; +} + +// Retourne le nombre total de lignes. + +int CList::RetTotal() +{ + return m_totalLine; +} + + +// Sélectionne une ligne. + +void CList::SetSelect(int i) +{ + if ( m_bSelectCap ) + { + m_selectLine = i; + } + else + { + m_firstLine = i; + UpdateScroll(); + } + + UpdateButton(); +} + +// Retourne la ligne sélectionnée. + +int CList::RetSelect() +{ + if ( m_bSelectCap ) + { + return m_selectLine; + } + else + { + return m_firstLine; + } +} + + +// Gestion de la capacité à sélectionner une case. + +void CList::SetSelectCap(BOOL bEnable) +{ + m_bSelectCap = bEnable; +} + +BOOL CList::RetSelectCap() +{ + return m_bSelectCap; +} + + +// Fait cligontter une ligne. + +void CList::SetBlink(BOOL bEnable) +{ + int i; + + m_bBlink = bEnable; + m_blinkTime = 0.0f; + + i = m_selectLine-m_firstLine; + + if ( i >= 0 && i < 4 && + m_button[i] != 0 ) + { + if ( !bEnable ) + { + m_button[i]->SetState(STATE_CHECK); + m_button[i]->ClearState(STATE_ENABLE); + } + } +} + +BOOL CList::RetBlink() +{ + return m_bBlink; +} + + +// Spécifie le texte d'une ligne. + +void CList::SetName(int i, char* name) +{ + if ( i < 0 || i >= LISTMAXTOTAL ) return; + + if ( i >= m_totalLine ) + { + m_totalLine = i+1; // allonge la liste + } + + if ( name[0] == 0 ) + { + strcpy(m_text[i], " "); + } + else + { + strcpy(m_text[i], name); + } + UpdateButton(); + UpdateScroll(); +} + +// Retourne le texte d'une ligne. + +char* CList::RetName(int i) +{ + if ( i < 0 || i >= m_totalLine ) return 0; + + return m_text[i]; +} + + +// Spécifie le bit "check" pour une case. + +void CList::SetCheck(int i, BOOL bMode) +{ + if ( i < 0 || i >= m_totalLine ) return; + + m_check[i] = bMode; +} + +// Retourne le bit "check" pour une case. + +BOOL CList::RetCheck(int i) +{ + if ( i < 0 || i >= m_totalLine ) return FALSE; + + return m_check[i]; +} + + +// Spécifie le bit "enable" pour une case. + +void CList::SetEnable(int i, BOOL bMode) +{ + if ( i < 0 || i >= m_totalLine ) return; + + m_enable[i] = bMode; +} + +// Retourne le bit "enable" pour une case. + +BOOL CList::RetEnable(int i) +{ + if ( i < 0 || i >= m_totalLine ) return FALSE; + + return m_enable[i]; +} + + +// Gestion de la position des tabulateurs. + +void CList::SetTabs(int i, float pos, int justif) +{ + if ( i < 0 || i >= 10 ) return; + m_tabs[i] = pos; + m_justifs[i] = justif; +} + +float CList::RetTabs(int i) +{ + if ( i < 0 || i >= 10 ) return 0.0f; + return m_tabs[i]; +} + + +// Déplace l'ascenseur de la liste pour voir la ligne sélectionnée. + +void CList::ShowSelect(BOOL bFixed) +{ + int sel; + + if ( bFixed && + m_selectLine >= m_firstLine && + m_selectLine < m_firstLine+m_displayLine ) return; // tout bon + + sel = m_selectLine; + + // Descend de 1/2*h. + sel += m_displayLine/2; + if ( sel > m_totalLine-1 ) sel = m_totalLine-1; + + // Remonte de h-1. + sel -= m_displayLine-1; + if ( sel < 0 ) sel = 0; + + m_firstLine = sel; + + UpdateButton(); + UpdateScroll(); +} + + +// Met à jour tous les noms des boutons. + +void CList::UpdateButton() +{ + int state, i, j; + + state = CControl::RetState(); + + j = m_firstLine; + for ( i=0 ; iSetState(STATE_CHECK, (j == m_selectLine)); + + if ( j < m_totalLine ) + { +//? m_button[i]->SetName(m_text[j]); + m_button[i]->SetName(" "); // bouton vide + m_button[i]->SetState(STATE_ENABLE, (state & STATE_ENABLE)); + } + else + { + m_button[i]->SetName(" "); // bouton vide + m_button[i]->ClearState(STATE_ENABLE); + } + j ++; + } +} + +// Met à jour l'ascenseur. + +void CList::UpdateScroll() +{ + float ratio, value, step; + + if ( m_scroll == 0 ) return; + + if ( m_totalLine <= m_displayLine ) + { + ratio = 1.0f; + value = 0.0f; + step = 0.0f; + } + else + { + ratio = (float)m_displayLine/m_totalLine; + if ( ratio > 1.0f ) ratio = 1.0f; + + value = (float)m_firstLine/(m_totalLine-m_displayLine); + if ( value < 0.0f ) value = 0.0f; + if ( value > 1.0f ) value = 1.0f; + + step = (float)1.0f/(m_totalLine-m_displayLine); + if ( step < 0.0f ) step = 0.0f; + } + + m_scroll->SetVisibleRatio(ratio); + m_scroll->SetVisibleValue(value); + m_scroll->SetArrowStep(step); +} + +// Mise à jour lorsque l'ascenseur a été bougé. + +void CList::MoveScroll() +{ + float pos; + int n; + + if ( m_scroll == 0 ) return; + + n = m_totalLine-m_displayLine; + pos = m_scroll->RetVisibleValue(); + pos += m_scroll->RetArrowStep()/2.0f; // c'est magique ! + m_firstLine = (int)(pos*n); + if ( m_firstLine < 0 ) m_firstLine = 0; + if ( m_firstLine > n ) m_firstLine = n; +} + + -- cgit v1.2.3-1-g7c22