LumaScroller.cpp
Go to the documentation of this file.
1 #include "LumaScroller.hpp"
2 
3 #include "Defs.hpp"
5 
6 namespace iv
7 {
8 
9 static constexpr float IndicatorWidth_px = 1;
10 
12  ProtectedSlot( inst ),
13  cm( inst, this, "LumaScroller" ),
14  child( &this->cm, this, nullptr ),
15  heap( inst, &this->cm ),
16  aheap( inst )
17 {
18  this->cm.inherits( this->ProtectedSlot::cm, this->InputNode::cm );
19  this->cm.owns( this->aheap.cm );
20 
22 
23  // background
24  this->root.
25  createChild< iv::Prefsize >()
26  ->prefsize( iv::float3( 0, 0, 0 ) )
27  ->createChild< iv::Image >()
28  ->filename( "/ivorium_graphics/generic/white.png" )
29  ->colorTransform( ColorTransform::Scale( iv::float4( 0.278f, 0.278f, 0.278f, 1.0f ) ) );
30 
31  // overlaps
32  auto overlap_top_prefsize = this->root.
33  createChild< Border >()
34  ->borderLeft( 0 )
35  ->borderRight( 0 )
36  ->borderTop( 0 )
38  ->prefsize( iv::float3( 0, 0, 0 ) );
39 
40  overlap_top_prefsize->
41  createChild< iv::Image >()
42  ->filename( "/ivorium_UI/LumaScroller/overlap.png" )
43  ->preblend( float4( 0.278, 0.278, 0.278, 1.0 ) );
44 
45  auto overlap_bot_prefsize = this->root.
46  createChild< Border >()
47  ->borderLeft( 0 )
48  ->borderRight( 0 )
49  ->borderBottom( 0 )
51  ->scale( iv::float3( 1, -1, 0 ) )
52  ->propagateSize( true )
54  ->prefsize( iv::float3( 0, 0, 0 ) );
55 
56  overlap_bot_prefsize->
57  createChild< iv::Image >()
58  ->filename( "/ivorium_UI/LumaScroller/overlap.png" )
59  ->preblend( float4( 0.278, 0.278, 0.278, 1.0 ) );
60 
61  // indicator
62  auto indicator_border = this->root.
63  createChild< iv::Border >()
64  ->borderRight( 0 )
65  ->borderTop( 0 )
66  ->borderBottom( 0 );
67 
68  auto img_indicator = indicator_border->
69  createChild< iv::Prefsize >()
70  ->prefsize( iv::float3( IndicatorWidth_px, 0, 0 ) )
71  ->createChild< iv::Image >()
72  ->filename( "/ivorium_graphics/generic/white.png" )
73  ->colorTransform( ColorTransform::Scale( float4( 0.55, 0.55, 0.55, 1.0 ) ) )
74  ->preblend( float4( 0.28, 0.28, 0.28, 1.0 ) );
75 
76  // scroller
77  this->scroller = this->root.
78  createChild< iv::Border >()
79  ->borderLeft( 0 )
80  ->borderRight( IndicatorWidth_px )
81  ->borderTop( 0 )
82  ->borderBottom( 0 )
83  ->createChild< Scroller >()
84  ->input_id( Defs::Input::UI_MousePrimary );
85 
86  //---------- animation ---------------
87  // sources
88  AnimNode< float > * in_overlap_top = this->aheap.Attribute_SourceNode< float >( &this->scroller->attr_overlapTop, 0.0f )
89  ->label( "in_overlap_top" );
90  AnimNode< float > * in_overlap_bot = this->aheap.Attribute_SourceNode< float >( &this->scroller->attr_overlapBottom, 0.0f )
91  ->label( "in_overlap_bot" );
92  AnimNode< float > * in_position = this->aheap.Attribute_SourceNode< float >( &this->scroller->attr_position, 0.0f )
93  ->label( "in_position" );
94  AnimNode< float > * in_insize = this->aheap.Attribute_SourceNode< float >( &this->scroller->attr_insize, 0.0f )
95  ->label( "in_insize" );
96  AnimNode< float > * in_outsize = this->aheap.Attribute_SourceNode< float >( &this->scroller->attr_outsize, 0.0f )
97  ->label( "in_outsize" );
98 
99  // destinations
100  AnimNode< std::optional< float > > * out_overlap_top_height = this->aheap.Attribute_DestinationNode( &overlap_top_prefsize->attr_prefsizeY, std::optional< float >() )
101  ->label( "out_overlap_top_height" );
102  AnimNode< std::optional< float > > * out_overlap_bot_height = this->aheap.Attribute_DestinationNode( &overlap_bot_prefsize->attr_prefsizeY, std::optional< float >() )
103  ->Speed( 10.0f )
104  ->label( "out_overlap_bot_height" );
105  AnimNode< std::optional< float > > * out_indicator_top = this->aheap.Attribute_DestinationNode( &indicator_border->attr_borderTop, std::optional< float >() )
106  ->Speed_inf()
107  ->label( "out_indicator_top" );
108  AnimNode< std::optional< float > > * out_indicator_bot = this->aheap.Attribute_DestinationNode( &indicator_border->attr_borderBottom, std::optional< float >() )
109  ->Speed_inf()
110  ->label( "out_indicator_bot" );
111  AnimNode< float > * out_indicator_alpha = this->aheap.Attribute_DestinationNode( &img_indicator->shading.alpha, 0.0f )
112  ->Speed( 1.0f )
113  ->label( "out_indicator_alpha" );
114 
115  // lambda connector
116  Lambda_Connector * lambda = this->aheap.Make_Lambda_Connector()
117  ->AddParent( in_overlap_top )
118  ->AddParent( in_overlap_bot )
119  ->AddParent( in_position )
120  ->AddParent( in_insize )
121  ->AddParent( in_outsize )
122  ->AddChild( out_overlap_top_height )
123  ->AddChild( out_overlap_bot_height )
124  ->AddChild( out_indicator_top )
125  ->AddChild( out_indicator_bot )
126  ->AddChild( out_indicator_alpha );
127 
128  lambda->Retargeting(
129  [ in_overlap_top, in_overlap_bot, in_position, in_insize, in_outsize, out_overlap_top_height, out_overlap_bot_height, out_indicator_top, out_indicator_bot, out_indicator_alpha ]( bool warping )
130  {
131  //std::cout << "LumaScroller: Retarget" << std::endl;
132 
133  // top overlap
134  if( in_overlap_top->Target() > out_overlap_top_height->Target() ) // Imperfect direction detection, but it might work.
135  out_overlap_top_height->Speed_inf();
136  else
137  out_overlap_top_height->Speed( 25.0f );
138 
139  out_overlap_top_height->Target( in_overlap_top->Target() );
140 
141  // bottom overlap
142  if( in_overlap_bot->Target() > out_overlap_bot_height->Target() ) // Imperfect direction detection, but it might work.
143  out_overlap_bot_height->Speed_inf();
144  else
145  out_overlap_bot_height->Speed( 25.0f );
146  out_overlap_bot_height->Target( in_overlap_bot->Target() );
147 
148  // indicator
149  if( in_outsize->Target() >= in_insize->Target() )
150  {
151  out_indicator_alpha->Target( 0.0f );
152 
153  out_indicator_top->Target( 0.0f );
154  out_indicator_bot->Target( 0.0f );
155  }
156  else
157  {
158  out_indicator_alpha->Target( 1.0f );
159 
160  float outsize = in_outsize->Target();
161  float insize = in_insize->Target();
162  float pos = std::clamp( in_position->Target(), 0.0f, insize - outsize );
163 
164  float top = outsize * pos / insize;
165  float height = outsize * outsize / insize;
166  float bottom = outsize - top - height;
167 
168  out_indicator_top->Target( top );
169  out_indicator_bot->Target( bottom );
170  }
171  }
172  );
173 }
174 
176 {
177  this->scroller->setChild( this->child.Get() );
178 }
179 
181 {
182  this->ProtectedSlot::first_pass_impl( er );
183 }
184 
185 }