如何在FLTK中为两个不同的小部件使用键盘箭头和鼠标点击?

时间:2016-12-06 03:13:12

标签: c++ user-interface fltk

我正在使用FLTK和C ++编写程序来滚动图像文件夹。我有一个下一个按钮,下一个图像的缩略图,以及前一个按钮的缩略图。我希望能够通过单击上一个和下一个按钮以及使用键盘上的左右箭头来浏览图像。

我成功地做到了这一点,但不是在同一时间。当我只写一个像这样的回调函数时:

void buttonCallback(Fl_Widget* widget, void* viewerPtr) {
   Viewer* viewer = static_cast<Viewer*>(viewerPtr);
   viewer->navPressed(widget);

   viewer->redraw();
}

我可以单击相应的按钮前进和后退,但是当我重置手柄功能来处理键盘箭头时,这样:

int Viewer::handle(int e) {
switch(e) {
    case FL_FOCUS:
    case FL_UNFOCUS:
        return 1;
    case FL_KEYBOARD:
        if ( Fl::event_key() == FL_Left) {
            prev->do_callback();
            return(1);
        } else if (Fl::event_key() == FL_Right) {
            next->do_callback();
            return(1);
        }
        return 1;
    case FL_RELEASE:
        do_callback();
        return 1;
}
   return Fl_Widget::handle(e);
}

我可以使用箭头,但我无法弄清楚如何使用两个箭头并单击按钮。我已经尝试将Fl_Widget * w传递给handle函数并返回到回调,我可以单击按钮,但不能再使用箭头了。

这是Viewer.cpp文件:

#include <iostream>
#include "Viewer.h"

using namespace std;

void buttonCallback(Fl_Widget* widget, void* viewerPtr) {
    //cout << "Callback called" << endl;
    Viewer* viewer = static_cast<Viewer*>(viewerPtr);
    viewer->navPressed(widget);

    viewer->redraw();
}



Viewer::Viewer(string imageFolder, vector<string> imageFilenames, int width = 800, int height = 600) :
    Fl_Window(width, height, "Image Viewer"), imageFolder(imageFolder), imageFilenames(imageFilenames), currentIndex(0), nextIndex(1), prevIndex(imageFilenames.size()-1),
    prev(nullptr), next(nullptr), imageBox(nullptr), pic(nullptr) {


    prev = new NavButton(getPathFilename(imageFilenames.at(prevIndex), true), "Previous Button", borderSize, this->h() - borderSize - thumbnailSize - borderSize, thumbnailSize, imageFilenames.size() - 1);


    next = new NavButton(getPathFilename(imageFilenames.at(nextIndex), true), "Next Button",
        this->w() - borderSize - thumbnailSize - borderSize, this->h() - borderSize - thumbnailSize - borderSize, thumbnailSize, imageFilenames.size()-1);


    imageBox = new Fl_Box(borderSize, borderSize, this->w() - (2*borderSize), this->h() - (2*borderSize) - thumbnailSize - 2*borderSize);


    //imageBox->box(FL_BORDER_BOX); // useful to see where the full size of the widget holding the images

    pic = new Fl_JPEG_Image(getPathFilename(imageFilenames.at(currentIndex)).c_str());
    imageBox->image(pic);
    this->end();
    prev->callback(buttonCallback, static_cast<void*>(this));
    next->callback(buttonCallback, static_cast<void*>(this));

}

string Viewer::getPathFilename(string filename, bool thumb) {
    string thumbPart = "";
    if (thumb) thumbPart = "t_";
    return imageFolder + "/" + thumbPart+ filename;
}

