//| Copyright: (C) 2009-2020 Kevin Larke //| License: GNU GPL version 3.0 or above. See the accompanying LICENSE file. #ifndef cmGr_h #define cmGr_h #ifdef __cplusplus extern "C" { #endif //( { file_desc:"Low level device independent API for descibing interactive graphics objects." kw:[plot] } enum { kAliceBlueGrId = 0xf0f8ff, kAntiqueWhiteGrId = 0xfaebd7, kAquaGrId = 0x00ffff, kAquamarineGrId = 0x7fffd4, kAzureGrId = 0xf0ffff, kBeigeGrId = 0xf5f5dc, kBisqueGrId = 0xffe4c4, kBlackGrId = 0x000000, kBlanchedAlmondGrId = 0xffebcd, kBlueGrId = 0x0000ff, kBlueVioletGrId = 0x8a2be2, kBrownGrId = 0xa52a2a, kBurlyWoodGrId = 0xdeb887, kCadetBlueGrId = 0x5f9ea0, kChartreuseGrId = 0x7fff00, kChocolateGrId = 0xd2691e, kCoralGrId = 0xff7f50, kCornflowerBlueGrId = 0x6495ed, kCornsilkGrId = 0xfff8dc, kCrimsonGrId = 0xdc143c, kCyanGrId = 0x00ffff, kDarkBlueGrId = 0x00008b, kDarkCyanGrId = 0x008b8b, kDarkGoldenRodGrId = 0xb8860b, kDarkGrayGrId = 0xa9a9a9, kDarkGreyGrId = 0xa9a9a9, kDarkGreenGrId = 0x006400, kDarkKhakiGrId = 0xbdb76b, kDarkMagentaGrId = 0x8b008b, kDarkOliveGreenGrId = 0x556b2f, kDarkorangeGrId = 0xff8c00, kDarkOrchidGrId = 0x9932cc, kDarkRedGrId = 0x8b0000, kDarkSalmonGrId = 0xe9967a, kDarkSeaGreenGrId = 0x8fbc8f, kDarkSlateBlueGrId = 0x483d8b, kDarkSlateGrayGrId = 0x2f4f4f, kDarkSlateGreyGrId = 0x2f4f4f, kDarkTurquoiseGrId = 0x00ced1, kDarkVioletGrId = 0x9400d3, kDeepPinkGrId = 0xff1493, kDeepSkyBlueGrId = 0x00bfff, kDimGrayGrId = 0x696969, kDimGreyGrId = 0x696969, kDodgerBlueGrId = 0x1e90ff, kFireBrickGrId = 0xb22222, kFloralWhiteGrId = 0xfffaf0, kForestGreenGrId = 0x228b22, kFuchsiaGrId = 0xff00ff, kGainsboroGrId = 0xdcdcdc, kGhostWhiteGrId = 0xf8f8ff, kGoldGrId = 0xffd700, kGoldenRodGrId = 0xdaa520, kGrayGrId = 0x808080, kGreyGrId = 0x808080, kGreenGrId = 0x008000, kGreenYellowGrId = 0xadff2f, kHoneyDewGrId = 0xf0fff0, kHotPinkGrId = 0xff69b4, kIndianRedGrId = 0xcd5c5c, kIndigoGrId = 0x4b0082, kIvoryGrId = 0xfffff0, kKhakiGrId = 0xf0e68c, kLavenderGrId = 0xe6e6fa, kLavenderBlushGrId = 0xfff0f5, kLawnGreenGrId = 0x7cfc00, kLemonChiffonGrId = 0xfffacd, kLightBlueGrId = 0xadd8e6, kLightCoralGrId = 0xf08080, kLightCyanGrId = 0xe0ffff, kLightGoldenRodYellowGrId = 0xfafad2, kLightGrayGrId = 0xd3d3d3, kLightGreyGrId = 0xd3d3d3, kLightGreenGrId = 0x90ee90, kLightPinkGrId = 0xffb6c1, kLightSalmonGrId = 0xffa07a, kLightSeaGreenGrId = 0x20b2aa, kLightSkyBlueGrId = 0x87cefa, kLightSlateGrayGrId = 0x778899, kLightSlateGreyGrId = 0x778899, kLightSteelBlueGrId = 0xb0c4de, kLightYellowGrId = 0xffffe0, kLimeGrId = 0x00ff00, kLimeGreenGrId = 0x32cd32, kLinenGrId = 0xfaf0e6, kMagentaGrId = 0xff00ff, kMaroonGrId = 0x800000, kMediumAquaMarineGrId = 0x66cdaa, kMediumBlueGrId = 0x0000cd, kMediumOrchidGrId = 0xba55d3, kMediumPurpleGrId = 0x9370d8, kMediumSeaGreenGrId = 0x3cb371, kMediumSlateBlueGrId = 0x7b68ee, kMediumSpringGreenGrId = 0x00fa9a, kMediumTurquoiseGrId = 0x48d1cc, kMediumVioletRedGrId = 0xc71585, kMidnightBlueGrId = 0x191970, kMintCreamGrId = 0xf5fffa, kMistyRoseGrId = 0xffe4e1, kMoccasinGrId = 0xffe4b5, kNavajoWhiteGrId = 0xffdead, kNavyGrId = 0x000080, kOldLaceGrId = 0xfdf5e6, kOliveGrId = 0x808000, kOliveDrabGrId = 0x6b8e23, kOrangeGrId = 0xffa500, kOrangeRedGrId = 0xff4500, kOrchidGrId = 0xda70d6, kPaleGoldenRodGrId = 0xeee8aa, kPaleGreenGrId = 0x98fb98, kPaleTurquoiseGrId = 0xafeeee, kPaleVioletRedGrId = 0xd87093, kPapayaWhipGrId = 0xffefd5, kPeachPuffGrId = 0xffdab9, kPeruGrId = 0xcd853f, kPinkGrId = 0xffc0cb, kPlumGrId = 0xdda0dd, kPowderBlueGrId = 0xb0e0e6, kPurpleGrId = 0x800080, kRedGrId = 0xff0000, kRosyBrownGrId = 0xbc8f8f, kRoyalBlueGrId = 0x4169e1, kSaddleBrownGrId = 0x8b4513, kSalmonGrId = 0xfa8072, kSandyBrownGrId = 0xf4a460, kSeaGreenGrId = 0x2e8b57, kSeaShellGrId = 0xfff5ee, kSiennaGrId = 0xa0522d, kSilverGrId = 0xc0c0c0, kSkyBlueGrId = 0x87ceeb, kSlateBlueGrId = 0x6a5acd, kSlateGrayGrId = 0x708090, kSlateGreyGrId = 0x708090, kSnowGrId = 0xfffafa, kSpringGreenGrId = 0x00ff7f, kSteelBlueGrId = 0x4682b4, kTanGrId = 0xd2b48c, kTealGrId = 0x008080, kThistleGrId = 0xd8bfd8, kTomatoGrId = 0xff6347, kTurquoiseGrId = 0x40e0d0, kVioletGrId = 0xee82ee, kWheatGrId = 0xf5deb3, kWhiteGrId = 0xffffff, kWhiteSmokeGrId = 0xf5f5f5, kYellowGrId = 0xffff00, kYellowGreenGrId = 0x9acd32 }; typedef enum { kHomeGrId = 5, // 5 kPageUpGrId, // 6 kEndGrId, // 7 kBackSpaceGrId = 8, // 8 kTabGrId = 9, // 9 kPageDownGrId, // 10 kLeftGrId, // 11 kUpGrId, // 12 kEnterGrId = 13, // 13 kRightGrId, // 14 kDownGrId, // 15 kInsertGrId, // 16 kPrintGrId, // 17 kScrollLockGrId, // 18 kPauseGrId, // 19 kMenuGrId, // 20 kLShiftGrId, // 21 kRShiftGrId, // 22 kLCtrlGrId, // 23 kRCtrlGrId, // 24 kLAltGrId, // 25 kRAltGrId, // 26 kEscapeGrId = 27, // 27 kLSuperGrId, // 28 kRSuperGrId, // 29 kNumLockGrId, // 30 kCapsLockGrId, // 31 kSpaceGrId = 32, // 32 Min. printable ASCII kExclMarkGrId, // 33 kDQuoteGrId, // 34 kPoundGrId, // 35 kDollarGrId, // 36 kPercentGrId, // 37 kAmpersandGrId, // 38 kApostropheGrId, // 39 kLParenGrId, // 40 kRParenGrId, // 41 kAsteriskGrId, // 42 kPlusGrId, // 43 kCommaGrId, // 44 kHyphenGrId, // 45 kPeriodGrId, // 46 kForwardSlashGrId, // 47 k0GrId, // 48 k1GrId, // 49 k2GrId, // 50 k3GrId, // 51 k4GrId, // 52 k5GrId, // 53 k6GrId, // 54 k7GrId, // 55 k8GrId, // 56 k9GrId, // 57 kColonGrId, // 58 kSemiColonGrId, // 59 kLesserGrId, // 60 kEqualGrId, // 61 kGreaterGrId, // 62 kQMarkGrId, // 63 kAtGrId, // 64 kA_GrId, // 65 kB_GrId, // 66 kC_GrId, // 67 kD_GrId, // 68 kE_GrId, // 69 kF_GrId, // 70 kG_GrId, // 71 kH_GrId, // 72 kI_GrId, // 73 kJ_GrId, // 74 kK_GrId, // 75 kL_GrId, // 76 kM_GrId, // 77 kN_GrId, // 78 kO_GrId, // 79 kP_GrId, // 80 kQ_GrId, // 81 kR_GrId, // 82 kS_GrId, // 83 kT_GrId, // 84 kU_GrId, // 85 kV_GrId, // 86 kW_GrId, // 87 kX_GrId, // 88 kY_GrId, // 89 kZ_GrId, // 90 kLBracketGrId, // 91 kBackSlashGrId, // 92 kRBracketGrId, // 93 kCaretGrId, // 94 kUnderScoreGrId, // 95 kAccentGrId, // 96 ka_GrId, // 97 kb_GrId, // 98 kc_GrId, // 99 kd_GrId, // 100 ke_GrId, // 101 kf_GrId, // 102 kg_GrId, // 103 kh_GrId, // 104 ki_GrId, // 105 kj_GrId, // 106 kk_GrId, // 107 kl_GrId, // 108 km_GrId, // 109 kn_GrId, // 110 ko_GrId, // 111 kp_GrId, // 112 kq_GrId, // 113 kr_GrId, // 114 ks_GrId, // 115 kt_GrId, // 116 ku_GrId, // 117 kv_GrId, // 118 kw_GrId, // 119 kx_GrId, // 120 ky_GrId, // 121 kz_GrId, // 122 kLBraceGrId, // 123 kPipeGrId, // 124 kRBraceGrId, // 125 kTildeGrId, // 126 kDeleteGrId, // 127 kNP_MultGrId, // 128 kNP_PlusGrId, // 129 kNP_MinusGrId, // 130 kNP_DecPtGrId, // 131 kNP_DivGrId, // 132 kNP_0GrId, // 133 kNP_1GrId, // 134 kNP_2GrId, // 135 kNP_3GrId, // 136 kNP_4GrId, // 137 kNP_5GrId, // 138 kNP_6GrId, // 139 kNP_7GrId, // 140 kNP_8GrId, // 141 kNP_9GrId, // 142 kNP_EqualGrId, // 143 kNP_EnterGrId, // 144 kFunc_1GrId, // 145 kFunc_2GrId, // 146 kFunc_3GrId, // 147 kFunc_4GrId, // 148 kFunc_5GrId, // 149 kFunc_6GrId, // 150 kFunc_7GrId, // 151 kFunc_8GrId, // 152 kFunc_9GrId, // 153 kFunc_10GrId, // 154 kFunc_11GrId, // 155 kFunc_12GrId, // 156 kBrightUpGrId, // 157 kBrightDnGrId, // 158 kAudio_PrevGrId, // 159 kAudio_PlayGrId, // 160 kAudio_NextGrId, // 161 kAudio_MuteGrId, // 162 kAudio_UpGrId, // 163 kAudio_DnGrId, // 164 kEjectGrId, // 165 kInvalidKeyCodeGrId } cmGrKeyCodeId_t; enum { kMinAsciiGrId = kSpaceGrId, kMaxAsciiGrId = kDeleteGrId }; enum { kOkGrRC, kLHeapFailGrRC, kAppErrGrRC, kRootObjCreateFailGrRC, kInvalidCoordsGrRC, kExtsErrGrRC }; enum { kLeftGrFl = 0x01, kTopGrFl = 0x02, kRightGrFl = 0x04, kBottomGrFl = 0x08, }; typedef enum { kLeftGrIdx = 0, // min-x kTopGrIdx = 1, // max-y kRightGrIdx = 2, // max-x kBottomGrIdx = 3, // min-y kAxisGrCnt = 4 } cmGrAxisIdx_t; typedef cmHandle_t cmGrH_t; typedef cmHandle_t cmGrObjH_t; typedef cmHandle_t cmGrDcH_t; typedef unsigned cmGrRC_t; extern cmGrH_t cmGrNullHandle; extern cmGrObjH_t cmGrObjNullHandle; typedef cmReal_t cmGrV_t; //==================================================================================================== // Calculate the width and height between two pixels. // This implies that the first and last pixel are inside the valid range. #define cmGrXtoW(x0,x1) (abs((x1)-(x0))+1) #define cmGrWtoX(x0,w) (((x0)+(w))-1) #define cmGrYtoH(y0,y1) (abs((y1)-(y0))+1) #define cmGrHtoY(y0,h) (((y0)+(h))-1) #define cmGrPIsXInRange(x,x0,w) ((x0)<=(x)&&(x)<=cmGrWtoX((x0),(w))) #define cmGrPIsYInRange(y,y0,h) ((y0)<=(y)&&(y)<=cmGrHtoY((y0),(h))) #define cmGrVIsXInRange(x,x0,w) ((x0)<=(x)&&(x)<=((x0)+(w))) #define cmGrVIsYInRange(y,y0,h) ((y0)<=(y)&&(y)<=((y0)+(h))) typedef struct { int x; int y; } cmGrPPt_t; #define cmGrPPtSet( p, xx, yy ) do{ (p)->x=(xx); (p)->y=(yy); }while(0) #define cmGrPPtIsEqual(p0,p1) ((p0)->x==(p1)->x && (p0)->y==(p1)->y) #define cmGrPPtPrint(lbl,p) printf("%s x=%i y=%i\n",(lbl),(p)->x,(p)->y) //==================================================================================================== typedef struct { int w; int h; } cmGrPSz_t; #define cmGrPSzSet( s, ww, hh ) do{ (s)->w=(ww); (s)->h=(hh);}while(0) #define cmGrPSzSetD( s, x0, y0, x1, y1 ) cmGrPSzSet(cmGrXtoW(x0,x1),cmGrYtoH(y0,y1)) #define cmGrPSzSetEmpty( s ) ((s)->w = (s)->h = 0) #define cmGrPSzSetNull( s ) ((s)->w = (s)->h = -1) #define cmGrPSzIsEmpty( s ) ((s)->w== 0 && (s)->h== 0) #define cmGrPSzIsNull( s ) ((s)->w==-1 && (s)->h==-1) #define cmGrPSzIsEqual(s0,s1) ((s0)->w==(s1)->w && (s0)->h==(s1)->h) #define cmGrPSzPrint(lbl,s) printf("%s w=%i h=%i\n",(lbl),(s)->w,(s)->h) //==================================================================================================== typedef struct { cmGrPPt_t loc; cmGrPSz_t sz; } cmGrPExt_t; #define cmGrPExtSet( e, x, y, w, h ) do{ cmGrPPtSet(&(e)->loc,(x),(y)); cmGrPSzSet(&(e)->sz,(w),(h)); }while(0) #define cmGrPExtSetD(e, x0, y0, x1, y1) cmGrPExtSet(e,cmMin(x0,x1),cmMin(y0,y1),cmGrXtoW(x0,x1),cmGrYtoH(y0,y1)) #define cmGrPExtL(e) ((e)->loc.x) #define cmGrPExtT(e) ((e)->loc.y) #define cmGrPExtR(e) (cmGrWtoX((e)->loc.x,(e)->sz.w)) #define cmGrPExtB(e) (cmGrHtoY((e)->loc.y,(e)->sz.h)) #define cmGrPExtW(e) ((e)->sz.w) #define cmGrPExtH(e) ((e)->sz.h) #define cmGrPExtSetL(e,v) ((e)->loc.x = (v)) #define cmGrPExtSetT(e,v) ((e)->loc.y = (v)) #define cmGrPExtSetR(e,v) cmGrPExtSetW(e,cmGrXtoW((e)->loc.x,(v))) #define cmGrPExtSetB(e,v) cmGrPExtSetH(e,cmGrYtoH((e)->loc.y,(v))) #define cmGrPExtSetW(e,v) ((e)->sz.w = (v)) #define cmGrPExtSetH(e,v) ((e)->sz.h = (v)) #define cmGrPExtCtrX(e) ((e)->loc.x + (e)->sz.w / 2) #define cmGrPExtCtrY(e) ((e)->loc.y + (e)->sz.h / 2) #define cmGrPExtCtr(e,pt) do{ (pt)->x=cmGrPExtCtrX(e); (pt)->y=cmGrPExtCtrY(e); }while(0) #define cmGrPExtSetEmpty( e ) do{ cmGrPSzSetEmpty(&(e)->sz); cmGrPPtSet(&(e)->loc,0,0); }while(0) #define cmGrPExtSetNull( e ) do{ cmGrPSzSetNull( &(e)->sz); cmGrPPtSet(&(e)->loc,0,0); }while(0) #define cmGrPExtIsEmpty( e ) cmGrPSzIsEmpty( &(e)->sz ) #define cmGrPExtIsNull( e ) cmGrPSzIsNull( &(e)->sz ) #define cmGrPExtIsNullOrEmpty(e) (cmGrPExtIsNull(e)||cmGrPExtIsEmpty(e)) #define cmGrPExtIsNotEmpty(e) (!cmGrPExtIsEmpty(e)) #define cmGrPExtIsNotNull(e) (!cmGrPExtIsNull(e)) #define cmGrPExtIsNotNullOrEmpty(e) (cmGrPExtIsNotNull(e)&&cmGrPExtIsNotEmpty(e)) #define cmGrPExtIsEqual( e0, e1 ) (cmGrPPtIsEqual(&(e0)->loc,&(e1)->loc) && cmGrPSzIsEqual(&(e0)->sz, &(e1)->sz)) #define cmGrPExtIsXyInside( e, xx, yy) (cmGrPIsXInRange((xx),(e)->loc.x,(e)->sz.w) && cmGrPIsYInRange((yy), (e)->loc.y, (e)->sz.h) ) #define cmGrPExtIsPtInside( e, pt ) (cmGrPExtIsXyInside((e),(pt)->x,(pt)->y)) #define cmGrPExtIsExtInside(e0, e1) (cmGrPExtIsPtInside((e0),&((e1)->loc)) && cmGrPExtIsXyInside((e0), cmGrWtoX((e1)->loc.x,(e1)->sz.w), cmGrHtoY((e1)->loc.y,(e1)->sz.h))) #define cmGrPExtExpand(e,l,t,r,b) do{(e)->loc.x+=(l); (e)->loc.y+=(t); (e)->sz.w+=(abs(l)+abs(r)); (e)->sz.h+=(abs(t)+abs(b));}while(0) #define cmGrPExtRpt(e,rpt) cmRptPrintf(rpt,"x:%i y:%i w:%i h:%i",(e)->loc.x,(e)->loc.y,(e)->sz.w,(e)->sz.h) #define cmGrPExtPrint(lbl,e) printf("%s %i %i %i %i\n",lbl,(e)->loc.x,(e)->loc.y,(e)->sz.w,(e)->sz.h) void cmGrPExtIntersect( cmGrPExt_t* r, const cmGrPExt_t* e0, const cmGrPExt_t* e1 ); //==================================================================================================== typedef struct { cmGrV_t x; cmGrV_t y; } cmGrVPt_t; #define cmGrVPtSet( p, xx, yy ) do{ (p)->x=(xx); (p)->y=(yy); }while(0) #define cmGrVPtIsEqual(p0,p1) ((p0)->x==(p1)->x && (p0)->y==(p1)->y) #define cmGrVPtIsNotEqual(p0,p1) (!cmGrVPtIsEqual(p0,p1)) //==================================================================================================== typedef struct { cmGrV_t w; cmGrV_t h; } cmGrVSz_t; #define cmGrVSzSet( s, ww, hh ) do{ (s)->w=(ww); (s)->h=(hh);}while(0) #define cmGrVSzSetD( s, x0, y0, x1, y1 ) cmGrVSzSet((x1)-(x0),(y1)-(y0)) #define cmGrVSzSetEmpty( s ) ((s)->w = (s)->h = 0) #define cmGrVSzSetNull( s ) ((s)->w = (s)->h = -1) #define cmGrVSzIsEmpty( s ) ((s)->w== 0 && (s)->h== 0) #define cmGrVSzIsNull( s ) ((s)->w==-1 || (s)->h==-1) #define cmGrVSzIsEqual(s0,s1) ((s0)->w==(s1)->w && (s0)->h==(s1)->h) //==================================================================================================== typedef struct { cmGrVPt_t loc; cmGrVSz_t sz; } cmGrVExt_t; #define cmGrVExtIsNorm( e ) ((e)->sz.w>=0 && (e)->sz.h>=0) #define cmGrVExtNorm( e ) do{ if( cmGrVExtIsNotNull(e) ){ if((e)->sz.w<0){(e)->loc.x += (e)->sz.w; (e)->sz.w*=-1;} if((e)->sz.h<0){(e)->loc.y += (e)->sz.h; (e)->sz.h*=-1;}} }while(0) #define cmGrVExtSet( e, x, y, w, h ) do{ cmGrVPtSet(&(e)->loc,(x),(y)); cmGrVSzSet(&(e)->sz,(w),(h)); cmGrVExtNorm(e); }while(0) #define cmGrVExtSetD(e, x0, y0, x1, y1) cmGrVExtSet((e),(x0),(y0),(x1)-(x0),(y1)-(y0)) // // l,t minx,maxy // r,b maxx,miny // #define cmGrVExtMinX(e) ((e)->loc.x) #define cmGrVExtMinY(e) ((e)->loc.y) #define cmGrVExtMaxX(e) ((e)->loc.x + (e)->sz.w) #define cmGrVExtMaxY(e) ((e)->loc.y + (e)->sz.h) #define cmGrVExtW(e) ((e)->sz.w) #define cmGrVExtH(e) ((e)->sz.h) #define cmGrVExtSetMinX(e,v) ((e)->loc.x = (v)) #define cmGrVExtSetMinY(e,v) ((e)->loc.y = (v)) // Beware: setting maxx and maxy depends on the current value of minx and miny. // If both minx and maxx are being changed then be sure to set minx first. // If both miny and maxy are being changed then be sure to set miny first. #define cmGrVExtSetMaxX(e,v) ((e)->sz.w = (v) - cmGrVExtMinX(e)) #define cmGrVExtSetMaxY(e,v) ((e)->sz.h = (v) - cmGrVExtMinY(e)) #define cmGrVExtSetW(e,v) ((e)->sz.w = (v)) #define cmGrVExtSetH(e,v) ((e)->sz.h = (v)) #define cmGrVExtSetEmpty( e ) do{ cmGrVSzSetEmpty(&(e)->sz); cmGrVPtSet(&(e)->loc,0,0); }while(0) #define cmGrVExtSetNull( e ) do{ cmGrVSzSetNull(&(e)->sz); cmGrVPtSet(&(e)->loc,0,0); }while(0) #define cmGrVExtIsEmpty( e ) cmGrVSzIsEmpty(&(e)->sz) #define cmGrVExtIsNull( e ) cmGrVSzIsNull( &(e)->sz) #define cmGrVExtIsNullOrEmpty(e) (cmGrVExtIsNull(e)||cmGrVExtIsEmpty(e)) #define cmGrVExtIsNotEmpty(e) (!cmGrVExtIsEmpty(e)) #define cmGrVExtIsNotNull(e) (!cmGrVExtIsNull(e)) #define cmGrVExtIsNotNullOrEmpty(e) (cmGrVExtIsNotNull(e)&&cmGrVExtIsNotEmpty(e)) #define cmGrVExtIsEqual( e0, e1 ) (cmGrVPtIsEqual(&(e0)->loc,&(e1)->loc) && cmGrVSzIsEqual(&(e0)->sz, &(e1)->sz)) #define cmGrVExtIsXyInside( e, xx, yy) (cmGrVIsXInRange((xx),(e)->loc.x,(e)->sz.w) && cmGrVIsYInRange((yy),(e)->loc.y,(e)->sz.h)) #define cmGrVExtIsPtInside( e, pt ) (cmGrVExtIsXyInside((e),(pt)->x,(pt)->y)) // e1 is inside e0 #define cmGrVExtIsExtInside(e0, e1) (cmGrVExtIsXyInside((e0),cmGrVExtMinX(e1),cmGrVExtMinY(e1)) && cmGrVExtIsXyInside((e0), cmGrVExtMaxX(e1), cmGrVExtMaxY(e1))) #define cmGrVExtRpt(e,rpt) cmRptPrintf(rpt,"x:%f y:%f w:%f h:%f",(e)->loc.x,(e)->loc.y,(e)->sz.w,(e)->sz.h) #define cmGrVExtPrint(lbl,e) printf("%s %f %f %f %f\n",lbl,(e)->loc.x,(e)->loc.y,(e)->sz.w,(e)->sz.h) // Shift and expand e0 to contain e1. Return true if e0 actually changes. bool cmGrVExtExpandToContain( cmGrVExt_t* e0, const cmGrVExt_t* e1 ); // Force e1 to be contained by e0 by shifting e1's location. This function // will never change the width or height of e1. Return true if e1 is changed. bool cmGrVExtContain( const cmGrVExt_t* e0, cmGrVExt_t* e1 ); // Return the intersection of 'e0' with 'e1' in 'r'. void cmGrVExtIntersect( cmGrVExt_t* r, const cmGrVExt_t* e0, const cmGrVExt_t* e1 ); //==================================================================================================== #define cmGrRgbToColor( r, g, b ) (((r) << 16) + ((g) << 8) + (b)) #define cmGrColorToR( c ) (((c) >> 16) & 0x000000ff) #define cmGrColorToG( c ) (((c) >> 8) & 0x000000ff) #define cmGrColorToB( c ) (((c) ) & 0x000000ff) typedef unsigned cmGrColor_t; enum { kGrDefaultColorMapIdx = 0, kGrDefaultColorMapId=0 }; unsigned cmGrColorMapCount( cmGrH_t grH ); unsigned cmGrColorMapId( cmGrH_t grH, unsigned mapIdx ); const cmChar_t* cmGrColorMapLabel( cmGrH_t grH, unsigned id ); unsigned cmGrColorMapRegister( cmGrH_t grH, cmChar_t* label, const cmGrColor_t* array, unsigned cnt ); cmGrColor_t* cmGrColorMap( cmGrH_t grH, unsigned mapId ); unsigned cmGrColorMapEleCount( cmGrH_t grH, unsigned mapId ); //==================================================================================================== typedef struct { cmCtx_t* ctx; // application context cmGrH_t grH; // graphics system handle to which this graphic object belongs cmGrObjH_t objH; // this graphics object handle void* cbArg; // user callback arg cmGrPPt_t msDnPPt; // mouse down phys point cmGrVPt_t msDnVPt; // mouse down virt point inside op->parent->wext cmGrVSz_t msDnVOffs; // virtual offset from mouse down point to msDnObj->vext cmGrObjH_t msDnObjH; // handle of object which recv'd mouse down cmGrVPt_t msVPt; // cur ms virtual point } cmGrObjFuncArgs_t; typedef cmGrRC_t (*cmGrCreateObjCb_t)( cmGrObjFuncArgs_t* args ); typedef void (*cmGrDestroyObjCb_t)( cmGrObjFuncArgs_t* args ); typedef bool (*cmGrRenderObjCb_t)( cmGrObjFuncArgs_t* args, cmGrDcH_t dcH ); typedef int (*cmGrDistanceObjCb_t)( cmGrObjFuncArgs_t* args, int x, int y ); typedef bool (*cmGrEventObjCb_t)( cmGrObjFuncArgs_t* args, unsigned flags, unsigned key, int px, int py ); typedef void (*cmGrVExtObjCb_t)( cmGrObjFuncArgs_t* args, cmGrVExt_t* vext ); typedef bool (*cmGrIsInsideObjCb_t)( cmGrObjFuncArgs_t* args, unsigned evtFlags, int px, int py, cmGrV_t vx, cmGrV_t vy ); typedef struct cmGrObjFunc_str { // User defined constructor. cmGrCreateObjCb_t createCbFunc; void* createCbArg; // User defined destructor. cmGrDestroyObjCb_t destroyCbFunc; void* destroyCbArg; // Draw the object by calling back to the cmGrDrawXXX() functions cmGrRenderObjCb_t renderCbFunc; void* renderCbArg; // Return the physical distance from a physical view location to the object. // (NOT USED) cmGrDistanceObjCb_t distanceCbFunc; void* distanceCbArg; // Handle an event. gx,gy are in the same coord's as args.objH.vext (they are inside args.objH.parent.wext). // Return true if the event objects dirty flag should be set. cmGrEventObjCb_t eventCbFunc; void* eventCbArg; // Return the objects location and size inside op->parent->wext cmGrVExtObjCb_t vextCbFunc; void* vextCbArg; // Called to determine which object is under the mouse and whether the event can // handle the event as described by the 'evtFlags' args. // Return true if the point is inside this obj. vx,vy is in the the same coord's // as op->vext (i.e. vx,vy is inside op->parent->wext) and the object will accept // the event implied by the 'evtFlags' argument. // The simple answer to this call is cmGrVExtIsXyInside( *vext, vx, vy ). cmGrIsInsideObjCb_t isInsideCbFunc; void* isInsideCbArg; } cmGrObjFunc_t; // Create a graphic object. This function calls the user defined (*create)() function. // ('flags' is not used) cmGrRC_t cmGrObjCreate( cmGrH_t h, cmGrObjH_t* hp, cmGrObjH_t parentH, cmGrObjFunc_t* f, unsigned id, unsigned flags, const cmGrVExt_t* wext ); // Destroy a graphic object and all of it's children. // This function calls the user defined (*destroy)() function. cmGrRC_t cmGrObjDestroy( cmGrH_t h, cmGrObjH_t* hp ); // Return true if 'oh' is a valid handle. cmGrRC_t cmGrObjIsValid( cmGrH_t h, cmGrObjH_t oh ); // Return the user id associated with this object. unsigned cmGrObjId( cmGrObjH_t oh ); void cmGrObjSetId( cmGrObjH_t oh, unsigned id ); // Return the handle to the parent object. cmGrObjH_t cmGrObjParent( cmGrObjH_t oh ); // An object world coord's are used to place child objects. cmGrRC_t cmGrObjSetWorldExt( cmGrH_t h, cmGrObjH_t oh, const cmGrVExt_t* vext ); void cmGrObjWorldExt( cmGrObjH_t oh, cmGrVExt_t* vext ); cmGrRC_t cmGrObjSetWorldLimitExt( cmGrH_t h, cmGrObjH_t oh, const cmGrVExt_t* vext, unsigned limitFlags ); void cmGrObjWorldLimitExt( cmGrObjH_t oh, cmGrVExt_t* vext, unsigned* limitFlags ); void cmGrObjSetCreateCb( cmGrObjH_t oh, cmGrCreateObjCb_t cbFunc, void* cbArg ); void cmGrObjSetDestroyCb( cmGrObjH_t oh, cmGrDestroyObjCb_t cbFunc, void* cbArg ); void cmGrObjSetRenderCb( cmGrObjH_t oh, cmGrRenderObjCb_t cbFunc, void* cbArg ); void cmGrObjSetDistanceCb( cmGrObjH_t oh, cmGrDistanceObjCb_t cbFunc, void* cbArg ); void cmGrObjSetEventCb( cmGrObjH_t oh, cmGrEventObjCb_t cbFunc, void* cbArg ); void cmGrObjSetVExtCb( cmGrObjH_t oh, cmGrVExtObjCb_t cbFunc, void* cbArg ); void cmGrObjSetIsInsideCb( cmGrObjH_t oh, cmGrIsInsideObjCb_t cbFunc, void* cbArg ); cmGrCreateObjCb_t cmGrObjCreateCbFunc( cmGrObjH_t oh ); cmGrDestroyObjCb_t cmGrObjDestroyCbFunc( cmGrObjH_t oh ); cmGrRenderObjCb_t cmGrObjRenderCbFunc( cmGrObjH_t oh ); cmGrDistanceObjCb_t cmGrObjDistanceCbFunc( cmGrObjH_t oh ); cmGrEventObjCb_t cmGrObjEventCbFunc( cmGrObjH_t oh ); cmGrVExtObjCb_t cmGrObjVExtCbFunc( cmGrObjH_t oh ); cmGrIsInsideObjCb_t cmGrObjIsInsideCbFunc( cmGrObjH_t oh ); void* cmGrObjCreateCbArg( cmGrObjH_t oh ); void* cmGrObjDestroyCbArg( cmGrObjH_t oh ); void* cmGrObjRenderCbArg( cmGrObjH_t oh ); void* cmGrObjDistanceCbArg( cmGrObjH_t oh ); void* cmGrObjEventCbArg( cmGrObjH_t oh ); void* cmGrObjVExtCbArg( cmGrObjH_t oh ); void* cmGrObjIsInsideCbArg( cmGrObjH_t oh ); // Same as call to user defined (*vect)(). void cmGrObjLocalVExt( cmGrH_t h, cmGrObjH_t oh, cmGrVExt_t* vext ); // Given an objects id return it's handle. cmGrObjH_t cmGrObjIdToHandle( cmGrH_t h, unsigned id ); // Move 'aoH' such that it is drawn above 'boH' in the z-order. // This means that 'boH' will be drawn before 'aoH'. void cmGrObjDrawAbove( cmGrObjH_t boH, cmGrObjH_t aoH ); void cmGrObjReport( cmGrH_t h, cmGrObjH_t oh, cmRpt_t* rpt ); void cmGrObjReportR( cmGrH_t h, cmGrObjH_t oh, cmRpt_t* rpt ); // print children //==================================================================================================== // Drawing Functions - called by objects to draw themselves int cmGrX_VtoP( cmGrH_t hh, cmGrObjH_t oh, cmGrV_t y ); int cmGrY_VtoP( cmGrH_t hh, cmGrObjH_t oh, cmGrV_t x ); void cmGrXY_VtoP( cmGrH_t hh, cmGrObjH_t oh, cmGrV_t x, cmGrV_t y, cmGrPPt_t* rp ); void cmGrXYWH_VtoP( cmGrH_t hh, cmGrObjH_t oh, cmGrV_t x, cmGrV_t y, cmGrV_t w, cmGrV_t h, cmGrPExt_t* pext ); void cmGrVExt_VtoP( cmGrH_t hh, cmGrObjH_t oh, const cmGrVExt_t* vext, cmGrPExt_t* pext ); void cmGrXY_PtoV( cmGrH_t hh, cmGrObjH_t oh, int x, int y, cmGrVPt_t* rp ); void cmGrXYWH_PtoV( cmGrH_t hh, cmGrObjH_t oh, int x, int y, int w, int h, cmGrVExt_t* vext ); void cmGrPExt_PtoV( cmGrH_t hh, cmGrObjH_t oh, const cmGrPExt_t* pext, cmGrVExt_t* vext ); void cmGrDrawVLine( cmGrH_t hh, cmGrDcH_t dcH, cmGrObjH_t oh, cmGrV_t x0, cmGrV_t y0, cmGrV_t x1, cmGrV_t y1 ); void cmGrDrawVRect( cmGrH_t hh, cmGrDcH_t dcH, cmGrObjH_t oh, cmGrV_t x, cmGrV_t y, cmGrV_t w, cmGrV_t h ); //==================================================================================================== // Callback identifiers typedef enum { kCreateCbGrId, kDestroyCbGrId, kLocalPtCbGrId, kGlobalPtCbGrId, kPhysExtCbGrId, kViewExtCbGrId, kSelectExtCbGrId, kFocusCbGrId, kKeyUpCbGrId, kKeyDnCbGrId } cmGrCbId_t; // Callback function associated with this canvas. typedef void (*cmGrCbFunc_t)( void* arg, cmGrH_t grH, cmGrCbId_t id, unsigned evtFlags, cmGrKeyCodeId_t keycode ); // Configuration Flags enum { kExpandViewGrFl = 0x01, // expand the view to show new objects kSelectHorzGrFl = 0x02, // select along x-axis only kSelectVertGrFl = 0x04 // select along y-axis only }; // 'wext' is optional. // 'id' is an arbitrary user definable identifier - although it is used // as the view index by cmGrPage(). cmGrRC_t cmGrCreate( cmCtx_t* ctx, cmGrH_t* hp, unsigned id, unsigned cfgFlags, cmGrCbFunc_t cbFunc, void* cbArg, const cmGrVExt_t* wext ); // Optional internal world extents for this object // Destroy this canvas. cmGrRC_t cmGrDestroy( cmGrH_t* hp ); // Remove all objects from the root object and restore the canvas to it's default state. cmGrRC_t cmGrClear( cmGrH_t h ); // Get the root object handle cmGrObjH_t cmGrRootObjH( cmGrH_t h ); // Get and set the configuration flags (e.g. kExpandViewGrFl | kSelectHorzGrFl | kSelectVertHorzGrFl ) unsigned cmGrCfgFlags( cmGrH_t h ); void cmGrSetCfgFlags( cmGrH_t h, unsigned cfgFlags ); // Draw the objects on the canvas. cmGrRC_t cmGrDraw( cmGrH_t h, cmGrDcH_t dcH ); // event flags enum { kMsDownGrFl = 0x0001, kMsUpGrFl = 0x0002, kMsMoveGrFl = 0x0004, kMsWheelGrFl= 0x0008, kMsDragGrFl = 0x0010, kMsClickGrFl= 0x0020, kKeyDnGrFl = 0x0040, kKeyUpGrFl = 0x0080, kMsEvtMask = 0x02f, kEvtMask = 0x00ff, kMsLBtnGrFl = 0x0100, kMsCBtnGrFl = 0x0200, kMsRBtnGrFl = 0x0400, kShiftKeyGrFl = 0x0800, kAltKeyGrFl = 0x1000, kCtlKeyGrFl = 0x2000, }; // Receive a UI event. bool cmGrEvent( cmGrH_t h, unsigned flags, cmGrKeyCodeId_t key, int x, int y ); // Return true if 'h' is valid. bool cmGrIsValid( cmGrH_t h ); // Return the user defined 'id' set in cmGrCreate() unsigned cmGrId( cmGrH_t h ); // Return the last mouse location in root object coordinates. const cmGrVPt_t* cmGrGlobalPt( cmGrH_t h ); // Return the last mouse location in coordinates of the object the mouse was over. const cmGrVPt_t* cmGrLocalPt( cmGrH_t h ); // The new view extents must fit inside the world extents. // Return true if the view extents actually changed. bool cmGrSetViewExtents( cmGrH_t hh, cmGrV_t minx, cmGrV_t miny, cmGrV_t maxx, cmGrV_t maxy ); bool cmGrSetViewExtentsE(cmGrH_t h, const cmGrVExt_t* ext ); void cmGrViewExtents( cmGrH_t h, cmGrVExt_t* exts ); // View Location // Return true if the phys extents actually changed. bool cmGrSetPhysExtents( cmGrH_t hh, int x, int y, int w, int h ); bool cmGrSetPhysExtentsE(cmGrH_t h, const cmGrPExt_t* ext ); void cmGrPhysExtents( cmGrH_t h, cmGrPExt_t* exts ); // Return some scroll bar values for this canvas. // tot=world pixels, vis=vis pixels, max=max scroll pos pos=cur scroll pos // All return values are optional. void cmGrScrollExtents( cmGrH_t h, cmGrPSz_t* tot, cmGrPSz_t* vis, cmGrPSz_t* max, cmGrPPt_t* pos ); // Return true if the view location actually changed. bool cmGrSetScrollH( cmGrH_t h, int x ); int cmGrScrollH( cmGrH_t h ); bool cmGrSetScrollV( cmGrH_t h, int y ); int cmGrScrollV( cmGrH_t h ); // Get the current selection extents. // If the selection extents are not valid then the function returns false // and sets the return extents to their null state. bool cmGrSelectExtents( cmGrH_t h, cmGrVExt_t* vext, cmGrPExt_t* pext ); // Both pts are optional void cmGrSetSelectPoints(cmGrH_t h, const cmGrVPt_t* pt0, const cmGrVPt_t* pt1 ); void cmGrSelectPoints( cmGrH_t h, cmGrVPt_t* pt0, cmGrVPt_t* pt1 ); enum { kZoomInGrFl=0x01, kXAxisGrFl=0x02, kYAxisGrFl=0x04, kSelectGrFl=0x08, kShowAllGrFl=0x10 }; // 1) If kSelectGrFl is not set then the center 1/3 of the current view // becomes the new view. // 2) If kSelectGrFl is set then the selection area becomes the view. // 3) If kSelectGrFl is set but no selection area exists then // option 1) is selected used and using the selection point as center. void cmGrZoom( cmGrH_t h, unsigned flags ); // Synchronize the 'syncGrH' horz. and/or verical, world,view,select extents to // this gr's extents. Changes to this gr's extents will be automatically // applied to 'syncGrH'. // If 'syncGrH' was used in a previous call to this function then flags will // modify the previously set flags value. // Clear the kHorzSyncFl and kVertSyncFl to disable the synchronization. // Set flags to 0 to prevent future sync calls. enum { kWorldSyncGrFl=0x01, kViewSyncGrFl=0x02, kSelectSyncGrFl=0x04, kHorzSyncGrFl=0x08, kVertSyncGrFl=0x10 }; void cmGrSetSync( cmGrH_t h, cmGrH_t syncGrH, unsigned flags ); void cmGrReport( cmGrH_t h, cmRpt_t* rpt ); //) #ifdef __cplusplus } #endif #endif