Skip to content

Commit

Permalink
Included timeline and altered it
Browse files Browse the repository at this point in the history
  • Loading branch information
wtrsltnk committed Jan 16, 2019
1 parent 3fb98c6 commit 7fc9713
Show file tree
Hide file tree
Showing 3 changed files with 177 additions and 67 deletions.
46 changes: 33 additions & 13 deletions app.threedee/app.threedee.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@

#include "examples/imgui_impl_glfw.h"
#include "examples/imgui_impl_opengl3.h"
#include "imgui_addons/imgui_Timeline.h"
#include "imgui_addons/imgui_checkbutton.h"
#include "imgui_addons/imgui_knob.h"
#include "imgui_addons/imgui_Timeline.h"
#include "stb_image.h"
#include <algorithm>
#include <cmath>
Expand Down Expand Up @@ -128,6 +128,12 @@ void AppThreeDee::Tick()
_stepper.Tick();
}

struct timelineEvent
{
float values[2];
};

static std::vector<struct timelineEvent> values{{20.f, 40.f}, {15.f, 22.5f}};
void AppThreeDee::Render()
{
ImGui_ImplOpenGL3_NewFrame();
Expand Down Expand Up @@ -167,20 +173,34 @@ void AppThreeDee::Render()
}
ImGui::PopStyleVar();

static double time_in = 0.0;
static double time_out = 0.0;
if (ImGui::BeginTimeline("MyTimeline",50.f,4,6)) // label, max_value, num_visible_rows, opt_exact_num_rows (for item culling)
if (ImGui::BeginTimelines("MyTimeline", 50.f, 4, 6)) // label, max_value, num_visible_rows, opt_exact_num_rows (for item culling)
{
static float events[12]={10.f,20.f,0.5f,30.f,40.f,50.f,20.f,40.f,15.f,22.5f,35.f,45.f};
if (ImGui::TimelineEvent("Event1",&events[0])) {/*events[0] and/or events[1] modified*/}
ImGui::TimelineEvent("Event2",&events[2]);
ImGui::TimelineEvent("Event3",&events[4],true); // Event3 can only be shifted
ImGui::TimelineEvent("Event4",&events[6]);
ImGui::TimelineEvent("Event5",&events[8]);
ImGui::TimelineEvent("Event6",&events[10]);
static float events[12] = {10.f, 20.f, 0.5f, 30.f, 40.f, 50.f, 20.f, 40.f, 15.f, 22.5f, 35.f, 45.f};
if (ImGui::TimelineEvent("Event1", &events[0]))
{ /*events[0] and/or events[1] modified*/
}
ImGui::TimelineEvent("Event2", &events[2]);
ImGui::TimelineEvent("Event3", &events[4], true); // Event3 can only be shifted
ImGui::TimelineStart("Event4");
for (size_t i = 0; i < values.size(); i += 2)
{
ImGui::TimelineEvent(values[i].values);
}
float new_values[2];
if (ImGui::TimelineEnd(new_values))
{
timelineEvent e{
std::fmin(new_values[0], new_values[1]),
std::fmax(new_values[0], new_values[1])
};

values.push_back(e);
}
// ImGui::TimelineEvent("Event5", &events[8]);
ImGui::TimelineEvent("Event6", &events[10]);
}
const float elapsedTime = (float)(((unsigned)(ImGui::GetTime()*1000))%50000)/1000.f; // So that it's always in [0,50]
ImGui::EndTimeline(5,elapsedTime); // num_vertical_grid_lines, current_time (optional), timeline_running_color (optional)
const float elapsedTime = static_cast<float>((static_cast<unsigned>(ImGui::GetTime() * 1000)) % 50000) / 1000.f; // So that it's always in [0,50]
ImGui::EndTimelines(5, elapsedTime); // num_vertical_grid_lines, current_time (optional), timeline_running_color (optional)

ImGui::Render();

Expand Down
12 changes: 6 additions & 6 deletions app.threedee/imgui.ini
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[Window][Debug##Default]
ViewportPos=1250,637
ViewportPos=911,482
ViewportId=0x9F5F46A1
Size=731,681
Size=1592,651
Collapsed=0

[Window][Hello, world!]
Expand Down Expand Up @@ -43,8 +43,8 @@ Size=1024,768
Collapsed=0

[Window][Sequencer]
Pos=435,98
Size=856,1305
Pos=8,98
Size=1167,1305
Collapsed=0
DockId=0x0000000D,1

Expand All @@ -71,7 +71,7 @@ Collapsed=0
DockId=0x00000009,0

[Window][Pattern editor]
Pos=1293,98
Pos=1177,98
Size=602,1305
Collapsed=0
DockId=0x0000000E,0
Expand Down Expand Up @@ -179,7 +179,7 @@ DockId=0x00000012,2

[Docking][Data]
DockSpace ID=0x353B2190 Pos=207,162 Size=1008,733 CentralNode=1 SelectedTab=0xEBE6C6E6
DockSpace ID=0xB073454D Pos=350,294 Size=1008,728 Split=X SelectedTab=0x421602A9
DockSpace ID=0xB073454D Pos=286,230 Size=1008,728 Split=X SelectedTab=0x421602A9
DockNode ID=0x0000001F Parent=0xB073454D SizeRef=446,728 SelectedTab=0x1E4E8AD5
DockNode ID=0x00000020 Parent=0xB073454D SizeRef=1987,728 Split=Y
DockNode ID=0x00000005 Parent=0x00000020 SizeRef=1008,549 Split=Y
Expand Down
186 changes: 138 additions & 48 deletions app.threedee/imgui_addons/imgui_Timeline.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

#include <cmath>
#include <imgui.h>
#include <imgui_internal.h>
#include <iostream>

ImVec2 operator+(ImVec2 const &a, ImVec2 const &b)
{
Expand All @@ -20,9 +21,12 @@ namespace ImGui {
* Add zooming with CTRL+MouseWheel, and a horizontal scrollbar
* Add different types of TimelineEvent (e.g. multiple ranges in a single line, dot-like markers, etc.)
*/
IMGUI_API bool BeginTimeline(const char *str_id, float max_value = 0.f, int num_visible_rows = 5, int opt_exact_num_rows = 0); // last arg, when !=0, enables item culling
IMGUI_API bool BeginTimelines(const char *str_id, float max_value = 0.f, int num_visible_rows = 5, int opt_exact_num_rows = 0); // last arg, when !=0, enables item culling
IMGUI_API bool TimelineEvent(const char *str_id, float *values, bool keep_range_constant = false);
IMGUI_API void EndTimeline(int num_vertical_grid_lines = 5.f, float current_time = 0.f, ImU32 timeline_running_color = IM_COL32(0, 128, 0, 200));
IMGUI_API void TimelineStart(const char *str_id, bool keep_range_constant = false);
IMGUI_API bool TimelineEvent(float *values);
IMGUI_API bool TimelineEnd(float *new_values = nullptr);
IMGUI_API void EndTimelines(int num_vertical_grid_lines = 5.f, float current_time = 0.f, ImU32 timeline_running_color = IM_COL32(0, 128, 0, 200));
} // namespace ImGui

namespace ImGui {
Expand All @@ -32,8 +36,16 @@ static int s_timeline_num_rows = 0;
static int s_timeline_display_start = 0;
static int s_timeline_display_end = 0;
static int s_timeline_display_index = 0;
static const char *s_str_id = nullptr;
static bool s_keep_range_constant = false;
static ImVec2 s_cursor_pos;
static const float TIMELINE_RADIUS = 6;
static int s_event_counter = 0;
static float *s_lastval = nullptr;
static bool s_is_event_hovered = false;
static float s_start_new_value = 0.0f;

bool BeginTimeline(const char *str_id, float max_value, int num_visible_rows, int opt_exact_num_rows)
bool BeginTimelines(const char *str_id, float max_value, int num_visible_rows, int opt_exact_num_rows)
{
// reset global variables
s_max_timeline_value = 0.f;
Expand All @@ -57,10 +69,87 @@ bool BeginTimeline(const char *str_id, float max_value, int num_visible_rows, in
}
return rv;
}
static const float TIMELINE_RADIUS = 6;

bool TimelineEvent(const char *str_id, float *values, bool keep_range_constant)
{
TimelineStart(str_id, keep_range_constant);
auto result = TimelineEvent(values);
TimelineEnd();

return result;
}

void TimelineStart(const char *str_id, bool keep_range_constant)
{
++s_timeline_display_index;

if (s_timeline_num_rows > 0 &&
(s_timeline_display_index < s_timeline_display_start || s_timeline_display_index >= s_timeline_display_end)) return; // item culling

s_str_id = str_id;
s_keep_range_constant = keep_range_constant;
ImGuiWindow *win = GetCurrentWindow();
const float columnOffset = ImGui::GetColumnOffset(1);
s_cursor_pos = ImVec2(GetWindowContentRegionMin().x + win->Pos.x + columnOffset - TIMELINE_RADIUS, win->DC.CursorPos.y);

ImGui::Text("%s", str_id);
ImGui::NextColumn();

s_event_counter = 0;
s_lastval = nullptr;
s_is_event_hovered = false;
}

bool TimelineEnd(float *new_values)
{
if (s_timeline_num_rows > 0 &&
(s_timeline_display_index < s_timeline_display_start || s_timeline_display_index >= s_timeline_display_end)) return false; // item culling

bool result = false;
ImGuiWindow *win = GetCurrentWindow();
const ImU32 active_color = ColorConvertFloat4ToU32(GImGui->Style.Colors[ImGuiCol_ButtonHovered]);
const float columnWidth = ImGui::GetColumnWidth(1) - GImGui->Style.ScrollbarSize;

auto nextPos = s_cursor_pos + ImVec2(0, GetTextLineHeightWithSpacing());

float end_new_value = (GetIO().MousePos.x - s_cursor_pos.x) / columnWidth * s_max_timeline_value;

SetCursorScreenPos(s_cursor_pos);
if (InvisibleButton(s_str_id, ImVec2(GetWindowContentRegionWidth(), GetTextLineHeight())) && new_values != nullptr)
{
std::cout << s_start_new_value << " => " << end_new_value << std::endl;
new_values[0] = s_start_new_value;
new_values[1] = end_new_value;
result = true;
}
if (!s_is_event_hovered && IsItemHovered())
{
ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
}
if (IsItemActive() && !IsMouseDragging(0))
{
s_start_new_value = (GetIO().MousePos.x - s_cursor_pos.x) / columnWidth * s_max_timeline_value;
}
if (IsItemHovered() && IsItemActive() && IsMouseDragging(0))
{
ImVec2 start = s_cursor_pos;
start.x += columnWidth * s_start_new_value / s_max_timeline_value + (2 * TIMELINE_RADIUS);
start.y += (ImGui::GetTextLineHeight() - TIMELINE_RADIUS) / 2.0f + TIMELINE_RADIUS * 0.5f;
ImVec2 end = start + ImVec2(columnWidth * (end_new_value - s_start_new_value) / s_max_timeline_value - (2 * TIMELINE_RADIUS),
TIMELINE_RADIUS);

win->DrawList->AddRectFilled(start, end, active_color);
}

SetCursorScreenPos(nextPos);

ImGui::NextColumn();

return result;
}

bool TimelineEvent(float *values)
{
if (s_timeline_num_rows > 0 &&
(s_timeline_display_index < s_timeline_display_start || s_timeline_display_index >= s_timeline_display_end)) return false; // item culling

Expand All @@ -70,79 +159,74 @@ bool TimelineEvent(const char *str_id, float *values, bool keep_range_constant)
const ImU32 line_color = ColorConvertFloat4ToU32(GImGui->Style.Colors[ImGuiCol_ColumnActive]);
bool changed = false;
bool hovered = false;
bool allhovered = false;
bool active = false;

ImGui::Text("%s", str_id);
ImGui::NextColumn();

const float columnOffset = ImGui::GetColumnOffset(1);
const float columnWidth = ImGui::GetColumnWidth(1) - GImGui->Style.ScrollbarSize;
ImVec2 cursor_pos(GetWindowContentRegionMin().x + win->Pos.x + columnOffset - TIMELINE_RADIUS, win->DC.CursorPos.y);

PushID(s_event_counter++);
bool mustMoveBothEnds = false;
const bool isMouseDraggingZero = IsMouseDragging(0);

ImVec2 start = s_cursor_pos;
start.x += columnWidth * values[0] / s_max_timeline_value + (2 * TIMELINE_RADIUS);
start.y += (ImGui::GetTextLineHeight() - TIMELINE_RADIUS) / 2.0f;
ImVec2 end = start + ImVec2(columnWidth * (values[1] - values[0]) / s_max_timeline_value - (2 * TIMELINE_RADIUS), TIMELINE_RADIUS * 2.0f);

PushID(-1);
SetCursorScreenPos(start);
InvisibleButton(s_str_id, end - start);
if ((IsItemActive() && isMouseDraggingZero) || mustMoveBothEnds)
{
const float deltaX = GetIO().MouseDelta.x / columnWidth * s_max_timeline_value;
values[0] += deltaX;
values[1] += deltaX;
changed = hovered = allhovered = true;
}
else if (IsItemHovered())
{
hovered = allhovered = true;
}
PopID();

win->DrawList->AddRectFilled(start, end, IsItemActive() || IsItemHovered() ? active_color : inactive_color);

for (int i = 0; i < 2; ++i)
{
ImVec2 pos = cursor_pos;
ImVec2 pos = s_cursor_pos;
pos.x += columnWidth * values[i] / s_max_timeline_value + TIMELINE_RADIUS;
pos.y += TIMELINE_RADIUS;
pos.y += (ImGui::GetTextLineHeight() - TIMELINE_RADIUS) / 2.0f + TIMELINE_RADIUS;

SetCursorScreenPos(pos - ImVec2(TIMELINE_RADIUS, TIMELINE_RADIUS));
PushID(i);
InvisibleButton(str_id, ImVec2(2 * TIMELINE_RADIUS, 2 * TIMELINE_RADIUS));
InvisibleButton(s_str_id, ImVec2(2 * TIMELINE_RADIUS, 2 * TIMELINE_RADIUS));
active = IsItemActive();
if (active || IsItemHovered())
{
ImGui::SetTooltip("%f", values[i]);
if (!keep_range_constant)
if (!s_keep_range_constant)
{
// @meshula:The item hovered line needs to be compensated for vertical scrolling. Thx!
ImVec2 a(pos.x, GetWindowContentRegionMin().y + win->Pos.y + win->Scroll.y);
ImVec2 b(pos.x, GetWindowContentRegionMax().y + win->Pos.y + win->Scroll.y);
// possible aternative:
//ImVec2 a(pos.x, win->Pos.y);
//ImVec2 b(pos.x, win->Pos.y+win->Size.y);
win->DrawList->AddLine(a, b, line_color);
}
hovered = true;
}
if (active && isMouseDraggingZero)
{
if (!keep_range_constant)
if (!s_keep_range_constant)
values[i] += GetIO().MouseDelta.x / columnWidth * s_max_timeline_value;
else
mustMoveBothEnds = true;
changed = hovered = true;
}
PopID();
win->DrawList->AddCircleFilled(
pos, TIMELINE_RADIUS, IsItemActive() || IsItemHovered() ? active_color : inactive_color);
win->DrawList->AddRectFilled(pos - ImVec2(TIMELINE_RADIUS, TIMELINE_RADIUS),
pos + ImVec2(TIMELINE_RADIUS, TIMELINE_RADIUS),
IsItemActive() || IsItemHovered() || allhovered ? active_color : inactive_color);
}

ImVec2 start = cursor_pos;
start.x += columnWidth * values[0] / s_max_timeline_value + 2 * TIMELINE_RADIUS;
start.y += TIMELINE_RADIUS * 0.5f;
ImVec2 end = start + ImVec2(columnWidth * (values[1] - values[0]) / s_max_timeline_value - 2 * TIMELINE_RADIUS,
TIMELINE_RADIUS);

PushID(-1);
SetCursorScreenPos(start);
InvisibleButton(str_id, end - start);
if ((IsItemActive() && isMouseDraggingZero) || mustMoveBothEnds)
{
const float deltaX = GetIO().MouseDelta.x / columnWidth * s_max_timeline_value;
values[0] += deltaX;
values[1] += deltaX;
changed = hovered = true;
}
else if (IsItemHovered())
hovered = true;
PopID();

SetCursorScreenPos(cursor_pos + ImVec2(0, GetTextLineHeightWithSpacing()));

win->DrawList->AddRectFilled(start, end, IsItemActive() || IsItemHovered() ? active_color : inactive_color);

if (values[0] > values[1])
{
float tmp = values[0];
Expand All @@ -159,13 +243,19 @@ bool TimelineEvent(const char *str_id, float *values, bool keep_range_constant)
values[1] -= values[0];
values[0] = 0;
}
s_lastval = values + 1;
values += 2;
PopID();
if (hovered)
{
ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW);
s_is_event_hovered = true;
}

// if (hovered) ImGui::SetMouseCursor(ImGuiMouseCursor_Move);

ImGui::NextColumn();
return changed;
}
void EndTimeline(int num_vertical_grid_lines, float current_time, ImU32 timeline_running_color)

void EndTimelines(int num_vertical_grid_lines, float current_time, ImU32 timeline_running_color)
{
const float row_height = ImGui::GetTextLineHeightWithSpacing();
if (s_timeline_num_rows > 0) ImGui::SetCursorPosY(ImGui::GetCursorPosY() + ((s_timeline_num_rows - s_timeline_display_end) * row_height));
Expand Down

0 comments on commit 7fc9713

Please sign in to comment.