void Viewer::navPressed(Fl_Widget *widget) {

    NavButton* b = dynamic_cast<NavButton*>(widget);
    // adds to the click counts to keep track of them
    b->addClickCount(); b->addTotalClicks();
    cout <<  b->getLabel() << " has been pressed " << b->getClickCount() << " times." << endl;
    cout << "All buttons have been pressed " << b->getTotClicks() << " times." << endl;

    // determines which button is pressed
    if (b->getLabel() == "Next Button") {
        changeAllInds(true);

        // check to see if at end of list
        if ((nextIndex) > imageFilenames.size()-1) {
            nextIndex = 0;
        } else if (currentIndex > imageFilenames.size()-1) {
            currentIndex = 0;
        } else if (prevIndex > imageFilenames.size()-1) {
            prevIndex = 0;
        }

        // changes main image
        pic = new Fl_JPEG_Image(getPathFilename(imageFilenames.at(currentIndex)).c_str());
        imageBox->image(pic);

        // changes thumbnails
        prev->setImage(getPathFilename(imageFilenames.at(prevIndex), true).c_str());
        next->setImage(getPathFilename(imageFilenames.at(nextIndex), true).c_str());


    } else {
        changeAllInds(false);

        // check to see if at end of list
        if ((nextIndex) < 0) {
            nextIndex = imageFilenames.size()-1;
        } else if (currentIndex < 0) {
            currentIndex = imageFilenames.size()-1;
        } else if (prevIndex < 0) {
            prevIndex = imageFilenames.size()-1;
        }

        // changes main image
        pic = new Fl_JPEG_Image(getPathFilename(imageFilenames.at(currentIndex)).c_str());
        imageBox->image(pic);

        // changes thumbnails
        prev->setImage(getPathFilename(imageFilenames.at(prevIndex), true).c_str());
        next->setImage(getPathFilename(imageFilenames.at(nextIndex), true).c_str());

    }
    //cout << currentIndex << endl;
    cout << endl;

}

void Viewer::changeAllInds(bool increase) {
    if (increase) {
        currentIndex++; nextIndex++; prevIndex++;
    } else {
        currentIndex--; nextIndex--; prevIndex--;
    }
}

int Viewer::handle(int e) {
    switch(e) {
        case FL_FOCUS:
        case FL_UNFOCUS:
            return 1;
        case FL_KEYBOARD:
            if ( Fl::event_key() == FL_Left) {
                prev->do_callback();
                return(1);
            } else if (Fl::event_key() == FL_Right) {
                next->do_callback();
                return(1);
            }
            return 1;
        case FL_RELEASE:
            do_callback();
            return 1;
    }
    return Fl_Widget::handle(e);
}

这是Viewer.h:

#ifndef VIEWER_H
#define VIEWER_H

#include <vector>
#include <string>
#include <FL/Fl_Window.H>
#include <FL/Fl_Box.H>
#include "NavButton.h"

class Viewer : public Fl_Window {
    std::vector<std::string> imageFilenames;
    Fl_Box *imageBox;   // Holds image being shown
    Fl_JPEG_Image *pic; // Image being shown
    NavButton* prev;    // Button to go to previous item
                        //   Image is thumbnail of previous image
    NavButton* next;    // Button to go to next item
                        //   Image is thumbnail of next image
    int currentIndex;   // Index of the image currently shown
    int nextIndex;      // Index of next image
    int prevIndex;      // Index of previous image

    // private helper functions
    std::string imageFolder;
    std::string getPathFilename(std::string filename, bool thumb=false);

public:
    static const int thumbnailSize = 50; // size of NavButton
    static const int borderSize = 10; // size of border between window edge     and widgets

    void navPressed(Fl_Widget* widget);

    // constructor
    Viewer(std::string, std::vector<std::string>, int, int);

    virtual int handle(int e);
    //int key_handle(int e, int key);
    //int mouse_handle(int e);

    void changeAllInds(bool increase);
};

#endif

如果您需要更多信息来帮助我,请告诉我,并提前感谢您!

1 个答案:

答案 0 :(得分:0)

这可能会达到你想要的效果。添加第三个例程来进行导航

int Navigate(int key)
{
    if ( key == FL_Left) {
        prev->do_callback();
        return(1);
    } else if (key == FL_Right) {
        next->do_callback();
        return(1);
    }
    return 1;
}

然后改变另外两个来调用它。在你的处理程序

int Viewer::handle(int e) {
switch(e) {
    ...
    case FL_KEYBOARD:
        return Navigate(Fl::event_key());
    case FL_RELEASE:
    ...
    }
...

在navpressed中,

...
if (b->getLabel() == "Next Button") {
    ...
    Navigate(FL_Right);
}
else {
    ...
    Navigate(FL_Left);
}