5 public struct AnchorValue
16 set { distance = value; type = offset; }
17 get { return distance; }
21 set { distance = value; type = offset; }
22 get { return distance; }
26 set { percent = (float) value; type = relative; }
27 get { return (double) percent; }
30 const char * OnGetString(char * stringOutput, void * fieldData, bool * needClass)
34 sprintf(stringOutput, "%d", distance);
36 else if(type == relative)
40 sprintf(stringOutput, "%f", percent);
41 c = strlen(stringOutput)-1;
44 if(stringOutput[c] != '0')
46 if(stringOutput[c] == '.')
50 stringOutput[c+1] = '0';
51 stringOutput[c+2] = 0;
54 stringOutput[last+1] = 0;
59 if(needClass) *needClass = false;
63 bool OnGetDataFromString(const char * stringOutput)
66 if(strchr(stringOutput, '.'))
68 float percent = (float)strtod(stringOutput, &end);
70 if(end != stringOutput)
72 this.percent = percent;
77 else if(stringOutput[0])
79 int distance = strtol(stringOutput, &end, 0);
80 if(end != stringOutput)
82 this.distance = distance;
97 public struct MiddleAnchorValue
108 set { distance = value; type = none; }
109 get { return distance; }
113 set { distance = value; type = none; }
114 get { return distance; }
118 set { percent = (float) value; type = middleRelative; }
119 get { return (double) percent; }
122 const char * OnGetString(char * stringOutput, void * fieldData, bool * needClass)
124 if(type == middleRelative)
128 sprintf(stringOutput, "%f", percent);
129 c = strlen(stringOutput)-1;
132 if(stringOutput[c] != '0')
134 if(stringOutput[c] == '.')
138 stringOutput[c+1] = '0';
139 stringOutput[c+2] = 0;
142 stringOutput[last+1] = 0;
147 else if(type == none && distance)
149 sprintf(stringOutput, "%d", distance);
151 if(needClass) *needClass = false;
155 bool OnGetDataFromString(const char * stringOutput)
157 if(strchr(stringOutput, '.'))
159 percent = (float)strtod(stringOutput, null);
160 type = middleRelative;
164 distance = strtol(stringOutput, null, 0);
171 public enum AnchorValueType { none, offset, relative, middleRelative, cascade, vTiled, hTiled };
175 union { AnchorValue left; MiddleAnchorValue horz; };
176 union { AnchorValue top; MiddleAnchorValue vert; };
177 AnchorValue right, bottom;
179 const char * OnGetString(char * stringOutput, void * fieldData, bool * needClass)
181 char tempString[256];
182 const char * anchorValue;
186 tempString[0] = '\0';
187 anchorValue = left.OnGetString(tempString, null, &subNeedClass);
188 if(anchorValue[0]) { if(stringOutput[0]) strcat(stringOutput, ", "); strcat(stringOutput, "left = "); strcat(stringOutput, anchorValue); }
190 //if(((!left.type && !right.type) && horz.distance) || horz.type == middleRelative)
191 if(!right.type && ((!left.type && horz.distance) || horz.type == middleRelative))
193 tempString[0] = '\0';
194 anchorValue = horz.OnGetString(tempString, null, &subNeedClass);
195 if(anchorValue[0]) { if(stringOutput[0]) strcat(stringOutput, ", "); strcat(stringOutput, "horz = "); strcat(stringOutput, anchorValue); }
198 tempString[0] = '\0';
199 anchorValue = top.OnGetString(tempString, null, &subNeedClass);
200 if(anchorValue[0]) { if(stringOutput[0]) strcat(stringOutput, ", "); strcat(stringOutput, "top = "); strcat(stringOutput, anchorValue); }
202 tempString[0] = '\0';
203 anchorValue = right.OnGetString(tempString, null, &subNeedClass);
204 if(anchorValue[0]) { if(stringOutput[0]) strcat(stringOutput, ", "); strcat(stringOutput, "right = "); strcat(stringOutput, anchorValue); }
206 // if(((!top.type && !bottom.type) && vert.distance) || vert.type == middleRelative)
207 if(!bottom.type && ((!top.type && vert.distance) || vert.type == middleRelative))
209 tempString[0] = '\0';
210 anchorValue = vert.OnGetString(tempString, null, &subNeedClass);
211 if(anchorValue[0]) { if(stringOutput[0]) strcat(stringOutput, ", "); strcat(stringOutput, "vert = "); strcat(stringOutput, anchorValue); }
214 tempString[0] = '\0';
215 anchorValue = bottom.OnGetString(tempString, null, &subNeedClass);
216 if(anchorValue[0]) { if(stringOutput[0]) strcat(stringOutput, ", "); strcat(stringOutput, "bottom = "); strcat(stringOutput, anchorValue); }
221 bool OnGetDataFromString(const char * string)
224 return class::OnGetDataFromString(string);
227 bool OnSaveEdit(DropBox dropBox, void * object)
229 return dropBox.Save();
232 Window OnEdit(Window listBox, Window master, int x, int y, int w, int h, Window control)
234 const char * string = "";
235 AnchorDropBox comboBox
240 position = Point { x, y };
241 //clientSize = Size { h = h };
252 char tempString[MAX_F_STRING] = "";
253 bool needClass = false;
254 const char * result = OnGetString(tempString, null, &needClass);
255 if(result) string = result;
257 comboBox.contents = string;
262 private class AnchorButton : Button
264 toggle = true, bevel = false;
266 void OnRedraw(Surface surface)
268 int cw = clientSize.w;
269 int ch = clientSize.h;
271 surface.SetForeground(black);
274 surface.SetBackground(Color { 85,85,85 });
275 surface.Area(0,0, cw-1, ch-1);
278 surface.LineStipple(0xAAAA);
280 surface.Rectangle(0,0,cw-1,ch-1);
284 surface.LineStipple(0xAAAA);
285 surface.Rectangle(2,2,cw-3,ch-3);
289 bool AnchorEditor::NotifyClicked(Button button, int x, int y, Modifiers mods)
291 AnchorDropBox anchorDropBox = (AnchorDropBox)master;
292 Anchor anchor = anchorDropBox.anchorValue;
293 Window control = anchorDropBox.control;
294 DataBox dropMaster = (DataBox)anchorDropBox.master;
295 int64 id = button.id;
299 case 0: anchor.left.type = button.checked ? offset : none; break;
300 case 1: anchor.top.type = button.checked ? offset : none; break;
301 case 2: anchor.right.type = button.checked ? offset : none; break;
302 case 3: anchor.bottom.type = button.checked ? offset : none; break;
305 if(anchor.horz.type == middleRelative && (id == 0 || id == 2))
307 anchorDropBox.relButtons[0].checked = false;
308 anchorDropBox.relButtons[2].checked = false;
310 if(anchor.vert.type == middleRelative && (id == 1 || id == 3))
312 anchorDropBox.relButtons[1].checked = false;
313 anchorDropBox.relButtons[3].checked = false;
315 anchorDropBox.relButtons[id].checked = false;
317 //anchor.horz.type = none;
318 //anchor.vert.type = none;
323 Window parent = control.parent;
326 x = control.position.x;
327 y = control.position.y;
331 vpw = parent.clientSize.w;
332 vph = parent.clientSize.h;
333 if(control.nonClient)
338 else if(((BorderBits)control.borderStyle).fixed)
340 if(!control.dontScrollHorz && parent.scrollArea.w) vpw = parent.scrollArea.w;
341 if(!control.dontScrollVert && parent.scrollArea.h) vph = parent.scrollArea.h;
344 if(anchor.left.type == offset) anchor.left.distance = x;
345 else if(anchor.left.type == relative) anchor.left.percent = (float)x / vpw;
346 if(anchor.top.type == offset) anchor.top.distance = y;
347 else if(anchor.top.type == relative) anchor.top.percent = (float)y / vph;
348 if(anchor.right.type == offset) anchor.right.distance = vpw - (x + w);
349 //else if(anchor.right.type == relative) anchor.right.percent = (float) (x + w) / vpw;
350 else if(anchor.right.type == relative) anchor.right.percent = (float) (vpw - (x + w)) / vpw;
351 if(anchor.bottom.type == offset) anchor.bottom.distance = vph - (y + h);
352 //else if(anchor.bottom.type == relative) anchor.bottom.percent = (float) (y + h) / vph;
353 else if(anchor.bottom.type == relative) anchor.bottom.percent = (float) (vph - (y + h)) / vph;
355 if(!anchor.left.type && !anchor.right.type)
357 anchor.horz.distance = (x + w / 2) - (vpw / 2);
358 //anchor.horz.type = anchor.horz.distance ? offset : 0;
360 else if(anchor.horz.type == middleRelative) anchor.horz.percent = (float) ((x + w / 2) - (vpw / 2)) / vpw;
361 if(!anchor.top.type && !anchor.bottom.type)
363 anchor.vert.distance = (y + h / 2) - (vph / 2);
364 //anchor.vert.type = anchor.vert.distance ? offset : 0;
366 else if(anchor.vert.type == middleRelative) anchor.vert.percent = (float)((y + h / 2) - (vph / 2)) / vph;
370 char tempString[1024] = "";
371 bool needClass = false;
372 const char * string = anchor.OnGetString(tempString, null, &needClass);
373 anchorDropBox.contents = string;
376 dropMaster.SetData(&anchor, false);
377 anchorDropBox.anchorValue = anchor;
382 private class AnchorRelButton : Button
389 void OnRedraw(Surface surface)
391 int cw = clientSize.w;
392 int ch = clientSize.h;
396 surface.SetForeground(black);
400 surface.SetForeground(Color{170,170,170});
402 surface.WriteText(5,2, "%", 1);
406 surface.LineStipple(0xAAAA);
407 surface.Rectangle(3,3,cw-4,ch-4);
411 bool AnchorEditor::NotifyClicked(Button button, int x, int y, Modifiers mods)
413 AnchorDropBox anchorDropBox = (AnchorDropBox)master;
414 Anchor anchor = anchorDropBox.anchorValue;
415 Window control = anchorDropBox.control;
416 DataBox dropMaster = (DataBox)anchorDropBox.master;
417 int64 id = button.id;
419 if((id == 0 || id == 2) && ((!anchor.left.type && !anchor.right.type) || anchor.left.type == middleRelative))
421 if(button.checked) anchor.horz.type = middleRelative; else anchor.horz.type = none;
422 anchorDropBox.relButtons[(id + 2)%4].checked = button.checked;
424 else if((id == 1 || id == 3) && ((!anchor.top.type && !anchor.bottom.type) || anchor.top.type == middleRelative))
426 if(button.checked) anchor.vert.type = middleRelative; else anchor.vert.type = none;
427 anchorDropBox.relButtons[(id + 2)%4].checked = button.checked;
433 case 0: anchor.left.type = button.checked ? relative : (anchor.left.type ? offset : none); break;
434 case 1: anchor.top.type = button.checked ? relative : (anchor.top.type ? offset : none); break;
435 case 2: anchor.right.type = button.checked ? relative : (anchor.right.type ? offset : none); break;
436 case 3: anchor.bottom.type = button.checked ? relative : (anchor.bottom.type ? offset : none); break;
438 anchorDropBox.buttons[id].checked = true;
439 if(anchor.horz.type == middleRelative) anchor.horz.type = none;
440 if(anchor.vert.type == middleRelative) anchor.vert.type = none;
446 Window parent = control.parent;
449 x = control.position.x;
450 y = control.position.y;
454 vpw = parent.clientSize.w;
455 vph = parent.clientSize.h;
456 if(control.nonClient)
461 else if(((BorderBits)control.borderStyle).fixed)
463 if(!control.dontScrollHorz && parent.scrollArea.w) vpw = parent.scrollArea.w;
464 if(!control.dontScrollVert && parent.scrollArea.h) vph = parent.scrollArea.h;
467 if(anchor.left.type == offset) anchor.left.distance = x;
468 else if(anchor.left.type == relative) anchor.left.percent = (float)x / vpw;
469 if(anchor.top.type == offset) anchor.top.distance = y;
470 else if(anchor.top.type == relative) anchor.top.percent = (float)y / vph;
471 if(anchor.right.type == offset) anchor.right.distance = vpw - (x + w);
472 //else if(anchor.right.type == relative) anchor.right.percent = (float) (x + w) / vpw;
473 else if(anchor.right.type == relative) anchor.right.percent = (float) (vpw - (x + w)) / vpw;
474 if(anchor.bottom.type == offset) anchor.bottom.distance = vph - (y + h);
475 //else if(anchor.bottom.type == relative) anchor.bottom.percent = (float) (y + h) / vph;
476 else if(anchor.bottom.type == relative) anchor.bottom.percent = (float) (vph - (y + h)) / vph;
478 if(!anchor.left.type && !anchor.right.type)
480 anchor.horz.distance = (x + w / 2) - (vpw / 2);
481 //anchor.horz.type = anchor.horz.distance ? offset : none;
483 else if(anchor.horz.type == middleRelative) anchor.horz.percent = (float) ((x + w / 2) - (vpw / 2)) / vpw;
484 if(!anchor.top.type && !anchor.bottom.type)
486 anchor.vert.distance = (y + h / 2) - (vph / 2);
487 //anchor.vert.type = anchor.vert.distance ? offset : none;
489 else if(anchor.vert.type == middleRelative) anchor.vert.percent = (float)((y + h / 2) - (vph / 2)) / vph;
493 char tempString[1024] = "";
494 bool needClass = false;
495 const char * string = anchor.OnGetString(tempString, null, &needClass);
496 anchorDropBox.contents = string;
499 dropMaster.SetData(&anchor, false);
500 anchorDropBox.anchorValue = anchor;
505 private class AnchorEditor : Window
508 borderStyle = deepContour;
511 bool OnKeyDown(Key key, unichar ch)
514 return master.OnKeyDown(key, ch);
519 private class AnchorDropBox : DropBox
523 Button relButtons[4], buttons[4];
525 AnchorEditor anchorEditor
537 anchor = Anchor { left = 28, top = 28, right = 28, bottom = 28 },
538 inactive = true, disabled = true
542 Button button = buttons[c] = AnchorButton
544 anchorEditor, id = c,
545 size = Size { (c%2)?10:28, (c%2)?28:10 }
547 Button relButton = relButtons[c] = AnchorRelButton
549 anchorEditor, id = c;
555 if(anchorValue.left.type && anchorValue.left.type != middleRelative) button.checked = true;
556 if(anchorValue.left.type == relative || anchorValue.horz.type == middleRelative) relButton.checked = true;
558 button.anchor = Anchor { left = 0 };
559 relButton.anchor = Anchor { left = 5, vert = 16 };
562 if(anchorValue.top.type && anchorValue.top.type != middleRelative) button.checked = true;
563 if(anchorValue.top.type == relative || anchorValue.vert.type == middleRelative) relButton.checked = true;
565 button.anchor = Anchor { top = 0 };
566 relButton.anchor = Anchor { top = 5, horz = 16 };
569 if(anchorValue.right.type && anchorValue.right.type != middleRelative) button.checked = true;
570 if(anchorValue.right.type == relative || anchorValue.horz.type == middleRelative) relButton.checked = true;
572 button.anchor = Anchor { right = 0 };
573 relButton.anchor = Anchor { right = 5, vert = 16 };
576 if(anchorValue.bottom.type && anchorValue.bottom.type != middleRelative) button.checked = true;
577 if(anchorValue.bottom.type == relative || anchorValue.vert.type == middleRelative) relButton.checked = true;
579 button.anchor = Anchor { bottom = 0 };
580 relButton.anchor = Anchor { bottom = 5, horz = 16 };
584 anchorEditor.Create();
588 void OnCloseDropDown(Window anchorEditor)
590 // TOFIX: Patch for update bug
592 anchorEditor.Destroy(0);
595 bool DataBox::NotifyTextEntry(AnchorDropBox dropBox, const char * string, bool save)
597 Anchor anchor = dropBox.anchorValue;
601 if(anchor.OnGetDataFromString(string))
603 SetData(&anchor, false);
604 dropBox.anchorValue = anchor;
609 char tempString[1024] = "";
610 bool needClass = false;
611 const char * string = anchor.OnGetString(tempString, null, &needClass);
612 dropBox.contents = string;