// CAsNumericTextCell.cpp
//
#include "stdafx.h"
#include "AsNumericTextCell.h"
#include "AsNumericEdit.h"
#include "DrawUtils.h"
#include <assert.h>
CAsNumericTextCell::CAsNumericTextCell():
editBox_(NULL),
minValue_(0),
maxValue_(0),
minMaxCheckEnable_(false),
precision_(1),
value_(0),
readOnly_(false)
{
}
CAsNumericTextCell::~CAsNumericTextCell()
{
KillFocus(false, false);
}
void CAsNumericTextCell::SetDrawArea(const CRect& drawArea)
{
CAsBaseCell::SetDrawArea(drawArea);
if (HasFocus()) {
CRect textArea;
textArea = GetTextBoxArea();
editBox_->SetWindowPos(&CWnd::wndTop, textArea.left, textArea.top, textArea.Width(), textArea.Height(), SWP_SHOWWINDOW);
}
}
CSize CAsNumericTextCell::GetMinSize()
{
return drawArea_.Size();
}
void CAsNumericTextCell::Draw(CDC* pDC)
{
if (!visible_ || IsHidden())
return;
CAsBaseCell::Draw(pDC);
if (HasFocus())
editBox_->RedrawWindow(drawArea_);
}
bool CAsNumericTextCell::HitTest(const CPoint& pt)
{
BOOL ret;
ret = drawArea_.PtInRect(pt);
return ret == TRUE;
}
void CAsNumericTextCell::SetVisible(bool visible)
{
CAsBaseCell::SetVisible(visible);
if (visible)
SetFocus();
else
KillFocus(false);
}
void CAsNumericTextCell::SetText(const cmString& text)
{
CAsBaseCell::SetText(text);
if (HasFocus())
editBox_->SetWindowText(text);
}
bool CAsNumericTextCell::ProcessMessage(DWORD msg, DWORD lParam, DWORD wParam, const CPoint& pt, const CRect& parentRect, bool& needRedraw)
{
bool processed;
bool selected;
selected = IsSelected();
// if selection changed after a WM_LBUTTOMDOWON SetFocus
//
if (!selected && IsSelected())
SetFocus(false);
processed = CAsBaseCell::ProcessMessage(msg, lParam, wParam, pt, parentRect, needRedraw);
//processed = false;
switch (msg) {
case WM_LBUTTONDOWN:
{
BOOL ret;
ret = parentRect.PtInRect(drawArea_.TopLeft()) && drawArea_.PtInRect(pt);
if (ret)
SetFocus();
else
KillFocus(true);
break;
}
case WM_KEYDOWN:
{
if (HasFocus()) {
switch (wParam) {
case VK_ESCAPE:
KillFocus(false, false);
processed = true;
needRedraw = true;
break;
case VK_RETURN:
KillFocus(true, false);
processed = true;
needRedraw = true;
break;
}
}
}
}
return processed;
}
void CAsNumericTextCell::SetFocus(bool redraw)
{
if (HasFocus() || readOnly_)
return;
CAsBaseCell::SetFocus(false);
CRect textArea;
textArea = GetTextBoxArea();
assert(editBox_ == NULL);
editBox_ = new CAsNumericEdit;
editBox_->Create(WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL, textArea, parentWnd_, -1);
font_.CreateFont(-fontInfo_.GetFontSize(),
0, /* width */
0, /* escapement */
0, /* orientation */
fontInfo_.GetFontBold() ? FW_BOLD : FW_NORMAL, /* weight*/
0, /* italic*/
0, /* underline */
0, /* strikeout */
ANSI_CHARSET, /* charset */
OUT_DEFAULT_PRECIS, /* out precision */
CLIP_DEFAULT_PRECIS, /* clip precision */
DEFAULT_QUALITY, /* quality */
DEFAULT_PITCH, /* pitch family */
fontInfo_.GetFontName());
editBox_->SetFont(&font_);
editBox_->SetMinValue(minValue_);
editBox_->SetMaxValue(maxValue_);
editBox_->SetPrecision(precision_);
editBox_->SetMinMaxCheckEnable(minMaxCheckEnable_);
editBox_->SetWindowText(text_);
editBox_->SetFocus();
editBox_->SetValue(value_);
editBox_->SetSel((int)text_.GetLength(), text_.GetLength());
editBox_->SetWindowPos(&CWnd::wndTop, textArea.left, textArea.top, textArea.Width(), textArea.Height(), SWP_SHOWWINDOW);
editBox_->ModifyStyleEx(0, WS_EX_CONTROLPARENT);
if (redraw && parentWnd_)
parentWnd_->RedrawWindow(drawArea_);
}
void CAsNumericTextCell::SetFontInfo(const CAsFontInfo& fontInfo)
{
fontInfo_ = fontInfo;
// if (editMode_)
// editBox_->SetFont(fontInfo_.GetFont());
}
void CAsNumericTextCell::KillFocus(bool storeData, bool redraw)
{
if (!HasFocus())
return;
if (storeData)
StoreData();
CAsBaseCell::KillFocus(storeData, false);
if (editBox_ == NULL || !editBox_->GetSafeHwnd())
return;
delete editBox_;
editBox_ = NULL;
if (font_.GetSafeHandle())
font_.DeleteObject();
if (redraw && parentWnd_)
parentWnd_->RedrawWindow(drawArea_);
}
void CAsNumericTextCell::SetMinValue(double minValue)
{
minValue_ = minValue;
if (editBox_)
editBox_->SetMinValue(minValue);
}
double CAsNumericTextCell::GetMinValue() const
{
return minValue_;
}
void CAsNumericTextCell::SetMaxValue(double maxValue)
{
maxValue_ = maxValue;
if (editBox_)
editBox_->SetMaxValue(maxValue);
}
double CAsNumericTextCell::GetMaxValue() const
{
return maxValue_;
}
void CAsNumericTextCell::SetPrecision(int precision)
{
if (precision < 0)
precision = 0;
precision_ = precision;
if (editBox_)
editBox_->SetPrecision(precision);
}
int CAsNumericTextCell::GetPrecision()
{
return precision_;
}
void CAsNumericTextCell::SetMinMaxCheckEnable(bool enable)
{
if (editBox_)
editBox_->SetMinMaxCheckEnable(enable);
minMaxCheckEnable_ = enable;
}
bool CAsNumericTextCell::GetMinMaxCheckEnable() const
{
return minMaxCheckEnable_;
}
void CAsNumericTextCell::SetValue(double value, bool redraw)
{
cmString newText;
value = ValidateValue(value);
value_ = value;
if (editBox_)
editBox_->SetValue(value);
newText = FormatValue(value);
if (text_ != newText) {
text_ = newText;
if (parentWnd_ && redraw)
parentWnd_->RedrawWindow();
}
}
double CAsNumericTextCell::GetValue()
{
if (HasFocus())
StoreData();
return value_;
}
double CAsNumericTextCell::ValidateValue(double value)
{
if (minMaxCheckEnable_) {
value = min(value, maxValue_);
value = max(value, minValue_);
}
return value;
}
cmString CAsNumericTextCell::FormatValue(double value)
{
cmString tmp;
cmString fmt;
fmt.Format(_T("%%1.%df"), precision_);
tmp.Format(fmt, value);
return tmp;
}
CRect CAsNumericTextCell::GetTextBoxArea()
{
CRect tmp;
tmp = drawArea_;
//tmp.DeflateRect(6, 3, 5, 1);
tmp.DeflateRect(7, 4, 5, 1);
return tmp;
}
void CAsNumericTextCell::StoreData()
{
if (HasFocus()) {
cmString tmp;
double oldValue;
oldValue = value_;
editBox_->Validate();
editBox_->GetWindowText(tmp);
text_ = tmp;
value_ = editBox_->GetValue();
if (value_ != oldValue && cellListener_) {
bool ret;
ret = cellListener_->OnValueChanged(name_, oldValue, value_);
if (!ret) {
editBox_->SetWindowText(FormatValue(oldValue));
text_ = FormatValue(oldValue);
}
}
}
}
void CAsNumericTextCell::SetReadOnly(bool readOnly)
{
readOnly_ = readOnly;
KillFocus(true, true);
}
bool CAsNumericTextCell::IsReadOnly() const
{
return readOnly_;
}