/* BrowserCanvas::showItem * Scrolls the view to show [item] if it is currently off-screen. If * [top] is true, the item will be shown on the top row, otherwise, * the item will be shown on the bottom row *******************************************************************/ void BrowserCanvas::showItem(int item, bool top) { // Check item index if (item < 0 || item >= (int)items_filter.size()) return; // Determine y-position of item int num_cols = GetSize().x / fullItemSizeX(); int y_top = (item / num_cols) * fullItemSizeY(); int y_bottom = y_top + fullItemSizeY(); // Check if item is above current view if (y_top < yoff || y_bottom > yoff + GetSize().y) { if (top) { // Scroll view to show the item on the top row yoff = y_top; if (scrollbar) scrollbar->SetThumbPosition(yoff); } else { // Scroll view to show the item on the bottom row yoff = y_bottom - GetSize().y; if (scrollbar) scrollbar->SetThumbPosition(yoff); } } }
/* BrowserCanvas::showItem * Scrolls the view to show [item] if it is currently off-screen. If * [where] is positive, the item will be shown on the top row; if * negative, the item will be shown on the bottom row; if zero, the * item will be roughly centered. *******************************************************************/ void BrowserCanvas::showItem(int item, int where) { // Check item index if (item < 0 || item >= (int)items_filter.size()) return; // Determine y-position of item int num_cols = GetSize().x / fullItemSizeX(); int y_top = (item / num_cols) * fullItemSizeY(); int y_bottom = y_top + fullItemSizeY(); int _yoff = yoff; // Check if item is outside current view (but always center an item if // asked) if (y_top < yoff || y_bottom > yoff + GetSize().y || where == 0) { if (where > 0) // Scroll view to show the item on the top row yoff = y_top; else if (where < 0) // Scroll view to show the item on the bottom row yoff = y_bottom - GetSize().y; else { // Scroll view to put the item's middle in the middle of the canvas yoff = y_top + (fullItemSizeY() - GetSize().y) / 2; if (yoff < 0) yoff = 0; } if (scrollbar) scrollbar->SetThumbPosition(yoff); } }
/* BrowserCanvas::updateLayout * Updates variables concerning the object layout *******************************************************************/ void BrowserCanvas::updateLayout() { // Determine number of columns num_cols = GetSize().x / fullItemSizeX(); // Update the scrollbar updateScrollBar(); Refresh(); }
/* BrowserCanvas::onMouseEvent * Called when a key is pressed within the canvas *******************************************************************/ void BrowserCanvas::onKeyDown(wxKeyEvent& e) { bool handled = true; int num_cols = GetSize().x / fullItemSizeX(); int selected = itemIndex(item_selected); // Down arrow if (e.GetKeyCode() == WXK_DOWN) { selected += num_cols; showItem(selected, false); } // Up arrow else if (e.GetKeyCode() == WXK_UP) { selected -= num_cols; showItem(selected); } // Left arrow else if (e.GetKeyCode() == WXK_LEFT) { selected--; showItem(selected); } // Right arrow else if (e.GetKeyCode() == WXK_RIGHT) { selected++; showItem(selected, false); } else { e.Skip(); handled = false; } if (handled) { // Clamp selection if (selected >= (int)items_filter.size()) selectItem((int)items_filter.size() - 1); if (selected < 0) selectItem(0); // Refresh canvas Refresh(); } }
/* BrowserCanvas::onMouseEvent * Called when a key is pressed within the canvas *******************************************************************/ void BrowserCanvas::onKeyDown(wxKeyEvent& e) { int num_cols = GetSize().x / fullItemSizeX(); int offset; // Down arrow if (e.GetKeyCode() == WXK_DOWN) offset = num_cols; // Up arrow else if (e.GetKeyCode() == WXK_UP) offset = -1 * num_cols; // Left arrow else if (e.GetKeyCode() == WXK_LEFT) offset = -1; // Right arrow else if (e.GetKeyCode() == WXK_RIGHT) offset = 1; // Page up else if (e.GetKeyCode() == WXK_PAGEUP) offset = -1 * num_cols * max(GetSize().y / fullItemSizeY(), 1); // Page down else if (e.GetKeyCode() == WXK_PAGEDOWN) offset = num_cols * max(GetSize().y / fullItemSizeY(), 1); else { e.Skip(); return; } // Clamp selection int selected = itemIndex(item_selected) + offset; if (selected < 0) selected = 0; else if (selected >= (int)items_filter.size()) selected = (int)items_filter.size() - 1; selectItem(selected); showItem(selected, -1 * offset); // Refresh canvas Refresh(); }
/* BrowserCanvas::updateLayout * Updates variables concerning the object layout, then updates the * associated scrollbar's properties depending on the number of * items, the canvas size, etc. *******************************************************************/ void BrowserCanvas::updateLayout(int viewed_index) { if (scrollbar && viewed_index < 0) viewed_index = getViewedIndex(); // Determine number of columns num_cols = GetSize().x / fullItemSizeX(); // Update the scrollbar, if present if (scrollbar) { // Try to keep the view scrolled to roughly the same area: find the // item currently in the middle, and keep it there // If the given item is no longer visible, find the first filtered item // after it that is int filtered_viewed_index = -1; for (unsigned a = 0; a < items_filter.size(); a++) if (items_filter[a] >= viewed_index) { filtered_viewed_index = a; break; } if (filtered_viewed_index < 0) filtered_viewed_index = items_filter.size() - 1; // Determine total height of all items int rows = (double)items_filter.size() / (double)num_cols + 0.9999; int total_height = rows * fullItemSizeY(); int viewport_height = GetSize().y; // Setup scrollbar scrollbar->SetScrollbar(scrollbar->GetThumbPosition(), viewport_height, total_height, viewport_height); showItem(filtered_viewed_index, 0); } Refresh(); }
/* BrowserCanvas::draw * Handles drawing of the canvas content *******************************************************************/ void BrowserCanvas::draw() { // Setup the viewport glViewport(0, 0, GetSize().x, GetSize().y); // Setup the screen projection glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, GetSize().x, GetSize().y, 0, -1, 1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); // Setup colours rgba_t col_bg, col_text; bool text_shadow = true; if (browser_bg_type == 1) { // Get system panel background colour wxColour bgcolwx = Drawing::getPanelBGColour(); col_bg.set(bgcolwx.Red(), bgcolwx.Green(), bgcolwx.Blue()); // Get system text colour wxColour textcol = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); col_text.set(textcol.Red(), textcol.Green(), textcol.Blue()); // Check text colour brightness, if it's dark don't draw text shadow rgba_t col_temp = col_text; wxColor::MakeGrey(&col_temp.r, &col_temp.g, &col_temp.b); if (col_temp.r < 60) text_shadow = false; } else { // Otherwise use black background col_bg.set(0, 0, 0); // And white text col_text.set(255, 255, 255); } // Clear glClearColor(col_bg.fr(), col_bg.fg(), col_bg.fb(), 1.0f); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); // Translate to inside of pixel (otherwise inaccuracies can occur on certain gl implementations) if (OpenGL::accuracyTweak()) glTranslatef(0.375f, 0.375f, 0); // Draw background if required if (browser_bg_type == 0) drawCheckeredBackground(); // Init for texture drawing glEnable(GL_TEXTURE_2D); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glLineWidth(2.0f); // Draw items int x = item_border; int y = item_border; int col_width = GetSize().x / num_cols; int col = 0; top_index = -1; for (unsigned a = 0; a < items_filter.size(); a++) { // If we're not yet into the viewable area, skip if (y < yoff - fullItemSizeY()) { col++; if (col >= num_cols) { col = 0; y += fullItemSizeY(); // Canvas is filled, stop drawing if (y > yoff + GetSize().y) break; } continue; } // If we're drawing the first non-hidden item, save it if (top_index < 0) { top_index = a; top_y = y - yoff; } // Determine current x position int xgap = (col_width - fullItemSizeX()) * 0.5; x = item_border + xgap + (col * col_width); // Draw selection box if selected if (item_selected == items[items_filter[a]]) { // Setup glDisable(GL_TEXTURE_2D); glColor4f(0.3f, 0.5f, 1.0f, 0.3f); glPushMatrix(); glTranslated(x, y - yoff, 0); glTranslated(-item_border, -item_border, 0); // Selection background glBegin(GL_QUADS); glVertex2i(2, 2); glVertex2i(2, fullItemSizeY()-3); glVertex2i(fullItemSizeX()-3, fullItemSizeY()-3); glVertex2i(fullItemSizeX()-3, 2); glEnd(); // Selection border glColor4f(0.6f, 0.8f, 1.0f, 1.0f); glBegin(GL_LINE_LOOP); glVertex2i(2, 2); glVertex2i(2, fullItemSizeY()-3); glVertex2i(fullItemSizeX()-3, fullItemSizeY()-3); glVertex2i(fullItemSizeX()-3, 2); glEnd(); // Finish glPopMatrix(); glEnable(GL_TEXTURE_2D); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); } // Draw item if (item_size <= 0) items[items_filter[a]]->draw(browser_item_size, x, y - yoff, font, show_names, item_type, col_text, text_shadow); else items[items_filter[a]]->draw(item_size, x, y - yoff, font, show_names, item_type, col_text, text_shadow); // Move over for next item col++; if (col >= num_cols) { col = 0; y += fullItemSizeY(); // Canvas is filled, stop drawing if (y > yoff + GetSize().y) break; } } // Swap Buffers SwapBuffers(); }