Updated Anchors features (read description)

Anchors controls have been updated, updated anchors' save and load
-WIP-, adapted anchors linking for all controls.
This commit is contained in:
Ray San
2018-02-28 13:59:29 +01:00
parent af61279375
commit 757bfc1fdc

View File

@ -69,7 +69,6 @@ typedef struct {
int type;
Rectangle rec;
char text[32];
//int anchorId;
AnchorPoint *ap;
} GuiControl;
@ -394,6 +393,14 @@ int main()
controlsCounter--;
selectedControl = -1;
}
// Unlinks the control selected from its current anchor
if(IsKeyPressed(KEY_R))
{
layout[selectedControl].rec.x += layout[selectedControl].ap->x;
layout[selectedControl].rec.y += layout[selectedControl].ap->y;
layout[selectedControl].ap = &anchors[0];
}
}
else
{
@ -505,7 +512,25 @@ int main()
lockMode = false;
}
// Create anchor points
// Checks if mouse is over an anchor
for (int i = 1; i < MAX_ANCHOR_POINTS; i++)
{
if (anchorLinkMode || controlDrag) break;
if (CheckCollisionPointCircle(GetMousePosition(), (Vector2){ anchors[i].x, anchors[i].y }, anchors[i].radius))
{
selectedAnchor = i;
anchorMode = true;
break;
}
else
{
selectedAnchor = -1;
if (!IsKeyDown(KEY_A)) anchorMode = false;
}
}
// Create and edit anchor points
if (anchorMode)
{
// On mouse click anchor is created
@ -518,23 +543,12 @@ int main()
anchors[i].x = mouseX;
anchors[i].y = mouseY;
anchors[i].enabled = true;
anchorMode = false;
break;
}
}
}
for (int i = 1; i < MAX_ANCHOR_POINTS; i++)
{
if (anchorLinkMode || controlDrag) break;
if (CheckCollisionPointCircle(GetMousePosition(), (Vector2){ anchors[i].x, anchors[i].y }, anchors[i].radius))
{
selectedAnchor = i;
break;
}
else selectedAnchor = -1;
}
if (selectedAnchor > 0)
{
// Unlinks and deletes the selected anchor point
@ -551,30 +565,36 @@ int main()
}
anchors[selectedAnchor].x = 0;
anchors[selectedAnchor].y = 0;
anchors[selectedAnchor].enabled = false;
anchors[selectedAnchor].enabled = false;
anchorMode = false;
}
if (IsMouseButtonPressed(MOUSE_RIGHT_BUTTON)) controlDrag = true;
// Allows to drag an anchor without losing collision
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) controlDrag = true;
if (IsMouseButtonReleased(MOUSE_RIGHT_BUTTON))
if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON))
{
controlDrag = false;
selectedAnchor = -1;
anchorMode = false;
}
// Moves the anchor to the mouse position
if (controlDrag)
{
anchors[selectedAnchor].x = mouseX;
anchors[selectedAnchor].y = mouseY;
}
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
// Enables the linking between anchor and control
if (IsMouseButtonPressed(MOUSE_RIGHT_BUTTON))
{
linkedAnchor = selectedAnchor;
anchorLinkMode = true;
}
if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON))
// Links the selected control to the current anchor
if (IsMouseButtonReleased(MOUSE_RIGHT_BUTTON))
{
if (selectedControl != -1 && !lockMode /*&& (layout[selectedControl].ap != &anchors[linkedAnchor])*/)
{
@ -584,17 +604,17 @@ int main()
layout[selectedControl].rec.x -= anchors[linkedAnchor].x;
layout[selectedControl].rec.y -= anchors[linkedAnchor].y;
}
anchorLinkMode = false;
anchorLinkMode = false;
anchorMode = false;
}
}
}
// Enable anchor mode editing
if (IsKeyPressed(KEY_A) && !textEditMode && (layout[selectedControl].type != TEXTBOX) && !anchorMode) anchorMode = true;
else if (IsKeyPressed(KEY_A) && !textEditMode && (layout[selectedControl].type != TEXTBOX) && anchorMode) anchorMode = false;
if (IsKeyDown(KEY_A) && !textEditMode && (layout[selectedControl].type != TEXTBOX)) anchorMode = true;
// Checks the minimum size of the rec
if (selectedControl != -1)
{
@ -617,11 +637,6 @@ int main()
else if (layout[selectedControl].rec.height <= 20) layout[selectedControl].rec.height = 20;
}
// TODO: If mouse over anchor (define default bounds) and click, start anchor line
// TODO: On mouse up over an existing control, anchor is created (draw line for reference)
// TODO: On anchor line created, control (x, y) will be (x - ap, y - ap), and anchorId will be saved
// TODO: When create new anchor (anchorId++)
// TODO: if (IsKeyPressed(KEY_R)) remove control anchors (reset)
// TODO: Draw global app screen limits (black rectangle with black default anchor)
@ -644,7 +659,7 @@ int main()
if (fileName != NULL)
{
// Save layout file (text or binary)
SaveLayoutRGL("test_layout.rgl", false);
SaveLayoutRGL("test_layout.rgl", true);
fileName = "";
}
}
@ -697,24 +712,24 @@ int main()
// Draws the Controls when placed on the grid.
switch (layout[i].type)
{
case LABEL: GuiLabel(layout[i].rec, layout[i].text); break;
case LABEL: GuiLabel((Rectangle){ layout[i].ap->x + layout[i].rec.x, layout[i].ap->y + layout[i].rec.y, layout[i].rec.width, layout[i].rec.height }, layout[i].text); break;
case BUTTON: GuiButton((Rectangle){ layout[i].ap->x + layout[i].rec.x, layout[i].ap->y + layout[i].rec.y, layout[i].rec.width, layout[i].rec.height }, layout[i].text); break;
case IMAGEBUTTON: GuiImageButtonEx(layout[i].rec, texture, (Rectangle){ 0, 0, texture.width/3, texture.height/6 }, layout[i].text); break;
case TOGGLE: GuiToggleButton(layout[i].rec, layout[i].text, false); break;
case TOGGLEGROUP: GuiToggleGroup(layout[i].rec, list, 3, 1); break;
case SLIDER: GuiSlider(layout[i].rec, 40, 0, 100); break;
case SLIDERBAR: GuiSliderBar(layout[i].rec, 40, 0, 100); break;
case PROGRESSBAR: GuiProgressBar(layout[i].rec, 40, 0, 100); break;
case SPINNER: GuiSpinner(layout[i].rec, 40, 0, 100); break;
case COMBOBOX: GuiComboBox(layout[i].rec, list, 3, 1); break;
case CHECKBOX: GuiCheckBox(layout[i].rec, false); break;
case TEXTBOX: GuiTextBox(layout[i].rec, layout[i].text, 32); break;
case LISTVIEW: GuiListView(layout[i].rec, guiControls, 14, 1); break;
case COLORPICKER: GuiColorPicker(layout[i].rec, RED); break;
case IMAGEBUTTON: GuiImageButtonEx((Rectangle){ layout[i].ap->x + layout[i].rec.x, layout[i].ap->y + layout[i].rec.y, layout[i].rec.width, layout[i].rec.height }, texture, (Rectangle){ 0, 0, texture.width/3, texture.height/6 }, layout[i].text); break;
case TOGGLE: GuiToggleButton((Rectangle){ layout[i].ap->x + layout[i].rec.x, layout[i].ap->y + layout[i].rec.y, layout[i].rec.width, layout[i].rec.height }, layout[i].text, false); break;
case TOGGLEGROUP: GuiToggleGroup((Rectangle){ layout[i].ap->x + layout[i].rec.x, layout[i].ap->y + layout[i].rec.y, layout[i].rec.width, layout[i].rec.height }, list, 3, 1); break;
case SLIDER: GuiSlider((Rectangle){ layout[i].ap->x + layout[i].rec.x, layout[i].ap->y + layout[i].rec.y, layout[i].rec.width, layout[i].rec.height }, 40, 0, 100); break;
case SLIDERBAR: GuiSliderBar((Rectangle){ layout[i].ap->x + layout[i].rec.x, layout[i].ap->y + layout[i].rec.y, layout[i].rec.width, layout[i].rec.height }, 40, 0, 100); break;
case PROGRESSBAR: GuiProgressBar((Rectangle){ layout[i].ap->x + layout[i].rec.x, layout[i].ap->y + layout[i].rec.y, layout[i].rec.width, layout[i].rec.height }, 40, 0, 100); break;
case SPINNER: GuiSpinner((Rectangle){ layout[i].ap->x + layout[i].rec.x, layout[i].ap->y + layout[i].rec.y, layout[i].rec.width, layout[i].rec.height }, 40, 0, 100); break;
case COMBOBOX: GuiComboBox((Rectangle){ layout[i].ap->x + layout[i].rec.x, layout[i].ap->y + layout[i].rec.y, layout[i].rec.width, layout[i].rec.height }, list, 3, 1); break;
case CHECKBOX: GuiCheckBox((Rectangle){ layout[i].ap->x + layout[i].rec.x, layout[i].ap->y + layout[i].rec.y, layout[i].rec.width, layout[i].rec.height }, false); break;
case TEXTBOX: GuiTextBox((Rectangle){ layout[i].ap->x + layout[i].rec.x, layout[i].ap->y + layout[i].rec.y, layout[i].rec.width, layout[i].rec.height }, layout[i].text, 32); break;
case LISTVIEW: GuiListView((Rectangle){ layout[i].ap->x + layout[i].rec.x, layout[i].ap->y + layout[i].rec.y, layout[i].rec.width, layout[i].rec.height }, guiControls, 14, 1); break;
case COLORPICKER: GuiColorPicker((Rectangle){ layout[i].ap->x + layout[i].rec.x, layout[i].ap->y + layout[i].rec.y, layout[i].rec.width, layout[i].rec.height }, RED); break;
default: break;
}
if (layout[i].ap->id > 0) DrawLine(layout[i].ap->x, layout[i].ap->y, layout[i].ap->x + layout[i].rec.x, layout[i].ap->y + layout[i].rec.y, RED);
if ((layout[i].ap->id == selectedAnchor) && (layout[i].ap->id > 0)) DrawLine(layout[i].ap->x, layout[i].ap->y, layout[i].ap->x + layout[i].rec.x, layout[i].ap->y + layout[i].rec.y, RED);
// Draw Control anchor information
// DrawText(FormatText("Id: %i | X: %i | Y: %i | Enabled: %i", layout[0].ap->id, layout[0].ap->x, layout[0].ap->y, layout[0].ap->enabled), 100, 100, style[DEFAULT_TEXT_SIZE], RED);
}
@ -728,26 +743,35 @@ int main()
DrawRectangleRec(listViewControlsCounter, Fade(WHITE, 0.7f));
GuiListView(listViewControlsCounter, guiControlsCounter, controlsCounter, selectedControl);
// Draw the global anchors
//DrawRectangleRec(anchors[0].bounds, Fade(BLACK, 0.5f));
//DrawLine(anchors[0].position.x - 15, anchors[0].position.y, anchors[0].position.x + 15, anchors[0].position.y, BLACK);
//DrawLine(anchors[0].position.x, anchors[0].position.y - 15, anchors[0].position.x, anchors[0].position.y + 15, BLACK);
// Draw the anchorPoints
for (int i = 1; i < MAX_ANCHOR_POINTS; i++)
{
if (anchors[i].id == selectedAnchor) DrawCircle(anchors[i].x, anchors[i].y, anchors[i].radius, Fade(RED, 0.5f));
else DrawCircleLines(anchors[i].x, anchors[i].y, anchors[i].radius, Fade(RED, 0.5f));
DrawLine(anchors[i].x - anchors[i].radius - 5, anchors[i].y, anchors[i].x + anchors[i].radius + 5, anchors[i].y, RED);
DrawLine(anchors[i].x, anchors[i].y - anchors[i].radius - 5, anchors[i].x, anchors[i].y + anchors[i].radius + 5, RED);
DrawRectangle(anchors[i].x - anchors[i].radius - 5, anchors[i].y, anchors[i].radius*2 + 10, 1, RED);
DrawRectangle(anchors[i].x, anchors[i].y - anchors[i].radius - 5, 1, anchors[i].radius*2 + 10, RED);
}
if ((selectedControl != -1) && (selectedControl < controlsCounter)) DrawRectangleRec((Rectangle){ layout[selectedControl].ap->x + layout[selectedControl].rec.x, layout[selectedControl].ap->y + layout[selectedControl].rec.y, layout[selectedControl].rec.width, layout[selectedControl].rec.height }, Fade(RED, 0.5f));
if ((selectedControl != -1) && (selectedControl < controlsCounter))
{
DrawRectangleRec((Rectangle){ layout[selectedControl].ap->x + layout[selectedControl].rec.x, layout[selectedControl].ap->y + layout[selectedControl].rec.y, layout[selectedControl].rec.width, layout[selectedControl].rec.height }, Fade(RED, 0.5f));
if (layout[selectedControl].ap->id > 0) DrawLine(layout[selectedControl].ap->x, layout[selectedControl].ap->y, layout[selectedControl].ap->x + layout[selectedControl].rec.x, layout[selectedControl].ap->y + layout[selectedControl].rec.y, RED);
}
if (selectedControl == -1)
{
DrawRectangle(mouseX - 8, mouseY, 17, 1, RED);
DrawRectangle(mouseX, mouseY - 8, 1, 17, RED);
if (anchorMode)
{
DrawCircleLines(mouseX, mouseY, anchors[0].radius, Fade(RED, 0.5f));
DrawRectangle(mouseX - anchors[0].radius - 5, mouseY, anchors[0].radius*2 + 10, 1, RED);
DrawRectangle(mouseX, mouseY - anchors[0].radius - 5, 1, anchors[0].radius*2 + 10, RED);
}
else
{
DrawRectangle(mouseX - 8, mouseY, 17, 1, RED);
DrawRectangle(mouseX, mouseY - 8, 1, 17, RED);
}
}
// Draws the cursor of textEditMode
@ -857,16 +881,37 @@ static void SaveLayoutRGL(const char *fileName, bool binary)
fwrite(&numControls, 1, sizeof(short), rglFile);
fwrite(&reserved, 1, sizeof(int), rglFile);
// Export anchors data
for (int i = 0; i < MAX_ANCHOR_POINTS; i++)
{
fwrite(&anchors[i].id, 1, sizeof(int), rglFile);
fwrite(&anchors[i].x, 1, sizeof(int), rglFile);
fwrite(&anchors[i].y, 1, sizeof(int), rglFile);
fwrite(&anchors[i].radius, 1, sizeof(float), rglFile);
}
for (int i = 0; i < controlsCounter; i++)
{
// TODO: Export data in independent way
fwrite(&layout[i], 1, sizeof(GuiControl), rglFile);
// TODO: Export anchor id and position
// Export data in independent way
printf("Writing %i\n", i);
printf("Id: %i\n", layout[i].id);
printf("Type: %i\n", layout[i].type);
printf("X: %i\n", layout[i].rec.x);
printf("Y: %i\n", layout[i].rec.y);
printf("Width: %i\n", layout[i].rec.width);
printf("Height: %i\n", layout[i].rec.height);
//printf("Text: %s\n", layout[i].text);
fwrite(&layout[i].id, 1, sizeof(int), rglFile);
fwrite(&layout[i].type, 1, sizeof(int), rglFile);
fwrite(&layout[i].rec.x, 1, sizeof(int), rglFile);
fwrite(&layout[i].rec.y, 1, sizeof(int), rglFile);
fwrite(&layout[i].rec.width, 1, sizeof(int), rglFile);
fwrite(&layout[i].rec.height, 1, sizeof(int), rglFile);
//fwrite(layout[i].text, 1, 32, rglFile);
}
fclose(rglFile);
}
}
else
{
@ -883,11 +928,6 @@ static void SaveLayoutRGL(const char *fileName, bool binary)
for (int i = 0; i < controlsCounter; i++)
{
// fprintf(rglFile, "Control %03i : %s\n", layout[i].id, controlTypeName[layout[i].type]);
// fprintf(rglFile, "Rec %i %i %i %i\n", layout[i].rec.x, layout[i].rec.y, layout[i].rec.width, layout[i].rec.height);
// fprintf(rglFile, "Text %s\n", layout[i].text);
// fprintf(rglFile, "Anchor Id %i\n\n", layout[i].anchorId);
fprintf(rglFile, "c %03i %i %i %i %i %i %i %s\n", layout[i].id, layout[i].type, layout[i].rec.x, layout[i].rec.y, layout[i].rec.width, layout[i].rec.height, 0, layout[i].text);
}
@ -941,6 +981,7 @@ static void LoadLayoutRGL(const char *fileName)
char signature[5] = "";
short version = 0;
int reserved = 0;
int counter = 0;
fread(signature, 1, 4, rglFile);
fread(&version, 1, sizeof(short), rglFile);
@ -952,9 +993,61 @@ static void LoadLayoutRGL(const char *fileName)
(signature[2] == 'L') &&
(signature[3] == ' '))
{
// Import anchors data
for (int i = 0; i < MAX_ANCHOR_POINTS; i++)
{
fread(&anchors[i].id, 1, sizeof(int), rglFile);
fread(&anchors[i].x, 1, sizeof(int), rglFile);
fread(&anchors[i].y, 1, sizeof(int), rglFile);
fread(&anchors[i].radius, 1, sizeof(float), rglFile);
}
while (!feof(rglFile))
{
for (int i = 0; i < controlsCounter; i++) fread(&layout[i], 1, sizeof(GuiControl), rglFile);
/*for (int i = 0; i < controlsCounter; i++)
{
// Import data in independent way
fread(&layout[i].id, 1, sizeof(int), rglFile);
fread(&layout[i].type, 1, sizeof(int), rglFile);
fread(&layout[i].rec.x, 1, sizeof(int), rglFile);
fread(&layout[i].rec.y, 1, sizeof(int), rglFile);
fread(&layout[i].rec.width, 1, sizeof(int), rglFile);
fread(&layout[i].rec.height, 1, sizeof(int), rglFile);
fread(layout[i].text, 1, 32, rglFile);
printf("Reading %i\n", i);
printf("Id: %i\n", layout[i].id);
printf("Type: %i\n", layout[i].type);
printf("X: %i\n", layout[i].rec.x);
printf("Y: %i\n", layout[i].rec.y);
printf("Width: %i\n", layout[i].rec.width);
printf("Height: %i\n", layout[i].rec.height);
printf("Text: %s\n", layout[i].text);
// Import anchor id and position
// fread(&layout[i].ap->id, 1, sizeof(int), rglFile);
// fread(&layout[i].ap->x, 1, sizeof(int), rglFile);
// fread(&layout[i].ap->y, 1, sizeof(int), rglFile);
}*/
if (counter < controlsCounter)
{
fread(&layout[counter].id, 1, sizeof(int), rglFile);
fread(&layout[counter].type, 1, sizeof(int), rglFile);
fread(&layout[counter].rec.x, 1, sizeof(int), rglFile);
fread(&layout[counter].rec.y, 1, sizeof(int), rglFile);
fread(&layout[counter].rec.width, 1, sizeof(int), rglFile);
fread(&layout[counter].rec.height, 1, sizeof(int), rglFile);
//fread(layout[counter].text, 1, 32, rglFile);
printf("Reading %i\n", counter);
printf("Id: %i\n", layout[counter].id);
printf("Type: %i\n", layout[counter].type);
printf("X: %i\n", layout[counter].rec.x);
printf("Y: %i\n", layout[counter].rec.y);
printf("Width: %i\n", layout[counter].rec.width);
printf("Height: %i\n", layout[counter].rec.height);
//printf("Text: %s\n", layout[counter].text);
counter++;
}
else break;
}
}
else TraceLog(LOG_WARNING, "[raygui] Invalid layout file");
@ -1097,4 +1190,4 @@ static void GenerateLayoutCode(const char *fileName)
fprintf(ftool, "static void Button%03i()\n{\n // TODO: Implement control logic\n}\n\n", i);
fclose(ftool);
}
}