1
2 #include "dialog.hxx"
3
4 #include "button.hxx"
5 #include "ui.hxx"
6 #include "theme.hxx"
7
8 #include <stdio.h>
9
10 using namespace Avtk;
11
Dialog(Avtk::UI * ui,int x_,int y_,int w_,int h_,std::string label_)12 Dialog::Dialog( Avtk::UI* ui, int x_, int y_, int w_, int h_, std::string label_) :
13 Group( ui, x_, y_, w_, h_, label_ )
14 {
15 mx = my = -1;
16
17 ok = new Button( ui, 0, 0, 60, 20, "OK" );
18 cancel = new Button( ui, 0, 0, 60, 20, "Cancel" );
19
20 add( ok );
21 add( cancel );
22
23 visible_ = false;
24
25 end();
26 }
27
draw(cairo_t * cr)28 void Dialog::draw( cairo_t* cr )
29 {
30 cairo_save( cr );
31
32 // buttons_
33 if( buttons_ == OK ) {
34 ok->x( x_ + w_ * 0.8 );
35 ok->y( y_ + h_ * 0.75 );
36 ok->visible( true );
37 } else if( buttons_ == OK_CANCEL ) {
38 ok->x( x_ + w_ * 0.8 - 70 );
39 ok->y( y_ + h_ * 0.75 );
40 cancel->x( x_ + w_ * 0.8 );
41 cancel->y( y_ + h_ * 0.75 );
42 ok->visible( true );
43 cancel->visible( true );
44 }
45
46 if( mx != -1 || my != -1 ) {
47 // get co-ords of the OK button, and find delta to mx/my
48 int xd = mx - (ok->x()+ok->w()/2.f);
49 int yd = my - (ok->y()+10);
50
51 // clip to *always* show entire dialog (aka, no "off-window" drawing)
52 int diagX = x_ + xd;
53 int diagY = y_ + yd;
54
55 // clip top left
56 if( diagX < 0 ) diagX = 0;
57 if( diagY < 0 ) diagY = 0;
58
59 // clip lower right
60 if( diagX + w_ > ui->w() ) diagX = ui->w() - w_;
61 if( diagY + h_ > ui->h() ) diagY = ui->h() - h_;
62
63 // set
64 x( diagX );
65 y( diagY );
66 }
67
68 // transparent-out the *entire* UI
69 cairo_rectangle( cr, 0, 0, ui->w(), ui->h() );
70 //theme_->color( cr, BG_DARK, 0.8 );
71 cairo_set_source_rgba( cr, 1, 1, 1, 0.2 );
72 cairo_fill_preserve( cr );
73 cairo_stroke( cr );
74
75 // draw diagonal lines
76 int end = ui->w() + ui->h();
77 for(int i = 0; i < end; i += 40 ) {
78 cairo_move_to( cr, -10, i + 10 );
79 cairo_line_to( cr, i + 10, -10 );
80 }
81 theme_->color( cr, BG_DARK, 0.2 );
82 //cairo_set_source_rgba( cr, 1, 1, 1, 0.2 );
83 cairo_set_line_width( cr, 13 );
84 cairo_stroke( cr );
85
86 // draw dark BG
87 cairo_rectangle( cr, x_+1, y_+1, w_-2, h_-1 );
88 theme_->color( cr, BG_DARK, 1 );
89 cairo_fill_preserve( cr );
90 cairo_set_line_width( cr, 1.0 );
91 cairo_stroke( cr );
92 theme_->color( cr, BG_DARK, 1 );
93 cairo_select_font_face(cr, "impact", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
94
95 // draw header
96 cairo_rectangle( cr, x_, y_, w_, 14 );
97 theme_->color( cr, HIGHLIGHT, 1.0 );
98 cairo_fill( cr );
99
100 /// TODO: get the dialog text amount, wrap based on text extents
101 /// and draw buttons in Y position to not interfere with text
102
103 // show the header
104 cairo_text_extents_t extents;
105 cairo_set_font_size(cr, 10.0);
106 cairo_text_extents(cr, label(), &extents);
107 cairo_move_to(cr, x_ + 4, y_ + 7 + (extents.height / 2) );
108 theme_->color( cr, BG_DARK, 1 );
109 cairo_show_text( cr, label() );
110
111 // show the content
112 cairo_set_font_size(cr, 12.0);
113 cairo_text_extents(cr, contents.c_str(), &extents);
114 cairo_move_to(cr, x_ + 4, y_ + 25 + 7 + (extents.height / 2) );
115 //theme_->color( cr, BG_DARK, 1 );
116 cairo_set_source_rgb( cr, 1,1,1 );
117 cairo_show_text( cr, contents.c_str() );
118
119
120 Group::draw( cr );
121
122 cairo_restore( cr );
123 }
124
125 // to highjack the OK / Cancel buttons events
valueCB(Avtk::Widget * widget)126 void Dialog::valueCB( Avtk::Widget* widget)
127 {
128 if( widget == ok ) {
129 ui->handleOnly( 0x0 );
130 visible( false );
131 value( 1.f );
132
133 callback( this, ui );
134 } else if( widget == cancel ) {
135 ui->handleOnly( 0x0 );
136 visible( false );
137 value( 0.f );
138
139 callback( this, ui );
140 } else {
141 //printf("Dialog::widgetValueCB() widget %s\n", widget->label() );
142 }
143 }
144
run(const char * header,const char * text,BUTTONS b,int mx_,int my_)145 void Dialog::run( const char* header, const char* text, BUTTONS b, int mx_, int my_ )
146 {
147 // show the dialog
148 label( header );
149 contents = text;
150 buttons_ = b;
151
152 ok->value( false );
153 cancel->value( false );
154
155 visible( true );
156 // position to have OK/YES under mouse cursor. When -1, ignore
157 mx = mx_;
158 my = my_;
159
160 // make UI route all events to here, and wait for the valueCB to be called to
161 // release the handleOnly
162 ui->handleOnly( this );
163 }
164