hschumann2/TempleOS-Source-Code
0847
1 2public CCtrl *CtrlFindUnique(CTask *haystack_task,I64 needle_type)3{//Find task ctrl given ctrl_type.4 CCtrl *c;5 c=haystack_task->next_ctrl;6 while (c!=&haystack_task->next_ctrl) {7 if (c->type==needle_type)8 return c;9 c=c->next;10 }11 return NULL;12}13 14U0 CtrlsUpdate(CTask *task)15{16 CCtrl *c;17 c=task->next_ctrl;18 while (c!=&task->next_ctrl) {19 if (c->update_derived_vals)20 (*c->update_derived_vals)(c);21 if (c->flags&CTRLF_BORDER) {22 c->scrn_left =gr.pan_text_x+task->pix_left+c->left-FONT_WIDTH;23 c->scrn_right =gr.pan_text_x+task->pix_left+c->right-FONT_WIDTH;24 c->scrn_top =gr.pan_text_y+task->pix_top+c->top-FONT_HEIGHT;25 c->scrn_bottom=gr.pan_text_y+task->pix_top+c->bottom-FONT_HEIGHT;26 } else {27 c->scrn_left =gr.pan_text_x+task->pix_left+c->left;28 c->scrn_right =gr.pan_text_x+task->pix_left+c->right;29 c->scrn_top =gr.pan_text_y+task->pix_top+c->top;30 c->scrn_bottom=gr.pan_text_y+task->pix_top+c->bottom;31 }32 c=c->next;33 }34}35 36fp_update_ctrls=&CtrlsUpdate;37 38Bool CtrlInsideRect(CCtrl *c,I64 x,I64 y)39{//scrn coordinates40 if (c->scrn_left<=x<=c->scrn_right &&41 c->scrn_top<=y<=c->scrn_bottom)42 return TRUE;43 else44 return FALSE;45}46 47public Bool CtrlInside(CCtrl *c,I64 x,I64 y)48{//Is x,y inside a ctrl?49 if (c->flags&CTRLF_SHOW) {50 if (c->inside_ctrl)51 return (*c->inside_ctrl)(c,x,y);52 else53 return CtrlInsideRect(c,x,y);54 } else55 return FALSE;56}57 58U0 DrawCtrls(CTask *task)59{60 CCtrl *c;61 CDC *dc=DCAlias(gr.dc2,task);62 c=task->next_ctrl;63 while (c!=&task->next_ctrl) {64 if (c->flags&CTRLF_SHOW) {65 if (c->flags&CTRLF_BORDER) {66 if (!Bt(&task->display_flags,DISPLAYf_NO_BORDER)) {67 PUSHFD68 CLI69 while (LBts(&task->task_flags,TASKf_TASK_LOCK))70 PAUSE71 72 task->win_left--; //Allow drawing on border73 task->win_right++;74 task->win_top--;75 task->win_bottom++;76 WinDerivedValsUpdate(task);77 78 LBtr(&task->task_flags,TASKf_TASK_LOCK);79 POPFD80 81 if (c->draw_it)82 (*c->draw_it)(dc,c);83 84 PUSHFD85 CLI86 while (LBts(&task->task_flags,TASKf_TASK_LOCK))87 PAUSE88 89 task->win_left++;90 task->win_right--;91 task->win_top++;92 task->win_bottom--;93 WinDerivedValsUpdate(task);94 95 LBtr(&task->task_flags,TASKf_TASK_LOCK);96 POPFD97 }98 } else99 if (c->draw_it)100 (*c->draw_it)(dc,c);101 }102 c=c->next;103 }104 DCDel(dc);105}106 107#define WIN_SCROLL_SIZE 8108#define WIN_SCROLL_BORDER_BONUS 4109U0 DrawWinScroll(CDC *dc,CCtrl *c)110{111 CWinScroll *s=c->state;112 113 if (c->flags&CTRLF_CLICKED)114 dc->color=s->color>>4;115 else116 dc->color=s->color&0xF;117 GrRect(dc,c->left,c->top,c->right-c->left+1,c->bottom-c->top+1);118 119 if (c->flags&CTRLF_CLICKED)120 dc->color=s->color&0xF;121 else122 dc->color=s->color>>4;123 GrRect(dc,c->left+2,c->top+2,c->right-c->left+1-4,c->bottom-c->top+1-4);124}125 126U0 WinDerivedScrollValsUpdate(CCtrl *c)127{128 CWinScroll *s=c->state;129 I64 range;130 if (s->max<s->min) s->max=s->min;131 if (s->pos<s->min) s->pos=s->min;132 if (s->pos>s->max) s->pos=s->max;133 s->color=c->win_task->border_attr&0xF^0xF+134 (c->win_task->border_attr&0xF)<<4;135 range=s->max-s->min;136 if (!range) range=1;137 switch (c->type) {138 case CTRLT_WIN_HSCROLL:139 c->left =gr.pan_text_x+FONT_WIDTH-WIN_SCROLL_BORDER_BONUS+140 (s->pos-s->min)*(c->win_task->pix_width+2*WIN_SCROLL_BORDER_BONUS141 -WIN_SCROLL_SIZE)/range;142 c->right =c->left+WIN_SCROLL_SIZE-1;143 c->top =gr.pan_text_y+FONT_HEIGHT+144 (FONT_WIDTH-WIN_SCROLL_SIZE)/2+c->win_task->pix_height;145 c->bottom=c->top+WIN_SCROLL_SIZE-1;146 break;147 case CTRLT_WIN_VSCROLL:148 c->left =gr.pan_text_x+FONT_WIDTH+149 (FONT_WIDTH-WIN_SCROLL_SIZE)/2+c->win_task->pix_width;150 c->right =c->left+WIN_SCROLL_SIZE-1;151 c->top =gr.pan_text_y+FONT_HEIGHT-WIN_SCROLL_BORDER_BONUS+152 (s->pos-s->min)*(c->win_task->pix_height+153 2*WIN_SCROLL_BORDER_BONUS-WIN_SCROLL_SIZE)/range;154 c->bottom=c->top+WIN_SCROLL_SIZE-1;155 break;156 }157}158 159U0 LeftClickHWinScroll(CCtrl *c,I64 x,I64,Bool down)160{161 CTask *task=c->win_task;162 CWinScroll *s=c->state;163 I64 range=task->pix_width+2*WIN_SCROLL_BORDER_BONUS-WIN_SCROLL_SIZE;164 LBts(&s->flags,WSSf_SET_TO_POS);165 s->pos=((x-(FONT_WIDTH-WIN_SCROLL_BORDER_BONUS))166 *(s->max-s->min+1)+range/2)/range+s->min;167 if (down)168 c->flags|=CTRLF_CLICKED;169 else170 c->flags&=~CTRLF_CLICKED;171 if (c->update_derived_vals)172 (*c->update_derived_vals)(c);173}174 175U0 LeftClickVWinScroll(CCtrl *c,I64,I64 y,Bool down)176{177 CTask *task=c->win_task;178 CWinScroll *s=c->state;179 I64 range=task->pix_height+2*WIN_SCROLL_BORDER_BONUS-WIN_SCROLL_SIZE;180 LBts(&s->flags,WSSf_SET_TO_POS);181 s->pos=((y-(FONT_HEIGHT-WIN_SCROLL_BORDER_BONUS))182 *(s->max-s->min+1)+range/2)/range+s->min;183 if (down)184 c->flags|=CTRLF_CLICKED;185 else186 c->flags&=~CTRLF_CLICKED;187 if (c->update_derived_vals)188 (*c->update_derived_vals)(c);189}190 191U0 WheelChangeWinScroll(CCtrl *c,I64 delta)192{193 CWinScroll *s=c->state;194 LBts(&s->flags,WSSf_SET_TO_POS);195 s->pos+=delta;196 if (c->update_derived_vals)197 (*c->update_derived_vals)(c);198}199 200U0 WinScrollsInit(CTask *task)201{202 CCtrl *c;203 204 if (!CtrlFindUnique(task,CTRLT_WIN_HSCROLL)) {205 c=CAlloc(sizeof(CCtrl));206 c->win_task=task;207 c->flags=CTRLF_SHOW|CTRLF_BORDER|CTRLF_CAPTURE_LEFT_MS;208 c->type=CTRLT_WIN_HSCROLL;209 c->state=&task->horz_scroll;210 c->update_derived_vals=&WinDerivedScrollValsUpdate;211 c->draw_it=&DrawWinScroll;212 c->left_click=&LeftClickHWinScroll;213 QueIns(c,task->last_ctrl);214 }215 216 if (!CtrlFindUnique(task,CTRLT_WIN_VSCROLL)) {217 c=CAlloc(sizeof(CCtrl));218 c->win_task=task;219 c->flags=CTRLF_SHOW|CTRLF_BORDER|CTRLF_CAPTURE_LEFT_MS;220 c->type=CTRLT_WIN_VSCROLL;221 c->state=&task->vert_scroll;222 c->update_derived_vals=&WinDerivedScrollValsUpdate;223 c->draw_it=&DrawWinScroll;224 c->left_click=&LeftClickVWinScroll;225 c->wheel_chg=&WheelChangeWinScroll;226 QueIns(c,task->last_ctrl);227 }228 TaskDerivedValsUpdate(task);229}230#define VIEWANGLES_SPACING 22231#define VIEWANGLES_RANGE 48232#define VIEWANGLES_BORDER 2233#define VIEWANGLES_SNAP 2234 235U0 DrawViewAnglesCtrl(CDC *dc,CCtrl *c)236{237 I64 i,j;238 CViewAngles *s=c->state;239 240 dc->color=s->cbd;241 GrRect(dc, c->left,c->top,VIEWANGLES_SPACING*4+3,242 VIEWANGLES_SPACING*2+VIEWANGLES_RANGE);243 dc->color=s->cbg;244 GrRect(dc, c->left+VIEWANGLES_BORDER,c->top+VIEWANGLES_BORDER,245 VIEWANGLES_SPACING*4+3-2*VIEWANGLES_BORDER,246 VIEWANGLES_SPACING*2+VIEWANGLES_RANGE-2*VIEWANGLES_BORDER);247 dc->color=s->cfg;248 GrLine(dc,c->left+VIEWANGLES_SPACING,c->top+VIEWANGLES_SPACING,249 c->left+VIEWANGLES_SPACING,c->top+VIEWANGLES_SPACING+250 VIEWANGLES_RANGE-1);251 GrLine(dc,c->left+2*VIEWANGLES_SPACING+1,c->top+VIEWANGLES_SPACING,252 c->left+2*VIEWANGLES_SPACING+1,c->top+VIEWANGLES_SPACING+253 VIEWANGLES_RANGE-1);254 GrLine(dc,c->left+3*VIEWANGLES_SPACING+2,c->top+VIEWANGLES_SPACING,255 c->left+3*VIEWANGLES_SPACING+2,c->top+VIEWANGLES_SPACING+256 VIEWANGLES_RANGE-1);257 for (i=1;i<VIEWANGLES_RANGE+1;i+=2*VIEWANGLES_SNAP) {258 j=2-i/3&1;259 GrLine(dc,c->left+VIEWANGLES_SPACING-j,c->bottom-VIEWANGLES_SPACING-i,260 c->left+VIEWANGLES_SPACING+j,c->bottom261 -VIEWANGLES_SPACING-i);262 GrLine(dc,c->left+2*VIEWANGLES_SPACING+1-j,c->bottom-VIEWANGLES_SPACING-i,263 c->left+2*VIEWANGLES_SPACING+1+j,c->bottom264 -VIEWANGLES_SPACING-i);265 GrLine(dc,c->left+3*VIEWANGLES_SPACING+2-j,c->bottom-VIEWANGLES_SPACING-i,266 c->left+3*VIEWANGLES_SPACING+2+j,c->bottom267 -VIEWANGLES_SPACING-i);268 }269 270 dc->color=s->cx;271 GrPrint(dc,c->left+VIEWANGLES_SPACING-FONT_WIDTH/2,272 c->top+VIEWANGLES_SPACING-(1+FONT_HEIGHT),"X");273 GrPrint(dc,c->left+VIEWANGLES_SPACING-3*FONT_WIDTH/2,274 c->top+VIEWANGLES_SPACING+VIEWANGLES_RANGE+3,275 "%3d",s->sx*360/VIEWANGLES_RANGE);276 i=c->left+VIEWANGLES_SPACING;277 if (s->sx>VIEWANGLES_RANGE/2)278 j=-VIEWANGLES_RANGE/2+s->sx;279 else280 j=s->sx+VIEWANGLES_RANGE/2;281 j=c->top+VIEWANGLES_SPACING+VIEWANGLES_RANGE-1-j;282 GrRect(dc,i-3,j-2,7,5);283 dc->color=s->cx^8;284 GrRect(dc,i-2,j-1,5,3);285 286 dc->color=s->cy;287 GrPrint(dc,c->left+2*VIEWANGLES_SPACING+1-FONT_WIDTH/2,288 c->top+VIEWANGLES_SPACING-(1+FONT_HEIGHT),"Y");289 GrPrint(dc,c->left+2*VIEWANGLES_SPACING+1-3*FONT_WIDTH/2,290 c->top+VIEWANGLES_SPACING+VIEWANGLES_RANGE+3,291 "%3d",s->sy*360/VIEWANGLES_RANGE);292 i=c->left+2*VIEWANGLES_SPACING+1;293 if (s->sy>VIEWANGLES_RANGE/2)294 j=-VIEWANGLES_RANGE/2+s->sy;295 else296 j=s->sy+VIEWANGLES_RANGE/2;297 j=c->top+VIEWANGLES_SPACING+VIEWANGLES_RANGE-1-j;298 GrRect(dc,i-3,j-2,7,5);299 dc->color=s->cy^8;300 GrRect(dc,i-2,j-1,5,3);301 302 dc->color=s->cz;303 GrPrint(dc,c->left+3*VIEWANGLES_SPACING+2-FONT_WIDTH/2,304 c->top+VIEWANGLES_SPACING-(1+FONT_HEIGHT),"Z");305 GrPrint(dc,c->left+3*VIEWANGLES_SPACING+2-3*FONT_WIDTH/2,306 c->top+VIEWANGLES_SPACING+VIEWANGLES_RANGE+3,307 "%3d",s->sz*360/VIEWANGLES_RANGE);308 i=c->left+3*VIEWANGLES_SPACING+2;309 if (s->sz>VIEWANGLES_RANGE/2)310 j=-VIEWANGLES_RANGE/2+s->sz;311 else312 j=s->sz+VIEWANGLES_RANGE/2;313 j=c->top+VIEWANGLES_SPACING+VIEWANGLES_RANGE-1-j;314 GrRect(dc,i-3,j-2,7,5);315 dc->color=s->cz^8;316 GrRect(dc,i-2,j-1,5,3);317}318 319U0 UpdateDerivedViewAnglesCtrl(CCtrl *c)320{321 CViewAngles *s=c->state;322 c->left=c->win_task->pix_width-(VIEWANGLES_SPACING*4+3);323 c->right=c->left+VIEWANGLES_SPACING*4+3;324 c->top=c->win_task->pix_height-(VIEWANGLES_SPACING*2+VIEWANGLES_RANGE);325 c->bottom=c->top+VIEWANGLES_SPACING*2+VIEWANGLES_RANGE;326 s->sx=ClampI64(RoundI64(s->sx,VIEWANGLES_SNAP),0,VIEWANGLES_RANGE-1);327 s->sy=ClampI64(RoundI64(s->sy,VIEWANGLES_SNAP),0,VIEWANGLES_RANGE-1);328 s->sz=ClampI64(RoundI64(s->sz,VIEWANGLES_SNAP),0,VIEWANGLES_RANGE-1);329 s->ax=2*pi*s->sx/VIEWANGLES_RANGE;330 s->ay=2*pi*s->sy/VIEWANGLES_RANGE;331 s->az=2*pi*s->sz/VIEWANGLES_RANGE;332}333 334U0 LeftClickViewAngles(CCtrl *c,I64 x,I64 y,Bool)335{336 CViewAngles *s=c->state;337 I64 i;338 i=VIEWANGLES_RANGE-1-(y-(c->top+VIEWANGLES_SPACING));339 if (i>=VIEWANGLES_RANGE/2)340 i-=VIEWANGLES_RANGE/2;341 else342 i+=VIEWANGLES_RANGE/2;343 if (x<c->left+(c->right-c->left)/3)344 s->sx=i;345 else if (x<c->left+2*(c->right-c->left)/3)346 s->sy=i;347 else348 s->sz=i;349 if (c->update_derived_vals)350 (*c->update_derived_vals)(c);351}352 353public CCtrl *ViewAnglesNew(CTask *task=NULL)354{//Create view angle ctrl. See ::/Demo/Graphics/Shading.HC.355 CCtrl *c;356 CViewAngles *s;357 if (!task) task=Fs;358 if (!(c=CtrlFindUnique(task,CTRLT_VIEWING_ANGLES))) {359 s=CAlloc(sizeof(CViewAngles),task);360 c=CAlloc(sizeof(CCtrl));361 s->cbd=BLUE;362 s->cbg=LTBLUE;363 s->cfg=BLACK;364 s->cx=LTGREEN;365 s->cy=GREEN;366 s->cz=LTGREEN;367 c->win_task=task;368 c->flags=CTRLF_SHOW|CTRLF_CAPTURE_LEFT_MS;369 c->type=CTRLT_VIEWING_ANGLES;370 c->state=s;371 c->draw_it=&DrawViewAnglesCtrl;372 c->left_click=&LeftClickViewAngles;373 c->update_derived_vals=&UpdateDerivedViewAnglesCtrl;374 QueIns(c,task->last_ctrl);375 TaskDerivedValsUpdate(task);376 }377 return c;378}379 380public U0 ViewAnglesDel(CTask *task=NULL)381{//Free view angle ctrl.382 CCtrl *c;383 if (!task) task=Fs;384 if (c=CtrlFindUnique(task,CTRLT_VIEWING_ANGLES)) {385 QueRem(c);386 Free(c->state);387 Free(c);388 }389}390 