// MyCell - version 1.1
// Written by Yanxueming <yanxm2003@hotmail.com>
// Copyright (C) 2006-2007
// All rights reserved.
//
// The code and information is provided "as-is" without
// warranty of any kind, either expressed or implied.
#include "stdafx.h"
#include "../include/Worksheet.h"
#include "../include/Workbook.h"
namespace mycell{
//-------------------------------------------------------------------------------//
//��������y���y��������[topRow,bottomRow)��
//�ĵڼ���,���������������INVALIDATE_ROW
//heightΪ��ʼ��topRow����ڿͻ������˵ĸ߶�
//��̽���ʵ����y>=0�����
//-------------------------------------------------------------------------------//
int HitTestRow(const RowHeader& rh,const int y,int topRow,int bottomRow,int& height)
{
_ASSERT(topRow<=bottomRow);
_ASSERT(y>=height);
for(int i=topRow;i!=bottomRow;++i){
height+=rh.get_RowHeight(i);
if(y<height)
return i;
}
return INVALIDATE_ROW;
}
//-------------------------------------------------------------------------------//
//��������x���x��������[leftCol,rightCol)��
//�ĵڼ���,���������������INVALIDATE_COL
//widthΪ��ʼ��leftCol����ڿͻ�����˵Ŀ��
//��̽���ʵ����x>=0�����
//-------------------------------------------------------------------------------//
int HitTestCol(const ColHeader& ch,const int x,int leftCol,int rightCol,int& width)
{
_ASSERT(leftCol<=rightCol);
_ASSERT(x>=width);
for(int i=leftCol;i!=rightCol;++i){
width+=ch.get_ColWidth(i);
if(x<width)
return i;
}
return INVALIDATE_COL;
}
//x,y should be client coords
CCell Worksheet::GetCellByPos(int const x,int const y)const
{
//const short x=(const short)_x;
//const short y=(const short)_y;
CCell cell(INVALIDATE_ROW,INVALIDATE_COL);
const RowHeader& rh=get_RowHeader();
const ColHeader& ch=get_ColHeader();
const CellAxisInfo& cai=get_CellAxisInfo();
int height=get_ShowColHeader()?ch.get_height():0;
int width=get_ShowRowHeader()?rh.get_width():0;
if(y<0){
height=cai.HFreezeAxis;
for(cell.row=rh.get_TopVisScrollRow()-1;cell.row>=0;){
height-=rh.get_RowHeight(cell.row);
if(height<y)
break;
--cell.row;
}
if(HEADER_ROW==cell.row)
cell.row=INVALIDATE_ROW;
}else if(y<height){
cell.row=HEADER_ROW;
}else{
if(rh.IsFreezeRowVisible()){//�Ƿ����ڶ�����
cell.row=HitTestRow(rh,y,rh.get_FreezeTopRow(),rh.get_FreezeBottomRow()+1,height);
}
if(INVALIDATE_ROW==cell.row){
cell.row=HitTestRow(rh,y,rh.get_TopVisScrollRow(),rh.get_rows()/*get_BottomVisScrollRow()+1*/,height);
}
if(INVALIDATE_ROW==cell.row)
cell.row=rh.get_rows();
}
if(x<0){
//cell.col=-2;
width=cai.VFreezeAxis;
for(cell.col=rh.get_TopVisScrollRow()-1;cell.col>=0;){
width-=rh.get_RowHeight(cell.col);
if(width<x)
break;
--cell.col;
}
if(HEADER_COL==cell.col)
cell.col=INVALIDATE_COL;
}else if(x<width){
cell.col=HEADER_COL;
}else{
if(ch.IsFreezeColVisible()){
cell.col=HitTestCol(ch,x,ch.get_FreezeLeftCol(),ch.get_FreezeRightCol()+1,width);
}
if(INVALIDATE_COL==cell.col){
cell.col=HitTestCol(ch,x,ch.get_LeftVisScrollCol(),ch.get_cols(),width);
}
if(INVALIDATE_COL==cell.col)
cell.col=ch.get_cols();
}
return cell;
}
//CCell Worksheet::GetCellByScreenPos(int x,int y)const
//{
//}
//-------------------------------------------------------------------------//
//���ؿͻ������꣬�÷���Ӧ��Ϊ�Ͳ�ε���
//�������ǵ�Ԫ���Ƿ��ںϲ���Ԫ���ж�
//���������ϲ���Ԫ��Χ�����⡣�����Ҫ
//�õ������ϲ���Ԫ��ķ�Χ�������GetCellRectEx
//������ֱ�ӵ���Worksheet��get_RangeRect����
//˵����������raw_��ͷ�ķ����������Ǻϲ���Ԫ��������
//-------------------------------------------------------------------------//
RECT Worksheet::raw_GetCellRect(CCell cell/*int row,int col*/)const
{
//_ASSERT(row>=-1);
//_ASSERT(col>=-1);
RECT rc;
if(cell.row<HEADER_ROW || cell.col<HEADER_COL)
{
SetRect(&rc,0,0,0,0);
return rc;
}
//const RowHeader& rh=get_RowHeader();
//const ColHeader& ch=get_ColHeader();
int const topRow=rh_.get_TopVisScrollRow();
int const leftCol=ch_.get_LeftVisScrollCol();
if(HEADER_ROW==cell.row){
rc.top=0;
rc.bottom=ch_.get_height();
}else{
rc.top=get_ShowColHeader()?ch_.get_height():0;
int const nFreezeTopRow=rh_.get_FreezeTopRow();
int const nFreezeBottomRow=rh_.get_FreezeBottomRow();
if(cell.row>=nFreezeTopRow && cell.row<=nFreezeBottomRow){
rc.top+=rh_.get_DiffHeights(nFreezeTopRow,cell.row);
}else{
if(rh_.IsFreezeRowVisible())
rc.top+=rh_.get_DiffHeights(nFreezeTopRow,nFreezeBottomRow+1);
if(cell.row>topRow){
rc.top+=rh_.get_DiffHeights(max(0,topRow),cell.row);
}else if(cell.row<topRow){
rc.top-=rh_.get_DiffHeights(cell.row,topRow);
}
}
rc.bottom=rc.top+rh_.get_RowHeight(cell.row);
}
if(HEADER_COL==cell.col){
rc.left=0;
rc.right=rh_.get_width();
}else{
rc.left=get_ShowRowHeader()?rh_.get_width():0;
int const nFreezeLeftCol=ch_.get_FreezeLeftCol();
int const nFreezeRightCol=ch_.get_FreezeRightCol();
if(cell.col>=nFreezeLeftCol && cell.col<=nFreezeRightCol){
rc.left+=ch_.get_DiffWidths(nFreezeLeftCol,cell.col);
}else{
if(ch_.IsFreezeColVisible())
rc.left+=ch_.get_DiffWidths(nFreezeLeftCol,nFreezeRightCol+1);
if(cell.col>leftCol){
rc.left+=ch_.get_DiffWidths(max(0,leftCol),cell.col);
}else if(cell.col<leftCol){
rc.left-=ch_.get_DiffWidths(cell.col,leftCol);
}
}
rc.right=rc.left+ch_.get_ColWidth(cell.col);
/*
rc.left=get_ShowRowHeader()?rh_.get_width():0;
if(ch_.IsFreezeColVisible())
rc.left+=ch_.get_DiffWidths(ch_.get_FreezeLeftCol(),ch_.get_FreezeRightCol()+1);
if(col>leftCol){
rc.left+=ch_.get_DiffWidths(leftCol,col);
}else if(col<leftCol){
rc.left-=ch_.get_DiffWidths(col,leftCol);
}
rc.right=rc.left+ch_.get_ColWidth(col);
*/
}
/*
if(row<0){
rc.top=0;
rc.bottom=ch_.get_height();
}else{
int const topRow=rh_.get_TopVisScrollRow();
if(!(row>=topRow && row<=rh_.get_BottomVisScrollRow())){
SetRect(&rc,-1,-1,-1,-1);
return rc;
}
rc.top=get_ShowColHeader()?ch_.get_height():0;
for(int i=topRow;i!=row;++i){
rc.top+=rh_.get_RowHeight(i);
}
rc.bottom=rc.top+rh_.get_RowHeight(row);
}
if(col<0){
rc.left=0;
rc.right=rh_.get_width();
}else{
int const leftCol=ch_.get_LeftVisScrollCol();
if(!(col>=leftCol && col<=ch_.get_RightVisScrollCol())){
SetRect(&rc,-1,-1,-1,-1);
return rc;
}
rc.left=get_ShowRowHeader()?rh_.get_width():0;
for(int i=leftCol;i!=col;++i){
rc.left+=ch_.get_ColWidth(i);
}
rc.right=rc.left+ch_.get_ColWidth(col);
}
*/
return rc;
}
/*
//Ӧ��ʹ��CELLHITTESTINFO Worksheet::HitTest(int x,int y)const
//
CCell Worksheet::HitTest(int const x, int const y,ECellHitTestConstants& hct)const
{
CCell cell=GetCellByPos(x,y);
const Worksheet* pSheet=static_cast<const Worksheet*>(this);
const RowHeader& rh=pSheet->get_RowHeader();
const ColHeader& ch=pSheet->get_ColHeader();
if(cell.col>=ch.get_cols() || cell.row>=rh.get_rows() || cell.row<-1 || cell.col<-1){
hct=cellHTOuter;
return cell;
}
int const delta=ResizeCaptureRange/2;
RECT rcCell=raw_GetCellRect(cell.row,cell.col);
if(x<rcCell.left-delta||x>rcCell.right+delta||y<rcCell.top-delta||y>rcCell.bottom+delta)
{//Is out of Cell
hct = cellHTOuter;
}else if(x>=rcCell.right-delta-1){//�Ƿ����ұ�
if(y<=rcCell.top+delta)
hct = cellHTRightTop;
else if(y>=rcCell.bottom-delta)
hct = cellHTRightBottom;
else
hct = cellHTRight;
}else if(x<=rcCell.left+delta){//�Ƿ������
if(y<=rcCell.top+delta)//Is LeftTop
hct = cellHTLeftTop;
else if(y>=rcCell.bottom-delta)
hct = cellHTLeftBottom;
else
hct = cellHTLeft;
}else if(y>=rcCell.bottom-delta){//�Ƿ����±�
hct = cellHTBottom;
}else if(y<=rcCell.top+delta){//�Ƿ����ϱ�
hct = cellHTTop;
}else
hct = cellHTInterior;
return cell;
}
*/
//------------------------------------------------------------------------------//
//chi.pt must validate and chi.pt should be client coords.
//��������Ļ��������̽�⣬̽�����chi.cell�����ڿɼ�
//����Ҳ�����ڲ��ɼ����䡣
//------------------------------------------------------------------------------//
CELLHITTESTINFO& Worksheet::HitTest(CELLHITTESTINFO& chi)const
{
static int const delta=3;
const CellAxisInfo& cai=get_CellAxisInfo();
const int x=chi.pt.x;
const int y=chi.pt.y;
chi.flags=0;
chi.cell=GetCellByPos(x,y);
const int nLeftVisScrollCol=ch_.get_LeftVisScrollCol();
const int nTopVisScrollRow=rh_.get_TopVisScrollRow();
if(x>cai.VRemainAxis && x<=cai.VClientAxis || y>cai.HRemainAxis && y<=cai.HClientAxis)
{
chi.flags|=CHTC_IN_REMAIN_PART;
if(x>cai.VRemainAxis && x<cai.VRemainAxis+delta){
chi.flags|=CHTC_ON_VREMAIN_PART_LEFT;
if(y<cai.HHeaderAxis && get_ColHeader().get_cols()>0){
chi.flags|=CHTC_INCOLHEADER;
}
}
if(y>cai.HRemainAxis && y<cai.HRemainAxis+delta){
chi.flags|=CHTC_ON_HREMAIN_PART_TOP;
if(x<cai.VHeaderAxis && get_RowHeader().get_rows()>0){
chi.flags|=CHTC_ON_ROWDIVIDER;
}
}
}
if(CHTC_IN_REMAIN_PART&chi.flags){
return chi;
}
const RECT rcCell=raw_GetCellRect(chi.cell);
if(x<rcCell.left+delta){
chi.flags|=CHTC_LEFT;
}
if(y<=rcCell.top+delta){
chi.flags|=CHTC_TOP;
}
if(x>=rcCell.right-delta-1){
chi.flags|=CHTC_RIGHT;
}
if(y>=rcCell.bottom-delta){
chi.flags|=CHTC_BOTTOM;
}
if(HEADER_ROW==chi.cell.row && HEADER_COL!=chi.cell.col){
chi.flags|=CHTC_INCOLHEADER;
if(((chi.flags&CHTC_LEFT)||(chi.flags&CHTC_RIGHT)) && !(/*0*/nLeftVisScrollCol==chi.cell.col && (chi.flags&CHTC_LEFT)))
chi.flags|=CHTC_ON_COLDIVIDER;
}
if(HEADER_COL==chi.cell.col && HEADER_ROW!=chi.cell.row){
chi.flags|=CHTC_INROWHEADER;
if(((chi.flags&CHTC_TOP)||(chi.flags&CHTC_BOTTOM)) && !(nTopVisScrollRow==chi.cell.row&&(chi.flags&CHTC_TOP)))
chi.flags|=CHTC_ON_ROWDIVIDER;
}
//CCell const acell=GetActiveCell();
const ESelectionMode esm=GetWorkbook()->get_SelectionMode();
if(ESM_SINGLESELECTION==esm/*ESM_MULTISELECTION==esm && !get_Selections()->IsMultiSelectionMode()*/)
{
const CCellRange acr=get_Selections()->GetActiveSelection();
RECT rc=get_RangeRect(acr);
InflateRect(&rc,1,1);
if(PtInRect(&rc,chi.pt)){
if(x>rc.left && x<rc.left+3 || x>rc.right-3 && x<rc.right
|| y>rc.top && y<rc.top+3 && y>rc.bottom-3 && y<rc.bottom)
{
chi.flags|=CHTC_ON_DRAGBOUNDS;
}
}
if(acr.RightBottom()==chi.cell){
if(x>rcCell.right-5 && y>rcCell.bottom-3){
chi.flags|=CHTC_ON_DRAGCORNER;
}
}else if(acr.RightCol()+1==chi.cell.col){
if(acr.BottomRow()==chi.cell.row
&& x<rcCell.left+4 && y>rcCell.bottom-3
||acr.BottomRow()+1==chi.cell.row
&& x<rcCell.left+4 && y<rcCell.top+4)
{
chi.flags|=CHTC_ON_DRAGCORNER;
}
}else if(acr.RightCol()==chi.cell.col){
//AtlTrace(_T("\nx=%d,y=%d,cell.left=%d,cell.bottom=%d"),x,y,rcCell.left,rcCell.bottom);
if(acr.BottomRow()==chi.cell.row && x>rcCell.right-5 && y>rcCell.bottom-3
||acr.BottomRow()+1==chi.cell.row && x>rcCell.right-5&&y<rcCell.top+4
)
{
chi.flags|=CHTC_ON_DRAGCORNER;
}
}
}
return chi;
}
//-------------------------------------------------------------------------//
//���ؿͻ������ꡣ
//�÷��������жϵ�Ԫ���Ƿ��ںϲ���Ԫ������
//�У�����ǽ����������ϲ���Ԫ��ķ�Χ��
//-------------------------------------------------------------------------//
//RECT Worksheet::GetCellRectEx(int row,int col)const;
//{
// const Worksheet* pSheet=static_cast<const Worksheet*>(this);
// CCellRange const* pmerge=pSheet->GetMergeCells(row,col);
// if(!pmerge)
// return raw_GetCellRect(row,col);
// return pSheet->get_RangeRect(*pmerge);
//}
}//namespace mycell