📄 axes.cpp
字号:
return true;
}
}
}
break;
default:
return GridLine::Command(cmd, tmpl, o);
}
return false;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Each axis tick is a graphic object managing tick labels and grid lines
Tick::Tick(GraphObj *par, DataObj *d, double val, DWORD Flags):GraphObj(par, d)
{
FileIO(INIT_VARS);
value = val; flags = Flags;
Id = GO_TICK; bModified = false;
}
Tick::Tick(int src):GraphObj(0L, 0L)
{
FileIO(INIT_VARS);
if(src == FILE_READ) {
FileIO(FILE_READ);
}
bModified = false;
}
Tick::~Tick()
{
Command(CMD_FLUSH, 0L, 0L);
if(mo) DelBitmapClass(mo); mo = 0L;
if(bModified) Undo.InvalidGO(this);
}
double
Tick::GetSize(int select)
{
switch(select){
case SIZE_LB_XPOS: return lbx;
case SIZE_XBASE: return fix;
case SIZE_LB_YPOS: return lby;
case SIZE_YBASE: return fiy;
case SIZE_ZBASE: return fiz;
case SIZE_LB_XDIST:
if(parent && parent->Id == GO_AXIS) return parent->GetSize(SIZE_TLB_XDIST);
return 0.0f;
case SIZE_LB_YDIST:
if(parent && parent->Id == GO_AXIS) return parent->GetSize(SIZE_TLB_YDIST);
return 0.0f;
case SIZE_MINE: return value;
default:
if(parent) return parent->GetSize(select);
}
return 0.0;
}
bool
Tick::SetSize(int select, double value)
{
switch(select & 0xfff) {
case SIZE_AXIS_TICKS:
size = value;
break;
case SIZE_LB_XDIST:
case SIZE_LB_YDIST:
if(label)return label->SetSize(select, value);
break;
case SIZE_TICK_ANGLE:
angle = value;
}
return false;
}
bool
Tick::SetColor(int select, DWORD col)
{
switch(select & 0xfff) {
case COL_AXIS:
if(label)label->SetColor((select & UNDO_STORESET) ?
COL_TEXT | UNDO_STORESET : COL_TEXT, col);
return true;
case COL_BG:
if(label) return label->SetColor(select, col);
return false;
}
return false;
}
void
Tick::DoMark(anyOutput *o, bool mark)
{
if(mark){
memcpy(&mrc, &rDims, sizeof(RECT));
IncrementMinMaxRect(&mrc, 6);
mo = GetRectBitmap(&mrc, o);
InvertLine(pts, 2, defs.GetOutLine(), &rDims, o, mark);
}
else RestoreRectBitmap(&mo, &mrc, o);
}
bool
Tick::Command(int cmd, void *tmpl, anyOutput *o)
{
MouseEvent *mev;
TextDEF *LabelDef;
GraphObj **tmpPlots;
AxisDEF *axis;
switch(cmd){
case CMD_SET_AXDEF:
if(axis = (AxisDEF*)tmpl) {
flags = (flags & AXIS_MINORTICK) | axis->flags;
}
break;
case CMD_FLUSH:
if(Grid) DeleteGO(Grid); Grid = 0L;
if(label) DeleteGO(label); label = 0L;
if(name) free(name); name = 0L;
if(ls) delete(ls); ls = 0L;
return true;
case CMD_HIDE_MARK:
if(!tmpl || !o) return false;
if(tmpl == (void*)label){
label->DoMark(o, false);
return true;
}
else if(tmpl == (void*)Grid){
Grid->DoMark(o, false);
return true;
}
return false;
case CMD_SET_TICKSTYLE:
flags &= ~0x07;
flags |= (0x07 & *((DWORD*)tmpl));
return true;
case CMD_TICK_TYPE:
if(tmpl) type = *((int*)tmpl);
return true;
case CMD_SETSCROLL:
case CMD_REDRAW:
//this commands are usually issued from a child or from Undo
bModified = true;
return parent ? parent->Command(CMD_REDRAW, 0L, o) : false;
case CMD_MUTATE:
bModified = true;
if(!parent || !(tmpPlots = (GraphObj **)tmpl) || !tmpPlots[0] || !tmpPlots[1]) return false;
if(label == tmpPlots[0]) {
Undo.MutateGO((GraphObj**)&label, tmpPlots[1], 0L, o);
return true;
}
break;
case CMD_DELOBJ:
bModified = true;
if(parent && tmpl && o) {
if(tmpl == Grid) {
Undo.DeleteGO((GraphObj**)(&Grid), 0L, o);
flags &= ~AXIS_GRIDLINE;
return parent->Command(CMD_REDRAW, 0L, o);
}
if(tmpl == label) {
Undo.DeleteGO((GraphObj**)(&label), 0L, o);
label = 0L;
return parent->Command(CMD_REDRAW, 0L, o);
}
}
return false;
case CMD_SET_GO3D:
case CMD_GET_GRIDLINE:
if(parent) return parent->Command(cmd, tmpl, o);
return false;
case CMD_SET_GRIDTYPE:
if(tmpl && *((int*)tmpl)) gl_type = *((int*)tmpl);
case CMD_SET_GRIDLINE:
if(Grid && tmpl) return Grid->Command(cmd, tmpl, o);
return false;
case CMD_SET_DATAOBJ:
Id = GO_TICK;
if(Grid) Grid->Command(cmd, tmpl, o);
if(label) label->Command(cmd, tmpl, o);
return true;
case CMD_MOUSE_EVENT:
if((flags & AXIS_GRIDLINE) && Grid && Grid->Command(cmd, tmpl, o)) return true;
if(label && label->Command(cmd, tmpl, o)) return true;
mev = (MouseEvent *) tmpl;
switch (mev->Action) {
case MOUSE_LBUP:
if(IsInRect(&rDims, mev->x, mev->y) && !CurrGO &&
IsCloseToLine(&pts[0], &pts[1], mev->x, mev->y)) {
o->ShowMark(this, MRK_GODRAW);
return true;
}
break;
}
return false;
case CMD_TLB_TXTDEF:
if(label) return label->Command(CMD_SETTEXTDEF, tmpl, o);
else return false;
case CMD_SETTEXT:
if(label) return label->Command(cmd, tmpl, o);
if(!(LabelDef = (TextDEF *)calloc(1, sizeof(TextDEF))))return false;
LabelDef->ColTxt = parent ? parent->GetColor(COL_AXIS) : defs.Color(COL_AXIS);
LabelDef->ColBg = parent ? parent->GetColor(COL_BG) : defs.Color(COL_AXIS);
LabelDef->RotBL = LabelDef->RotCHAR = 0.0f;
LabelDef->fSize = parent ? parent->GetSize(SIZE_TICK_LABELS) : defs.GetSize(SIZE_TICK_LABELS);
switch(flags & 0x70) {
case AXIS_USER: LabelDef->Align = TXA_VCENTER | TXA_HCENTER; break;
case AXIS_LEFT: LabelDef->Align = TXA_VCENTER | TXA_HRIGHT; break;
case AXIS_RIGHT: LabelDef->Align = TXA_VCENTER | TXA_HLEFT; break;
case AXIS_TOP: LabelDef->Align = TXA_VBOTTOM | TXA_HCENTER; break;
case AXIS_BOTTOM: LabelDef->Align = TXA_VTOP | TXA_HCENTER; break;
default: LabelDef->Align = TXA_VTOP | TXA_HRIGHT; break;
}
LabelDef->Style = TXS_NORMAL;
LabelDef->Mode = TXM_TRANSPARENT;
LabelDef->Font = FONT_HELVETICA;
LabelDef->text = tmpl && *((char*)tmpl) ? strdup((char*)tmpl) : 0L;
label = new Label(this, 0L, fix, fiy, LabelDef, LB_X_PARENT | LB_Y_PARENT);
if(LabelDef->text) free(LabelDef->text);
delete (LabelDef);
return true;
}
return false;
}
void
Tick::DoPlot(double six, double csx, anyOutput *o)
{
fPOINT3D dp1, dp2;
POINT3D ip2, p31, p32;
if(!parent || parent->Id != GO_AXIS) return;
if(mo) DelBitmapClass(mo); mo = 0L;
if(ls) delete(ls); ls = 0L;
if(!((Axis*)parent)->GetValuePos(value, &fix, &fiy, &fiz, o))return;
lbx = fix; lby = fiy;
if(flags & AXIS_ANGULAR) {
dp1.fx = o->co2fix(parent->GetSize(SIZE_XCENT)+parent->GetSize(SIZE_GRECT_LEFT));
dp1.fy = o->co2fiy(parent->GetSize(SIZE_YCENT)+parent->GetSize(SIZE_GRECT_TOP));
dp1.fz = o->un2fix(parent->GetSize(SIZE_DRADIUS));
six = (fix - dp1.fx)/dp1.fz; csx = (dp1.fy - fiy)/dp1.fz;
lbx += (o->un2fix(defs.GetSize(SIZE_AXIS_TICKS)*3.0*six));
lby -= (o->un2fiy(defs.GetSize(SIZE_AXIS_TICKS)*3.0*csx));
}
switch(type & 0x0f) {
case 1: lsi = sin(angle/57.29577951); lcsi = cos(angle/57.29577951); break;
default: lsi = -csx; lcsi = six; break;
}
if(flags & AXIS_MINORTICK) {
ip2.x = o->un2ix(0.5 * size * lcsi); ip2.y = o->un2iy(0.5 * size * lsi);
}
else {
ip2.x = o->un2ix(size * lcsi); ip2.y = o->un2iy(size * lsi);
}
if(flags & AXIS_3D){
dp1.fx = dp1.fy = dp1.fz = 0.0;
switch(type & 0x0f){
case 2: dp1.fx = size; dp1.fy = dp1.fz = 0.0; break;
case 3: dp1.fy = -size; dp1.fx = dp1.fz = 0.0; break;
case 4: dp1.fz = size; dp1.fx = dp1.fy = 0.0; break;
}
if(dp1.fx != dp1.fy || dp1.fx != dp1.fz) {
if(flags & AXIS_MINORTICK) {
dp1.fx *= 0.5; dp1.fy *= 0.5; dp1.fz *= 0.5;
}
o->uvec2ivec(&dp1, &dp2);
ip2.x = iround(dp2.fx); ip2.y = iround(dp2.fy);
ip2.z = iround(dp2.fz);
}
}
switch (flags &0x03) {
case AXIS_NOTICKS:
return; //no ticks
case AXIS_POSTICKS: //ticks are positive
break;
case AXIS_NEGTICKS: //ticks are negative
ip2.x *= -1; ip2.y *= -1; break;
case AXIS_SYMTICKS: //symmetrical ticks around axis: process later
break;
}
pts[1].x = iround(fix); pts[1].y = iround(fiy);
p31.z = p32.z = iround(fiz);
if((flags &0x03) == AXIS_SYMTICKS) { //tick is symetrical !
pts[1].x -= (ip2.x >>1); pts[1].y -= (ip2.y >>1);
p31.z -= (ip2.z >>1); p32.z = p31.z;
}
p31.x = p32.x = pts[0].x = pts[1].x; p31.y = p32.y = pts[0].y = pts[1].y;
pts[1].x += ip2.x; pts[1].y += ip2.y; p32.z += ip2.z;
p32.x += ip2.x; p32.y += ip2.y;
SetMinMaxRect(&rDims, pts[0].x, pts[0].y, pts[1].x, pts[1].y);
IncrementMinMaxRect(&rDims, 6);
if(parent && parent->Id == GO_AXIS && (flags & AXIS_3D)){
if(ls = new line_segment(this, data, &((Axis*)parent)->axline, &p31, &p32)){
ls->DoPlot(o);
}
}
else o->oSolidLine(pts);
if(flags & AXIS_MINORTICK) return;
if(flags & AXIS_GRIDLINE) {
if(!Grid){
if(flags & AXIS_3D) {
Grid = new GridLine3D(this, data, gl_type, flags);
}
else if((flags & AXIS_ANGULAR) == AXIS_ANGULAR){
Grid = new GridRadial(this, data, gl_type, flags);
}
else {
Grid = new GridLine(this, data, gl_type, flags);
}
}
if(Grid) Grid->DoPlot(o);
// we lost the line definition from the parent axis
if(parent) parent->Command(CMD_RESET_LINE, 0L, o);
}
if(label){
if(flags & AXIS_3D) label->SetSize(SIZE_ZPOS, fiz);
label->DoPlot(o);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Axes are graphic objects containing ticks
Axis::Axis(GraphObj *par, DataObj *d, AxisDEF *ax, DWORD flags):
GraphObj(par, d)
{
if(!(axis = (AxisDEF*)malloc(sizeof(AxisDEF))))return;
FileIO(INIT_VARS);
if(flags & AXIS_3D) GridLine.pattern = 0L;
if(ax->owner){
if(axis) free(axis);
axis = ax;
}
else {
if(axis) {
memcpy((void*)axis, (void*)ax, sizeof(AxisDEF));
axis->owner = (void*)this;
}
}
axis->flags = flags;
if ((flags & AXIS_ANGULAR) || (flags & AXIS_RADIAL)) {
GridLine.color = colAxis;
GridLine.pattern = 0x0;
}
Id = GO_AXIS;
}
Axis::Axis(int src):GraphObj(0L, 0L)
{
if(!(axis = (AxisDEF*)malloc(sizeof(AxisDEF))))return;
FileIO(INIT_VARS);
if(src == FILE_READ) {
FileIO(FILE_READ);
}
}
Axis::~Axis()
{
Undo.InvalidGO(this);
if(axis && axis->owner == (void*)this){
if(axis->breaks) free(axis->breaks);
free(axis);
}
Command(CMD_FLUSH, 0L, 0L);
if(ssMATval) free(ssMATval); if(ssMATlbl) free(ssMATlbl);
if(ssMITval) free(ssMITval); ssMATval = ssMATlbl = ssMITval = 0L;
if(axisLabel) DeleteGO(axisLabel); axisLabel = 0L;
if(mo) DelBitmapClass(mo); mo = 0L;
}
double
Axis::GetSize(int select)
{
switch(select) {
case SIZE_LB_XDIST: return lbdist.fx;
case SIZE_LB_YDIST: return lbdist.fy;
case SIZE_TLB_XDIST: return tlbdist.fx;
case SIZE_TLB_YDIST: return tlbdist.fy;
case SIZE_LB_XPOS: return(flim[0].fx + flim[1].fx)/2.0f;
case SIZE_LB_YPOS: return(flim[0].fy + flim[1].fy)/2.0f;
case SIZE_TICK_LABELS: return sizAxTickLabel;
case SIZE_AXIS_TICKS: return sizAxTick;
case SIZE_AXIS_LINE: return sizAxLine;
case SIZE_XPOS: return axis->loc[0].fx;
case SIZE_XPOS+1: return axis->loc[1].fx;
case SIZE_YPOS: return axis->loc[0].fy;
case SIZE_YPOS+1: return axis->loc[1].fy;
case SIZE_ZPOS: return axis->loc[0].fz;
case SIZE_ZPOS+1: return axis->loc[1].fz;
case SIZE_XCENT: return axis->Center.fx;
case SIZE_YCENT: return axis->Center.fy;
case SIZE_RADIUS1: case SIZE_RADIUS2: case SIZE_DRADIUS:
return axis->Radius;
}
//DEBUG: we should return a reasonable value for SIZE_BOUNDS_...
// if the axis is not scaling (i.e. parent == this).
if(parent) return parent->GetSize(select);
else return defs.GetSize(select);
}
DWORD
Axis::GetColor(int select)
{
switch(select){
case COL_AXIS:
return colAxis;
}
if(parent) return parent->GetColor(select);
else return defs.Color(select);
}
bool
Axis::SetSize(int select, double value)
{
int i;
switch(select & 0xfff) {
case SIZE_AXIS_LINE:
sizAxLine = value;
break;
case SIZE_LB_XDIST:
lbdist.fx = value;
if(axisLabel)axisLabel->SetSize(select,value);
break;
case SIZE_LB_YDIST:
lbdist.fy = value;
if(axisLabel)axisLabel->SetSize(select,value);
break;
case SIZE_TLB_XDIST:
case SIZE_TLB_YDIST:
case SIZE_AXIS_TICKS:
case SIZE_TICK_ANGLE:
switch (select){
case SIZE_TLB_XDIST:
tlbdist.fx = value; select = SIZE_LB_XDIST;
break;
case SIZE_TLB_YDIST:
tlbdist.fy = value; select = SIZE_LB_YDIST;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -