Artifact Content

Not logged in

Artifact a25d583a35063324b2ae17f17017948ea1d6763a


#ifndef _EDITWING_IP_VIEW_H_
#define _EDITWING_IP_VIEW_H_
#include "ewView.h"
#include "ip_doc.h"
using namespace ki;
#ifndef __ccdoc__
namespace editwing {
namespace view {
#endif



using doc::DocImpl;



//=========================================================================
//@{ @pkg editwing.View.Impl //@}
//@{
//	�`���{���[�`��
//
//	���p����ɂ́ACanvas�I�u�W�F�N�g���� getPainter ���Ďg���܂��B
//	��ʗp�f�o�C�X�R���e�L�X�g�̃��C���ł��B������Ə����Ă����Έ���@�\��
//	�lj�����Ƃ��Ɋy�Ȃ̂�������܂��񂪁A����Ȃ��Ƃ��l����v�搫��
//	����͂����Ȃ��ɂ߂ēK���Ɂc�B
//@}
//=========================================================================

class Painter : public Object
{
public:

	~Painter();

	//@{ �w��ʒu�Ɉꕶ���o�� //@}
	void CharOut( unicode ch, int x, int y );

	//@{ �w��ʒu�ɕ�������o�� //@}
	void StringOut( const unicode* str, int len, int x, int y );

	//@{ �����F�؂�ւ� //@}
	void SetColor( int i );

	//@{ �w�i�F�œh��‚Ԃ� //@}
	void Fill( const RECT& rc );

	//@{ ���] //@}
	void Invert( const RECT& rc );

	//@{ �������� //@}
	void DrawLine( int x1, int y1, int x2, int y2 );

	//@{ �N���b�v�̈�ݒ� //@}
	void SetClip( const RECT& rc );

	//@{ �N���b�v�̈���� //@}
	void ClearClip();

	//@{ ���p�X�y�[�X�p�L���`�� //@}
	void DrawHSP( int x, int y, int times );

	//@{ �S�p�X�y�[�X�p�L���`�� //@}
	void DrawZSP( int x, int y, int times );

public:

	//@{ ����(pixel) //@}
	int H() const { return height_; }

	//@{ ������(pixel) //@}
	int F() const { return figWidth_; }

	//@{ ������(pixel) //@}
	int Wc( unicode ch ) const
		{
			if( widthTable_[ ch ] == -1 )
				::GetCharWidthW( dc_, ch, ch, widthTable_+ch );
			return widthTable_[ ch ];
		}
	int W( const unicode* pch ) const // 1.08 �T���Q�[�g�y�A���
		{
			unicode ch = *pch;
			if( widthTable_[ ch ] == -1 )
			{
				if( isHighSurrogate(ch) )
				{
					SIZE sz;
					if( ::GetTextExtentPoint32W( dc_, pch, 2, &sz ) )
						return sz.cx;
					int w = 0;
					::GetCharWidthW( dc_, ch, ch, &w );
					return w;
				}
				::GetCharWidthW( dc_, ch, ch, widthTable_+ch );
			}
			return widthTable_[ ch ];
		}

	//@{ �W��������(pixel) //@}
	int W() const { return widthTable_[ L'x' ]; }

	//@{ ���̃^�u�����ʒu���v�Z //@}
	//int nextTab(int x) const { int t=T(); return (x/t+1)*t; }
	int nextTab(int x) const { int t=T(); return ((x+4)/t+1)*t; }
	private: int T() const { return widthTable_[ L'\t' ]; } public:

	//@{ ���݂̃t�H���g��� //@}
	const LOGFONT& LogFont() const { return logfont_; }

	//@{ ���ʕ�����`�悷�邩�ۂ� //@}
	bool sc( int i ) const { return scDraw_[i]; }

private:

	const HDC    dc_;
	const HFONT  font_;
	const HPEN   pen_;
	const HBRUSH brush_;
	int          height_;
	int*         widthTable_;
	int          figWidth_;
	LOGFONT      logfont_;
	COLORREF     colorTable_[7];
	bool         scDraw_[5];

private:

	Painter( HDC hdc, const VConfig& vc );
	HDC getDC() { return dc_; }
	friend class Canvas;
	NOCOPY(Painter);
};



//=========================================================================
//@{
//	�`��”\�̈�
//
//	�E�C���h�E�T�C�Y�̕ύX��܂�Ԃ��̗L����t�H���g�̐ݒ�Ȃǂ�
//	�Ή����āA�`��̈�̃T�C�Y��K���ɊǗ����܂��B��邱�Ƃ�
//	�Ƃ肠�������ꂾ���B
//@}
//=========================================================================

class Canvas : public Object
{
public:

	Canvas( const View& vw );

	//@{ View�̑傫���ύX�C�x���g����
	//	 @return �܂�Ԃ������ς������true //@}
	bool on_view_resize( int cx, int cy );

