前提・実現したいこと
画面端に要素を追加した時に自動でスケールを1.2倍にしたいです.
発生している問題
試したことと同じように変化させた場合上と右に要素を追加した場合のみ予定通りに動作をしますが,
左と下に追加した場合の動作が正常に動きません.
該当のソースコード
cpp
1#ifndef MYDRAWINGAREA_INCLDED 2#define MYDRAWINGAREA_INCLDED 3#include <gtkmm/drawingarea.h> 4 5#include <vector> 6#include <utility> // std::pair 7#include <algorithm> 8 9namespace ClusteringDataApp{ 10 template < typename T = double > 11 using dataType = std::vector< std::pair<T, T> >; 12 13 class MyDrawingArea : public Gtk::DrawingArea{ 14 public: 15 explicit MyDrawingArea( dataType< >& data ); 16 virtual ~MyDrawingArea( ) = default; 17 18 protected: 19 bool on_draw( const Cairo::RefPtr<Cairo::Context>& cr ) override; 20 bool on_button_press_event( GdkEventButton* event ) override; 21 22 private: 23 void prepareProperties( ); 24 25 dataType< >& data_; 26 27 std::pair< 28 dataType< >::const_iterator, 29 dataType< >::const_iterator > minMaxPairForX0_, minMaxPairForX1_; 30 31 double width_, height_; 32 }; 33} 34#endif
cpp
1#include "MyDrawingArea.h" 2 3namespace ClusteringDataApp{ 4 MyDrawingArea::MyDrawingArea( dataType< >& data ) : 5 data_( data ){ 6 add_events( Gdk::BUTTON_PRESS_MASK ); 7 } 8 9 void MyDrawingArea::prepareProperties( ) { 10 minMaxPairForX0_ = std::minmax_element( data_.cbegin( ), data_.cend( ), 11 [ ]( const std::pair< double, double >& a, const std::pair< double, double >& b ){ 12 return a.first > b.first; 13 } ); 14 minMaxPairForX1_ = std::minmax_element( data_.cbegin( ), data_.cend( ), 15 [ ]( const std::pair< double, double >& a, const std::pair< double, double >& b ){ 16 return a.second > b.second; 17 } ); 18 19 width_ = get_width( ); 20 height_ = get_height( ); 21 } 22 23 bool MyDrawingArea::on_draw( const Cairo::RefPtr<Cairo::Context>& cr ){ 24 if( 0 == data_.size( ) ) return false; 25 26 prepareProperties( ); 27 auto x0band = (*minMaxPairForX0_.first).first - (*minMaxPairForX0_.second).first; 28 auto x1band = (*minMaxPairForX1_.first).second - (*minMaxPairForX1_.second).second; 29 30 auto f0 = [ & ]( double x ){ 31 return ( x - (*minMaxPairForX0_.second).first ) * width_ / x0band; }; 32 auto f1 = [ & ]( double x ){ 33 return height_ - ( x - (*minMaxPairForX1_.second).second ) * height_ / x1band; }; 34 35 cr->set_source_rgb( 1., 1., .8 ); // LIGHT YELLOW 36 cr->rectangle( 0.,0., width_, height_ ); 37 cr->fill( ); 38 39 cr->set_source_rgb( 1., 0., 0. ); // RED 40 for( const auto& pair : data_ ){ 41 cr->arc( 42 f0( pair.first ), f1( pair.second ), 43 3., 0., 2. * G_PI ); // size 3. circle 44 cr->fill( ); 45 } 46 return false; 47 } 48 49 bool MyDrawingArea::on_button_press_event( GdkEventButton* event ){ 50 if( 0 == data_.size( ) ) return false; 51 52 prepareProperties( ); 53 auto x0band = (*minMaxPairForX0_.first).first - (*minMaxPairForX0_.second).first; 54 auto x1band = (*minMaxPairForX1_.first).second - (*minMaxPairForX1_.second).second; 55 56 auto f0 = [ & ]( double x ){ 57 return (*minMaxPairForX0_.second).first + x * x0band / width_; }; 58 auto f1 = [ & ]( double x ){ 59 return x1band * ( height_ - x ) / height_ + (*minMaxPairForX1_.second).second; }; 60 61 if( ( event->type == GDK_BUTTON_PRESS ) && ( event->button == 1 ) ) 62 data_.emplace_back( f0( event->x ), f1( event->y ) ); 63 64 queue_draw( ); 65 return false; 66 } 67}
試したこと
2つめのソースの各行に下記のように追加した.
cpp
1 auto x0band = (*minMaxPairForX0_.first).first - (*minMaxPairForX0_.second).first/1.2; 2 auto x1band = (*minMaxPairForX1_.first).second - (*minMaxPairForX1_.second).second/1.2;
補足情報
ぜひご助力頂けると幸いです.
あなたの回答
tips
プレビュー