@@ -113,15 +113,42 @@ ExitStatus App::Application::run() {
113113 const ImVec2 base_pos = viewport->Pos ;
114114 const ImVec2 base_size = viewport->Size ;
115115
116- static char function[1024 ] = " r = 1 + 0.5*cos(theta)" ;
117116 static float zoom = 100 .0f ;
118117
119- // Left Pane (expression )
118+ // Left Pane (expressions )
120119 {
121120 ImGui::SetNextWindowPos (base_pos);
122121 ImGui::SetNextWindowSize (ImVec2 (base_size.x * 0 .25f , base_size.y ));
123122 ImGui::Begin (" Left Pane" , nullptr , ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar);
124- ImGui::InputTextMultiline (" ##search" , function, sizeof (function), ImVec2 (-FLT_MIN, ImGui::GetTextLineHeight () * 4 ));
123+
124+ // Loop through all expressions
125+ for (size_t i = 0 ; i < m_expressions.size (); ++i) {
126+ ImGui::PushID (i);
127+
128+ // Color picker button
129+ ImGui::ColorEdit3 (" ##color" , m_expressions[i].color , ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel);
130+ ImGui::SameLine ();
131+
132+ // Expression input
133+ ImGui::InputTextMultiline (" ##expr" , m_expressions[i].text , sizeof (m_expressions[i].text ),
134+ ImVec2 (-FLT_MIN, ImGui::GetTextLineHeight () * 2 ));
135+
136+ ImGui::PopID ();
137+ }
138+
139+ // Add expression button
140+ if (ImGui::Button (" + Add Expression" )) {
141+ Expression new_expr;
142+ new_expr.text [0 ] = ' \0 ' ;
143+ // Cycle through some nice colors
144+ const float colors[][3 ] = {{0 .25f , 0 .5f , 0 .78f }, {0 .8f , 0 .2f , 0 .2f }, {0 .2f , 0 .8f , 0 .2f }, {0 .9f , 0 .6f , 0 .1f }};
145+ int color_idx = m_expressions.size () % 4 ;
146+ new_expr.color [0 ] = colors[color_idx][0 ];
147+ new_expr.color [1 ] = colors[color_idx][1 ];
148+ new_expr.color [2 ] = colors[color_idx][2 ];
149+ m_expressions.push_back (new_expr);
150+ }
151+
125152 ImGui::SliderFloat (" Graph Scale" , &zoom, 10 .0f , 500 .0f , " %.1f" );
126153 ImGui::End ();
127154 }
@@ -140,13 +167,22 @@ ExitStatus App::Application::run() {
140167 float lineThickness = 6 .0f ;
141168 draw_list->AddLine (ImVec2 (canvas_p0.x , origin.y ), ImVec2 (canvas_p1.x , origin.y ), IM_COL32 (0 , 0 , 0 , 255 ), lineThickness);
142169 draw_list->AddLine (ImVec2 (origin.x , canvas_p0.y ), ImVec2 (origin.x , canvas_p1.y ), IM_COL32 (0 , 0 , 0 , 255 ), lineThickness);
143- std::vector<ImVec2> points;
144-
145- // (f(t), g(t))
146- std::string func_str (function);
147170
148-
149- bool plotted = false ;
171+ // Loop through all expressions and plot each
172+ for (const auto & expr : m_expressions) {
173+ std::string func_str (expr.text );
174+ if (func_str.empty ()) continue ;
175+
176+ std::vector<ImVec2> points;
177+ bool plotted = false ;
178+
179+ // Convert color to ImU32
180+ ImU32 line_color = IM_COL32 (
181+ static_cast <int >(expr.color [0 ] * 255 ),
182+ static_cast <int >(expr.color [1 ] * 255 ),
183+ static_cast <int >(expr.color [2 ] * 255 ),
184+ 255
185+ );
150186
151187 if (!func_str.empty () && func_str.front () == ' (' && func_str.back () == ' )' ) {
152188 const std::string inner = func_str.substr (1 , func_str.size () - 2 );
@@ -204,7 +240,7 @@ ExitStatus App::Application::run() {
204240 // Draw curve
205241 draw_list->AddPolyline (points.data (),
206242 points.size (),
207- IM_COL32 ( 64 , 128 , 199 , 255 ) ,
243+ line_color ,
208244 ImDrawFlags_None,
209245 lineThickness);
210246 plotted = true ;
@@ -235,7 +271,6 @@ ExitStatus App::Application::run() {
235271
236272 // adaptive step size with performance limit
237273 const double step = std::max (0.025 , 1.5 / zoom);
238- const ImU32 inequality_color = IM_COL32 (100 , 150 , 255 , 180 );
239274 const float dot_size = std::max (1 .5f , zoom / 60 .0f );
240275
241276
@@ -246,7 +281,7 @@ ExitStatus App::Application::run() {
246281 if (expression.value () == 1.0 ) {
247282 ImVec2 screen_pos (origin.x + static_cast <float >(x * zoom),
248283 origin.y - static_cast <float >(y * zoom));
249- draw_list->AddCircleFilled (screen_pos, dot_size, inequality_color );
284+ draw_list->AddCircleFilled (screen_pos, dot_size, line_color );
250285 }
251286 }
252287 }
@@ -316,7 +351,6 @@ ExitStatus App::Application::run() {
316351 const double y_max = canvas_sz.y / (2 * zoom);
317352 const double step = std::max (0.008 , 1.0 / zoom); // dynamic step based on zoom level
318353
319- const ImU32 implicit_color = IM_COL32 (64 , 199 , 128 , 255 );
320354 const float dot_radius = 2 .5f ;
321355
322356 // scan horizontally for sign changes
@@ -336,7 +370,7 @@ ExitStatus App::Application::run() {
336370 // transform to screen coordinates and draw immediately
337371 ImVec2 screen_pos (origin.x + static_cast <float >(x_zero * zoom),
338372 origin.y - static_cast <float >(y_zero * zoom));
339- draw_list->AddCircleFilled (screen_pos, dot_radius, implicit_color );
373+ draw_list->AddCircleFilled (screen_pos, dot_radius, line_color );
340374 }
341375
342376 prev_val = curr_val;
@@ -360,7 +394,7 @@ ExitStatus App::Application::run() {
360394
361395 ImVec2 screen_pos (origin.x + static_cast <float >(x_zero * zoom),
362396 origin.y - static_cast <float >(y_zero * zoom));
363- draw_list->AddCircleFilled (screen_pos, dot_radius, implicit_color );
397+ draw_list->AddCircleFilled (screen_pos, dot_radius, line_color );
364398 }
365399
366400 prev_val = curr_val;
@@ -375,7 +409,6 @@ ExitStatus App::Application::run() {
375409 }
376410
377411 if (!plotted) {
378- std::string func_str (function);
379412 bool is_polar = func_str.find (" r=" ) != std::string::npos || func_str.find (" r =" ) != std::string::npos;
380413
381414 if (is_polar) {
@@ -419,7 +452,7 @@ ExitStatus App::Application::run() {
419452
420453 draw_list->AddPolyline (points.data (),
421454 points.size (),
422- IM_COL32 ( 128 , 64 , 199 , 255 ) ,
455+ line_color ,
423456 ImDrawFlags_None,
424457 lineThickness);
425458 }
@@ -435,7 +468,7 @@ ExitStatus App::Application::run() {
435468 expression.register_symbol_table (symbolTable);
436469
437470 exprtk::parser<double > parser;
438- parser.compile (function , expression);
471+ parser.compile (expr. text , expression);
439472
440473 for (x = -canvas_sz.x / (2 * zoom); x < canvas_sz.x / (2 * zoom); x += 0.05 ) {
441474 const double y = expression.value ();
@@ -446,11 +479,12 @@ ExitStatus App::Application::run() {
446479
447480 draw_list->AddPolyline (points.data (),
448481 points.size (),
449- IM_COL32 ( 199 , 68 , 64 , 255 ) ,
482+ line_color ,
450483 ImDrawFlags_None,
451484 lineThickness);
452485 }
453486 }
487+ } // end expression loop
454488
455489 ImGui::End ();
456490 ImGui::PopStyleColor ();
0 commit comments