dlib C++ Library - gui_api_ex.cpp

// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
/*
 This is an example illustrating the use of the gui api from the dlib C++ Library.
 This is a pretty simple example. It makes a window with a user
 defined widget (a draggable colored box) and a button. You can drag the
 box around or click the button which increments a counter. 
*/
#include <dlib/gui_widgets.h>
#include <sstream>
#include <string>
using namespace std;
using namespace dlib;
// ----------------------------------------------------------------------------
class color_box : public draggable 
{
 /*
 Here I am defining a custom drawable widget that is a colored box that
 you can drag around on the screen. draggable is a special kind of drawable
 object that, as the name implies, is draggable by the user via the mouse.
 To make my color_box draggable all I need to do is inherit from draggable.
 */
 unsigned char red, green,blue;
public:
 color_box (
 drawable_window& w,
 rectangle area,
 unsigned char red_,
 unsigned char green_,
 unsigned char blue_
 ) :
 draggable(w),
 red(red_),
 green(green_),
 blue(blue_)
 {
 rect = area;
 set_draggable_area(rectangle(10,10,400,400));
 
 // Whenever you make your own drawable widget (or inherit from any drawable widget 
 // or interface such as draggable) you have to remember to call this function to 
 // enable the events. The idea here is that you can perform whatever setup you 
 // need to do to get your object into a valid state without needing to worry about 
 // event handlers triggering before you are ready.
 enable_events();
 }
 ~color_box (
 )
 {
 // Disable all further events for this drawable object. We have to do this 
 // because we don't want any events (like draw()) coming to this object while or 
 // after it has been destructed.
 disable_events();
 
 // Tell the parent window to redraw its area that previously contained this
 // drawable object.
 parent.invalidate_rectangle(rect);
 }
private:
 void draw (
 const canvas& c
 ) const
 {
 // The canvas is an object that represents a part of the parent window
 // that needs to be redrawn. 
 // The first thing I usually do is check if the draw call is for part
 // of the window that overlaps with my widget. We don't have to do this 
 // but it is usually good to do as a speed hack. Also, the reason
 // I don't have it set to only give you draw calls when it does indeed
 // overlap is because you might want to do some drawing outside of your
 // widget's rectangle. But usually you don't want to do that :)
 rectangle area = c.intersect(rect);
 if (area.is_empty() == true)
 return;
 // This simple widget is just going to draw a box on the screen. 
 fill_rect(c,rect,rgb_pixel(red,green,blue));
 }
};
// ----------------------------------------------------------------------------
class win : public drawable_window 
{
 /*
 Here I am going to define our window. In general, you can define as 
 many window types as you like and make as many instances of them as you want.
 In this example I am only making one though.
 */
public:
 win(
 ) : // All widgets take their parent window as an argument to their constructor.
 c(*this),
 b(*this),
 cb(*this,rectangle(100,100,200,200),0,0,255), // the color_box will be blue and 101 pixels wide and tall
 mbar(*this)
 {
 // tell our button to put itself at the position (10,60). 
 b.set_pos(10,60);
 b.set_name("button");
 // let's put the label 5 pixels below the button
 c.set_pos(b.left(),b.bottom()+5);
 // set which function should get called when the button gets clicked. In this case we want
 // the on_button_clicked member to be called on *this.
 b.set_click_handler(*this,&win::on_button_clicked);
 // Alternatively, if you have a compiler which supports the lambda functions from the
 // new C++ standard then you can use a lambda function instead of telling the click
 // handler to call one of the member functions. So for example, you could do this
 // instead (uncomment the code if you have C++0x support):
 /*
 b.set_click_handler([&](){
 ++counter;
 ostringstream sout;
 sout << "Counter: " << counter;
 c.set_text(sout.str());
 });
 */
 // In general, all the functions which register events can take either member 
 // functions or lambda functions.
 
 // Let's also make a simple menu bar. 
 // First we say how many menus we want in our menu bar. In this example we only want 1.
 mbar.set_number_of_menus(1);
 // Now we set the name of our menu. The 'M' means that the M in Menu will be underlined
 // and the user will be able to select it by hitting alt+M
 mbar.set_menu_name(0,"Menu",'M');
 // Now we add some items to the menu. Note that items in a menu are listed in the
 // order in which they were added.
 // First let's make a menu item that does the same thing as our button does when it is clicked.
 // Again, the 'C' means the C in Click is underlined in the menu. 
 mbar.menu(0).add_menu_item(menu_item_text("Click Button!",*this,&win::on_button_clicked,'C'));
 // let's add a separator (i.e. a horizontal separating line) to the menu
 mbar.menu(0).add_menu_item(menu_item_separator());
 // Now let's make a menu item that calls show_about when the user selects it. 
 mbar.menu(0).add_menu_item(menu_item_text("About",*this,&win::show_about,'A'));
 // set the size of this window
 set_size(430,380);
 counter = 0;
 set_title("dlib gui example");
 show();
 } 
 ~win(
 )
 {
 // You should always call close_window() in the destructor of window
 // objects to ensure that no events will be sent to this window while 
 // it is being destructed. 
 close_window();
 }
private:
 void on_button_clicked (
 )
 {
 // when someone clicks our button it will increment the counter and 
 // display it in our label c.
 ++counter;
 ostringstream sout;
 sout << "counter: " << counter;
 c.set_text(sout.str());
 }
 void show_about(
 )
 {
 message_box("About","This is a dlib gui example program");
 }
 unsigned long counter;
 label c;
 button b;
 color_box cb;
 menu_bar mbar;
};
// ----------------------------------------------------------------------------
int main()
{
 // create our window
 win my_window;
 // wait until the user closes this window before we let the program 
 // terminate.
 my_window.wait_until_closed();
 return 0;
}
// ----------------------------------------------------------------------------
// Normally, if you built this application on MS Windows in Visual Studio you
// would see a black console window pop up when you ran it. The following
// #pragma directives tell Visual Studio to not include a console window along
// with your application. However, if you prefer to have the console pop up as
// well then simply remove these #pragma statements.
#ifdef _MSC_VER
# pragma comment( linker, "/entry:mainCRTStartup" )
# pragma comment( linker, "/SUBSYSTEM:WINDOWS" )
#endif
// ----------------------------------------------------------------------------

AltStyle によって変換されたページ (->オリジナル) /