table_cell_t* table_get_cell(table_t* table, WORD col, WORD row) { TABLE_TRACE("table_get_cell(%p, %hd, %hd)", table, col, row); if(MC_ERR(col >= table->col_count && col != MC_TABLE_HEADER)) { MC_TRACE("table_get_cell: Column ID %hd does not exist", col); SetLastError(ERROR_INVALID_PARAMETER); return NULL; } if(MC_ERR(row >= table->row_count && row != MC_TABLE_HEADER)) { MC_TRACE("table_get_cell: Row ID %hd does not exist", row); SetLastError(ERROR_INVALID_PARAMETER); return NULL; } if(MC_ERR(col == MC_TABLE_HEADER && row == MC_TABLE_HEADER)) { MC_TRACE("table_get_cell: The \"dead\" cell requested."); SetLastError(ERROR_INVALID_PARAMETER); return NULL; } if(col == MC_TABLE_HEADER) return &table->rows[row]; else if(row == MC_TABLE_HEADER) return &table->cols[col]; else return table_cell(table, col, row); }
void litehtml::table_grid::add_cell( element* el ) { table_cell cell; cell.el = el; cell.colspan = t_atoi(el->get_attr(_t("colspan"), _t("1"))); cell.rowspan = t_atoi(el->get_attr(_t("rowspan"), _t("1"))); cell.borders = el->get_borders(); while( is_rowspanned( (int) m_cells.size() - 1, (int) m_cells.back().size() ) ) { m_cells.back().push_back(table_cell()); } m_cells.back().push_back(cell); for(int i = 1; i < cell.colspan; i++) { table_cell empty_cell; m_cells.back().push_back(empty_cell); } }
static void grid_paint(void* control, HDC dc, RECT* dirty, BOOL erase) { grid_t* grid = (grid_t*) control; RECT client; RECT rect; int header_w, header_h; int old_dc_state; int col0, row0; int x0, y0; int col, row; int col_count = grid->col_count; int row_count = grid->row_count; table_t* table = grid->table; table_cell_t* cell; GRID_TRACE("grid_paint(%p, %d, %d, %d, %d)", grid, dirty->left, dirty->top, dirty->right, dirty->bottom); if(table == NULL && !(grid->style & MC_GS_OWNERDATA)) return; old_dc_state = SaveDC(dc); GetClientRect(grid->win, &client); header_w = grid_header_width(grid); header_h = grid_header_height(grid); if(grid->font != NULL) SelectObject(dc, grid->font); SetBkMode(dc, TRANSPARENT); SetTextColor(dc, RGB(0,0,0)); SelectObject(dc, GetStockObject(BLACK_PEN)); /* Find 1st visible column */ rect.left = header_w - grid->scroll_x; for(col = 0; col < col_count; col++) { rect.right = rect.left + grid_col_width(grid, col); if(rect.right > header_w) { col0 = col; x0 = rect.left; break; } rect.left = rect.right; } /* Find 1st visible row */ rect.top = header_h - grid->scroll_y; for(row = 0; row < row_count; row++) { rect.bottom = rect.top + grid_row_height(grid, row); if(rect.bottom > header_h) { row0 = row; y0 = rect.top; break; } rect.top = rect.bottom; } /* If needed, send MC_GN_ODCACHEHINT */ if(grid->style & MC_GS_OWNERDATA) { WORD col1, row1; rect.right = x0; for(col1 = col0; col1+1 < grid->col_count; col1++) { rect.right += grid_col_width(grid, col1); if(rect.right >= client.right) break; } rect.bottom = y0; for(row1 = row0; row1+1 < grid->row_count; row1++) { rect.bottom += grid_row_height(grid, row1); if(rect.bottom >= client.bottom) break; } if(col0 != grid->cache_hint[0] || row0 != grid->cache_hint[1] || col1 != grid->cache_hint[2] || row1 != grid->cache_hint[3]) { MC_NMGCACHEHINT hint; hint.hdr.hwndFrom = grid->win; hint.hdr.idFrom = GetWindowLong(grid->win, GWL_ID); hint.hdr.code = MC_GN_ODCACHEHINT; hint.wColumnFrom = col0; hint.wRowFrom = row0; hint.wColumnTo = col1; hint.wRowTo = row1; GRID_TRACE("grid_paint: Sending MC_GN_ODCACHEHINT (%hu, %hu, %hu, %hu)", col0, row0, col1, row1); MC_SEND(grid->notify_win, WM_NOTIFY, hint.hdr.idFrom, &hint); grid->cache_hint[0] = col0; grid->cache_hint[1] = row0; grid->cache_hint[2] = col1; grid->cache_hint[3] = row1; } } /* Paint the "dead" top left header cell */ if(header_w > 0 && header_h > 0 && dirty->left < header_w && dirty->top < header_h) { mc_rect_set(&rect, 0, 0, grid->header_width, grid->header_height); mc_clip_set(dc, 0, 0, MC_MIN(header_w, client.right), MC_MIN(header_h, client.bottom)); grid_paint_header_cell(grid, MC_TABLE_HEADER, MC_TABLE_HEADER, NULL, dc, &rect, -1, 0); } /* Paint column headers */ if(header_h > 0 && dirty->top < header_h) { rect.left = x0; rect.top = 0; rect.bottom = header_h; for(col = col0; col < col_count; col++) { rect.right = rect.left + grid_col_width(grid, col); mc_clip_set(dc, MC_MAX(header_w, rect.left), rect.top, MC_MIN(rect.right, client.right), MC_MIN(rect.bottom, client.bottom)); grid_paint_header_cell(grid, col, MC_TABLE_HEADER, (table ? &table->cols[col] : NULL), dc, &rect, col, (grid->style & MC_GS_COLUMNHEADERMASK)); rect.left = rect.right; if(rect.right >= client.right) break; } } /* Paint row headers */ if(header_w > 0 && dirty->left <= header_w) { rect.left = 0; rect.top = y0; rect.right = header_w; for(row = row0; row < row_count; row++) { rect.bottom = rect.top + grid_row_height(grid, row); mc_clip_set(dc, rect.left, MC_MAX(header_h, rect.top), MC_MIN(rect.right, client.right), MC_MIN(rect.bottom, client.bottom)); grid_paint_header_cell(grid, MC_TABLE_HEADER, row, (table ? &table->rows[row] : NULL), dc, &rect, row, (grid->style & MC_GS_ROWHEADERMASK)); rect.top = rect.bottom; if(rect.bottom >= client.bottom) break; } } /* Paint grid lines */ if(!(grid->style & MC_GS_NOGRIDLINES)) { HPEN pen, old_pen; int x, y; mc_clip_set(dc, header_w, header_h, client.right, client.bottom); pen = CreatePen(PS_SOLID, 0, mcGetThemeSysColor(grid->theme_listview, COLOR_3DFACE)); old_pen = SelectObject(dc, pen); x = x0; y = header_h + grid->scroll_y_max - grid->scroll_y; for(col = col0; col < col_count; col++) { x += grid_col_width(grid, col); MoveToEx(dc, x-1, header_h, NULL); LineTo(dc, x-1, y); if(x >= client.right) break; } x = header_w + grid->scroll_x_max - grid->scroll_x; y = y0; for(row = 0; row < row_count; row++) { y += grid_row_height(grid, row); MoveToEx(dc, header_w, y-1, NULL); LineTo(dc, x, y-1); if(y >= client.bottom) break; } SelectObject(dc, old_pen); DeleteObject(pen); } /* Paint grid cells */ rect.top = y0; for(row = row0; row < row_count; row++) { rect.bottom = rect.top + grid_row_height(grid, row); rect.left = x0; for(col = col0; col < col_count; col++) { if(table != NULL) cell = table_cell(table, col, row); else cell = NULL; rect.right = rect.left + grid_col_width(grid, col); grid_paint_cell(grid, col, row, cell, dc, &rect); if(rect.right >= client.right) break; rect.left = rect.right; } if(rect.bottom >= client.bottom) break; rect.top = rect.bottom; } RestoreDC(dc, old_dc_state); }