	//@{ �s���ύX�C�x���g����
	//	 @return �e�L�X�g�̈�̕����ς������true //@}
	bool on_tln_change( ulong tln );

	//@{ �t�H���g�ύX�C�x���g���� //@}
	void on_font_change( const VConfig& vc );

	//@{ �ݒ�ύX�C�x���g���� //@}
	void on_config_change( int wrap, bool showln );

public:

	//@{ [�s�ԍ���\�����邩�ۂ�] //@}
	bool showLN() const { return showLN_; }

	//@{ [-1:�܂�Ԃ�����  0:���E�[  else:�w�蕶����] //@}
	int wrapType() const { return wrapType_; }

	//@{ �܂�Ԃ���(pixel) //@}
	ulong wrapWidth() const { return wrapWidth_; }

	//@{ �\���̈�̈ʒu(pixel) //@}
	const RECT& zone() const { return txtZone_; }

	//@{ �`��p�I�u�W�F�N�g //@}
	Painter& getPainter() const { return *font_; }

private:

	int  wrapType_;  // [ -1:�܂�Ԃ�����  0:���E�[  else:�w�蕶���� ]
	bool showLN_;    // [ �s�ԍ���\�����邩�ۂ� ]

	dptr<Painter> font_; // �`��p�I�u�W�F�N�g
	ulong    wrapWidth_; // �܂�Ԃ���(pixel)
	RECT       txtZone_; // �e�L�X�g�\����̈ʒu(pixel)
	int         figNum_; // �s�ԍ��̌���

private:

	bool CalcLNAreaWidth();
	void CalcWrapWidth();

private:

	NOCOPY(Canvas);
};



//=========================================================================
//@{
//	�s���̐܂�Ԃ����
//@}
//=========================================================================

struct WLine : public storage<ulong>
{
	// [0]   : ���̍s�̐܂�Ԃ������ł̉������i�[
	// [1-n] : n�s�ڂ̏I�[��index���i�[�B
	//
	//   �Ⴆ�� "aaabbb" �Ƃ����_���s�� "aaab" "bb" �Ɛ܂�Ȃ�
	//   {48, 4, 6} �ȂǂƂ��������R�̔z��ƂȂ�B

	WLine() : storage<ulong>(2) {}
	ulong& width()      { return (*this)[0]; }
	ulong width() const { return (*this)[0]; }
	ulong rln() const   { return size()-1; }
};



//=========================================================================
//@{
//	�ĕ`��͈͂��w�肷�邽�߂̃t���O
//@}
//=========================================================================

enum ReDrawType
{
	LNAREA, // �s�ԍ��]�[���̂�
	LINE,   // �ύX�̂�������s�̂�
	AFTER,  // �ύX�̂������s�ȉ��S��
	ALL     // �S���
};



//=========================================================================
//@{
//	�`�揈�����ׂ����w�肷��\����
//@}
//=========================================================================

struct VDrawInfo
{
	const RECT rc;  // �ĕ`��͈�
	int XBASE;      // ��ԍ��̕�����x���W
	int XMIN;       // �e�L�X�g�ĕ`��͈͍��[
	int XMAX;       // �e�L�X�g�ĕ`��͈͉E�[
	int YMIN;       // �e�L�X�g�ĕ`��͈͏�[
	int YMAX;       // �e�L�X�g�ĕ`��͈͉��[
	ulong TLMIN;    // �e�L�X�g�ĕ`��͈͏�[�_���s�ԍ�
	int SXB, SXE;   // �I��͈͂�x���W
	int SYB, SYE;   // �I��͈͂�y���W

	explicit VDrawInfo( const RECT& r ) : rc(r) {}
};



//=========================================================================
//@{
//	�܂�Ԃ�ed�e�L�X�g�̊Ǘ��E�\����
//
//	Canvas�N���X�ɂ���Čv�Z���ꂽ�̈�T�C�Y���Q�l�ɁA�e�L�X�g��
//	�܂�Ԃ����������s����B�����ŁA�X�N���[������A�`�揈���Ȃ�
//	��v�ȏ����͑S�Ď��s���邱�ƂɂȂ�B
//@}
//=========================================================================

class ViewImpl : public Object
{
public:

	ViewImpl( View& vw, DocImpl& dc );

	//@{ �܂�Ԃ������ؑ� //@}
	void SetWrapType( int wt );

	//@{ �s�ԍ��\��/��\���ؑ� //@}
	void ShowLineNo( bool show );

	//@{ �\���F�E�t�H���g�ؑ� //@}
	void SetFont( const VConfig& vc );

		//@{ �e�L�X�g�̈�̃T�C�Y�ύX�C�x���g //@}
		void on_view_resize( int cx, int cy );

	void DoResize( bool wrapWidthChanged );
	void DoConfigChange();

