ArthurSonzogni / FTXUI

:computer: C++ Functional Terminal User Interface. :heart:
MIT License
6.73k stars 401 forks source link

scroll indicator not colorable? #754

Closed jeSuisFaim closed 11 months ago

jeSuisFaim commented 11 months ago

Hi there,

I'm using a vscroll_indicator in an app where I change the color of every element using the decorators color and bgcolor. Those work well on everything that I throw at them except the vscroll_indicator.

I can modify the vscroll_indicator implementation to change the colors in the render but that's definitely a dirty solution. I'm a bit confused as to why/how the color and bgcolor decorators can catch all the pixels in the screen except the ones from the vscroll_indicator :thinking: .

Here is the example button_in_frame.cpp with a custom color scheme that applies to every element except the scroll bar:

// Copyright 2022 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <memory>  // for allocator, __shared_ptr_access, shared_ptr
#include <string>  // for to_string, operator+

#include "ftxui/component/captured_mouse.hpp"  // for ftxui
#include "ftxui/component/component.hpp"       // for Button, Renderer, Vertical
#include "ftxui/component/component_base.hpp"  // for ComponentBase
#include "ftxui/component/component_options.hpp"   // for ButtonOption
#include "ftxui/component/screen_interactive.hpp"  // for ScreenInteractive
#include "ftxui/dom/elements.hpp"  // for operator|, text, Element, hbox, separator, size, vbox, border, frame, vscroll_indicator, HEIGHT, LESS_THAN
#include "ftxui/screen/color.hpp"  // for Color, Color::Default, Color::GrayDark, Color::White

using namespace ftxui;

int main() {
  int counter = 0;
  auto on_click = [&] { counter++; };

  Color foregroundColor = Color::RGB(253, 202, 85);
  Color backgroundColor = Color::RGB(63, 41, 30);

  auto style = ButtonOption::Animated(backgroundColor, foregroundColor,
                                      backgroundColor, foregroundColor);

  auto container = Container::Vertical({});
  for (int i = 0; i < 30; ++i) {
    auto button = Button("Button " + std::to_string(i), on_click, style);
    container->Add(button);
  }

  auto renderer = Renderer(container, [&] {
    return vbox({
               hbox({
                   text("Counter:"),
                   text(std::to_string(counter)),
               }),
               separator(),
               container->Render()| vscroll_indicator | frame |
                   size(HEIGHT, LESS_THAN, 20),
           }) |
           border | color(Color::RGB(253, 202, 85)) | bgcolor(Color::RGB(63, 41, 30));
  });

  auto screen = ScreenInteractive::FitComponent();
  screen.Loop(renderer);

  return 0;
}
ArthurSonzogni commented 11 months ago

Thanks!

It looks like we are resetting the pixel in:

I am not sure why are we doing this. Would you like to propose a PR removing those lines?

clement-roblot commented 11 months ago

(mixed up my accounts, I reported this issue)

How did I not see that!? I looked at this code, forced the color here to test, and noticed it worked but the overwritting of the pixel didn´t shock me! :exploding_head:

Anyway, I made an MR #755 with the fix :+1: