FLTK: как сделать виджеты изменяемого размера путем перетаскивания?

В FLTK есть ли способ позволить пользователям изменять размеры виджетов во время выполнения, перетаскивая границы поля виджета? Я имею в виду, например, чтобы изменить размер Fl_Text_Display или Fl_Box или Fl_Pack так же, как мы это обычно делаем для окна в любой ОС?

Я прошел все демонстрации, которые идут с FLTK, и я провел довольно много поиска, но нашел только примеры изменения размера с помощью кода или для пользователя, чтобы изменить размер с помощью нажатия кнопки. Я не смог найти ничего, что бы указывало мне правильное направление, как сделать так, чтобы границы виджета стали перетаскиваемыми, чтобы можно было изменять размеры виджетов путем перетаскивания.

0

Решение

Вы можете изучить возможности изменения размеров Fl_Group и Fl_Tile, возможно, используя их в качестве оболочки. К сожалению, FLTK не поддерживает это из коробки для каждого виджета, поэтому вы должны сделать это самостоятельно. Если вам нужно всего лишь создать пару пользовательских виджетов, приведенный ниже код дает вам общее представление о том, как начать:

#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Box.H>
#include <FL/fl_draw.H>
#include <cmath>

class Resizeable : public Fl_Box
{
public:
Resizeable(int X, int Y, int W, int H)
: Fl_Box(X, Y, W, H, "Resize Me") {}

private:
bool can_resize;
bool is_on_right_bottom_corner;

void draw()
{
Fl_Box::draw();
fl_rect(x(), y(), w(), h(), FL_RED);
int bottom_right_x = w() + x();
int bottom_right_y = h() + y();
fl_polygon(bottom_right_x - 6, bottom_right_y - 1,
bottom_right_x - 1, bottom_right_y - 6,
bottom_right_x -1, bottom_right_y - 1);
}

int handle(int event)
{
switch (event) {
case FL_PUSH: {
can_resize = is_on_right_bottom_corner;
return 1;
}
case FL_RELEASE:
can_resize = false;
return 1;
case FL_DRAG: {
if (can_resize) {
int X = Fl::event_x();
int Y = Fl::event_y();
int W = X > x() + 1 ? X - x() : w();
int H = Y > y() + 1 ? Y - y() : h();
size(W, H);
parent()->redraw();
}
return 1;
}
case FL_MOVE: {
int dist_right_border  = std::abs(x() + w() - Fl::event_x());
int dist_bottom_border = std::abs(y() + h() - Fl::event_y());
is_on_right_bottom_corner = (dist_right_border < 10 && dist_bottom_border < 10);
window()->cursor(is_on_right_bottom_corner ? FL_CURSOR_SE : FL_CURSOR_DEFAULT);
return 1;
}
case FL_ENTER:
return 1;
case FL_LEAVE:
window()->cursor(FL_CURSOR_DEFAULT);
return 1;
}
return 0;
}
};

int main()
{
Fl_Double_Window win(300, 300, "Resize Example");
Resizeable res(50, 50, 100, 40);
win.show();
return Fl::run();
}
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]