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