/* * Descent 3 * Copyright (C) 2024 Parallax Software * * 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 . --- HISTORICAL COMMENTS FOLLOW --- * $Logfile: /DescentIII/Main/editor/PictListBox.cpp $ * $Revision: 1.1.1.1 $ * $Date: 2003-08-26 03:57:38 $ * $Author: kevinb $ * * Picture list box * * $Log: not supported by cvs2svn $ * * 2 8/12/97 10:48p Matt * Force redraw when SelectItem() is called, though this causes a double * redraw when a picture of an item is clicked on. * * 8 5/28/97 6:16p Samir * When NextListItem returns the same itemnum as before, we are done also. * * 7 4/25/97 11:52a Samir * Took out annoying mprintfs * * 6 4/01/97 3:26p Samir * Now when scrolling up, always refresh if at zero the get any * undisplayed objects. * * 5 3/25/97 6:30p Samir * Fixed problem when no items in listbox * * 4 3/21/97 11:21a Samir * Fixed scroll up problems when adding new poweups. * * 3 2/28/97 3:05p Samir * Moved StartIterateItems to before checking size of list. * * 2 2/21/97 6:24p Samir * Fixed scrolling probs. * * $NoKeywords: $ */ #include "stdafx.h" #include "PictListBox.h" #include "d3edit.h" #include "pserror.h" #include "gr.h" // Construction and destruction editorPictListBox::editorPictListBox() { m_ItemStart = 0; m_ListPos = 0; m_ItemsPerRow = 0; m_ItemsMaxRow = 0; m_ItemsMax = 0; m_PageLen = 0; m_Redraw = 0; m_CheckForSelect = 0; m_CheckX = m_CheckY = 0; m_ItemSelected = -1; m_OldItemCount = -1; m_ParentWnd = NULL; } // Initialization void editorPictListBox::Create(CWnd *parent, int static_id, int scroll_id, int item_dim, int init_item) { m_SurfDim = item_dim; m_ParentWnd = parent; m_StaticID = static_id; m_ScrollbarID = scroll_id; m_ItemSelected = init_item; } // Operations void editorPictListBox::Invalidate() { if (!m_ParentWnd) return; m_Redraw = 1; // force a complete redraw of the listbox Update(); } // Listbox handlers // updates the display of the listbox if needed. void editorPictListBox::SelectItem(int item) { if (!m_ParentWnd) return; m_ItemSelected = item; OnItemSelected(item); // Need to redraw to show new selected item Invalidate(); } void editorPictListBox::Update() { RECT rect; int do_update; if (!m_ParentWnd) return; // create necessary graphics objects Desktop_surf->attach_to_window((unsigned)m_ParentWnd->GetDlgItem(m_StaticID)->m_hWnd); m_ParentWnd->GetDlgItem(m_StaticID)->GetClientRect(&m_ListRect); ::CopyRect(&rect, &m_ListRect); // determine if we need to update the list box. StartIterateListItems(); if (m_OldItemCount == m_ItemsMax && !m_Redraw) { do_update = 0; } else { do_update = 1; m_Redraw = 0; m_OldItemCount = m_ItemsMax; } // draw listbox if (do_update) { int itemnum = m_ItemStart, count = 0, q, r; int left, top; bool done = 0; Desktop_surf->clear(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top); m_ItemSurf.create(m_SurfDim, m_SurfDim, BPP_16); m_ItemSurfSel.create(m_SurfDim + 8, m_SurfDim + 8, BPP_16); // determine number of contents that can fit in the listbox. q = rect.right - rect.left; r = rect.bottom - rect.top; m_ItemsPerRow = q / (m_SurfDim + 8); m_ItemsMaxRow = r / (m_SurfDim + 8); ASSERT(m_ItemsPerRow && m_ItemsMaxRow); // No no no no... left = (q / 2) - ((m_ItemsPerRow * (m_SurfDim + 8)) / 2); top = (r / 2) - ((m_ItemsMaxRow * (m_SurfDim + 8)) / 2); if (m_ItemsMax == 0) done = 1; // if no items, then we just wont draw. // okay draw each item. while (!done) { int x, y; int olditemnum; x = left + rect.left + ((count % m_ItemsPerRow) * (m_SurfDim + 8)); y = top + rect.top + ((count / m_ItemsPerRow) * (m_SurfDim + 8)); if (m_CheckForSelect) { // note that if we've detected a switch in textures, we need to redraw the box // yet again to prevent multiple selected textures. This should be okay, since // m_CheckForTextureList is cleared. if (m_CheckX >= x && m_CheckX <= (x + 48) && m_CheckY >= y && m_CheckY <= (y + 48)) { m_CheckForSelect = 0; SelectItem(itemnum); m_Redraw = 1; Update(); return; } } olditemnum = itemnum; DrawItem(x, y, itemnum); itemnum = NextListItem(itemnum); // repeated itemnum, means there is no more. if (itemnum == olditemnum) done = 1; else count++; if (count == m_ItemsPerRow * m_ItemsMaxRow) done = 1; if (itemnum <= m_ItemStart) done = 1; } m_ItemSurfSel.free(); m_ItemSurf.free(); // must define the vertical scroll bar dimensions CScrollBar *bar = (CScrollBar *)m_ParentWnd->GetDlgItem(m_ScrollbarID); SCROLLINFO si; m_PageLen = m_ItemsMaxRow; //(count/m_ItemsPerRow)+ ((count%m_ItemsPerRow) ? 1 : 0); m_ListPos = bar->GetScrollPos(); si.cbSize = sizeof(si); si.fMask = SIF_ALL; si.nMin = 0; si.nMax = (m_ItemsMax / m_ItemsPerRow) + ((m_ItemsMax % m_ItemsPerRow) ? 1 : 0) - 1; si.nPos = m_ListPos; si.nPage = m_PageLen; bar->SetScrollInfo(&si); bar->ShowScrollBar(TRUE); } // restore graphics state Desktop_surf->attach_to_window((unsigned)NULL); } // Handlers called by external source void editorPictListBox::OnVScroll(UINT nSBCode, int nPos, CScrollBar *pScrollBar) { int id = -1, min, max; int new_pos = 0; if (!m_ParentWnd) return; ASSERT(pScrollBar == (CScrollBar *)m_ParentWnd->GetDlgItem(m_ScrollbarID)); if (pScrollBar) { id = pScrollBar->GetDlgCtrlID(); pScrollBar->GetScrollRange(&min, &max); switch (nSBCode) { case SB_LINEDOWN: new_pos = m_ListPos + 1; break; case SB_LINEUP: new_pos = m_ListPos - 1; break; case SB_THUMBPOSITION: new_pos = nPos; break; case SB_THUMBTRACK: new_pos = nPos; break; case SB_PAGEDOWN: new_pos = m_ListPos + m_PageLen; break; case SB_PAGEUP: new_pos = m_ListPos - m_PageLen; break; default: new_pos = m_ListPos; } if (new_pos < 0) new_pos = 0; if (new_pos > (max - m_PageLen)) new_pos = (max - m_PageLen) + 1; if (new_pos == 0) ListUp((m_ListPos - new_pos) + 1); // list up until start of list. prevents missing items if (new_pos != m_ListPos) { // ok, new_pos will be an index into the listbox, NOT the texture list. // so we will get the number of texture rows we went up or down and change // tex_start accordingly. SCROLLINFO si; // mprintf(0, "scroll new_pos = %d. original_pos = %d\n", new_pos, m_ListPos); if (new_pos < m_ListPos) ListUp(m_ListPos - new_pos); if (new_pos > m_ListPos) ListDown(new_pos - m_ListPos); m_ListPos = new_pos; si.cbSize = sizeof(si); si.fMask = SIF_POS; si.nPos = m_ListPos; pScrollBar->SetScrollInfo(&si); } } } void editorPictListBox::OnLButtonDown(CPoint point) { if (!m_ParentWnd) return; m_CheckForSelect = 1; m_CheckX = point.x; m_CheckY = point.y; Invalidate(); } void editorPictListBox::ListUp(int rows) { int old = m_ItemStart; int done = 0, count = 0; while ((count < (m_ItemsPerRow * rows)) && !done) { int olditem; olditem = m_ItemStart; m_ItemStart = PrevListItem(m_ItemStart); // mprintf(0, "m_ItemStart = %d\n", m_ItemStart); if (m_ItemStart > olditem) { m_ItemStart = olditem; done = 1; // mprintf(0, "m_ItemStart = %d\n", m_ItemStart); } else if (old <= m_ItemStart) { m_ItemStart = old; done = 1; } else count++; } Invalidate(); } void editorPictListBox::ListDown(int rows) { int old = m_ItemStart; int done = 0, count = 0; while ((count < (m_ItemsPerRow * rows)) && !done) { m_ItemStart = NextListItem(m_ItemStart); if (old >= m_ItemStart) { m_ItemStart = old; done = 1; } else count++; } Invalidate(); }