5 public struct AnchorValue
16 set { distance = value; type = offset; }
17 get { return distance; }
21 set { percent = (float) value; type = relative; }
22 get { return (double) percent; }
25 char * OnGetString(char * stringOutput, void * fieldData, bool * needClass)
29 sprintf(stringOutput, "%d", distance);
31 else if(type == relative)
35 sprintf(stringOutput, "%f", percent);
36 c = strlen(stringOutput)-1;
39 if(stringOutput[c] != '0')
41 if(stringOutput[c] == '.')
45 stringOutput[c+1] = '0';
46 stringOutput[c+2] = 0;
49 stringOutput[last+1] = 0;
54 if(needClass) *needClass = false;
58 bool OnGetDataFromString(char * stringOutput)
61 if(strchr(stringOutput, '.'))
63 float percent = (float)strtod(stringOutput, &end);
65 if(end != stringOutput)
67 this.percent = percent;
72 else if(stringOutput[0])
74 int distance = strtol(stringOutput, &end, 0);
75 if(end != stringOutput)
77 this.distance = distance;
92 public struct MiddleAnchorValue
103 set { distance = value; type = none; }
104 get { return distance; }
108 set { percent = (float) value; type = middleRelative; }
109 get { return (double) percent; }
112 char * OnGetString(char * stringOutput, void * fieldData, bool * needClass)
114 if(type == middleRelative)
118 sprintf(stringOutput, "%f", percent);
119 c = strlen(stringOutput)-1;
122 if(stringOutput[c] != '0')
124 if(stringOutput[c] == '.')
128 stringOutput[c+1] = '0';
129 stringOutput[c+2] = 0;
132 stringOutput[last+1] = 0;
137 else if(type == none && distance)
139 sprintf(stringOutput, "%d", distance);
141 if(needClass) *needClass = false;
145 bool OnGetDataFromString(char * stringOutput)
147 if(strchr(stringOutput, '.'))
149 percent = (float)strtod(stringOutput, null);
150 type = middleRelative;
154 distance = strtol(stringOutput, null, 0);
161 public enum AnchorValueType { none, offset, relative, middleRelative, cascade, vTiled, hTiled };
165 union { AnchorValue left; MiddleAnchorValue horz; };
166 union { AnchorValue top; MiddleAnchorValue vert; };
167 AnchorValue right, bottom;
169 char * OnGetString(char * stringOutput, void * fieldData, bool * needClass)
171 char tempString[256];
175 tempString[0] = '\0';
176 anchorValue = left.OnGetString(tempString, null, &subNeedClass);
177 if(anchorValue[0]) { if(stringOutput[0]) strcat(stringOutput, ", "); strcat(stringOutput, "left = "); strcat(stringOutput, anchorValue); }
179 //if(((!left.type && !right.type) && horz.distance) || horz.type == middleRelative)
180 if(!right.type && ((!left.type && horz.distance) || horz.type == middleRelative))
182 tempString[0] = '\0';
183 anchorValue = horz.OnGetString(tempString, null, &subNeedClass);
184 if(anchorValue[0]) { if(stringOutput[0]) strcat(stringOutput, ", "); strcat(stringOutput, "horz = "); strcat(stringOutput, anchorValue); }
187 tempString[0] = '\0';
188 anchorValue = top.OnGetString(tempString, null, &subNeedClass);
189 if(anchorValue[0]) { if(stringOutput[0]) strcat(stringOutput, ", "); strcat(stringOutput, "top = "); strcat(stringOutput, anchorValue); }
191 tempString[0] = '\0';
192 anchorValue = right.OnGetString(tempString, null, &subNeedClass);
193 if(anchorValue[0]) { if(stringOutput[0]) strcat(stringOutput, ", "); strcat(stringOutput, "right = "); strcat(stringOutput, anchorValue); }
195 // if(((!top.type && !bottom.type) && vert.distance) || vert.type == middleRelative)
196 if(!bottom.type && ((!top.type && vert.distance) || vert.type == middleRelative))
198 tempString[0] = '\0';
199 anchorValue = vert.OnGetString(tempString, null, &subNeedClass);
200 if(anchorValue[0]) { if(stringOutput[0]) strcat(stringOutput, ", "); strcat(stringOutput, "vert = "); strcat(stringOutput, anchorValue); }
203 tempString[0] = '\0';
204 anchorValue = bottom.OnGetString(tempString, null, &subNeedClass);
205 if(anchorValue[0]) { if(stringOutput[0]) strcat(stringOutput, ", "); strcat(stringOutput, "bottom = "); strcat(stringOutput, anchorValue); }
210 bool OnGetDataFromString(char * string)
213 return class::OnGetDataFromString(string);
216 bool OnSaveEdit(DropBox dropBox, void * object)
218 return dropBox.Save();
221 Window OnEdit(Window listBox, Window master, int x, int y, int w, int h, Window control)
224 AnchorDropBox comboBox
229 position = Point { x, y };
230 //clientSize = Size { h = h };
241 char tempString[MAX_F_STRING] = "";
242 bool needClass = false;
243 char * result = OnGetString(tempString, null, &needClass);
244 if(result) string = result;
246 comboBox.contents = string;
251 private class AnchorButton : Button
253 toggle = true, bevel = false;
255 void OnRedraw(Surface surface)
257 int cw = clientSize.w;
258 int ch = clientSize.h;
260 surface.SetForeground(black);
263 surface.SetBackground(Color { 85,85,85 });
264 surface.Area(0,0, cw-1, ch-1);
267 surface.LineStipple(0xAAAA);
269 surface.Rectangle(0,0,cw-1,ch-1);
273 surface.LineStipple(0xAAAA);
274 surface.Rectangle(2,2,cw-3,ch-3);
278 bool AnchorEditor::NotifyClicked(Button button, int x, int y, Modifiers mods)
280 AnchorDropBox anchorDropBox = (AnchorDropBox)master;
281 Anchor anchor = anchorDropBox.anchorValue;
282 Window control = anchorDropBox.control;
283 DataBox dropMaster = (DataBox)anchorDropBox.master;
284 int64 id = button.id;
288 case 0: anchor.left.type = button.checked ? offset : none; break;
289 case 1: anchor.top.type = button.checked ? offset : none; break;
290 case 2: anchor.right.type = button.checked ? offset : none; break;
291 case 3: anchor.bottom.type = button.checked ? offset : none; break;
294 if(anchor.horz.type == middleRelative && (id == 0 || id == 2))
296 anchorDropBox.relButtons[0].checked = false;
297 anchorDropBox.relButtons[2].checked = false;
299 if(anchor.vert.type == middleRelative && (id == 1 || id == 3))
301 anchorDropBox.relButtons[1].checked = false;
302 anchorDropBox.relButtons[3].checked = false;
304 anchorDropBox.relButtons[id].checked = false;
306 //anchor.horz.type = none;
307 //anchor.vert.type = none;
312 Window parent = control.parent;
315 x = control.position.x;
316 y = control.position.y;
320 vpw = parent.clientSize.w;
321 vph = parent.clientSize.h;
322 if(control.nonClient)
327 else if(((BorderBits)control.borderStyle).fixed)
329 if(!control.dontScrollHorz && parent.scrollArea.w) vpw = parent.scrollArea.w;
330 if(!control.dontScrollVert && parent.scrollArea.h) vph = parent.scrollArea.h;
333 if(anchor.left.type == offset) anchor.left.distance = x;
334 else if(anchor.left.type == relative) anchor.left.percent = (float)x / vpw;
335 if(anchor.top.type == offset) anchor.top.distance = y;
336 else if(anchor.top.type == relative) anchor.top.percent = (float)y / vph;
337 if(anchor.right.type == offset) anchor.right.distance = vpw - (x + w);
338 //else if(anchor.right.type == relative) anchor.right.percent = (float) (x + w) / vpw;
339 else if(anchor.right.type == relative) anchor.right.percent = (float) (vpw - (x + w)) / vpw;
340 if(anchor.bottom.type == offset) anchor.bottom.distance = vph - (y + h);
341 //else if(anchor.bottom.type == relative) anchor.bottom.percent = (float) (y + h) / vph;
342 else if(anchor.bottom.type == relative) anchor.bottom.percent = (float) (vph - (y + h)) / vph;
344 if(!anchor.left.type && !anchor.right.type)
346 anchor.horz.distance = (x + w / 2) - (vpw / 2);
347 //anchor.horz.type = anchor.horz.distance ? offset : 0;
349 else if(anchor.horz.type == middleRelative) anchor.horz.percent = (float) ((x + w / 2) - (vpw / 2)) / vpw;
350 if(!anchor.top.type && !anchor.bottom.type)
352 anchor.vert.distance = (y + h / 2) - (vph / 2);
353 //anchor.vert.type = anchor.vert.distance ? offset : 0;
355 else if(anchor.vert.type == middleRelative) anchor.vert.percent = (float)((y + h / 2) - (vph / 2)) / vph;
359 char tempString[1024] = "";
360 bool needClass = false;
361 char * string = anchor.OnGetString(tempString, null, &needClass);
362 anchorDropBox.contents = string;
365 dropMaster.SetData(&anchor, false);
366 anchorDropBox.anchorValue = anchor;
371 private class AnchorRelButton : Button
378 void OnRedraw(Surface surface)
380 int cw = clientSize.w;
381 int ch = clientSize.h;
385 surface.SetForeground(black);
389 surface.SetForeground(Color{170,170,170});
391 surface.WriteText(5,2, "%", 1);
395 surface.LineStipple(0xAAAA);
396 surface.Rectangle(3,3,cw-4,ch-4);
400 bool AnchorEditor::NotifyClicked(Button button, int x, int y, Modifiers mods)
402 AnchorDropBox anchorDropBox = (AnchorDropBox)master;
403 Anchor anchor = anchorDropBox.anchorValue;
404 Window control = anchorDropBox.control;
405 DataBox dropMaster = (DataBox)anchorDropBox.master;
406 int64 id = button.id;
408 if((id == 0 || id == 2) && ((!anchor.left.type && !anchor.right.type) || anchor.left.type == middleRelative))
410 if(button.checked) anchor.horz.type = middleRelative; else anchor.horz.type = none;
411 anchorDropBox.relButtons[(id + 2)%4].checked = button.checked;
413 else if((id == 1 || id == 3) && ((!anchor.top.type && !anchor.bottom.type) || anchor.top.type == middleRelative))
415 if(button.checked) anchor.vert.type = middleRelative; else anchor.vert.type = none;
416 anchorDropBox.relButtons[(id + 2)%4].checked = button.checked;
422 case 0: anchor.left.type = button.checked ? relative : (anchor.left.type ? offset : none); break;
423 case 1: anchor.top.type = button.checked ? relative : (anchor.top.type ? offset : none); break;
424 case 2: anchor.right.type = button.checked ? relative : (anchor.right.type ? offset : none); break;
425 case 3: anchor.bottom.type = button.checked ? relative : (anchor.bottom.type ? offset : none); break;
427 anchorDropBox.buttons[id].checked = true;
428 if(anchor.horz.type == middleRelative) anchor.horz.type = none;
429 if(anchor.vert.type == middleRelative) anchor.vert.type = none;
435 Window parent = control.parent;
438 x = control.position.x;
439 y = control.position.y;
443 vpw = parent.clientSize.w;
444 vph = parent.clientSize.h;
445 if(control.nonClient)
450 else if(((BorderBits)control.borderStyle).fixed)
452 if(!control.dontScrollHorz && parent.scrollArea.w) vpw = parent.scrollArea.w;
453 if(!control.dontScrollVert && parent.scrollArea.h) vph = parent.scrollArea.h;
456 if(anchor.left.type == offset) anchor.left.distance = x;
457 else if(anchor.left.type == relative) anchor.left.percent = (float)x / vpw;
458 if(anchor.top.type == offset) anchor.top.distance = y;
459 else if(anchor.top.type == relative) anchor.top.percent = (float)y / vph;
460 if(anchor.right.type == offset) anchor.right.distance = vpw - (x + w);
461 //else if(anchor.right.type == relative) anchor.right.percent = (float) (x + w) / vpw;
462 else if(anchor.right.type == relative) anchor.right.percent = (float) (vpw - (x + w)) / vpw;
463 if(anchor.bottom.type == offset) anchor.bottom.distance = vph - (y + h);
464 //else if(anchor.bottom.type == relative) anchor.bottom.percent = (float) (y + h) / vph;
465 else if(anchor.bottom.type == relative) anchor.bottom.percent = (float) (vph - (y + h)) / vph;
467 if(!anchor.left.type && !anchor.right.type)
469 anchor.horz.distance = (x + w / 2) - (vpw / 2);
470 //anchor.horz.type = anchor.horz.distance ? offset : none;
472 else if(anchor.horz.type == middleRelative) anchor.horz.percent = (float) ((x + w / 2) - (vpw / 2)) / vpw;
473 if(!anchor.top.type && !anchor.bottom.type)
475 anchor.vert.distance = (y + h / 2) - (vph / 2);
476 //anchor.vert.type = anchor.vert.distance ? offset : none;
478 else if(anchor.vert.type == middleRelative) anchor.vert.percent = (float)((y + h / 2) - (vph / 2)) / vph;
482 char tempString[1024] = "";
483 bool needClass = false;
484 char * string = anchor.OnGetString(tempString, null, &needClass);
485 anchorDropBox.contents = string;
488 dropMaster.SetData(&anchor, false);
489 anchorDropBox.anchorValue = anchor;
494 private class AnchorEditor : Window
497 borderStyle = deepContour;
500 bool OnKeyDown(Key key, unichar ch)
503 return master.OnKeyDown(key, ch);
508 private class AnchorDropBox : DropBox
512 Button relButtons[4], buttons[4];
514 AnchorEditor anchorEditor
526 anchor = Anchor { left = 28, top = 28, right = 28, bottom = 28 },
527 inactive = true, disabled = true
531 Button button = buttons[c] = AnchorButton
533 anchorEditor, id = c,
534 size = Size { (c%2)?10:28, (c%2)?28:10 }
536 Button relButton = relButtons[c] = AnchorRelButton
538 anchorEditor, id = c;
544 if(anchorValue.left.type && anchorValue.left.type != middleRelative) button.checked = true;
545 if(anchorValue.left.type == relative || anchorValue.horz.type == middleRelative) relButton.checked = true;
547 button.anchor = Anchor { left = 0 };
548 relButton.anchor = Anchor { left = 5, vert = 16 };
551 if(anchorValue.top.type && anchorValue.top.type != middleRelative) button.checked = true;
552 if(anchorValue.top.type == relative || anchorValue.vert.type == middleRelative) relButton.checked = true;
554 button.anchor = Anchor { top = 0 };
555 relButton.anchor = Anchor { top = 5, horz = 16 };
558 if(anchorValue.right.type && anchorValue.right.type != middleRelative) button.checked = true;
559 if(anchorValue.right.type == relative || anchorValue.horz.type == middleRelative) relButton.checked = true;
561 button.anchor = Anchor { right = 0 };
562 relButton.anchor = Anchor { right = 5, vert = 16 };
565 if(anchorValue.bottom.type && anchorValue.bottom.type != middleRelative) button.checked = true;
566 if(anchorValue.bottom.type == relative || anchorValue.vert.type == middleRelative) relButton.checked = true;
568 button.anchor = Anchor { bottom = 0 };
569 relButton.anchor = Anchor { bottom = 5, horz = 16 };
573 anchorEditor.Create();
577 void OnCloseDropDown(Window anchorEditor)
579 // TOFIX: Patch for update bug
581 anchorEditor.Destroy(0);
584 bool DataBox::NotifyTextEntry(AnchorDropBox dropBox, char * string, bool save)
586 Anchor anchor = dropBox.anchorValue;
587 Window control = dropBox.control;
591 if(anchor.OnGetDataFromString(string))
593 SetData(&anchor, false);
594 dropBox.anchorValue = anchor;
599 char tempString[1024] = "";
600 bool needClass = false;
601 char * string = anchor.OnGetString(tempString, null, &needClass);
602 dropBox.contents = string;