	//@{ �e�L�X�g�f�[�^�̍X�V�C�x���g //@}
	void on_text_update( const DPos& s,
		const DPos& e, const DPos& e2, bool bAft, bool mCur );

	//@{ �`�揈�� //@}
	void on_paint( const PAINTSTRUCT& ps );

public:

	//@{ �S�\���s�� //@}
	ulong vln() const { return vlNum_; }

	//@{ ��s�̕\���s�� //@}
	ulong rln( ulong tl ) const { return wrap_[tl].rln(); }

	//@{ �܂�Ԃ��ʒu //@}
	ulong rlend( ulong tl, ulong rl ) const { return wrap_[tl][rl+1]; }

	//@{ ��‚ł��܂�Ԃ������݂��邩�ۂ� //@}
	bool wrapexists() const { return doc_.tln() != vln(); }

	//@{ �J�[�\�� //@}
	Cursor& cur() { return cur_; }

	//@{ �t�H���g //@}
	const Painter& fnt() const { return cvs_.getPainter(); }


	void on_hscroll( int code );
	void on_vscroll( int code );
	void on_wheel( short delta );

	void GetVPos( int x, int y, VPos* vp, bool linemode=false ) const;
	void GetOrigin( int* x, int* y ) const;
	void ConvDPosToVPos( DPos dp, VPos* vp, const VPos* base=NULL ) const;
	void ScrollTo( const VPos& vp );
	int  GetLastWidth( ulong tl ) const;

public:

	const RECT& zone() const { return cvs_.zone(); }
	int left()  const { return cvs_.zone().left; }
	int right() const { return cvs_.zone().right; }
	int bottom()const { return cvs_.zone().bottom; }
	int lna()   const { return cvs_.zone().left; }
	int cx()    const { return cvs_.zone().right - cvs_.zone().left; }
	int cxAll() const { return cvs_.zone().right; }
	int cy()    const { return cvs_.zone().bottom; }

private:

	const DocImpl&   doc_;
	Canvas           cvs_;
	Cursor           cur_;
	gapbufobj<WLine> wrap_;
	ulong            vlNum_;
	ulong            textCx_;

private:

	void DrawLNA( const VDrawInfo& v, Painter& p );
	void DrawTXT( const VDrawInfo v, Painter& p );
	void Inv( int y, int xb, int xe, Painter& p );

	void CalcEveryLineWidth();
	ulong CalcLineWidth( const unicode* txt, ulong len ) const;
	void ModifyWrapInfo( const unicode* txt, ulong len, WLine& wl, ulong stt );
	void ReWrapAll();
	int ReWrapSingle( const DPos& s );
	int InsertMulti( ulong ti_s, ulong ti_e );
	int DeleteMulti( ulong ti_s, ulong ti_e );
	void UpdateTextCx();
	void ReDraw( ReDrawType r, const DPos* s=NULL );

private:

	HWND hwnd_;
	SCROLLINFO rlScr_; // ���X�N���[�����ipixel�P�ʁj
	SCROLLINFO udScr_; // �c�X�N���[�����i�s�P�ʁj
	ulong udScr_tl_;   // ��ԏ�ɕ\�������_���s��TLine_Index
	ulong udScr_vrl_;  // ��ԏ�ɕ\�������\���s��VRLine_Index

private:

	bool ReSetScrollInfo();
	void ForceScrollTo( ulong tl );
	void UpdateScrollBar();
	ReDrawType TextUpdate_ScrollBar( const DPos& s, const DPos& e, const DPos& e2 );

	ulong tl2vl( ulong tl ) const;
	void GetDrawPosInfo( VDrawInfo& v ) const;
	void InvalidateView( const DPos& dp, bool afterall ) const;
	void ScrollView( int dx, int dy, bool update );
	void UpDown( int dy, bool thumb );
};



//-------------------------------------------------------------------------

inline void ViewImpl::on_view_resize( int cx, int cy )
	{ DoResize( cvs_.on_view_resize( cx, cy ) ); }

inline void ViewImpl::SetWrapType( int wt )
	{ cvs_.on_config_change( wt, cvs_.showLN() );
	  DoConfigChange(); }

inline void ViewImpl::ShowLineNo( bool show )
	{ cvs_.on_config_change( cvs_.wrapType(), show );
	  DoConfigChange(); }

inline void ViewImpl::SetFont( const VConfig& vc )
	{ cvs_.on_font_change( vc );
	  cur_.on_setfocus();
	  CalcEveryLineWidth(); // �s���Čv�Z
	  DoConfigChange(); }

inline void ViewImpl::GetOrigin( int* x, int* y ) const
	{ *x = left()-rlScr_.nPos, *y = -udScr_.nPos*cvs_.getPainter().H(); }



//=========================================================================

}}     // namespace editwing::view
#endif // _EDITWING_IP_VIEW_H_