2016-12-06 3 views
0

FLTKをC++で使用して、画像のフォルダをスクロールするプログラムを作成しています。私は、次の画像のサムネイルを持つ次のボタンと、前のボタンのサムネイルを持っています。前と次のボタンをクリックするだけでなく、キーボードの左右の矢印を使って画像を見ることができるようにしたい。FLTKの2つの異なるウィジェットに対して、キーボードの矢印とマウスのクリックの両方を使用するにはどうすればよいですか?

私はこれを行うのに成功しましたが、同時にはできませんでした。私はそうのようなコールバック関数を記述する場合:

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); 
} 
:私はそうのようなキーボードの矢印キーを処理するためのハンドル機能をオーバーロードするとき

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

    viewer->redraw(); 
} 

は、しかし私は、前方と後方に行くために、それぞれのボタンをクリックすることができます

私は矢印を使用することができますが、両方の矢印を使用してボタンをクリックする方法を理解することはできません。 Fl_Widget * wをハンドル関数に渡してコールバックに戻そうとしましたが、ボタンをクリックすることはできましたが、矢印を使用できなくなりました。 Viewer.h

#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); 
} 

そしてここにある:

#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 

あなたは私を支援するために任意のより多くの情報が必要な場合は私に知らせて、そしてあなたに感謝してください。ここ

はViewer.cppファイルですあらかじめ!

+0

アップデートでは:私はそれがNavButton.cppソースコードで私のハンドル機能を入れて取り組んでもらうことができました。 – chase1745

答えて

0

これは、あなたが望むものを達成する可能性があります。ナビゲーションを行う3番目のルーチンを追加します。

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; 
} 

次に、他の2つを変更して呼び出します。あなたのハンドラnavpressedで

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

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

ハンドル関数をNavButtonクラスの.cppファイルに入れて解決できました。それを見ると、あなたのソリューションはうまくいっていると思います。ご協力ありがとうございました! – chase1745

関連する問題