From: Paul Wisbey Date: Thu, 21 Jul 2016 09:49:51 +0000 (-0700) Subject: Merge "Fix for the cursor position with the arabic script." into devel/master X-Git-Tag: dali_1.1.44~3 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=d00a250741411c386d988e7ac34525cf94a1918e;hp=8d92a2cdf4665c1831b524af0a316208947e27c1 Merge "Fix for the cursor position with the arabic script." into devel/master --- diff --git a/automated-tests/patch-coverage.pl b/automated-tests/patch-coverage.pl new file mode 100755 index 0000000..68754eb --- /dev/null +++ b/automated-tests/patch-coverage.pl @@ -0,0 +1,555 @@ +#!/usr/bin/perl +# +# Copyright (c) 2016 Samsung Electronics Co., Ltd. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +use strict; +use Git; +use Getopt::Long; +use Error qw(:try); +use Pod::Usage; +use File::Basename; +use File::stat; +use Scalar::Util qw /looks_like_number/; +use Cwd qw /getcwd/; +use Term::ANSIColor qw(:constants); + +# Program to run gcov on files in patch (that are in source dirs - needs to be dali-aware). + +# A) Get patch +# B) Remove uninteresting files +# C) Find matching gcno/gcda files +# D) Copy and rename them to match source prefix (i.e. strip library name off front) +# E) Generate patch output with covered/uncovered lines marked in green/red +# F) Generate coverage data for changed lines +# G) Exit status should be 0 for high coverage (90% line coverage for all new/changed lines) +# or 1 for low coverage + +# Sources for conversion of gcno/gcda files: +# ~/bin/lcov +# Python git-coverage (From http://stef.thewalter.net/git-coverage-useful-code-coverage.html) + +our $repo = Git->repository(); +our $debug=0; +our $pd_debug=0; +our $opt_cached; +our $opt_head; +#our $opt_workingtree; +#our $opt_diff=1; +our $opt_help; +our $opt_verbose; +our $opt_quiet; + +my %options = ( + "cached" => { "optvar"=>\$opt_cached, "desc"=>"Use index" }, + "head" => { "optvar"=>\$opt_head, "desc"=>"Use git show" }, + "help" => { "optvar"=>\$opt_help, "desc"=>""}, + "quiet" => { "optvar"=>\$opt_quiet, "desc"=>""}, + "verbose" => { "optvar"=>\$opt_verbose, "desc"=>"" }); + +my %longOptions = map { $_ => $options{$_}->{"optvar"} } keys(%options); +GetOptions( %longOptions ) or pod2usage(2); +pod2usage(1) if $opt_help; + + +## Format per file, repeated, no linebreak +# +# index c1..c2 c3 +# --- a/ +# +++ b/ +# + +# Format of each diff hunk, repeated, no linebreak +# @@ @@ line +# 3 lines of context +# [-|+]lines removed on left, added on right +# 3 lines of context +# +# output: +sub parse_diff +{ + my $patchref = shift; + my $file=""; + my @checklines=(); + my %b_lines=(); + my $state = 0; + my $store_line=-1; + my %files=(); + + print "Patch size: ".scalar(@$patchref)."\n" if $pd_debug; + for my $line (@$patchref) + { + if($state == 0) + { + print "State: $state $line \n" if $pd_debug; + # Search for a line matching "+++ b/" + if( $line =~ m!^\+\+\+ b/([\w-_\./]*)!) + { + $file = $1; + $state = 1 ; + print "Found File: $file\n" if $pd_debug; + } + } + else #elsif($state == 1) + { + # If we find a line starting with diff, the previous + # file's diffs have finished, store them. + if( $line =~ /^diff/) + { + print "State: $state $line \n" if $pd_debug; + $state = 0; + # if the file had changes, store the new/modified line numbers + if( $file && scalar(@checklines)) + { + $files{$file}->{"patch"} = [@checklines]; + $files{$file}->{"b_lines"} = {%b_lines}; + @checklines=(); + %b_lines=(); + } + print("\n\n") if $pd_debug; + } + # If we find a line starting with @@, it tells us the line numbers + # of the old file and new file for this hunk. + elsif( $line =~ /^@@/) + { + print "State: $state $line \n" if $pd_debug; + + # Find the lines in the new file (of the form "+[,]) + my($start,$space,$length) = ($line =~ /\+([0-9]+)(,| )([0-9]+)?/); + if($length || $space eq " ") + { + if( $space eq " " ) + { + $length=1; + } + push(@checklines, [$start, $length]); + $store_line=$start; + } + else + { + $store_line = -1; + } + if($pd_debug) + { + my $last = scalar(@checklines)-1; + if( $last >= 0 ) + { + print "Checkline:" . $checklines[$last]->[0] . ", " . $checklines[$last]->[1] . "\n"; + } + } + } + # If we find a line starting with "+", it belongs to the new file's patch + elsif( $line =~ /^\+/) + { + if($store_line >= 0) + { + chomp; + $line = substr($line, 1); # Remove leading + + $b_lines{$store_line} = $line; + $store_line++; + } + } + } + } + # Store the final entry + $files{$file}->{"patch"} = [@checklines]; + $files{$file}->{"b_lines"} = {%b_lines}; + + my %filter = map { $_ => $files{$_} } grep {m!^dali(-toolkit)?/!} (keys(%files));; + + if($pd_debug) + { + print("Filtered files:\n"); + foreach my $file (keys(%filter)) + { + print("$file: "); + $patchref = $filter{$file}->{"patch"}; + foreach my $lineblock (@$patchref) + { + print "$lineblock->[0]($lineblock->[1]) " + } + print ( "\n"); + } + } + + return {%filter}; +} + +sub show_patch_lines +{ + my $filesref = shift; + print "\nNumber of files: " . scalar(keys(%$filesref)) . "\n"; + for my $file (keys(%$filesref)) + { + print("$file:"); + my $clref = $filesref->{$file}->{"patch"}; + for my $cl (@$clref) + { + print("($cl->[0],$cl->[1]) "); + } + print("\n"); + } +} + +sub get_gcno_file +{ + # Assumes test cases have been run, and "make rename_cov_data" has been executed + + my $file = shift; + my ($name, $path, $suffix) = fileparse($file, (".c", ".cpp", ".h")); + my $gcno_file = $repo->wc_path() . "/build/tizen/.cov/$name.gcno"; + + # Note, will translate headers to their source's object, which + # may miss execution code in the headers (e.g. inlines are usually + # not all used in the implementation, and require getting coverage + # from test cases. + + if( -f $gcno_file ) + { + my $gcno_st = stat($gcno_file); + my $fq_file = $repo->wc_path() . $file; + my $src_st = stat($fq_file); + if($gcno_st->ctime < $src_st->mtime) + { + print "WARNING: GCNO $gcno_file older than SRC $fq_file\n"; + $gcno_file=""; + } + + } + else + { + print("WARNING: No equivalent gcno file for $file\n"); + } + return $gcno_file; +} + +our %gcovfiles=(); +sub get_coverage +{ + my $file = shift; + my $filesref = shift; + print("get_coverage($file)\n") if $debug; + + my $gcno_file = get_gcno_file($file); + my @gcov_files = (); + my $gcovfile; + if( $gcno_file ) + { + print "Running gcov on $gcno_file:\n" if $debug; + open( my $fh, "gcov --preserve-paths $gcno_file |") || die "Can't run gcov:$!\n"; + while( <$fh> ) + { + print $_ if $debug>=3; + chomp; + if( m!'(.*\.gcov)'$! ) + { + my $coverage_file = $1; # File has / replaced with # and .. replaced with ^ + my $source_file = $coverage_file; + $source_file =~ s!\^!..!g; # Change ^ to .. + $source_file =~ s!\#!/!g; # change #'s to /s + $source_file =~ s!.gcov$!!; # Strip off .gcov suffix + + print "Matching $file against $source_file\n" if $debug >= 3; + # Only want the coverage files matching source file: + if(index( $source_file, $file ) > 0 ) + { + $gcovfile = $coverage_file; + last; + } + } + } + close($fh); + + if($gcovfile) + { + if($gcovfiles{$gcovfile} == undef) + { + # Only parse a gcov file once + $gcovfiles{$gcovfile}->{"seen"}=1; + + print "Getting coverage data from $gcovfile\n" if $debug; + + open( FH, "< $gcovfile" ) || die "Can't open $gcovfile for reading:$!\n"; + while() + { + my ($cov, $line, @code ) = split( /:/, $_ ); + $cov =~ s/^\s+//; # Strip leading space + $line =~ s/^\s+//; + my $code=join(":", @code); + if($cov =~ /\#/) + { + # There is no coverage data for these executable lines + $gcovfiles{$gcovfile}->{"uncovered"}->{$line}++; + $gcovfiles{$gcovfile}->{"src"}->{$line}=$code; + } + elsif( $cov ne "-" && looks_like_number($cov) && $cov > 0 ) + { + $gcovfiles{$gcovfile}->{"covered"}->{$line}=$cov; + $gcovfiles{$gcovfile}->{"src"}->{$line}=$code; + } + else + { + # All other lines are not executable. + $gcovfiles{$gcovfile}->{"src"}->{$line}=$code; + } + } + close( FH ); + } + $filesref->{$file}->{"coverage"} = $gcovfiles{$gcovfile}; # store hashref + } + else + { + # No gcov output - the gcno file produced no coverage of the source/header + # Probably means that there is no coverage for the file (with the given + # test case - there may be some somewhere, but for the sake of speed, don't + # check (yet). + } + } +} + +# Run the git diff command to get the patch, then check the coverage +# output for the patch. +sub run_diff +{ + my ($fh, $c) = $repo->command_output_pipe(@_); + our @patch=(); + while(<$fh>) + { + chomp; + push @patch, $_; + } + $repo->command_close_pipe($fh, $c); + + # @patch has slurped diff for all files... + my $filesref = parse_diff ( \@patch ); + show_patch_lines($filesref) if $debug; + + print "Checking coverage:\n" if $debug; + + my $cwd=getcwd(); + chdir ".cov" || die "Can't find $cwd/.cov:$!\n"; + + for my $file (keys(%$filesref)) + { + my ($name, $path, $suffix) = fileparse($file, qr{\.[^.]*$}); + if($suffix eq ".cpp" || $suffix eq ".c" || $suffix eq ".h") + { + get_coverage($file, $filesref); + } + } + chdir $cwd; + return $filesref; +} + + +sub calc_patch_coverage_percentage +{ + my $filesref = shift; + my $total_covered_lines = 0; + my $total_uncovered_lines = 0; + + foreach my $file (keys(%$filesref)) + { + my $covered_lines = 0; + my $uncovered_lines = 0; + + my $patchref = $filesref->{$file}->{"patch"}; + my $coverage_ref = $filesref->{$file}->{"coverage"}; + if( $coverage_ref ) + { + for my $patch (@$patchref) + { + for(my $i = 0; $i < $patch->[1]; $i++ ) + { + my $line = $i + $patch->[0]; + if($coverage_ref->{"covered"}->{$line}) + { + $covered_lines++; + $total_covered_lines++; + } + if($coverage_ref->{"uncovered"}->{$line}) + { + $uncovered_lines++; + $total_uncovered_lines++; + } + } + } + $coverage_ref->{"covered_lines"} = $covered_lines; + $coverage_ref->{"uncovered_lines"} = $uncovered_lines; + my $total = $covered_lines + $uncovered_lines; + my $percent = 0; + if($total > 0) + { + $percent = $covered_lines / $total; + } + $coverage_ref->{"percent_covered"} = 100 * $percent; + } + } + my $total_exec = $total_covered_lines + $total_uncovered_lines; + my $percent = 0; + if($total_exec > 0) { $percent = 100 * $total_covered_lines / $total_exec; } + + return $percent; +} + +sub patch_output +{ + my $filesref = shift; + foreach my $file (keys(%$filesref)) + { + my ($name, $path, $suffix) = fileparse($file, qr{\.[^.]*$}); + next if($path !~ /^dali/); + + my $patchref = $filesref->{$file}->{"patch"}; + my $b_lines_ref = $filesref->{$file}->{"b_lines"}; + my $coverage_ref = $filesref->{$file}->{"coverage"}; + print BOLD, "$file "; + + if($coverage_ref) + { + if( $coverage_ref->{"covered_lines"} > 0 + || + $coverage_ref->{"uncovered_lines"} > 0 ) + { + print GREEN, "Covered: " . $coverage_ref->{"covered_lines"}, RED, " Uncovered: " . $coverage_ref->{"uncovered_lines"}, RESET; + } + } + else + { + if($suffix eq ".cpp" || $suffix eq ".c" || $suffix eq ".h") + { + print RED; + } + print "No coverage found"; + } + print RESET "\n"; + + for my $patch (@$patchref) + { + my $hunkstr="Hunk: " . $patch->[0]; + if( $patch->[1] > 1 ) + { + $hunkstr .= " - " . ($patch->[0]+$patch->[1]-1); + } + print BOLD, "$hunkstr\n", RESET; + for(my $i = 0; $i < $patch->[1]; $i++ ) + { + my $line = $i + $patch->[0]; + printf "%-6s ", $line; + + if($coverage_ref) + { + my $color; + if($coverage_ref->{"covered"}->{$line}) + { + $color=GREEN; + } + elsif($coverage_ref->{"uncovered"}->{$line}) + { + $color=BOLD . RED; + } + else + { + $color=BLACK; + } + my $src=$coverage_ref->{"src"}->{$line}; + chomp($src); + print $color, "$src\n", RESET; + } + else + { + # We don't have coverage data, so print it from the patch instead. + my $src = $b_lines_ref->{$line}; + print "$src\n"; + } + } + } + } +} + + +################################################################################ +## MAIN ## +################################################################################ + +my $cwd = getcwd(); +chdir $repo->wc_path(); +chdir "build/tizen"; +`make rename_cov_data`; + +my @cmd=('--no-pager','diff','--no-ext-diff','-U0','--no-color'); + +my $status = $repo->command("status", "-s"); +if( $status eq "" ) +{ + # There are no changes in the index or working tree. Use the last patch instead + push @cmd, ('HEAD~1','HEAD'); +} +elsif($opt_cached) # TODO: Remove this option. Instead, need full diff +{ + push @cmd, "--cached"; +} + +push @cmd, @ARGV; +my $filesref = run_diff(@cmd); + +my $percent = calc_patch_coverage_percentage($filesref); +if( ! $opt_quiet ) +{ + patch_output($filesref); + my $color=BOLD RED; + if($percent>=90) + { + $color=GREEN; + } + printf("Percentage of change covered: $color %5.2f%\n" . RESET, $percent); +} +exit($percent<90); + + +__END__ + +=head1 NAME + +patch-coverage + +=head1 SYNOPSIS + +patch-coverage.pl - Determine if patch coverage is below 90% + +=head1 DESCRIPTION +Calculates how well the most recent patch is covered (either the +patch that is in the index+working directory, or HEAD). + +=head1 OPTIONS + +=over 28 + +=item B<-c|--cached> +Use index files if there is nothing in the working tree + +=item B< --help> +This help + +=item B<-q|--quiet> +Don't generate any output + +=head1 RETURN STATUS +0 if the coverage of source files is > 90%, otherwise 1 + +=head1 EXAMPLES + + +=cut diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/mesh-builder.h b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/mesh-builder.h index 16cd93d..d22f9c8 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/mesh-builder.h +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/mesh-builder.h @@ -1,7 +1,8 @@ #ifndef MESH_BUILDER_H #define MESH_BUILDER_H + /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,12 +18,8 @@ * */ +// EXTERNAL INCLUDES #include -#include -#include -#include -#include -#include namespace Dali { @@ -32,6 +29,7 @@ TextureSet CreateTextureSet(); TextureSet CreateTextureSet( Image image ); Geometry CreateQuadGeometry(); PropertyBuffer CreatePropertyBuffer(); + } #endif // MESH_BUILDER_H diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-actor-utils.cpp b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-actor-utils.cpp index 5a8a5d1..f8d7bf8 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-actor-utils.cpp +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-actor-utils.cpp @@ -21,7 +21,6 @@ // EXTERNAL INCLUDES #include #include -#include // INTERNAL INCLUDES #include "mesh-builder.h" diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-actor-utils.h b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-actor-utils.h index c5c5d0a..28953cb 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-actor-utils.h +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-actor-utils.h @@ -1,5 +1,5 @@ -#ifndef __DALI_TEST_ACTOR_UTILS_H__ -#define __DALI_TEST_ACTOR_UTILS_H__ +#ifndef DALI_TEST_ACTOR_UTILS_H +#define DALI_TEST_ACTOR_UTILS_H /* * Copyright (c) 2016 Samsung Electronics Co., Ltd. @@ -58,4 +58,4 @@ Image GetTexture( Actor actor ); } // namespace Dali -#endif // __DALI_TEST_ACTOR_UTILS_H__ +#endif // DALI_TEST_ACTOR_UTILS_H diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-bitmap-loader.h b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-bitmap-loader.h index 6b2c94a..acdc94a 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-bitmap-loader.h +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-bitmap-loader.h @@ -1,5 +1,5 @@ -#ifndef __DALI_TOOLKIT_BITMAP_LOADER_H__ -#define __DALI_TOOLKIT_BITMAP_LOADER_H__ +#ifndef DALI_TOOLKIT_BITMAP_LOADER_H +#define DALI_TOOLKIT_BITMAP_LOADER_H /* * Copyright (c) 2016 Samsung Electronics Co., Ltd. * @@ -16,14 +16,14 @@ * limitations under the License. */ -#define __DALI_BITMAP_LOADER_H__ +#define DALI_BITMAP_LOADER_H #include #include -#include #include +#include +#include #include -#include namespace Dali { @@ -63,4 +63,4 @@ public: // Not intended for application developers } // Dali -#endif /* __DALI_TOOLKIT_BITMAP_LOADER_H__ */ +#endif // DALI_TOOLKIT_BITMAP_LOADER_H diff --git a/automated-tests/src/dali-toolkit/utc-Dali-BubbleEmitter.cpp b/automated-tests/src/dali-toolkit/utc-Dali-BubbleEmitter.cpp index f17e30e..4c711f3 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-BubbleEmitter.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-BubbleEmitter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include diff --git a/automated-tests/src/dali-toolkit/utc-Dali-Button.cpp b/automated-tests/src/dali-toolkit/utc-Dali-Button.cpp index b5ec1f1..5aff146 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-Button.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-Button.cpp @@ -64,28 +64,6 @@ struct CallbackFunctor bool* mCallbackFlag; }; - -Image CreateSolidColorImage( const Vector4& color, unsigned int width, unsigned int height ) -{ - BufferImage imageData = BufferImage::New( width, height, Pixel::RGBA8888 ); - - // Create the image - PixelBuffer* pixbuf = imageData.GetBuffer(); - unsigned int size = width * height; - - for( size_t i = 0; i < size; i++ ) - { - pixbuf[i*4+0] = 0xFF * color.r; - pixbuf[i*4+1] = 0xFF * color.g; - pixbuf[i*4+2] = 0xFF * color.b; - pixbuf[i*4+3] = 0xFF * color.a; - } - - imageData.Update(); - - return imageData; -} - Dali::Integration::Point GetPointDownInside() { Dali::Integration::Point point; @@ -941,3 +919,56 @@ int UtcDaliButtonSetSelectedImageWithImageN(void) END_TEST; } + +int UtcDaliButtonSetSelectedColorP(void) +{ + ToolkitTestApplication application; + tet_infoline(" UtcDaliButtonSetSelectedColorP"); + + PushButton pushButton = PushButton::New(); + Stage::GetCurrent().Add( pushButton ); + + application.SendNotification(); + application.Render(); + + const Vector4 SET_COLOR = Color::BLUE; + + pushButton.SetSize( Vector2( 20.0f, 20.0f ) ); + pushButton.SetProperty( Button::Property::SELECTED_COLOR, SET_COLOR ); + + application.SendNotification(); + application.Render(); + + Vector4 color = pushButton.GetProperty( Button::Property::SELECTED_COLOR ); + + DALI_TEST_EQUALS( color, SET_COLOR, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliButtonSetUnSelectedColorP(void) +{ + ToolkitTestApplication application; + tet_infoline(" UtcDaliButtonSetUnSelectedColorP"); + + PushButton pushButton = PushButton::New(); + Stage::GetCurrent().Add( pushButton ); + + application.SendNotification(); + application.Render(); + + const Vector4 SET_COLOR = Color::BLUE; + + pushButton.SetSize( Vector2( 20.0f, 20.0f ) ); + pushButton.SetProperty( Button::Property::UNSELECTED_COLOR, SET_COLOR ); + + application.SendNotification(); + application.Render(); + + Vector4 color = pushButton.GetProperty( Button::Property::UNSELECTED_COLOR ); + + DALI_TEST_EQUALS( color, SET_COLOR, TEST_LOCATION ); + + END_TEST; +} + diff --git a/automated-tests/src/dali-toolkit/utc-Dali-Control.cpp b/automated-tests/src/dali-toolkit/utc-Dali-Control.cpp index 1ecf233..fdf25e7 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-Control.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-Control.cpp @@ -396,7 +396,7 @@ int UtcDaliControlBackgroundColor(void) Property::Value propValue = control.GetProperty( Control::Property::BACKGROUND ); Property::Map* resultMap = propValue.GetMap(); DALI_TEST_CHECK( resultMap->Find( "rendererType" ) ); - DALI_TEST_CHECK( resultMap->Find( "rendererType" )->Get() == "color" ); + DALI_TEST_CHECK( resultMap->Find( "rendererType" )->Get() == "COLOR" ); DALI_TEST_CHECK( resultMap->Find( "mixColor" ) ); DALI_TEST_CHECK( resultMap->Find( "mixColor" )->Get() == Color::RED ); @@ -427,7 +427,7 @@ int UtcDaliControlBackgroundImage(void) Property::Value propValue = control.GetProperty( Control::Property::BACKGROUND ); Property::Map* resultMap = propValue.GetMap(); DALI_TEST_CHECK( resultMap->Find( "rendererType" ) ); - DALI_TEST_CHECK( resultMap->Find( "rendererType" )->Get() == "image" ); + DALI_TEST_CHECK( resultMap->Find( "rendererType" )->Get() == "IMAGE" ); DALI_TEST_CHECK( resultMap->Find( "url" ) ); DALI_TEST_CHECK( resultMap->Find( "url" )->Get() == "TestImage" ); @@ -451,24 +451,24 @@ int UtcDaliControlBackgroundProperties(void) DALI_TEST_CHECK( control.GetProperty( Control::Property::BACKGROUND ).Get< Property::Map >().Empty() ); Property::Map imageMap; - imageMap[ "rendererType" ] = "image"; + imageMap[ "rendererType" ] = "IMAGE"; imageMap[ "url" ] = "TestImage"; control.SetProperty( Control::Property::BACKGROUND, imageMap ); Property::Value propValue = control.GetProperty( Control::Property::BACKGROUND ); Property::Map* resultMap = propValue.GetMap(); DALI_TEST_CHECK( resultMap->Find( "rendererType" ) ); - DALI_TEST_CHECK( resultMap->Find( "rendererType" )->Get() == "image" ); + DALI_TEST_CHECK( resultMap->Find( "rendererType" )->Get() == "IMAGE" ); DALI_TEST_CHECK( resultMap->Find( "url" ) ); DALI_TEST_CHECK( resultMap->Find( "url" )->Get() == "TestImage" ); Property::Map rendererMap; - rendererMap["rendererType"] = "color"; + rendererMap["rendererType"] = "COLOR"; rendererMap["mixColor"] = Color::CYAN; control.SetProperty( Control::Property::BACKGROUND, rendererMap ); propValue = control.GetProperty( Control::Property::BACKGROUND ); resultMap = propValue.GetMap(); DALI_TEST_CHECK( resultMap->Find( "rendererType" ) ); - DALI_TEST_CHECK( resultMap->Find( "rendererType" )->Get() == "color" ); + DALI_TEST_CHECK( resultMap->Find( "rendererType" )->Get() == "COLOR" ); DALI_TEST_CHECK( resultMap->Find( "mixColor" ) ); DALI_TEST_CHECK( resultMap->Find( "mixColor" )->Get() == Color::CYAN ); diff --git a/automated-tests/src/dali-toolkit/utc-Dali-ControlRenderer.cpp b/automated-tests/src/dali-toolkit/utc-Dali-ControlRenderer.cpp index 43caadd..8b3989f 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-ControlRenderer.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-ControlRenderer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,9 +17,9 @@ #include #include #include -#include -#include -#include +#include +#include +#include #include using namespace Dali; @@ -52,7 +52,7 @@ int UtcDaliControlRendererCopyAndAssignment(void) RendererFactory factory = RendererFactory::Get(); Property::Map propertyMap; - propertyMap.Insert("rendererType", "color"); + propertyMap.Insert("rendererType", "COLOR"); propertyMap.Insert("mixColor", Color::BLUE); ControlRenderer controlRenderer = factory.CreateControlRenderer( propertyMap ); @@ -85,7 +85,7 @@ int UtcDaliControlRendererSetGetDepthIndex(void) RendererFactory factory = RendererFactory::Get(); Property::Map propertyMap; - propertyMap.Insert("rendererType", "color"); + propertyMap.Insert("rendererType", "COLOR"); propertyMap.Insert("mixColor", Color::BLUE); ControlRenderer controlRenderer = factory.CreateControlRenderer( propertyMap ); @@ -119,7 +119,7 @@ int UtcDaliControlRendererSize(void) // color renderer Dali::Property::Map map; - map[ "rendererType" ] = "color"; + map[ "rendererType" ] = "COLOR"; map[ "mixColor" ] = Color::MAGENTA; ControlRenderer colorRenderer = factory.CreateControlRenderer( map ); colorRenderer.SetSize( rendererSize ); @@ -149,7 +149,7 @@ int UtcDaliControlRendererSize(void) // border renderer float borderSize = 5.f; map.Clear(); - map[ "rendererType" ] = "border"; + map[ "rendererType" ] = "BORDER"; map[ "borderColor" ] = Color::RED; map[ "borderSize" ] = borderSize; ControlRenderer borderRenderer = factory.CreateControlRenderer( map ); @@ -160,7 +160,7 @@ int UtcDaliControlRendererSize(void) // gradient renderer Property::Map propertyMap; - propertyMap.Insert("rendererType", "gradient"); + propertyMap.Insert("rendererType", "GRADIENT"); Vector2 start(-1.f, -1.f); Vector2 end(1.f, 1.f); propertyMap.Insert("startPosition", start); @@ -196,7 +196,7 @@ int UtcDaliControlRendererSetOnOffStage(void) RendererFactory factory = RendererFactory::Get(); Property::Map propertyMap; - propertyMap.Insert("rendererType", "color"); + propertyMap.Insert("rendererType", "COLOR"); propertyMap.Insert("mixColor", Color::BLUE); ControlRenderer controlRenderer = factory.CreateControlRenderer( propertyMap ); @@ -269,7 +269,7 @@ int UtcDaliControlRendererGetPropertyMap1(void) RendererFactory factory = RendererFactory::Get(); Property::Map propertyMap; - propertyMap.Insert("rendererType", "color"); + propertyMap.Insert("rendererType", "COLOR"); propertyMap.Insert("mixColor", Color::BLUE); ControlRenderer colorRenderer = factory.CreateControlRenderer( propertyMap ); @@ -278,7 +278,7 @@ int UtcDaliControlRendererGetPropertyMap1(void) Property::Value* typeValue = resultMap.Find( "rendererType", Property::STRING ); DALI_TEST_CHECK( typeValue ); - DALI_TEST_CHECK( typeValue->Get() == "color" ); + DALI_TEST_CHECK( typeValue->Get() == "COLOR" ); Property::Value* colorValue = resultMap.Find( "mixColor", Property::VECTOR4 ); DALI_TEST_CHECK( colorValue ); @@ -305,7 +305,7 @@ int UtcDaliControlRendererGetPropertyMap2(void) RendererFactory factory = RendererFactory::Get(); Property::Map propertyMap; - propertyMap.Insert("rendererType", "border"); + propertyMap.Insert("rendererType", "BORDER"); propertyMap.Insert("borderColor", Color::BLUE); propertyMap.Insert("borderSize", 5.f); ControlRenderer borderRenderer = factory.CreateControlRenderer( propertyMap ); @@ -316,7 +316,7 @@ int UtcDaliControlRendererGetPropertyMap2(void) // check the property values from the returned map from control renderer Property::Value* typeValue = resultMap.Find( "rendererType", Property::STRING ); DALI_TEST_CHECK( typeValue ); - DALI_TEST_CHECK( typeValue->Get() == "border" ); + DALI_TEST_CHECK( typeValue->Get() == "BORDER" ); Property::Value* colorValue = resultMap.Find( "borderColor", Property::VECTOR4 ); DALI_TEST_CHECK( colorValue ); @@ -327,7 +327,7 @@ int UtcDaliControlRendererGetPropertyMap2(void) DALI_TEST_CHECK( sizeValue->Get() == 5.f ); Property::Map propertyMap1; - propertyMap1[ "rendererType" ] = "border"; + propertyMap1[ "rendererType" ] = "BORDER"; propertyMap1[ "borderColor" ] = Color::CYAN; propertyMap1[ "borderSize" ] = 10.0f; borderRenderer = factory.CreateControlRenderer( propertyMap1 ); @@ -335,7 +335,7 @@ int UtcDaliControlRendererGetPropertyMap2(void) typeValue = resultMap.Find( "rendererType", Property::STRING ); DALI_TEST_CHECK( typeValue ); - DALI_TEST_CHECK( typeValue->Get() == "border" ); + DALI_TEST_CHECK( typeValue->Get() == "BORDER" ); colorValue = resultMap.Find( "borderColor", Property::VECTOR4 ); DALI_TEST_CHECK( colorValue ); @@ -357,13 +357,13 @@ int UtcDaliControlRendererGetPropertyMap3(void) DALI_TEST_CHECK( factory ); Property::Map propertyMap; - propertyMap.Insert("rendererType", "gradient"); + propertyMap.Insert("rendererType", "GRADIENT"); Vector2 start(-1.f, -1.f); Vector2 end(1.f, 1.f); - propertyMap.Insert("startPosition", start); - propertyMap.Insert("endPosition", end); - propertyMap.Insert("spreadMethod", "repeat"); + propertyMap.Insert("startPosition", start); + propertyMap.Insert("endPosition", end); + propertyMap.Insert("spreadMethod", "REPEAT"); propertyMap.Insert("stopOffset", Vector2(0.2f, 0.8f)); @@ -380,15 +380,15 @@ int UtcDaliControlRendererGetPropertyMap3(void) // check the property values from the returned map from control renderer Property::Value* value = resultMap.Find( "rendererType", Property::STRING ); DALI_TEST_CHECK( value ); - DALI_TEST_CHECK( value->Get() == "gradient" ); + DALI_TEST_CHECK( value->Get() == "GRADIENT" ); value = resultMap.Find( "units", Property::STRING ); DALI_TEST_CHECK( value ); - DALI_TEST_CHECK( value->Get() == "objectBoundingBox" ); + DALI_TEST_CHECK( value->Get() == "OBJECT_BOUNDING_BOX" ); value = resultMap.Find( "spreadMethod", Property::STRING ); DALI_TEST_CHECK( value ); - DALI_TEST_CHECK( value->Get() == "repeat" ); + DALI_TEST_CHECK( value->Get() == "REPEAT" ); value = resultMap.Find( "startPosition", Property::VECTOR2 ); DALI_TEST_CHECK( value ); @@ -424,11 +424,11 @@ int UtcDaliControlRendererGetPropertyMap4(void) DALI_TEST_CHECK( factory ); Property::Map propertyMap; - propertyMap.Insert("rendererType", "gradient"); + propertyMap.Insert("rendererType", "GRADIENT"); Vector2 center(100.f, 100.f); float radius = 100.f; - propertyMap.Insert("units", "userSpace"); + propertyMap.Insert("units", "USER_SPACE"); propertyMap.Insert("center", center); propertyMap.Insert("radius", radius); propertyMap.Insert("stopOffset", Vector3(0.1f, 0.3f, 1.1f)); @@ -448,15 +448,15 @@ int UtcDaliControlRendererGetPropertyMap4(void) // check the property values from the returned map from control renderer Property::Value* value = resultMap.Find( "rendererType", Property::STRING ); DALI_TEST_CHECK( value ); - DALI_TEST_CHECK( value->Get() == "gradient" ); + DALI_TEST_CHECK( value->Get() == "GRADIENT" ); value = resultMap.Find( "units", Property::STRING ); DALI_TEST_CHECK( value ); - DALI_TEST_CHECK( value->Get() == "userSpace" ); + DALI_TEST_CHECK( value->Get() == "USER_SPACE" ); value = resultMap.Find( "spreadMethod", Property::STRING ); DALI_TEST_CHECK( value ); - DALI_TEST_CHECK( value->Get() == "pad" ); + DALI_TEST_CHECK( value->Get() == "PAD" ); value = resultMap.Find( "center", Property::VECTOR2 ); DALI_TEST_CHECK( value ); @@ -493,7 +493,7 @@ int UtcDaliControlRendererGetPropertyMap5(void) RendererFactory factory = RendererFactory::Get(); Property::Map propertyMap; - propertyMap.Insert( "rendererType", "image" ); + propertyMap.Insert( "rendererType", "IMAGE" ); propertyMap.Insert( "url", TEST_IMAGE_FILE_NAME ); propertyMap.Insert( "desiredWidth", 20 ); propertyMap.Insert( "desiredHeight", 30 ); @@ -510,7 +510,7 @@ int UtcDaliControlRendererGetPropertyMap5(void) // check the property values from the returned map from control renderer Property::Value* value = resultMap.Find( "rendererType", Property::STRING ); DALI_TEST_CHECK( value ); - DALI_TEST_CHECK( value->Get() == "image" ); + DALI_TEST_CHECK( value->Get() == "IMAGE" ); value = resultMap.Find( "url", Property::STRING ); DALI_TEST_CHECK( value ); @@ -543,7 +543,7 @@ int UtcDaliControlRendererGetPropertyMap5(void) value = resultMap.Find( "rendererType", Property::STRING ); DALI_TEST_CHECK( value ); - DALI_TEST_CHECK( value->Get() == "image" ); + DALI_TEST_CHECK( value->Get() == "IMAGE" ); value = resultMap.Find( "url", Property::STRING ); DALI_TEST_CHECK( value ); @@ -579,7 +579,7 @@ int UtcDaliControlRendererGetPropertyMap6(void) RendererFactory factory = RendererFactory::Get(); Property::Map propertyMap; - propertyMap.Insert( "rendererType", "image" ); + propertyMap.Insert( "rendererType", "IMAGE" ); propertyMap.Insert( "url", TEST_NPATCH_FILE_NAME ); propertyMap.Insert( "borderOnly", true ); ControlRenderer nPatchRenderer = factory.CreateControlRenderer( propertyMap ); @@ -590,7 +590,7 @@ int UtcDaliControlRendererGetPropertyMap6(void) // check the property values from the returned map from control renderer Property::Value* value = resultMap.Find( "rendererType", Property::STRING ); DALI_TEST_CHECK( value ); - DALI_TEST_CHECK( value->Get() == "image" ); + DALI_TEST_CHECK( value->Get() == "IMAGE" ); value = resultMap.Find( "url", Property::STRING ); DALI_TEST_CHECK( value ); @@ -611,7 +611,7 @@ int UtcDaliControlRendererGetPropertyMap7(void) // request SvgRenderer with a property map RendererFactory factory = RendererFactory::Get(); Property::Map propertyMap; - propertyMap.Insert( "rendererType", "image" ); + propertyMap.Insert( "rendererType", "IMAGE" ); propertyMap.Insert( "url", TEST_SVG_FILE_NAME ); ControlRenderer svgRenderer = factory.CreateControlRenderer( propertyMap ); @@ -620,7 +620,7 @@ int UtcDaliControlRendererGetPropertyMap7(void) // check the property values from the returned map from control renderer Property::Value* value = resultMap.Find( "rendererType", Property::STRING ); DALI_TEST_CHECK( value ); - DALI_TEST_CHECK( value->Get() == "image" ); + DALI_TEST_CHECK( value->Get() == "IMAGE" ); value = resultMap.Find( "url", Property::STRING ); DALI_TEST_CHECK( value ); @@ -633,7 +633,7 @@ int UtcDaliControlRendererGetPropertyMap7(void) // check the property values from the returned map from control renderer value = resultMap.Find( "rendererType", Property::STRING ); DALI_TEST_CHECK( value ); - DALI_TEST_CHECK( value->Get() == "image" ); + DALI_TEST_CHECK( value->Get() == "IMAGE" ); value = resultMap.Find( "url", Property::STRING ); DALI_TEST_CHECK( value ); @@ -651,11 +651,11 @@ int UtcDaliControlRendererGetPropertyMap8(void) //Request MeshRenderer using a property map. RendererFactory factory = RendererFactory::Get(); Property::Map propertyMap; - propertyMap.Insert( "rendererType", "mesh" ); + propertyMap.Insert( "rendererType", "MESH" ); propertyMap.Insert( "objectUrl", TEST_OBJ_FILE_NAME ); propertyMap.Insert( "materialUrl", TEST_MTL_FILE_NAME ); propertyMap.Insert( "texturesPath", TEST_RESOURCE_LOCATION ); - propertyMap.Insert( "shaderType", "textureless" ); + propertyMap.Insert( "shaderType", "TEXTURELESS" ); ControlRenderer meshRenderer = factory.CreateControlRenderer( propertyMap ); Property::Map resultMap; @@ -664,23 +664,110 @@ int UtcDaliControlRendererGetPropertyMap8(void) //Check values in the result map are identical to the initial map's values. Property::Value* value = resultMap.Find( "rendererType", Property::STRING ); DALI_TEST_CHECK( value ); - DALI_TEST_CHECK( value->Get() == "mesh" ); + DALI_TEST_EQUALS( value->Get(), "MESH", TEST_LOCATION ); value = resultMap.Find( "objectUrl", Property::STRING ); DALI_TEST_CHECK( value ); - DALI_TEST_CHECK( value->Get() == TEST_OBJ_FILE_NAME ); + DALI_TEST_EQUALS( value->Get(), TEST_OBJ_FILE_NAME, TEST_LOCATION ); value = resultMap.Find( "materialUrl", Property::STRING ); DALI_TEST_CHECK( value ); - DALI_TEST_CHECK( value->Get() == TEST_MTL_FILE_NAME ); + DALI_TEST_EQUALS( value->Get(), TEST_MTL_FILE_NAME, TEST_LOCATION ); value = resultMap.Find( "texturesPath", Property::STRING ); DALI_TEST_CHECK( value ); - DALI_TEST_CHECK( value->Get() == TEST_RESOURCE_LOCATION ); + DALI_TEST_EQUALS( value->Get(), TEST_RESOURCE_LOCATION, TEST_LOCATION ); value = resultMap.Find( "shaderType", Property::STRING ); DALI_TEST_CHECK( value ); - DALI_TEST_CHECK( value->Get() == "textureless" ); + DALI_TEST_EQUALS( value->Get(), "TEXTURELESS", TEST_LOCATION ); + + END_TEST; +} + +//Primitive shape renderer +int UtcDaliControlRendererGetPropertyMap9(void) +{ + ToolkitTestApplication application; + tet_infoline( "UtcDaliControlRendererGetPropertyMap9: PrimitiveRenderer" ); + + Vector4 color = Vector4( 1.0, 0.8, 0.6, 1.0); + Vector3 dimensions = Vector3( 1.0, 2.0, 3.0 ); + + //Request PrimitiveRenderer using a property map. + RendererFactory factory = RendererFactory::Get(); + Property::Map propertyMap; + propertyMap.Insert( "rendererType", "PRIMITIVE" ); + propertyMap.Insert( "shape", "CUBE" ); + propertyMap.Insert( "color", color ); + propertyMap.Insert( "slices", 10 ); + propertyMap.Insert( "stacks", 20 ); + propertyMap.Insert( "scaleTopRadius", 30.0f ); + propertyMap.Insert( "scaleBottomRadius", 40.0f ); + propertyMap.Insert( "scaleHeight", 50.0f ); + propertyMap.Insert( "scaleRadius", 60.0f ); + propertyMap.Insert( "scaleDimensions", dimensions ); + propertyMap.Insert( "bevelPercentage", 0.3f ); + propertyMap.Insert( "bevelSmoothness", 0.6f ); + propertyMap.Insert( "uLightPosition", Vector3( 5.0f, 10.0f, 15.0f) ); + ControlRenderer primitiveRenderer = factory.CreateControlRenderer( propertyMap ); + + Property::Map resultMap; + primitiveRenderer.CreatePropertyMap( resultMap ); + + //Check values in the result map are identical to the initial map's values. + Property::Value* value = resultMap.Find( "rendererType", Property::STRING ); + DALI_TEST_CHECK( value ); + DALI_TEST_EQUALS( value->Get(), "PRIMITIVE", TEST_LOCATION ); + + value = resultMap.Find( "shape", Property::STRING ); + DALI_TEST_CHECK( value ); + DALI_TEST_EQUALS( value->Get(), "CUBE", TEST_LOCATION ); + + value = resultMap.Find( "color", Property::VECTOR4 ); + DALI_TEST_CHECK( value ); + DALI_TEST_CHECK( value->Get() == color ); + DALI_TEST_EQUALS( value->Get(), color, Math::MACHINE_EPSILON_100, TEST_LOCATION ); + + value = resultMap.Find( "slices", Property::INTEGER ); + DALI_TEST_CHECK( value ); + DALI_TEST_EQUALS( value->Get(), 10, TEST_LOCATION ); + + value = resultMap.Find( "stacks", Property::INTEGER ); + DALI_TEST_CHECK( value ); + DALI_TEST_EQUALS( value->Get(), 20, TEST_LOCATION ); + + value = resultMap.Find( "scaleTopRadius", Property::FLOAT ); + DALI_TEST_CHECK( value ); + DALI_TEST_EQUALS( value->Get(), 30.0f, Math::MACHINE_EPSILON_100, TEST_LOCATION ); + + value = resultMap.Find( "scaleBottomRadius", Property::FLOAT ); + DALI_TEST_CHECK( value ); + DALI_TEST_EQUALS( value->Get(), 40.0f, Math::MACHINE_EPSILON_100, TEST_LOCATION ); + + value = resultMap.Find( "scaleHeight", Property::FLOAT ); + DALI_TEST_CHECK( value ); + DALI_TEST_EQUALS( value->Get(), 50.0f, Math::MACHINE_EPSILON_100, TEST_LOCATION ); + + value = resultMap.Find( "scaleRadius", Property::FLOAT ); + DALI_TEST_CHECK( value ); + DALI_TEST_EQUALS( value->Get(), 60.0f, Math::MACHINE_EPSILON_100, TEST_LOCATION ); + + value = resultMap.Find( "scaleDimensions", Property::VECTOR3 ); + DALI_TEST_CHECK( value ); + DALI_TEST_EQUALS( value->Get(), dimensions, Math::MACHINE_EPSILON_100, TEST_LOCATION ); + + value = resultMap.Find( "bevelPercentage", Property::FLOAT ); + DALI_TEST_CHECK( value ); + DALI_TEST_EQUALS( value->Get(), 0.3f, Math::MACHINE_EPSILON_100, TEST_LOCATION ); + + value = resultMap.Find( "bevelSmoothness", Property::FLOAT ); + DALI_TEST_CHECK( value ); + DALI_TEST_EQUALS( value->Get(), 0.6f, Math::MACHINE_EPSILON_100, TEST_LOCATION ); + + value = resultMap.Find( "uLightPosition", Property::VECTOR3 ); + DALI_TEST_CHECK( value ); + DALI_TEST_EQUALS( value->Get(), Vector3( 5.0f, 10.0f, 15.0f), Math::MACHINE_EPSILON_100, TEST_LOCATION ); END_TEST; } diff --git a/automated-tests/src/dali-toolkit/utc-Dali-DebugRenderer.cpp b/automated-tests/src/dali-toolkit/utc-Dali-DebugRenderer.cpp index 52f16ed..57543d0 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-DebugRenderer.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-DebugRenderer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,10 +14,11 @@ * limitations under the License. * */ + #include #include -#include -#include +#include +#include #include // for setting environment variable: DALI_DEBUG_RENDERING @@ -39,7 +40,7 @@ bool IsDebugRenderer( ControlRenderer& renderer ) Property::Value* typeValue = propertyMap.Find( "rendererType", Property::STRING ); if ( typeValue ) { - isDebugRendererType = ( typeValue->Get() == "debug" ); + isDebugRendererType = ( typeValue->Get() == "DEBUG" ); } Actor actor = Actor::New(); @@ -72,7 +73,7 @@ int UtcDaliDebugRendererGetRenderer1(void) // Test that color renderer is replaced with debug renderer Property::Map propertyMap1; - propertyMap1.Insert("rendererType", "color"); + propertyMap1.Insert("rendererType", "COLOR"); propertyMap1.Insert("mixColor", Color::BLUE); ControlRenderer colorRenderer = factory.CreateControlRenderer(propertyMap1); DALI_TEST_CHECK( colorRenderer ); @@ -80,7 +81,7 @@ int UtcDaliDebugRendererGetRenderer1(void) // Test that border renderer is replaced with debug renderer Property::Map propertyMap2; - propertyMap2.Insert("rendererType", "border"); + propertyMap2.Insert("rendererType", "BORDER"); propertyMap2.Insert("borderColor", Color::BLUE); propertyMap2.Insert("borderSize", 2.f); ControlRenderer borderRenderer = factory.CreateControlRenderer(propertyMap2); @@ -89,27 +90,27 @@ int UtcDaliDebugRendererGetRenderer1(void) // Test that gradient renderer is replaced with debug renderer Property::Map propertyMap3; - propertyMap3.Insert("rendererType", "gradient"); + propertyMap3.Insert("rendererType", "GRADIENT"); Vector2 start(-1.f, -1.f); Vector2 end(1.f, 1.f); - propertyMap3.Insert("gradientStartPosition", start); - propertyMap3.Insert("gradientEndPosition", end); - propertyMap3.Insert("gradientSpreadMethod", "repeat"); + propertyMap3.Insert("startPosition", start); + propertyMap3.Insert("endPosition", end); + propertyMap3.Insert("spreadMethod", "REPEAT"); Property::Array stopOffsets; stopOffsets.PushBack( 0.2f ); stopOffsets.PushBack( 0.8f ); - propertyMap3.Insert("gradientStopOffset", stopOffsets); + propertyMap3.Insert("stopOffset", stopOffsets); Property::Array stopColors; stopColors.PushBack( Color::RED ); stopColors.PushBack( Color::GREEN ); - propertyMap3.Insert("gradientStopColor", stopColors); + propertyMap3.Insert("stopColor", stopColors); ControlRenderer gradientRenderer = factory.CreateControlRenderer(propertyMap3); DALI_TEST_CHECK( gradientRenderer ); DALI_TEST_CHECK( IsDebugRenderer( gradientRenderer ) ); // Test that image renderer is replaced with debug renderer Property::Map propertyMap4; - propertyMap4.Insert( "rendererType", "image" ); + propertyMap4.Insert( "rendererType", "IMAGE" ); propertyMap4.Insert( "url", TEST_IMAGE_FILE_NAME ); ControlRenderer imageRenderer = factory.CreateControlRenderer( propertyMap4 ); DALI_TEST_CHECK( imageRenderer ); @@ -117,7 +118,7 @@ int UtcDaliDebugRendererGetRenderer1(void) // Test that n patch renderer is replaced with debug renderer Property::Map propertyMap5; - propertyMap5.Insert( "rendererType", "image" ); + propertyMap5.Insert( "rendererType", "IMAGE" ); propertyMap5.Insert( "url", TEST_NPATCH_FILE_NAME ); ControlRenderer nPatchRenderer = factory.CreateControlRenderer( propertyMap4 ); DALI_TEST_CHECK( nPatchRenderer ); @@ -138,7 +139,7 @@ int UtcDaliDebugRendererGetRenderer2(void) // Test that color renderer is replaced with debug renderer Dali::Property::Map map; - map[ "rendererType" ] = "color"; + map[ "rendererType" ] = "COLOR"; map[ "mixColor" ] = Color::CYAN; ControlRenderer colorRenderer = factory.CreateControlRenderer( map); @@ -147,7 +148,7 @@ int UtcDaliDebugRendererGetRenderer2(void) // Test that border renderer is replaced with debug renderer map.Clear(); - map[ "rendererType" ] = "border"; + map[ "rendererType" ] = "BORDER"; map[ "borderColor" ] = Color::GREEN; map[ "borderSize" ] = 2.f; ControlRenderer borderRenderer = factory.CreateControlRenderer( map ); diff --git a/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp b/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp index 709282a..6348940 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include diff --git a/automated-tests/src/dali-toolkit/utc-Dali-PushButton.cpp b/automated-tests/src/dali-toolkit/utc-Dali-PushButton.cpp index 82d6a40..a191f43 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-PushButton.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-PushButton.cpp @@ -113,27 +113,6 @@ Dali::Integration::Point GetPointUpOutside() return point; } -Image CreateSolidColorImage( const Vector4& color, unsigned int width, unsigned int height ) -{ - BufferImage imageData = BufferImage::New( width, height, Pixel::RGBA8888 ); - - // Create the image - PixelBuffer* pixbuf = imageData.GetBuffer(); - unsigned int size = width * height; - - for( size_t i = 0; i < size; i++ ) - { - pixbuf[i*4+0] = 0xFF * color.r; - pixbuf[i*4+1] = 0xFF * color.g; - pixbuf[i*4+2] = 0xFF * color.b; - pixbuf[i*4+3] = 0xFF * color.a; - } - - imageData.Update(); - - return imageData; -} - } //namespace int UtcDaliPushButtonConstructorP(void) diff --git a/automated-tests/src/dali-toolkit/utc-Dali-RendererFactory.cpp b/automated-tests/src/dali-toolkit/utc-Dali-RendererFactory.cpp index 0e33b72..19df59d 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-RendererFactory.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-RendererFactory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,9 +18,9 @@ #include #include #include -#include -#include -#include +#include +#include +#include #include using namespace Dali; @@ -293,7 +293,7 @@ int UtcDaliRendererFactoryGetColorRenderer1(void) Property::Map propertyMap; Vector4 testColor( 1.f, 0.5f, 0.3f, 0.2f ); - propertyMap.Insert("rendererType", "color"); + propertyMap.Insert("rendererType", "COLOR"); propertyMap.Insert("mixColor", testColor); ControlRenderer controlRenderer = factory.CreateControlRenderer(propertyMap); @@ -320,7 +320,7 @@ int UtcDaliRendererFactoryGetColorRenderer2(void) Vector4 testColor( 1.f, 0.5f, 0.3f, 0.2f ); Dali::Property::Map map; - map[ "rendererType" ] = "color"; + map[ "rendererType" ] = "COLOR"; map[ "mixColor" ] = testColor; ControlRenderer controlRenderer = factory.CreateControlRenderer( map ); DALI_TEST_CHECK( controlRenderer ); @@ -350,7 +350,7 @@ int UtcDaliRendererFactoryGetBorderRenderer1(void) Property::Map propertyMap; Vector4 testColor( 1.f, 0.5f, 0.3f, 0.2f ); float testSize = 5.f; - propertyMap.Insert("rendererType", "border"); + propertyMap.Insert("rendererType", "BORDER"); propertyMap.Insert("borderColor", testColor); propertyMap.Insert("borderSize", testSize); @@ -398,7 +398,7 @@ int UtcDaliRendererFactoryGetBorderRenderer2(void) float testSize = 5.f; Dali::Property::Map propertyMap; - propertyMap[ "rendererType" ] = "border"; + propertyMap[ "rendererType" ] = "BORDER"; propertyMap[ "borderColor" ] = testColor; propertyMap[ "borderSize" ] = testSize; ControlRenderer controlRenderer = factory.CreateControlRenderer( propertyMap ); @@ -432,7 +432,7 @@ int UtcDaliRendererFactoryGetBorderRenderer2(void) // enable the anti-aliasing Dali::Property::Map map; - map[ "rendererType" ] = "border"; + map[ "rendererType" ] = "BORDER"; map[ "borderColor" ] = testColor; map[ "borderSize" ] = testSize; map[ "antiAliasing" ] = true; @@ -456,23 +456,23 @@ int UtcDaliRendererFactoryGetLinearGradientRenderer(void) DALI_TEST_CHECK( factory ); Property::Map propertyMap; - propertyMap.Insert("rendererType", "gradient"); + propertyMap.Insert("rendererType", "GRADIENT"); Vector2 start(-1.f, -1.f); Vector2 end(1.f, 1.f); - propertyMap.Insert("startPosition", start); - propertyMap.Insert("endPosition", end); - propertyMap.Insert("spreadMethod", "repeat"); + propertyMap.Insert("startPosition", start); + propertyMap.Insert("endPosition", end); + propertyMap.Insert("spreadMethod", "REPEAT"); Property::Array stopOffsets; stopOffsets.PushBack( 0.2f ); stopOffsets.PushBack( 0.8f ); - propertyMap.Insert("stopOffset", stopOffsets); + propertyMap.Insert("stopOffset", stopOffsets); Property::Array stopColors; stopColors.PushBack( Color::RED ); stopColors.PushBack( Color::GREEN ); - propertyMap.Insert("stopColor", stopColors); + propertyMap.Insert("stopColor", stopColors); ControlRenderer controlRenderer = factory.CreateControlRenderer(propertyMap); DALI_TEST_CHECK( controlRenderer ); @@ -496,11 +496,11 @@ int UtcDaliRendererFactoryGetRadialGradientRenderer(void) DALI_TEST_CHECK( factory ); Property::Map propertyMap; - propertyMap.Insert("rendererType", "gradient"); + propertyMap.Insert("rendererType", "GRADIENT"); Vector2 center(100.f, 100.f); float radius = 100.f; - propertyMap.Insert("units", "userSpace"); + propertyMap.Insert("units", "USER_SPACE"); propertyMap.Insert("center", center); propertyMap.Insert("radius", radius); @@ -541,18 +541,18 @@ int UtcDaliRendererFactoryDefaultOffsetsGradientRenderer(void) DALI_TEST_CHECK( factory ); Property::Map propertyMap; - propertyMap.Insert("rendererType", "gradient"); + propertyMap.Insert("rendererType", "GRADIENT"); Vector2 start(-1.f, -1.f); Vector2 end(1.f, 1.f); - propertyMap.Insert("startPosition", start); - propertyMap.Insert("endPosition", end); - propertyMap.Insert("spreadMethod", "repeat"); + propertyMap.Insert("startPosition", start); + propertyMap.Insert("endPosition", end); + propertyMap.Insert("spreadMethod", "REPEAT"); Property::Array stopColors; stopColors.PushBack( Color::RED ); stopColors.PushBack( Color::GREEN ); - propertyMap.Insert("stopColor", stopColors); + propertyMap.Insert("stopColor", stopColors); ControlRenderer controlRenderer = factory.CreateControlRenderer(propertyMap); DALI_TEST_CHECK( controlRenderer ); @@ -576,7 +576,7 @@ int UtcDaliRendererFactoryGetImageRenderer1(void) DALI_TEST_CHECK( factory ); Property::Map propertyMap; - propertyMap.Insert( "rendererType", "image" ); + propertyMap.Insert( "rendererType", "IMAGE" ); propertyMap.Insert( "url", TEST_IMAGE_FILE_NAME ); ControlRenderer controlRenderer = factory.CreateControlRenderer( propertyMap ); @@ -658,7 +658,7 @@ int UtcDaliRendererFactoryGetNPatchRenderer1(void) Integration::ResourcePointer ninePatchResource = CustomizeNinePatch( application, ninePatchImageWidth, ninePatchImageHeight, stretchRangesX, stretchRangesY ); Property::Map propertyMap; - propertyMap.Insert( "rendererType", "image" ); + propertyMap.Insert( "rendererType", "IMAGE" ); propertyMap.Insert( "url", TEST_NPATCH_FILE_NAME ); { tet_infoline( "whole grid" ); @@ -722,7 +722,7 @@ int UtcDaliRendererFactoryGetNPatchRenderer2(void) Integration::ResourcePointer ninePatchResource = CustomizeNinePatch( application, ninePatchImageWidth, ninePatchImageHeight, stretchRangesX, stretchRangesY ); Property::Map propertyMap; - propertyMap.Insert( "rendererType", "image" ); + propertyMap.Insert( "rendererType", "IMAGE" ); propertyMap.Insert( "url", TEST_NPATCH_FILE_NAME ); { ControlRenderer controlRenderer = factory.CreateControlRenderer( propertyMap ); @@ -960,7 +960,7 @@ int UtcDaliRendererFactoryGetMeshRenderer1(void) //Set up renderer properties. Property::Map propertyMap; - propertyMap.Insert( "rendererType", "mesh" ); + propertyMap.Insert( "rendererType", "MESH" ); propertyMap.Insert( "objectUrl", TEST_OBJ_FILE_NAME ); ControlRenderer controlRenderer = factory.CreateControlRenderer( propertyMap ); @@ -1012,7 +1012,7 @@ int UtcDaliRendererFactoryGetMeshRenderer2(void) //Set up renderer properties. Property::Map propertyMap; - propertyMap.Insert( "rendererType", "mesh" ); + propertyMap.Insert( "rendererType", "MESH" ); propertyMap.Insert( "objectUrl", TEST_OBJ_FILE_NAME ); propertyMap.Insert( "materialUrl", "" ); propertyMap.Insert( "texturesPath", "" ); @@ -1068,7 +1068,7 @@ int UtcDaliRendererFactoryGetMeshRenderer3(void) //Set up renderer properties. Property::Map propertyMap; - propertyMap.Insert( "rendererType", "mesh" ); + propertyMap.Insert( "rendererType", "MESH" ); propertyMap.Insert( "objectUrl", TEST_OBJ_FILE_NAME ); propertyMap.Insert( "materialUrl", TEST_MTL_FILE_NAME ); propertyMap.Insert( "texturesPath", TEST_RESOURCE_DIR "/" ); @@ -1124,7 +1124,7 @@ int UtcDaliRendererFactoryGetMeshRenderer4(void) //Set up renderer properties. Property::Map propertyMap; - propertyMap.Insert( "rendererType", "mesh" ); + propertyMap.Insert( "rendererType", "MESH" ); propertyMap.Insert( "objectUrl", TEST_OBJ_FILE_NAME ); propertyMap.Insert( "materialUrl", TEST_SIMPLE_MTL_FILE_NAME ); propertyMap.Insert( "texturesPath", TEST_RESOURCE_DIR "/" ); @@ -1180,7 +1180,7 @@ int UtcDaliRendererFactoryGetMeshRendererN1(void) //Set up renderer properties. Property::Map propertyMap; - propertyMap.Insert( "rendererType", "mesh" ); + propertyMap.Insert( "rendererType", "MESH" ); propertyMap.Insert( "materialUrl", TEST_MTL_FILE_NAME ); propertyMap.Insert( "texturesPath", TEST_RESOURCE_DIR "/" ); @@ -1231,7 +1231,7 @@ int UtcDaliRendererFactoryGetMeshRendererN2(void) //Set up renderer properties. Property::Map propertyMap; - propertyMap.Insert( "rendererType", "mesh" ); + propertyMap.Insert( "rendererType", "MESH" ); propertyMap.Insert( "objectUrl", TEST_OBJ_FILE_NAME ); propertyMap.Insert( "materialUrl", "invalid" ); propertyMap.Insert( "texturesPath", "also invalid" ); @@ -1283,7 +1283,7 @@ int UtcDaliRendererFactoryGetMeshRendererN3(void) //Set up renderer properties. Property::Map propertyMap; - propertyMap.Insert( "rendererType", "mesh" ); + propertyMap.Insert( "rendererType", "MESH" ); propertyMap.Insert( "objectUrl", "invalid" ); propertyMap.Insert( "materialUrl", TEST_MTL_FILE_NAME ); propertyMap.Insert( "texturesPath", TEST_RESOURCE_DIR "/" ); @@ -1323,3 +1323,235 @@ int UtcDaliRendererFactoryGetMeshRendererN3(void) END_TEST; } + +//Creates a primitive renderer with the given property map and tests to see if it correctly loads in the given application. +void TestPrimitiveRendererWithProperties( Property::Map& propertyMap, ToolkitTestApplication& application ) +{ + RendererFactory factory = RendererFactory::Get(); + DALI_TEST_CHECK( factory ); + + //Create a primitive renderer. + ControlRenderer controlRenderer = factory.CreateControlRenderer( propertyMap ); + DALI_TEST_CHECK( controlRenderer ); + + //Create an actor on stage to house the renderer. + Actor actor = Actor::New(); + actor.SetSize( 200.f, 200.f ); + Stage::GetCurrent().Add( actor ); + controlRenderer.SetSize( Vector2( 200.f, 200.f ) ); + controlRenderer.SetOnStage( actor ); + + //Ensure set on stage. + DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION ); + + //Tell test application to load the renderer. + application.SendNotification(); + application.Render(0); + + Matrix testScaleMatrix; + testScaleMatrix.SetIdentityAndScale( Vector3( 1.0, -1.0, 1.0 ) ); + Matrix actualScaleMatrix; + + //Test to see if the object has been successfully loaded. + DALI_TEST_CHECK( application.GetGlAbstraction().GetUniformValue( "uObjectMatrix", actualScaleMatrix ) ); + DALI_TEST_EQUALS( actualScaleMatrix, testScaleMatrix, Math::MACHINE_EPSILON_100, TEST_LOCATION ); + + //Finish by setting off stage, and ensuring this was successful. + controlRenderer.SetOffStage( actor ); + DALI_TEST_EQUALS( actor.GetRendererCount(), 0u, TEST_LOCATION ); +} + +//Test if primitive shape loads correctly when supplied with only the bare minimum requirements, the shape to use. +int UtcDaliRendererFactoryGetPrimitiveRenderer1(void) +{ + //Set up test application first, so everything else can be handled. + ToolkitTestApplication application; + + tet_infoline( "UtcDaliRendererFactoryGetPrimitiveRenderer1: Request primitive renderer with a shape only" ); + + //Set up renderer properties. + Property::Map propertyMap; + propertyMap.Insert( "rendererType", "PRIMITIVE" ); + propertyMap.Insert( "shape", "CUBE" ); + + //Test to see if shape loads correctly. + TestPrimitiveRendererWithProperties( propertyMap, application ); + + END_TEST; +} + +//Test if primitive shape loads correctly when supplied with all possible parameters +int UtcDaliRendererFactoryGetPrimitiveRenderer2(void) +{ + //Set up test application first, so everything else can be handled. + ToolkitTestApplication application; + + tet_infoline( "UtcDaliRendererFactoryGetPrimitiveRenderer2: Request primitive renderer with everything" ); + + //Set up renderer properties. + Property::Map propertyMap; + propertyMap.Insert( "rendererType", "PRIMITIVE" ); + propertyMap.Insert( "shape", "CUBE" ); + propertyMap.Insert( "color", Vector4( 0.5, 0.5, 0.5, 1.0 ) ); + propertyMap.Insert( "slices", 10 ); + propertyMap.Insert( "stacks", 20 ); + propertyMap.Insert( "scaleTopRadius", 30.0f ); + propertyMap.Insert( "scaleBottomRadius", 40.0f ); + propertyMap.Insert( "scaleHeight", 50.0f ); + propertyMap.Insert( "scaleRadius", 60.0f ); + propertyMap.Insert( "bevelPercentage", 0.7f ); + + //Test to see if shape loads correctly. + TestPrimitiveRendererWithProperties( propertyMap, application ); + + END_TEST; +} + +//Test if primitive shape loads a sphere correctly. +int UtcDaliRendererFactoryGetPrimitiveRenderer3(void) +{ + //Set up test application first, so everything else can be handled. + ToolkitTestApplication application; + + tet_infoline( "UtcDaliRendererFactoryGetPrimitiveRenderer3: Request primitive renderer to display a sphere" ); + + //Set up renderer properties. + Property::Map propertyMap; + propertyMap.Insert( "rendererType", "PRIMITIVE" ); + propertyMap.Insert( "shape", "SPHERE" ); + propertyMap.Insert( "color", Vector4( 0.5, 0.5, 0.5, 1.0 ) ); + propertyMap.Insert( "slices", 10 ); + propertyMap.Insert( "stacks", 20 ); + + //Test to see if shape loads correctly. + TestPrimitiveRendererWithProperties( propertyMap, application ); + + END_TEST; +} + +//Test if primitive shape loads a conic section correctly. +int UtcDaliRendererFactoryGetPrimitiveRenderer4(void) +{ + //Set up test application first, so everything else can be handled. + ToolkitTestApplication application; + + tet_infoline( "UtcDaliRendererFactoryGetPrimitiveRenderer4: Request primitive renderer to display a conic section" ); + + //Set up renderer properties. + Property::Map propertyMap; + propertyMap.Insert( "rendererType", "PRIMITIVE" ); + propertyMap.Insert( "shape", "CONICAL_FRUSTRUM" ); + propertyMap.Insert( "color", Vector4( 0.5, 0.5, 0.5, 1.0 ) ); + propertyMap.Insert( "slices", 10 ); + propertyMap.Insert( "scaleTopRadius", 30.0f ); + propertyMap.Insert( "scaleBottomRadius", 40.0f ); + propertyMap.Insert( "scaleHeight", 50.0f ); + + //Test to see if shape loads correctly. + TestPrimitiveRendererWithProperties( propertyMap, application ); + + END_TEST; +} + +//Test if primitive shape loads a bevelled cube correctly. +int UtcDaliRendererFactoryGetPrimitiveRenderer5(void) +{ + //Set up test application first, so everything else can be handled. + ToolkitTestApplication application; + + tet_infoline( "UtcDaliRendererFactoryGetPrimitiveRenderer5: Request primitive renderer to display a bevelled cube" ); + + //Set up renderer properties. + Property::Map propertyMap; + propertyMap.Insert( "rendererType", "PRIMITIVE" ); + propertyMap.Insert( "shape", "BEVELLED_CUBE" ); + propertyMap.Insert( "color", Vector4( 0.5, 0.5, 0.5, 1.0 ) ); + propertyMap.Insert( "bevelPercentage", 0.7f ); + + //Test to see if shape loads correctly. + TestPrimitiveRendererWithProperties( propertyMap, application ); + + END_TEST; +} + +//Test if primitive shape loads an octahedron correctly. +int UtcDaliRendererFactoryGetPrimitiveRenderer6(void) +{ + //Set up test application first, so everything else can be handled. + ToolkitTestApplication application; + + tet_infoline( "UtcDaliRendererFactoryGetPrimitiveRenderer6: Request primitive renderer to display an octahedron" ); + + //Set up renderer properties. + Property::Map propertyMap; + propertyMap.Insert( "rendererType", "PRIMITIVE" ); + propertyMap.Insert( "shape", "OCTAHEDRON" ); + propertyMap.Insert( "color", Vector4( 0.5, 0.5, 0.5, 1.0 ) ); + + //Test to see if shape loads correctly. + TestPrimitiveRendererWithProperties( propertyMap, application ); + + END_TEST; +} + +//Test if primitive shape loads a cone correctly. +int UtcDaliRendererFactoryGetPrimitiveRenderer7(void) +{ + //Set up test application first, so everything else can be handled. + ToolkitTestApplication application; + + tet_infoline( "UtcDaliRendererFactoryGetPrimitiveRenderer7: Request primitive renderer to display a cone" ); + + //Set up renderer properties. + Property::Map propertyMap; + propertyMap.Insert( "rendererType", "PRIMITIVE" ); + propertyMap.Insert( "shape", "CONE" ); + propertyMap.Insert( "color", Vector4( 0.5, 0.5, 0.5, 1.0 ) ); + propertyMap.Insert( "slices", 10 ); + propertyMap.Insert( "scaleTopRadius", 30.0f ); + propertyMap.Insert( "scaleHeight", 50.0f ); + + //Test to see if shape loads correctly. + TestPrimitiveRendererWithProperties( propertyMap, application ); + + END_TEST; +} + +//Test if primitive shape loads correctly when light position is manually set. +int UtcDaliRendererFactoryGetPrimitiveRenderer8(void) +{ + //Set up test application first, so everything else can be handled. + ToolkitTestApplication application; + + tet_infoline( "UtcDaliRendererFactoryGetPrimitiveRenderer8: Request primitive renderer with set light position" ); + + //Set up renderer properties. + Property::Map propertyMap; + propertyMap.Insert( "rendererType", "PRIMITIVE" ); + propertyMap.Insert( "shape", "SPHERE" ); + propertyMap.Insert( "color", Vector4( 0.5, 0.5, 0.5, 1.0 ) ); + propertyMap.Insert( "uLightPosition", Vector3( 0.0, 1.0, 2.0 ) ); + + //Test to see if shape loads correctly. + TestPrimitiveRendererWithProperties( propertyMap, application ); + + END_TEST; +} + +//Test if primitive shape renderer handles the case of not being passed a specific shape to use. +int UtcDaliRendererFactoryGetPrimitiveRendererN1(void) +{ + //Set up test application first, so everything else can be handled. + ToolkitTestApplication application; + + tet_infoline( "UtcDaliRendererFactoryGetPrimitiveRendererN1: Request primitive renderer without shape" ); + + //Set up renderer properties, without supplying shape. + Property::Map propertyMap; + propertyMap.Insert( "rendererType", "PRIMITIVE" ); + + //Test to see if shape loads regardless of missing input. + TestPrimitiveRendererWithProperties( propertyMap, application ); + + END_TEST; +} diff --git a/automated-tests/src/dali-toolkit/utc-Dali-Slider.cpp b/automated-tests/src/dali-toolkit/utc-Dali-Slider.cpp index fcfc821..4f1e000 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-Slider.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-Slider.cpp @@ -333,7 +333,7 @@ int UtcDaliSetPropertyP(void) { Property::Map map; - map["rendererType"] = "image"; + map["rendererType"] = "IMAGE"; map["size"] = Vector2(200, 200); map["url"] = "track2.png"; slider.SetProperty(Slider::Property::TRACK_VISUAL, map); diff --git a/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp b/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp index 52f4f87..2300b50 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include #include @@ -639,8 +639,13 @@ int utcDaliTextEditorEvent02(void) CameraActor camera = CameraActor::DownCast( offscreenRoot.GetChildAt( 0u ) ); DALI_TEST_CHECK( camera ); - Renderer renderer = offscreenRoot.GetChildAt( 1u ).GetRendererAt( 0u ); - DALI_TEST_CHECK( renderer ); + // The offscreen root actor has a container with all the actors which contain the text renderers. + Actor container = offscreenRoot.GetChildAt( 1u ); + for( unsigned int index = 0; index < container.GetChildCount(); ++index ) + { + Renderer renderer = container.GetChildAt( index ).GetRendererAt( 0u ); + DALI_TEST_CHECK( renderer ); + } // Move the cursor and check the position changes. Vector3 position1 = cursor.GetCurrentPosition(); @@ -762,8 +767,13 @@ int utcDaliTextEditorEvent03(void) CameraActor camera = CameraActor::DownCast( offscreenRoot.GetChildAt( 0u ) ); DALI_TEST_CHECK( camera ); - Renderer renderer = offscreenRoot.GetChildAt( 1u ).GetRendererAt( 0u ); - DALI_TEST_CHECK( renderer ); + // The offscreen root actor has a container with all the actors which contain the text renderers. + Actor container = offscreenRoot.GetChildAt( 1u ); + for( unsigned int index = 0; index < container.GetChildCount(); ++index ) + { + Renderer renderer = container.GetChildAt( index ).GetRendererAt( 0u ); + DALI_TEST_CHECK( renderer ); + } Renderer highlight = offscreenRoot.GetChildAt( 2u ).GetRendererAt( 0u ); DALI_TEST_CHECK( highlight ); diff --git a/automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp b/automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp index d3908ea..911a06e 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include #include @@ -867,8 +867,13 @@ int utcDaliTextFieldEvent02(void) CameraActor camera = CameraActor::DownCast( offscreenRoot.GetChildAt( 0u ) ); DALI_TEST_CHECK( camera ); - Renderer renderer = offscreenRoot.GetChildAt( 1u ).GetRendererAt( 0u ); - DALI_TEST_CHECK( renderer ); + // The offscreen root actor has a container with all the actors which contain the text renderers. + Actor container = offscreenRoot.GetChildAt( 1u ); + for( unsigned int index = 0; index < container.GetChildCount(); ++index ) + { + Renderer renderer = container.GetChildAt( index ).GetRendererAt( 0u ); + DALI_TEST_CHECK( renderer ); + } // Move the cursor and check the position changes. Vector3 position1 = cursor.GetCurrentPosition(); @@ -991,8 +996,13 @@ int utcDaliTextFieldEvent03(void) CameraActor camera = CameraActor::DownCast( offscreenRoot.GetChildAt( 0u ) ); DALI_TEST_CHECK( camera ); - Renderer renderer = offscreenRoot.GetChildAt( 1u ).GetRendererAt( 0u ); - DALI_TEST_CHECK( renderer ); + // The offscreen root actor has a container with all the actors which contain the text renderers. + Actor container = offscreenRoot.GetChildAt( 1u ); + for( unsigned int index = 0; index < container.GetChildCount(); ++index ) + { + Renderer renderer = container.GetChildAt( index ).GetRendererAt( 0u ); + DALI_TEST_CHECK( renderer ); + } Renderer highlight = offscreenRoot.GetChildAt( 2u ).GetRendererAt( 0u ); DALI_TEST_CHECK( highlight ); @@ -1186,7 +1196,7 @@ int utcDaliTextFieldEvent06(void) int utcDaliTextFieldEvent07(void) { ToolkitTestApplication application; - tet_infoline(" utcDaliTextFieldEvent06"); + tet_infoline(" utcDaliTextFieldEvent07"); // Checks Longpress to start edit mode @@ -1224,7 +1234,7 @@ int utcDaliTextFieldEvent07(void) int utcDaliTextFieldEvent08(void) { ToolkitTestApplication application; - tet_infoline(" utcDaliTextFieldEvent06"); + tet_infoline(" utcDaliTextFieldEvent08"); // Checks Longpress when only place holder text @@ -1258,3 +1268,78 @@ int utcDaliTextFieldEvent08(void) END_TEST; } + +int utcDaliTextFieldStyleWhilstSelected09(void) +{ + ToolkitTestApplication application; + tet_infoline(" utcDaliTextFieldEvent09"); + + // Change font and styles whilst text is selected whilst word selected + + TextField field = TextField::New(); + DALI_TEST_CHECK( field ); + Stage::GetCurrent().Add( field ); + LoadMarkerImages(application, field); + // Render and notify + application.SendNotification(); + application.Render(); + + field.SetProperty( TextField::Property::TEXT, "This is a long text for the size of the text-field." ); + field.SetProperty( TextField::Property::POINT_SIZE, 10.f ); + field.SetSize( 300.f, 50.f ); + field.SetParentOrigin( ParentOrigin::TOP_LEFT ); + field.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + + // Avoid a crash when core load gl resources. + application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE ); + // Render and notify + application.SendNotification(); + application.Render(); + + // Create a tap event to touch the text field. + application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 150.0f, 25.0f ) ) ); + application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 150.0f, 25.0f ) ) ); + // Render and notify + application.SendNotification(); + application.Render(); + + + // Tap first to get the focus. + application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 1.f, 25.0f ) ) ); + application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 1.f, 25.0f ) ) ); + + // Render and notify + application.SendNotification(); + application.Render(); + + // Double tap to select a word. + application.ProcessEvent( GenerateTap( Gesture::Possible, 2u, 1u, Vector2( 1.f, 25.0f ) ) ); + application.ProcessEvent( GenerateTap( Gesture::Started, 2u, 1u, Vector2( 1.f, 25.0f ) ) ); + + // Render and notify + application.SendNotification(); + application.Render(); + + field.SetProperty( TextField::Property::INPUT_FONT_FAMILY, "Setting input font family" ); + DALI_TEST_EQUALS( field.GetProperty( TextField::Property::INPUT_FONT_FAMILY ), "Setting input font family", TEST_LOCATION ); + + field.SetProperty( TextField::Property::INPUT_FONT_STYLE, "{\"weight\":\"bold\",\"slant\":\"italic\"}" ); + DALI_TEST_EQUALS( field.GetProperty( TextField::Property::INPUT_FONT_STYLE ), "{\"weight\":\"bold\",\"slant\":\"italic\"}", TEST_LOCATION ); + + field.SetProperty( TextField::Property::INPUT_FONT_STYLE, "{\"width\":\"expanded\",\"slant\":\"italic\"}" ); + DALI_TEST_EQUALS( field.GetProperty( TextField::Property::INPUT_FONT_STYLE ), "{\"width\":\"expanded\",\"slant\":\"italic\"}", TEST_LOCATION ); + + field.SetProperty( TextField::Property::INPUT_POINT_SIZE, 12.f ); + DALI_TEST_EQUALS( field.GetProperty( TextField::Property::INPUT_POINT_SIZE ), 12.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION ); + + field.SetProperty( TextField::Property::TEXT_COLOR, Color::RED ); + DALI_TEST_EQUALS( field.GetProperty( TextField::Property::TEXT_COLOR ), Color::RED, TEST_LOCATION ); + + field.SetProperty( TextField::Property::FONT_STYLE, "{\"weight\":\"bold\",\"slant\":\"italic\"}" ); + DALI_TEST_EQUALS( field.GetProperty( TextField::Property::FONT_STYLE ), "{\"weight\":\"bold\",\"slant\":\"italic\"}", TEST_LOCATION ); + + field.SetProperty( TextField::Property::FONT_STYLE, "{\"width\":\"expanded\"}" ); + DALI_TEST_EQUALS( field.GetProperty( TextField::Property::FONT_STYLE ), "{\"width\":\"expanded\"}", TEST_LOCATION ); + + END_TEST; +} diff --git a/automated-tests/src/dali-toolkit/utc-Dali-ToolBar.cpp b/automated-tests/src/dali-toolkit/utc-Dali-ToolBar.cpp index 9adf9cd..db745a4 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-ToolBar.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-ToolBar.cpp @@ -41,7 +41,7 @@ Actor CreateColorActor( const Vector4& color ) RendererFactory factory = RendererFactory::Get(); Dali::Property::Map map; - map[ "rendererType" ] = "color"; + map[ "rendererType" ] = "COLOR"; map[ "mixColor" ] = color; ControlRenderer colorRenderer = factory.CreateControlRenderer( map ); colorRenderer.SetOnStage( solidColorActor ); diff --git a/build/tizen/Makefile.am b/build/tizen/Makefile.am index a672053..0d0e733 100644 --- a/build/tizen/Makefile.am +++ b/build/tizen/Makefile.am @@ -48,12 +48,14 @@ COVERAGE_OUTPUT_DIR=doc/coverage # From lcov version 1.10 onwards, branch coverage is off by default and earlier versions do not support the rc option LCOV_OPTS=`if [ \`printf "\\\`lcov --version | cut -d' ' -f4\\\`\n1.10\n" | sort -V | head -n 1\` = 1.10 ] ; then echo "--rc lcov_branch_coverage=1" ; fi` -cov_data: +rename_cov_data: @test -z $(COVERAGE_DIR) || mkdir -p $(COVERAGE_DIR) @rm -f $(COVERAGE_DIR)/* @cp dali-toolkit/.libs/*.gcda dali-toolkit/.libs/*.gcno $(COVERAGE_DIR) @for i in `find $(COVERAGE_DIR) -name "libdali_toolkit_la-*.gcda" -o -name "libdali_toolkit_la-*.gcno"` ;\ do mv $$i `echo $$i | sed s/libdali_toolkit_la-//` ; echo $$i ; done + +cov_data: rename_cov_data @cd $(COVERAGE_DIR) ; lcov $(LCOV_OPTS) --base-directory . --directory . -c -o dali.info @cd $(COVERAGE_DIR) ; lcov $(LCOV_OPTS) --remove dali.info "/usr/include/*" "*/dali-env/*" "*solid-color-actor*" "*/dali-toolkit/third-party/*" -o dali.info @test -z $(COVERAGE_OUTPUT_DIR) || mkdir -p $(COVERAGE_OUTPUT_DIR) diff --git a/dali-toolkit/devel-api/image-atlas/image-atlas.h b/dali-toolkit/devel-api/image-atlas/image-atlas.h index 5ef9195..2bc97ae 100644 --- a/dali-toolkit/devel-api/image-atlas/image-atlas.h +++ b/dali-toolkit/devel-api/image-atlas/image-atlas.h @@ -1,7 +1,7 @@ -#ifndef __DALI_TOOLKIT_IMAGE_ATLAS_H__ -#define __DALI_TOOLKIT_IMAGE_ATLAS_H__ +#ifndef DALI_TOOLKIT_IMAGE_ATLAS_H +#define DALI_TOOLKIT_IMAGE_ATLAS_H /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,7 +24,7 @@ #include #include #include -#include +#include namespace Dali { @@ -153,4 +153,4 @@ public: // Not intended for developer use } // namespace Dali -#endif /* __DALI_TOOLKIT_IMAGE_ATLAS_H__ */ +#endif // DALI_TOOLKIT_IMAGE_ATLAS_H diff --git a/dali-toolkit/devel-api/shader-effects/dissolve-effect.h b/dali-toolkit/devel-api/shader-effects/dissolve-effect.h index 99036fd..fdea5d0 100644 --- a/dali-toolkit/devel-api/shader-effects/dissolve-effect.h +++ b/dali-toolkit/devel-api/shader-effects/dissolve-effect.h @@ -1,8 +1,8 @@ -#ifndef __DALI_TOOLKIT_SHADER_EFFECT_DISSOLVE_H__ -#define __DALI_TOOLKIT_SHADER_EFFECT_DISSOLVE_H__ +#ifndef DALI_TOOLKIT_SHADER_EFFECT_DISSOLVE_H_ +#define DALI_TOOLKIT_SHADER_EFFECT_DISSOLVE_H /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ // EXTERNAL INCLUDES #include -#include +#include namespace Dali { @@ -230,4 +230,4 @@ inline Property::Map CreateDissolveEffect( bool useHighPrecision = true ) } // namespace Dali -#endif // __DALI_TOOLKIT_SHADER_EFFECT_DISSOLVE_H__ +#endif // DALI_TOOLKIT_SHADER_EFFECT_DISSOLVE_H diff --git a/dali-toolkit/devel-api/transition-effects/cube-transition-effect.h b/dali-toolkit/devel-api/transition-effects/cube-transition-effect.h index 198d352..df51440 100644 --- a/dali-toolkit/devel-api/transition-effects/cube-transition-effect.h +++ b/dali-toolkit/devel-api/transition-effects/cube-transition-effect.h @@ -1,8 +1,8 @@ -#ifndef __DALI_TOOLKIT_CUBE_TRANSITION_EFFECT_H__ -#define __DALI_TOOLKIT_CUBE_TRANSITION_EFFECT_H__ +#ifndef DALI_TOOLKIT_CUBE_TRANSITION_EFFECT_H +#define DALI_TOOLKIT_CUBE_TRANSITION_EFFECT_H /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,7 +22,7 @@ #include // EXTERNAL INCLUDES -#include +#include namespace Dali { @@ -221,4 +221,4 @@ public: // Not intended for developer use } // namespace Dali -#endif /* __DALI_TOOLKIT_CUBE_TRANSITION_EFFECT_H__ */ +#endif // DALI_TOOLKIT_CUBE_TRANSITION_EFFECT_H diff --git a/dali-toolkit/internal/controls/bloom-view/bloom-view-impl.cpp b/dali-toolkit/internal/controls/bloom-view/bloom-view-impl.cpp index 4f8e79e..e64289e 100644 --- a/dali-toolkit/internal/controls/bloom-view/bloom-view-impl.cpp +++ b/dali-toolkit/internal/controls/bloom-view/bloom-view-impl.cpp @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include // INTERNAL INCLUDES diff --git a/dali-toolkit/internal/controls/bubble-effect/bubble-actor.h b/dali-toolkit/internal/controls/bubble-effect/bubble-actor.h index 213a425..3033032 100644 --- a/dali-toolkit/internal/controls/bubble-effect/bubble-actor.h +++ b/dali-toolkit/internal/controls/bubble-effect/bubble-actor.h @@ -1,8 +1,8 @@ -#ifndef __DALI_TOOLKIT_INTERNAL_BUBBLE_ACTOR_H_ -#define __DALI_TOOLKIT_INTERNAL_BUBBLE_ACTOR_H_ +#ifndef DALI_TOOLKIT_INTERNAL_BUBBLE_ACTOR_H +#define DALI_TOOLKIT_INTERNAL_BUBBLE_ACTOR_H /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,10 +19,10 @@ */ // EXTERNAL INCLUDES -#include #include +#include #include -#include +#include namespace Dali { @@ -151,4 +151,4 @@ private: } // namespace Dali -#endif /* __DALI_TOOLKIT_INTERNAL_BUBBLE_ACTOR_H_ */ +#endif // DALI_TOOLKIT_INTERNAL_BUBBLE_ACTOR_H diff --git a/dali-toolkit/internal/controls/bubble-effect/bubble-effect.h b/dali-toolkit/internal/controls/bubble-effect/bubble-effect.h index 9fc065a..6e265f6 100644 --- a/dali-toolkit/internal/controls/bubble-effect/bubble-effect.h +++ b/dali-toolkit/internal/controls/bubble-effect/bubble-effect.h @@ -1,8 +1,8 @@ -#ifndef __DALI_TOOLKIT_INTERNAL_BUBBLE_EFFECT_H_ -#define __DALI_TOOLKIT_INTERNAL_BUBBLE_EFFECT_H_ +#ifndef DALI_TOOLKIT_INTERNAL_BUBBLE_EFFECT_H +#define DALI_TOOLKIT_INTERNAL_BUBBLE_EFFECT_H /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ // EXTERNAL INCLUDES #include -#include +#include namespace Dali { @@ -128,4 +128,4 @@ inline Shader CreateBubbleShader( unsigned int numBubble ) } // namespace Toolkit } // namespace Dali -#endif /* __DALI_TOOLKIT_INTERNAL_BUBBLE_EFFECT_H_ */ +#endif // DALI_TOOLKIT_INTERNAL_BUBBLE_EFFECT_H diff --git a/dali-toolkit/internal/controls/bubble-effect/bubble-emitter-impl.h b/dali-toolkit/internal/controls/bubble-effect/bubble-emitter-impl.h index cbc1fc3..fecbd85 100644 --- a/dali-toolkit/internal/controls/bubble-effect/bubble-emitter-impl.h +++ b/dali-toolkit/internal/controls/bubble-effect/bubble-emitter-impl.h @@ -1,8 +1,8 @@ -#ifndef __DALI_TOOLKIT_INTERNAL_BUBBLE_EMITTER_IMPL_H__ -#define __DALI_TOOLKIT_INTERNAL_BUBBLE_EMITTER_IMPL_H__ +#ifndef DALI_TOOLKIT_INTERNAL_BUBBLE_EMITTER_IMPL_H +#define DALI_TOOLKIT_INTERNAL_BUBBLE_EMITTER_IMPL_H /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,11 +23,11 @@ #include #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include // INTERNAL INCLUDES #include @@ -197,4 +197,4 @@ inline const Internal::BubbleEmitter& GetImpl(const Dali::Toolkit::BubbleEmitter } // namespace Dali -#endif /* __DALI_TOOLKIT_INTERNAL_BUBBLE_EMITTER_IMPL_H__ */ +#endif // DALI_TOOLKIT_INTERNAL_BUBBLE_EMITTER_IMPL_H diff --git a/dali-toolkit/internal/controls/buttons/button-impl.cpp b/dali-toolkit/internal/controls/buttons/button-impl.cpp index dc00a3c..5e99442 100644 --- a/dali-toolkit/internal/controls/buttons/button-impl.cpp +++ b/dali-toolkit/internal/controls/buttons/button-impl.cpp @@ -29,6 +29,7 @@ // INTERNAL INCLUDES #include #include +#include /** * Button states and contents @@ -527,46 +528,53 @@ void Button::SetupContent( Actor& actorToModify, Actor newActor ) } } -void Button::SetUnselectedColor( const Vector4& color ) -{ - mUnselectedColor = color; - - if( mUnselectedContent && !GetUnselectedImageFilename().empty() ) - { - // If there is existing unselected content, change the color on it directly. - mUnselectedContent.SetColor( mUnselectedColor ); - } - else - { - // If there is no existing content, create a new actor to use for flat color. - Toolkit::Control unselectedContentActor = Toolkit::Control::New(); - unselectedContentActor.SetBackgroundColor( mUnselectedColor ); - SetupContent( mUnselectedContent, unselectedContentActor ); - mUnselectedContent.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS ); - } -} - const Vector4 Button::GetUnselectedColor() const { return mUnselectedColor; } -void Button::SetSelectedColor( const Vector4& color ) +void Button::SetColor( const Vector4& color, Button::PaintState selectedState ) { - mSelectedColor = color; + Actor* contentActor = NULL; // Using a pointer as SetupContent assigns the new Actor to this. + bool imageFileExists = false; - if( mSelectedContent && !GetSelectedImageFilename().empty() ) + if ( selectedState == SelectedState || selectedState == DisabledSelectedState ) { - // If there is existing unselected content, change the color on it directly. - mSelectedContent.SetColor( mSelectedColor ); + mSelectedColor = color; + contentActor = &mSelectedContent; + imageFileExists = !GetSelectedImageFilename().empty(); } else { - // If there is no existing content, create a new actor to use for flat color. - Toolkit::Control selectedContentActor = Toolkit::Control::New(); - selectedContentActor.SetBackgroundColor( mSelectedColor ); - SetupContent( mSelectedContent, selectedContentActor ); - mSelectedContent.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS ); + mUnselectedColor = color; + contentActor = &mUnselectedContent; + imageFileExists = !GetUnselectedImageFilename().empty(); + } + + if ( contentActor ) + { + if( imageFileExists ) + { + // If there is existing unselected content, change the color on it directly. + contentActor->SetColor( color ); + } + else + { + // If there is no existing content, create a new actor to use for flat color. + Actor placementActor = Actor::New(); + Toolkit::RendererFactory rendererFactory = Toolkit::RendererFactory::Get(); + Toolkit::ControlRenderer colorRenderer; + + Property::Map map; + map["rendererType"] = "COLOR"; + map["mixColor"] = color; + + colorRenderer = rendererFactory.CreateControlRenderer( map ); + colorRenderer.SetOnStage( placementActor ); + + SetupContent( *contentActor, placementActor ); // + contentActor->SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS ); + } } } @@ -1386,13 +1394,13 @@ void Button::SetProperty( BaseObject* object, Property::Index index, const Prope case Toolkit::Button::Property::UNSELECTED_COLOR: { - GetImplementation( button ).SetUnselectedColor( value.Get< Vector4 >() ); + GetImplementation( button ).SetColor( value.Get< Vector4 >(), UnselectedState ); break; } case Toolkit::Button::Property::SELECTED_COLOR: { - GetImplementation( button ).SetSelectedColor( value.Get< Vector4 >() ); + GetImplementation( button ).SetColor( value.Get< Vector4 >(), SelectedState ); break; } diff --git a/dali-toolkit/internal/controls/buttons/button-impl.h b/dali-toolkit/internal/controls/buttons/button-impl.h index 71a42fe..da2557f 100644 --- a/dali-toolkit/internal/controls/buttons/button-impl.h +++ b/dali-toolkit/internal/controls/buttons/button-impl.h @@ -43,18 +43,6 @@ namespace Internal class Button : public Control { -protected: - - /** - * Construct a new Button. - */ - Button(); - - /** - * A reference counted object may only be deleted by calling Unreference() - */ - virtual ~Button(); - public: /** @@ -285,6 +273,42 @@ public: // Deprecated API protected: + enum ButtonState + { + ButtonUp, ///< The button is up. + ButtonDown, ///< The button is down. + }; + + /** + * Button paint states. + */ + enum PaintState + { + UnselectedState, ///< The button is unselected. + SelectedState, ///< The button is selected. + DisabledUnselectedState, ///< The button is disabled and unselected. + DisabledSelectedState, ///< The button is disabled and selected. + }; + + /** + * Enum to specify which decoration when getting and setting decorations. + */ + enum DecorationState + { + UNSELECTED_DECORATION = 0, + SELECTED_DECORATION, + DECORATION_STATES + }; + + /** + * Construct a new Button. + */ + Button(); + + /** + * A reference counted object may only be deleted by calling Unreference() + */ + virtual ~Button(); /** * @return A reference to the label actor. */ @@ -494,6 +518,7 @@ protected: // From Control */ void OnStageDisconnection(); + private: /** @@ -551,24 +576,18 @@ private: void SetupContent( Actor& actorToModify, Actor newActor ); /** - * Sets the color of the unselected image. - * If no image exists, it is created. - * @param[in] color The color to use. - */ - void SetUnselectedColor( const Vector4& color ); - - /** * Gets the unselected content color. * @return The currently used unselected color. */ const Vector4 GetUnselectedColor() const; /** - * Sets the color of the selected image. - * If no image exists, it is created. + * Sets the color of button in selected or unselected state, if image also supplied this color will be appplied to it. + * If no visual exists, it is created. * @param[in] color The color to use. + * @param[in] selectedState The state to apply the color to, SelectedState or DisabledUnselectedState. */ - void SetSelectedColor( const Vector4& color ); + void SetColor( const Vector4& color, PaintState selectedState ); /** * Gets the selected content color. @@ -578,33 +597,6 @@ private: protected: - enum ButtonState - { - ButtonUp, ///< The button is up. - ButtonDown, ///< The button is down. - }; - - /** - * Button paint states. - */ - enum PaintState - { - UnselectedState, ///< The button is unselected. - SelectedState, ///< The button is selected. - DisabledUnselectedState, ///< The button is disabled and unselected. - DisabledSelectedState, ///< The button is disabled and selected. - }; - - /** - * Enum to specify which decoration when getting and setting decorations. - */ - enum DecorationState - { - UNSELECTED_DECORATION = 0, - SELECTED_DECORATION, - DECORATION_STATES - }; - ButtonState GetState(); PaintState GetPaintState(); void SetDecoration( DecorationState state, Actor actor ); diff --git a/dali-toolkit/internal/controls/effects-view/effects-view-impl.cpp b/dali-toolkit/internal/controls/effects-view/effects-view-impl.cpp index 332d322..4fb7e85 100644 --- a/dali-toolkit/internal/controls/effects-view/effects-view-impl.cpp +++ b/dali-toolkit/internal/controls/effects-view/effects-view-impl.cpp @@ -26,8 +26,8 @@ #include #include #include +#include #include -#include // INTERNAL INCLUDES #include @@ -161,7 +161,7 @@ void EffectsView::SetType( Toolkit::EffectsView::EffectType type ) Actor self = Self(); Property::Map rendererMap; - rendererMap.Insert( "rendererType", "image" ); + rendererMap.Insert( "rendererType", "IMAGE" ); switch( type ) { diff --git a/dali-toolkit/internal/controls/model3d-view/model3d-view-impl.h b/dali-toolkit/internal/controls/model3d-view/model3d-view-impl.h index 9c24faa..51388f3 100644 --- a/dali-toolkit/internal/controls/model3d-view/model3d-view-impl.h +++ b/dali-toolkit/internal/controls/model3d-view/model3d-view-impl.h @@ -1,8 +1,8 @@ -#ifndef __DALI_TOOLKIT_INTERNAL_MODEL3D_VIEW_H__ -#define __DALI_TOOLKIT_INTERNAL_MODEL3D_VIEW_H__ +#ifndef DALI_TOOLKIT_INTERNAL_MODEL3D_VIEW_H +#define DALI_TOOLKIT_INTERNAL_MODEL3D_VIEW_H /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,7 @@ */ // EXTERNAL INCLUDES -#include +#include // INTERNAL INCLUDES #include @@ -201,4 +201,4 @@ inline const Toolkit::Internal::Model3dView& GetImpl( const Toolkit::Model3dView } // namespace Dali -#endif // __DALI_TOOLKIT_INTERNAL_MODEL_VIEW_H__ +#endif // DALI_TOOLKIT_INTERNAL_MODEL_VIEW_H diff --git a/dali-toolkit/internal/controls/model3d-view/obj-loader.h b/dali-toolkit/internal/controls/model3d-view/obj-loader.h index a877bb9..5f4662d 100644 --- a/dali-toolkit/internal/controls/model3d-view/obj-loader.h +++ b/dali-toolkit/internal/controls/model3d-view/obj-loader.h @@ -1,8 +1,8 @@ -#ifndef __DALI_TOOLKIT_INTERNAL_OBJ_LOADER_H__ -#define __DALI_TOOLKIT_INTERNAL_OBJ_LOADER_H__ +#ifndef DALI_TOOLKIT_INTERNAL_OBJ_LOADER_H +#define DALI_TOOLKIT_INTERNAL_OBJ_LOADER_H /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,7 @@ */ // EXTERNAL INCLUDES -#include +#include #include namespace Dali @@ -171,4 +171,4 @@ private: -#endif // __DALI_TOOLKIT_INTERNAL_OBJ_LOADER_H__ +#endif // DALI_TOOLKIT_INTERNAL_OBJ_LOADER_H diff --git a/dali-toolkit/internal/controls/page-turn-view/page-turn-view-impl.h b/dali-toolkit/internal/controls/page-turn-view/page-turn-view-impl.h index 1f4bc16..078859d 100644 --- a/dali-toolkit/internal/controls/page-turn-view/page-turn-view-impl.h +++ b/dali-toolkit/internal/controls/page-turn-view/page-turn-view-impl.h @@ -1,8 +1,8 @@ -#ifndef __DALI_TOOLKIT_INTERNAL_PAGE_TURN_VIEW_IMPL_H__ -#define __DALI_TOOLKIT_INTERNAL_PAGE_TURN_VIEW_IMPL_H__ +#ifndef DALI_TOOLKIT_INTERNAL_PAGE_TURN_VIEW_IMPL_H +#define DALI_TOOLKIT_INTERNAL_PAGE_TURN_VIEW_IMPL_H /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,7 +21,7 @@ // EXTERNAL INCLUDES #include #include -#include +#include // INTERNAL INCLUDES #include @@ -454,4 +454,5 @@ inline const Toolkit::Internal::PageTurnView& GetImplementation(const Toolkit::P } // namespace Toolkit } // namespace Dali -#endif /* __DALI_TOOLKIT_INTERNAL_PAGE_TURN_VIEW_IMPL_H__ */ + +#endif // DALI_TOOLKIT_INTERNAL_PAGE_TURN_VIEW_IMPL_H diff --git a/dali-toolkit/internal/controls/renderers/border/border-renderer.h b/dali-toolkit/internal/controls/renderers/border/border-renderer.h index 56ff901..14eaf42 100644 --- a/dali-toolkit/internal/controls/renderers/border/border-renderer.h +++ b/dali-toolkit/internal/controls/renderers/border/border-renderer.h @@ -1,8 +1,8 @@ -#ifndef __DALI_TOOLKIT_INTERNAL_BORDER_RENDERER_H__ -#define __DALI_TOOLKIT_INTERNAL_BORDER_RENDERER_H__ +#ifndef DALI_TOOLKIT_INTERNAL_BORDER_RENDERER_H +#define DALI_TOOLKIT_INTERNAL_BORDER_RENDERER_H /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,8 +17,9 @@ * limitations under the License. * */ + // EXTERNAL INCLUDES -#include +#include // INTERNAL INCLUDES #include @@ -146,4 +147,4 @@ private: } // namespace Dali -#endif /* __DALI_TOOLKIT_INTERNAL_BORDER_RENDERER_H__ */ +#endif // DALI_TOOLKIT_INTERNAL_BORDER_RENDERER_H diff --git a/dali-toolkit/internal/controls/renderers/control-renderer-data-impl.h b/dali-toolkit/internal/controls/renderers/control-renderer-data-impl.h index 5092075..8349791 100644 --- a/dali-toolkit/internal/controls/renderers/control-renderer-data-impl.h +++ b/dali-toolkit/internal/controls/renderers/control-renderer-data-impl.h @@ -1,8 +1,8 @@ -#ifndef __DALI_TOOLKIT_INTERNAL_CONTROL_RENDERER_DATA_IMPL_H__ -#define __DALI_TOOLKIT_INTERNAL_CONTROL_RENDERER_DATA_IMPL_H__ +#ifndef DALI_TOOLKIT_INTERNAL_CONTROL_RENDERER_DATA_IMPL_H +#define DALI_TOOLKIT_INTERNAL_CONTROL_RENDERER_DATA_IMPL_H /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,8 +20,9 @@ // EXTERNAL INCLUDES #include -#include +#include +// INTERNAL INCLUDES #include namespace Dali @@ -74,4 +75,4 @@ struct Internal::ControlRenderer::Impl } // namespace Dali -#endif /* __DALI_TOOLKIT_INTERNAL_CONTROL_RENDERER_DATA_IMPL_H__ */ +#endif // DALI_TOOLKIT_INTERNAL_CONTROL_RENDERER_DATA_IMPL_H diff --git a/dali-toolkit/internal/controls/renderers/control-renderer-impl.h b/dali-toolkit/internal/controls/renderers/control-renderer-impl.h index 3880b0b..a1e91e6 100644 --- a/dali-toolkit/internal/controls/renderers/control-renderer-impl.h +++ b/dali-toolkit/internal/controls/renderers/control-renderer-impl.h @@ -1,8 +1,8 @@ -#ifndef __DALI_TOOLKIT_INTERNAL_CONTROL_RENDERER_H__ -#define __DALI_TOOLKIT_INTERNAL_CONTROL_RENDERER_H__ +#ifndef DALI_TOOLKIT_INTERNAL_CONTROL_RENDERER_H +#define DALI_TOOLKIT_INTERNAL_CONTROL_RENDERER_H /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,15 +18,14 @@ * */ - // EXTERNAL INCLUDES -#include #include -#include +#include +#include // INTERNAL INCLUDES -#include #include +#include #include namespace Dali @@ -251,4 +250,4 @@ inline Internal::ControlRenderer& GetImplementation(Toolkit::ControlRenderer& re } // namespace Dali -#endif /* __DALI_TOOLKIT_INTERNAL_CONTROL_RENDERER_H___ */ +#endif // DALI_TOOLKIT_INTERNAL_CONTROL_RENDERER_H diff --git a/dali-toolkit/internal/controls/renderers/debug/debug-renderer.cpp b/dali-toolkit/internal/controls/renderers/debug/debug-renderer.cpp index 1fc45ca..68dd38e 100644 --- a/dali-toolkit/internal/controls/renderers/debug/debug-renderer.cpp +++ b/dali-toolkit/internal/controls/renderers/debug/debug-renderer.cpp @@ -23,6 +23,7 @@ #include #include #include +#include namespace Dali { @@ -35,9 +36,6 @@ namespace Internal namespace { -const char * const RENDERER_TYPE("rendererType"); -const char * const RENDERER_TYPE_VALUE("debug"); - const char * const POSITION_ATTRIBUTE_NAME("aPosition"); const char * const INDEX_NAME("indices"); @@ -82,7 +80,7 @@ void DebugRenderer::DoSetOnStage( Actor& actor ) void DebugRenderer::DoCreatePropertyMap( Property::Map& map ) const { map.Clear(); - map.Insert( RENDERER_TYPE, RENDERER_TYPE_VALUE ); + map.Insert( RENDERER_TYPE, DEBUG_RENDERER ); } void DebugRenderer::InitializeRenderer() diff --git a/dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.cpp b/dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.cpp index 952bd3b..5923bb5 100644 --- a/dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.cpp +++ b/dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.cpp @@ -59,11 +59,11 @@ const char * const UNITS_NAME("units"); // Property::String "userSpaceOnUse | o const char * const SPREAD_METHOD_NAME("spreadMethod"); // Property::String "pad | reflect | repeat" // string values -const char * const UNIT_USER_SPACE("userSpace"); -const char * const UNIT_BOUNDING_BOX("objectBoundingBox"); -const char * const SPREAD_PAD("pad"); -const char * const SPREAD_REFLECT("reflect"); -const char * const SPREAD_REPEAT("repeat"); +const char * const UNIT_USER_SPACE("USER_SPACE"); +const char * const UNIT_BOUNDING_BOX("OBJECT_BOUNDING_BOX"); +const char * const SPREAD_PAD("PAD"); +const char * const SPREAD_REFLECT("REFLECT"); +const char * const SPREAD_REPEAT("REPEAT"); // uniform names const char * const UNIFORM_ALIGNMENT_MATRIX_NAME( "uAlignmentMatrix" ); @@ -196,7 +196,7 @@ void GradientRenderer::DoInitialize( Actor& actor, const Property::Map& property Property::Value* unitsValue = propertyMap.Find( UNITS_NAME ); std::string units; // The default unit is OBJECT_BOUNDING_BOX. - // Only need to set new units if 'user-space' + // Only need to set new units if 'USER_SPACE' if( unitsValue && unitsValue->Get( units ) && units == UNIT_USER_SPACE ) { gradientUnits = Gradient::USER_SPACE_ON_USE; diff --git a/dali-toolkit/internal/controls/renderers/gradient/gradient.h b/dali-toolkit/internal/controls/renderers/gradient/gradient.h index 64fd6b5..f08af99 100644 --- a/dali-toolkit/internal/controls/renderers/gradient/gradient.h +++ b/dali-toolkit/internal/controls/renderers/gradient/gradient.h @@ -1,5 +1,5 @@ -#ifndef __DALI_TOOLKIT_INTERNAL_GRADIENT_H__ -#define __DALI_TOOLKIT_INTERNAL_GRADIENT_H__ +#ifndef DALI_TOOLKIT_INTERNAL_GRADIENT_H +#define DALI_TOOLKIT_INTERNAL_GRADIENT_H /* * Copyright (c) 2016 Samsung Electronics Co., Ltd. @@ -19,11 +19,11 @@ */ //EXTERNAL INCLUDES -#include -#include #include #include -#include +#include +#include +#include namespace Dali { @@ -177,4 +177,4 @@ protected: } // namespace Dali -#endif /* __DALI_TOOLKIT_INTERNAL_GRADIENT_RENDERER_H__ */ +#endif // DALI_TOOLKIT_INTERNAL_GRADIENT_RENDERER_H diff --git a/dali-toolkit/internal/controls/renderers/image-atlas-manager.h b/dali-toolkit/internal/controls/renderers/image-atlas-manager.h index abe0123..fa1271e 100644 --- a/dali-toolkit/internal/controls/renderers/image-atlas-manager.h +++ b/dali-toolkit/internal/controls/renderers/image-atlas-manager.h @@ -1,8 +1,8 @@ -#ifndef __DALI_TOOLKIT_IMAGE_ATLAS_MANAGER_H__ -#define __DALI_TOOLKIT_IMAGE_ATLAS_MANAGER_H__ +#ifndef DALI_TOOLKIT_IMAGE_ATLAS_MANAGER_H +#define DALI_TOOLKIT_IMAGE_ATLAS_MANAGER_H /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,7 +21,7 @@ #include #include #include -#include +#include // INTERNAL INCLUDES #include @@ -144,4 +144,4 @@ private: } // namespace Dali -#endif // __DALI_TOOLKIT_ATLAS_MANAGER_H__ +#endif // DALI_TOOLKIT_ATLAS_MANAGER_H diff --git a/dali-toolkit/internal/controls/renderers/mesh/mesh-renderer.cpp b/dali-toolkit/internal/controls/renderers/mesh/mesh-renderer.cpp index dd52948..acc248c 100644 --- a/dali-toolkit/internal/controls/renderers/mesh/mesh-renderer.cpp +++ b/dali-toolkit/internal/controls/renderers/mesh/mesh-renderer.cpp @@ -28,8 +28,6 @@ //INTERNAL INCLUDES #include -#include -#include #include namespace Dali @@ -83,10 +81,13 @@ enum TextureIndex GLOSS_INDEX = 2u }; -const char * const RENDERER_TYPE_VALUE( "mesh" ); //String label for which type of control renderer this is. const char * const LIGHT_POSITION( "uLightPosition" ); //Shader property const char * const OBJECT_MATRIX( "uObjectMatrix" ); //Shader property +const char * const SHADER_TYPE_TEXTURELESS( "TEXTURELESS" ); +const char * const SHADER_TYPE_DIFFUSE_TEXTURE( "DIFFUSE_TEXTURE" ); +const char * const SHADER_TYPE_ALL_TEXTURES( "ALL_TEXTURES" ); + //Shaders //If a shader requires certain textures, they must be listed in order, //as detailed in the TextureIndex enum documentation. @@ -112,8 +113,8 @@ const char* SIMPLE_VERTEX_SHADER = DALI_COMPOSE_SHADER( //Illumination in Model-View space - Transform attributes and uniforms\n vec4 vertPos = uModelView * vec4( aPosition.xyz, 1.0 );\n vec3 normal = uNormalMatrix * mat3( uObjectMatrix ) * aNormal;\n - vec4 centre = uModelView * vec4( 0.0, 0.0, 0.0, 1.0 );\n - vec4 lightPos = vec4( centre.x, centre.y, uLightPosition.z, 1.0 );\n + vec4 center = uModelView * vec4( 0.0, 0.0, 0.0, 1.0 );\n + vec4 lightPos = vec4( center.x, center.y, uLightPosition.z, 1.0 );\n vec3 vecToLight = normalize( lightPos.xyz - vertPos.xyz );\n float lightDiffuse = max( dot( vecToLight, normal ), 0.0 );\n @@ -158,8 +159,8 @@ const char* VERTEX_SHADER = DALI_COMPOSE_SHADER( //Illumination in Model-View space - Transform attributes and uniforms\n vec4 vertPos = uModelView * vec4( aPosition.xyz, 1.0 );\n - vec4 centre = uModelView * vec4( 0.0, 0.0, 0.0, 1.0 );\n - vec4 lightPos = vec4( centre.x, centre.y, uLightPosition.z, 1.0 );\n + vec4 center = uModelView * vec4( 0.0, 0.0, 0.0, 1.0 );\n + vec4 lightPos = vec4( center.x, center.y, uLightPosition.z, 1.0 );\n vec3 normal = normalize( uNormalMatrix * mat3( uObjectMatrix ) * aNormal );\n vec3 vecToLight = normalize( lightPos.xyz - vertPos.xyz );\n @@ -220,8 +221,8 @@ const char* NORMAL_MAP_VERTEX_SHADER = DALI_COMPOSE_SHADER( vertexPosition = uMvpMatrix * vertexPosition;\n vec4 vertPos = uModelView * vec4( aPosition.xyz, 1.0 );\n - vec4 centre = uModelView * vec4( 0.0, 0.0, 0.0, 1.0 );\n - vec4 lightPos = vec4( centre.x, centre.y, uLightPosition.z, 1.0 );\n + vec4 center = uModelView * vec4( 0.0, 0.0, 0.0, 1.0 );\n + vec4 lightPos = vec4( center.x, center.y, uLightPosition.z, 1.0 );\n vec3 tangent = normalize( uNormalMatrix * aTangent ); vec3 binormal = normalize( uNormalMatrix * aBiNormal ); @@ -313,23 +314,27 @@ void MeshRenderer::DoInitialize( Actor& actor, const Property::Map& propertyMap } Property::Value* shaderType = propertyMap.Find( SHADER_TYPE ); - if( shaderType && shaderType->Get( mShaderTypeString ) ) + if( shaderType ) { - if( mShaderTypeString == "textureless" ) - { - mShaderType = TEXTURELESS; - } - else if( mShaderTypeString == "diffuseTexture" ) - { - mShaderType = DIFFUSE_TEXTURE; - } - else if( mShaderTypeString == "allTextures" ) - { - mShaderType = ALL_TEXTURES; - } - else + std::string shaderTypeString; + if( shaderType->Get( shaderTypeString ) ) { - DALI_LOG_ERROR( "Unknown shader type provided to the MeshRenderer object.\n"); + if( shaderTypeString == SHADER_TYPE_TEXTURELESS ) + { + mShaderType = TEXTURELESS; + } + else if( shaderTypeString == SHADER_TYPE_DIFFUSE_TEXTURE ) + { + mShaderType = DIFFUSE_TEXTURE; + } + else if( shaderTypeString == SHADER_TYPE_ALL_TEXTURES ) + { + mShaderType = ALL_TEXTURES; + } + else + { + DALI_LOG_ERROR( "Unknown shader type provided to the MeshRenderer object.\n"); + } } } } @@ -361,11 +366,33 @@ void MeshRenderer::DoSetOnStage( Actor& actor ) void MeshRenderer::DoCreatePropertyMap( Property::Map& map ) const { map.Clear(); - map.Insert( RENDERER_TYPE, RENDERER_TYPE_VALUE ); + map.Insert( RENDERER_TYPE, MESH_RENDERER ); map.Insert( OBJECT_URL, mObjectUrl ); map.Insert( MATERIAL_URL, mMaterialUrl ); map.Insert( TEXTURES_PATH, mTexturesPath ); - map.Insert( SHADER_TYPE, mShaderTypeString ); + + std::string shaderTypeString; + switch( mShaderType ) + { + case ALL_TEXTURES: + { + shaderTypeString = SHADER_TYPE_ALL_TEXTURES; + break; + } + + case DIFFUSE_TEXTURE: + { + shaderTypeString = SHADER_TYPE_DIFFUSE_TEXTURE; + break; + } + + case TEXTURELESS: + { + shaderTypeString = SHADER_TYPE_TEXTURELESS; + break; + } + } + map.Insert( SHADER_TYPE, shaderTypeString ); } void MeshRenderer::InitializeRenderer() diff --git a/dali-toolkit/internal/controls/renderers/mesh/mesh-renderer.h b/dali-toolkit/internal/controls/renderers/mesh/mesh-renderer.h index e5aaee5..30d032b 100644 --- a/dali-toolkit/internal/controls/renderers/mesh/mesh-renderer.h +++ b/dali-toolkit/internal/controls/renderers/mesh/mesh-renderer.h @@ -184,8 +184,6 @@ private: std::string mGlossTextureUrl; std::string mTexturesPath; - std::string mShaderTypeString; - Shader mShader; Geometry mGeometry; TextureSet mTextureSet; diff --git a/dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.h b/dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.h index 44754d7..1832e61 100644 --- a/dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.h +++ b/dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.h @@ -1,8 +1,8 @@ -#ifndef __DALI_TOOLKIT_INTERNAL_N_PATCH_RENDERER_H__ -#define __DALI_TOOLKIT_INTERNAL_N_PATCH_RENDERER_H__ +#ifndef DALI_TOOLKIT_INTERNAL_N_PATCH_RENDERER_H +#define DALI_TOOLKIT_INTERNAL_N_PATCH_RENDERER_H /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,11 +23,11 @@ // EXTERNAL INCLUDES #include -#include #include -#include -#include -#include +#include +#include +#include +#include namespace Dali { @@ -220,4 +220,4 @@ private: } // namespace Dali -#endif /* __DALI_TOOLKIT_INTERNAL_N_PATCH_RENDERER_H__ */ +#endif // DALI_TOOLKIT_INTERNAL_N_PATCH_RENDERER_H diff --git a/dali-toolkit/internal/controls/renderers/primitive/primitive-renderer.cpp b/dali-toolkit/internal/controls/renderers/primitive/primitive-renderer.cpp new file mode 100644 index 0000000..1ed6404 --- /dev/null +++ b/dali-toolkit/internal/controls/renderers/primitive/primitive-renderer.cpp @@ -0,0 +1,1464 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// CLASS HEADER +#include "primitive-renderer.h" + +// EXTERNAL INCLUDES +#include +#include +#include + +//INTERNAL INCLUDES +#include +#include + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Internal +{ + +namespace +{ + +//Primitive property defaults +const int DEFAULT_SLICES = 128; ///< For spheres and conics +const int DEFAULT_STACKS = 128; ///< For spheres and conics +const float DEFAULT_SCALE_TOP_RADIUS = 1.0; ///< For conical frustrums +const float DEFAULT_SCALE_BOTTOM_RADIUS = 1.5; ///< For cones and conical frustrums +const float DEFAULT_SCALE_HEIGHT = 3.0; ///< For all conics +const float DEFAULT_SCALE_RADIUS = 1.0; ///< For cylinders +const float DEFAULT_BEVEL_PERCENTAGE = 0.0; ///< For bevelled cubes +const float DEFAULT_BEVEL_SMOOTHNESS = 0.0; ///< For bevelled cubes +const Vector4 DEFAULT_COLOR = Vector4( 0.5, 0.5, 0.5, 0.0 ); ///< Grey, for all. + +//Property limits +const int MIN_SLICES = 1; ///< Minimum number of slices for spheres and conics +const int MIN_STACKS = 1; ///< Minimum number of stacks for spheres and conics +const int MAX_PARTITIONS = 255; ///< Maximum number of slices or stacks for spheres and conics +const float MIN_BEVEL_PERCENTAGE = 0.0; ///< Minimum bevel percentage for bevelled cubes +const float MAX_BEVEL_PERCENTAGE = 1.0; ///< Maximum bevel percentage for bevelled cubes +const float MIN_SMOOTHNESS = 0.0; ///< Minimum bevel smoothness for bevelled cubes +const float MAX_SMOOTHNESS = 1.0; ///< Maximum bevel smoothness for bevelled cubes + +const char * const RENDERER_TYPE_VALUE( "PRIMITIVE" ); + +//Specific shape labels. +const char * const SPHERE_LABEL( "SPHERE" ); +const char * const CONE_LABEL( "CONE" ); +const char * const CONICAL_FRUSTRUM_LABEL( "CONICAL_FRUSTRUM" ); +const char * const CYLINDER_LABEL( "CYLINDER" ); +const char * const CUBE_LABEL( "CUBE" ); +const char * const OCTAHEDRON_LABEL( "OCTAHEDRON" ); +const char * const BEVELLED_CUBE_LABEL( "BEVELLED_CUBE" ); + +//Shader properties +const char * const OBJECT_MATRIX_UNIFORM_NAME( "uObjectMatrix" ); +const char * const COLOR_UNIFORM_NAME( "uColor" ); +const char * const OBJECT_DIMENSIONS_UNIFORM_NAME( "uObjectDimensions" ); +const char * const STAGE_SIZE_UNIFORM_NAME( "uStageSize" ); + +//Vertex properties +const char * const POSITION( "aPosition"); +const char * const NORMAL( "aNormal" ); +const char * const INDICES( "aIndices" ); + +//A simple shader that applies diffuse lighting to a mono-coloured object. +const char* VERTEX_SHADER = DALI_COMPOSE_SHADER( + attribute highp vec3 aPosition;\n + attribute highp vec2 aTexCoord;\n + attribute highp vec3 aNormal;\n + varying mediump vec3 vIllumination;\n + uniform mediump vec3 uSize;\n + uniform mediump vec3 uObjectDimensions;\n + uniform mediump mat4 uMvpMatrix;\n + uniform mediump mat4 uModelView;\n + uniform mediump mat4 uViewMatrix;\n + uniform mediump mat3 uNormalMatrix;\n + uniform mediump mat4 uObjectMatrix;\n + uniform mediump vec3 uLightPosition;\n + uniform mediump vec3 uStageSize;\n + + void main()\n + {\n + float xRatio = uSize.x / uObjectDimensions.x;\n + float yRatio = uSize.y / uObjectDimensions.y;\n + float scaleFactor = min( xRatio, yRatio );\n + + vec4 normalisedVertexPosition = vec4( aPosition * scaleFactor, 1.0 );\n + vec4 vertexPosition = uObjectMatrix * normalisedVertexPosition;\n + vertexPosition = uMvpMatrix * vertexPosition;\n + + //Illumination in Model-View space - Transform attributes and uniforms\n + vec4 mvVertexPosition = uModelView * normalisedVertexPosition;\n + vec3 normal = uNormalMatrix * mat3( uObjectMatrix ) * aNormal;\n + + vec3 stageOffset = vec3( uStageSize.xy, 0 ) / 2.0;\n + vec4 lightPosition = vec4( ( uLightPosition - stageOffset ), 1.0 );\n + lightPosition = uViewMatrix * lightPosition;\n + vec3 vectorToLight = normalize( lightPosition.xyz - mvVertexPosition.xyz );\n + + float lightDiffuse = max( dot( vectorToLight, normal ), 0.0 );\n + vIllumination = vec3( lightDiffuse * 0.5 + 0.5 );\n + + gl_Position = vertexPosition;\n + }\n +); + +//Very simple fragment shader that merely applies the vertex shading to the color at each fragment. +const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER( + precision mediump float;\n + varying mediump vec3 vIllumination;\n + uniform lowp vec4 uColor;\n + + void main()\n + {\n + gl_FragColor = vec4( vIllumination.rgb * uColor.rgb, uColor.a );\n + }\n +); + +} // namespace + +PrimitiveRenderer::PrimitiveRenderer( RendererFactoryCache& factoryCache ) +: ControlRenderer( factoryCache ), + mColor( DEFAULT_COLOR ), + mScaleDimensions( Vector3::ONE ), + mScaleTopRadius( DEFAULT_SCALE_TOP_RADIUS ), + mScaleBottomRadius( DEFAULT_SCALE_BOTTOM_RADIUS ), + mScaleHeight( DEFAULT_SCALE_HEIGHT ), + mScaleRadius( DEFAULT_SCALE_RADIUS ), + mBevelPercentage( DEFAULT_BEVEL_PERCENTAGE ), + mBevelSmoothness( DEFAULT_BEVEL_SMOOTHNESS ), + mSlices( DEFAULT_SLICES ), + mStacks( DEFAULT_STACKS ), + mPrimitiveType( SPHERE ) +{ +} + +PrimitiveRenderer::~PrimitiveRenderer() +{ +} + +void PrimitiveRenderer::DoInitialize( Actor& actor, const Property::Map& propertyMap ) +{ + //Find out which shape to renderer. + Property::Value* primitiveType = propertyMap.Find( PRIMITIVE_SHAPE ); + if( primitiveType ) + { + if( primitiveType->Get( mShape ) ) + { + //Set property type as an enum. + if( mShape == SPHERE_LABEL ) + { + mPrimitiveType = SPHERE; + } + else if( mShape == CONE_LABEL ) + { + mPrimitiveType = CONE; + } + else if( mShape == CONICAL_FRUSTRUM_LABEL ) + { + mPrimitiveType = CONICAL_FRUSTRUM; + } + else if( mShape == CYLINDER_LABEL ) + { + mPrimitiveType = CYLINDER; + } + else if( mShape == CUBE_LABEL ) + { + mPrimitiveType = CUBE; + } + else if( mShape == OCTAHEDRON_LABEL ) + { + mPrimitiveType = OCTAHEDRON; + } + else if( mShape == BEVELLED_CUBE_LABEL ) + { + mPrimitiveType = BEVELLED_CUBE; + } + else + { + DALI_LOG_ERROR( "No known shape in PrimitiveRenderer.\n" ); + } + } + else + { + DALI_LOG_ERROR( "Invalid type for shape in PrimitiveRenderer.\n" ); + } + } + else + { + DALI_LOG_ERROR( "Fail to provide shape to the PrimitiveRenderer object.\n" ); + } + + //Read in other potential properties. + + Property::Value* color = propertyMap.Find( SHAPE_COLOR ); + if( color && !color->Get( mColor ) ) + { + DALI_LOG_ERROR( "Invalid type for color in PrimitiveRenderer.\n" ); + } + + Property::Value* slices = propertyMap.Find( SLICES ); + if( slices ) + { + if( slices->Get( mSlices ) ) + { + //Clamp value. + if( mSlices > MAX_PARTITIONS ) + { + mSlices = MAX_PARTITIONS; + } + else if ( mSlices < MIN_SLICES ) + { + mSlices = MIN_SLICES; + } + } + else + { + DALI_LOG_ERROR( "Invalid type for slices in PrimitiveRenderer.\n" ); + } + } + + Property::Value* stacks = propertyMap.Find( STACKS ); + if( stacks ) + { + if( stacks->Get( mStacks ) ) + { + //Clamp value. + if( mStacks > MAX_PARTITIONS ) + { + mStacks = MAX_PARTITIONS; + } + else if ( mStacks < MIN_STACKS ) + { + mStacks = MIN_STACKS; + } + } + else + { + DALI_LOG_ERROR( "Invalid type for stacks in PrimitiveRenderer.\n" ); + } + } + + Property::Value* scaleTop = propertyMap.Find( SCALE_TOP_RADIUS ); + if( scaleTop && !scaleTop->Get( mScaleTopRadius ) ) + { + DALI_LOG_ERROR( "Invalid type for scale top radius in PrimitiveRenderer.\n" ); + } + + Property::Value* scaleBottom = propertyMap.Find( SCALE_BOTTOM_RADIUS ); + if( scaleBottom && !scaleBottom->Get( mScaleBottomRadius ) ) + { + DALI_LOG_ERROR( "Invalid type for scale bottom radius in PrimitiveRenderer.\n" ); + } + + Property::Value* scaleHeight = propertyMap.Find( SCALE_HEIGHT ); + if( scaleHeight && !scaleHeight->Get( mScaleHeight ) ) + { + DALI_LOG_ERROR( "Invalid type for scale height in PrimitiveRenderer.\n" ); + } + + Property::Value* scaleRadius = propertyMap.Find( SCALE_RADIUS ); + if( scaleRadius && !scaleRadius->Get( mScaleRadius ) ) + { + DALI_LOG_ERROR( "Invalid type for scale radius in PrimitiveRenderer.\n" ); + } + + Property::Value* dimensions = propertyMap.Find( SCALE_DIMENSIONS ); + if( dimensions ) + { + if( dimensions->Get( mScaleDimensions ) ) + { + //If any dimension is invalid, set it to a sensible default. + if( mScaleDimensions.x <= 0.0 ) + { + mScaleDimensions.x = 1.0; + } + if( mScaleDimensions.y <= 0.0 ) + { + mScaleDimensions.y = 1.0; + } + if( mScaleDimensions.z <= 0.0 ) + { + mScaleDimensions.z = 1.0; + } + } + else + { + DALI_LOG_ERROR( "Invalid type for scale dimensions in PrimitiveRenderer.\n" ); + } + } + + Property::Value* bevel = propertyMap.Find( BEVEL_PERCENTAGE ); + if( bevel ) + { + if( bevel->Get( mBevelPercentage ) ) + { + //Clamp value. + if( mBevelPercentage < MIN_BEVEL_PERCENTAGE ) + { + mBevelPercentage = MIN_BEVEL_PERCENTAGE; + } + else if( mBevelPercentage > MAX_BEVEL_PERCENTAGE ) + { + mBevelPercentage = MAX_BEVEL_PERCENTAGE; + } + } + else + { + DALI_LOG_ERROR( "Invalid type for bevel percentage in PrimitiveRenderer.\n" ); + } + } + + Property::Value* smoothness = propertyMap.Find( BEVEL_SMOOTHNESS ); + if( smoothness ) + { + if( smoothness->Get( mBevelSmoothness ) ) + { + //Clamp value. + if( mBevelSmoothness < MIN_SMOOTHNESS ) + { + mBevelSmoothness = MIN_SMOOTHNESS; + } + else if( mBevelSmoothness > MAX_SMOOTHNESS ) + { + mBevelSmoothness = MAX_SMOOTHNESS; + } + } + else + { + DALI_LOG_ERROR( "Invalid type for bevel smoothness in PrimitiveRenderer.\n" ); + } + } + + //Read in light position. + Property::Value* lightPosition = propertyMap.Find( LIGHT_POSITION_UNIFORM_NAME ); + if( lightPosition ) + { + if( !lightPosition->Get( mLightPosition ) ) + { + DALI_LOG_ERROR( "Invalid value passed for light position in MeshRenderer object.\n" ); + mLightPosition = Vector3::ZERO; + } + } + else + { + //Default behaviour is to place the light directly in front of the object, + // at a reasonable distance to light everything on screen. + Stage stage = Stage::GetCurrent(); + + mLightPosition = Vector3( stage.GetSize().width / 2, stage.GetSize().height / 2, stage.GetSize().width * 5 ); + } +} + +void PrimitiveRenderer::SetSize( const Vector2& size ) +{ + ControlRenderer::SetSize( size ); + + // ToDo: renderer responds to the size change +} + +void PrimitiveRenderer::SetClipRect( const Rect& clipRect ) +{ + ControlRenderer::SetClipRect( clipRect ); + + //ToDo: renderer responds to the clipRect change +} + +void PrimitiveRenderer::SetOffset( const Vector2& offset ) +{ + //ToDo: renderer applies the offset +} + +void PrimitiveRenderer::DoSetOnStage( Actor& actor ) +{ + InitializeRenderer(); +} + +void PrimitiveRenderer::DoCreatePropertyMap( Property::Map& map ) const +{ + map.Clear(); + map.Insert( RENDERER_TYPE, RENDERER_TYPE_VALUE ); + map.Insert( PRIMITIVE_SHAPE, mShape ); + map.Insert( SHAPE_COLOR, mColor ); + map.Insert( SLICES, mSlices ); + map.Insert( STACKS, mStacks ); + map.Insert( SCALE_TOP_RADIUS, mScaleTopRadius ); + map.Insert( SCALE_BOTTOM_RADIUS, mScaleBottomRadius ); + map.Insert( SCALE_HEIGHT, mScaleHeight ); + map.Insert( SCALE_RADIUS, mScaleRadius ); + map.Insert( SCALE_DIMENSIONS, mScaleDimensions ); + map.Insert( BEVEL_PERCENTAGE, mBevelPercentage ); + map.Insert( BEVEL_SMOOTHNESS, mBevelSmoothness ); + map.Insert( LIGHT_POSITION_UNIFORM_NAME, mLightPosition ); +} + +void PrimitiveRenderer::InitializeRenderer() +{ + if( !mGeometry ) + { + CreateGeometry(); + } + + if( !mShader ) + { + CreateShader(); + } + + mImpl->mRenderer = Renderer::New( mGeometry, mShader ); +} + +void PrimitiveRenderer::UpdateShaderUniforms() +{ + Stage stage = Stage::GetCurrent(); + float width = stage.GetSize().width; + float height = stage.GetSize().height; + + //Flip model to account for DALi starting with (0, 0) at the top left. + Matrix scaleMatrix; + scaleMatrix.SetIdentityAndScale( Vector3( 1.0, -1.0, 1.0 ) ); + + mShader.RegisterProperty( STAGE_SIZE_UNIFORM_NAME, Vector3( width, height, std::min( width, height ) ) ); + mShader.RegisterProperty( LIGHT_POSITION_UNIFORM_NAME, mLightPosition ); + mShader.RegisterProperty( OBJECT_MATRIX_UNIFORM_NAME, scaleMatrix ); + mShader.RegisterProperty( COLOR_UNIFORM_NAME, mColor ); + mShader.RegisterProperty( OBJECT_DIMENSIONS_UNIFORM_NAME, mObjectDimensions ); +} + +void PrimitiveRenderer::CreateShader() +{ + mShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER ); + UpdateShaderUniforms(); +} + +void PrimitiveRenderer::CreateGeometry() +{ + Dali::Vector vertices; + Dali::Vector indices; + + switch( mPrimitiveType ) + { + case SPHERE: + { + CreateSphere( vertices, indices, mSlices, mStacks ); + break; + } + case CONE: + { + //Create a conic with zero top radius. + CreateConic( vertices, indices, 0, mScaleBottomRadius, mScaleHeight, mSlices ); + break; + } + case CONICAL_FRUSTRUM: + { + CreateConic( vertices, indices, mScaleTopRadius, mScaleBottomRadius, mScaleHeight, mSlices ); + break; + } + case CYLINDER: + { + //Create a conic with equal radii on the top and bottom. + CreateConic( vertices, indices, mScaleRadius, mScaleRadius, mScaleHeight, mSlices ); + break; + } + case CUBE: + { + //Create a cube by creating a bevelled cube with minimum bevel. + CreateBevelledCube( vertices, indices, mScaleDimensions, 0.0, 0.0 ); + break; + } + case OCTAHEDRON: + { + //Create an octahedron by creating a bevelled cube with maximum bevel. + CreateBevelledCube( vertices, indices, mScaleDimensions, 1.0, mBevelSmoothness ); + break; + } + case BEVELLED_CUBE: + { + CreateBevelledCube( vertices, indices, mScaleDimensions, mBevelPercentage, mBevelSmoothness ); + break; + } + } + + mGeometry = Geometry::New(); + + //Vertices + Property::Map vertexFormat; + vertexFormat[POSITION] = Property::VECTOR3; + vertexFormat[NORMAL] = Property::VECTOR3; + PropertyBuffer surfaceVertices = PropertyBuffer::New( vertexFormat ); + surfaceVertices.SetData( &vertices[0], vertices.Size() ); + + mGeometry.AddVertexBuffer( surfaceVertices ); + + //Indices for triangle formulation + mGeometry.SetIndexBuffer( &indices[0], indices.Size() ); +} + +void PrimitiveRenderer::CreateSphere( Vector& vertices, Vector& indices, int slices, int stacks ) +{ + ComputeSphereVertices( vertices, slices, stacks ); + FormSphereTriangles( indices, slices, stacks ); + + mObjectDimensions = Vector3::ONE; +} + +void PrimitiveRenderer::CreateConic( Vector& vertices, Vector& indices, float scaleTopRadius, + float scaleBottomRadius, float scaleHeight, int slices ) +{ + ComputeConicVertices( vertices, scaleTopRadius, scaleBottomRadius, scaleHeight, slices ); + FormConicTriangles( indices, scaleTopRadius, scaleBottomRadius, slices ); + + //Determine object dimensions, and scale them to be between 0.0 and 1.0. + float xDimension = std::max( scaleTopRadius, scaleBottomRadius ) * 2.0f; + float yDimension = scaleHeight; + float largestDimension = std::max( xDimension, yDimension ); + + mObjectDimensions = Vector3( xDimension / largestDimension, yDimension / largestDimension, + xDimension / largestDimension ); +} + +void PrimitiveRenderer::CreateBevelledCube( Vector& vertices, Vector& indices, + Vector3 dimensions, float bevelPercentage, float bevelSmoothness ) +{ + dimensions.Normalize(); + + if( bevelPercentage <= MIN_BEVEL_PERCENTAGE ) //No bevel, form a cube. + { + ComputeCubeVertices( vertices, dimensions ); + FormCubeTriangles( indices ); + } + else if( bevelPercentage >= MAX_BEVEL_PERCENTAGE ) //Max bevel, form an octahedron. + { + ComputeOctahedronVertices( vertices, dimensions, bevelSmoothness ); + FormOctahedronTriangles( indices ); + } + else //In between, form a bevelled cube. + { + ComputeBevelledCubeVertices( vertices, dimensions, bevelPercentage, bevelSmoothness ); + FormBevelledCubeTriangles( indices ); + } + + mObjectDimensions = dimensions; +} + +void PrimitiveRenderer::ComputeCircleTables( Vector& sinTable, Vector& cosTable, int divisions, + bool halfCircle ) +{ + if( divisions < 0 ) + { + return; + } + + const float angleDivision = ( halfCircle ? 1.0f : 2.0f ) * Dali::Math::PI / ( float ) divisions; + + sinTable.Resize( divisions ); + cosTable.Resize( divisions ); + + for( int i = 0; i < divisions; i++ ) + { + sinTable[i] = sin( angleDivision * i ); + cosTable[i] = cos( angleDivision * i ); + } +} + +void PrimitiveRenderer::ComputeSphereVertices( Vector& vertices, int slices, int stacks ) +{ + //Tables for calculating slices angles and stacks angles, respectively. + Vector sinTable1; + Vector cosTable1; + Vector sinTable2; + Vector cosTable2; + + ComputeCircleTables( sinTable1, cosTable1, slices, false ); + ComputeCircleTables( sinTable2, cosTable2, stacks, true ); + + int numVertices = slices * ( stacks - 1 ) + 2; + vertices.Resize( numVertices ); + + int vertexIndex = 0; //Track progress through vertices. + float x; + float y; + float z; + + //Top stack. + vertices[vertexIndex].position = Vector3( 0.0, 0.0, 0.5 ); + vertices[vertexIndex].normal = Vector3( 0.0, 0.0, 1.0 ); + vertexIndex++; + + //Middle stacks. + for( int i = 1; i < stacks; i++ ) + { + for( int j = 0; j < slices; j++, vertexIndex++ ) + { + x = cosTable1[j] * sinTable2[i]; + y = sinTable1[j] * sinTable2[i]; + z = cosTable2[i]; + + vertices[vertexIndex].position = Vector3( x / 2.0f, y / 2.0f, z / 2.0f ); + vertices[vertexIndex].normal = Vector3( x, y, z ); + } + } + + //Bottom stack. + vertices[vertexIndex].position = Vector3( 0.0, 0.0, -0.5 ); + vertices[vertexIndex].normal = Vector3( 0.0, 0.0, -1.0 ); +} + +void PrimitiveRenderer::FormSphereTriangles( Vector& indices, int slices, int stacks ) +{ + if( stacks <= 1 ) + { + //Set indices to placeholder "error" values. + //This will display nothing, which is the expected behaviour for this edge case. + indices.Resize( 3 ); + return; + } + + int numTriangles = 2 * slices * ( stacks - 1 ); + + indices.Resize( 3 * numTriangles ); + + int indiceIndex = 0; //Used to keep track of progress through indices. + int previousCycleBeginning = 1; //Stores the index of the vertex that started the cycle of the previous stack. + int currentCycleBeginning = 1 + slices; + + //Top stack. Loop from index 1 to index slices, as not counting the very first vertex. + for( int i = 1; i <= slices; i++, indiceIndex += 3 ) + { + indices[indiceIndex] = 0; + indices[indiceIndex + 1] = i; + if( i == slices ) + { + //End, so loop around. + indices[indiceIndex + 2] = 1; + } + else + { + indices[indiceIndex + 2] = i + 1; + } + } + + //Middle Stacks. Want to form triangles between the top and bottom stacks, so loop up to the number of stacks - 2. + for( int i = 0; i < stacks - 2; i++, previousCycleBeginning += slices, currentCycleBeginning += slices ) + { + for( int j = 0; j < slices; j++, indiceIndex += 6 ) + { + if( j == slices - 1 ) + { + //End, so loop around. + indices[indiceIndex] = previousCycleBeginning + j; + indices[indiceIndex + 1] = currentCycleBeginning + j; + indices[indiceIndex + 2] = previousCycleBeginning; + indices[indiceIndex + 3] = currentCycleBeginning + j; + indices[indiceIndex + 4] = currentCycleBeginning; + indices[indiceIndex + 5] = previousCycleBeginning; + } + else + { + indices[indiceIndex] = previousCycleBeginning + j; + indices[indiceIndex + 1] = currentCycleBeginning + j; + indices[indiceIndex + 2] = previousCycleBeginning + 1 + j; + indices[indiceIndex + 3] = currentCycleBeginning + j; + indices[indiceIndex + 4] = currentCycleBeginning + 1 + j; + indices[indiceIndex + 5] = previousCycleBeginning + 1 + j; + } + } + } + + //Bottom stack. Loop around the last stack from the previous loop, and go up to the penultimate vertex. + for( int i = 0; i < slices; i++, indiceIndex += 3 ) + { + indices[indiceIndex] = previousCycleBeginning + slices; + indices[indiceIndex + 1] = previousCycleBeginning + i; + if( i == slices - 1 ) + { + //End, so loop around. + indices[indiceIndex + 2] = previousCycleBeginning; + } + else + { + indices[indiceIndex + 2] = previousCycleBeginning + i + 1; + } + } +} + +void PrimitiveRenderer::ComputeConicVertices( Vector& vertices, float scaleTopRadius, + float scaleBottomRadius, float scaleHeight, int slices ) +{ + int vertexIndex = 0; //Track progress through vertices. + Vector sinTable; + Vector cosTable; + + ComputeCircleTables( sinTable, cosTable, slices, false ); + + int numVertices = 2; //Always will have one at the top and one at the bottom. + + //Add vertices for each circle. Need two per point for different face normals. + if( scaleTopRadius > 0.0 ) + { + numVertices += 2 * slices; + } + if( scaleBottomRadius > 0.0 ) + { + numVertices += 2 * slices; + } + + vertices.Resize( numVertices ); + + + //Scale to bounding region of -0.5 to 0.5 (i.e range of 1). + float biggestObjectDimension = std::max( std::max( scaleTopRadius * 2.0f, scaleBottomRadius * 2.0f ), scaleHeight ); + scaleTopRadius = scaleTopRadius / biggestObjectDimension; + scaleBottomRadius = scaleBottomRadius / biggestObjectDimension; + + //Dimensions for vertex coordinates. Y is constant, and so can be initialised now. + float x; + float y = scaleHeight / biggestObjectDimension / 2.0f; + float z; + + //Top center. + vertices[0].position = Vector3( 0, y, 0 ); + vertices[0].normal = Vector3( 0, 1, 0 ); + vertexIndex++; + + //Top circle. + if( scaleTopRadius > 0.0 ) + { + //Loop around the circle. + for( int i = 0; i < slices; i++, vertexIndex++ ) + { + x = sinTable[i] * scaleTopRadius; + z = cosTable[i] * scaleTopRadius; + + //Upward-facing normal. + vertices[vertexIndex].position = Vector3( x, y, z ); + vertices[vertexIndex].normal = Vector3( 0, 1, 0 ); + + //Outward-facing normal. + vertices[vertexIndex + slices].position = Vector3( x, y, z ); + vertices[vertexIndex + slices].normal = Vector3( x, 0, z ); + } + + vertexIndex += slices; + } + + //Bottom circle. + if( scaleBottomRadius > 0.0 ) + { + //Loop around the circle. + for( int i = 0; i < slices; i++, vertexIndex++ ) + { + x = sinTable[i] * scaleBottomRadius; + z = cosTable[i] * scaleBottomRadius; + + //Outward-facing normal. + vertices[vertexIndex].position = Vector3( x, -y, z ); + vertices[vertexIndex].normal = Vector3( x, 0, z ); + + //Downward-facing normal. + vertices[vertexIndex + slices].position = Vector3( x, -y, z ); + vertices[vertexIndex + slices].normal = Vector3( 0, -1, 0 ); + } + + vertexIndex += slices; + } + + //Bottom center. + vertices[vertexIndex].position = Vector3( 0, -y, 0 ); + vertices[vertexIndex].normal = Vector3( 0, -1, 0 ); + vertexIndex++; +} + +void PrimitiveRenderer::FormConicTriangles( Vector& indices, float scaleTopRadius, + float scaleBottomRadius, int slices ) +{ + int indiceIndex = 0; //Track progress through indices. + int numTriangles = 0; + bool coneTop = scaleTopRadius <= 0.0; + bool coneBottom = scaleBottomRadius <= 0.0; + + if( coneTop && coneBottom ) + { + //Set indices to placeholder "error" values. + //This will display nothing, which is the expected behaviour for this edge case. + indices.Resize( 3 ); + return; + } + + if( !coneTop ) + { + numTriangles += 2 * slices; + } + if( !coneBottom ) + { + numTriangles += 2 * slices; + } + + indices.Resize( 3 * numTriangles ); + + //Switch on the type of conic we have. + if( !coneTop && !coneBottom ) + { + //Top circle. Start at index of first outer point and go around. + for( int i = 1; i <= slices; i++, indiceIndex += 3 ) + { + indices[indiceIndex] = 0; + indices[indiceIndex + 1] = i; + if( i == slices ) + { + //End, so loop around. + indices[indiceIndex + 2] = 1; + } + else + { + indices[indiceIndex + 2] = i + 1; + } + } + + int topCycleBeginning = slices + 1; + int bottomCycleBeginning = topCycleBeginning + slices; + + //Vertical edges. + for( int i = 0; i < slices; i++, indiceIndex += 6 ) + { + if( i == slices - 1 ) + { + //End, so loop around. + indices[indiceIndex] = topCycleBeginning + i; + indices[indiceIndex + 1] = bottomCycleBeginning + i; + indices[indiceIndex + 2] = topCycleBeginning; + indices[indiceIndex + 3] = bottomCycleBeginning + i; + indices[indiceIndex + 4] = bottomCycleBeginning; + indices[indiceIndex + 5] = topCycleBeginning; + } + else + { + indices[indiceIndex] = topCycleBeginning + i; + indices[indiceIndex + 1] = bottomCycleBeginning + i; + indices[indiceIndex + 2] = topCycleBeginning + 1 + i; + indices[indiceIndex + 3] = bottomCycleBeginning + i; + indices[indiceIndex + 4] = bottomCycleBeginning + 1 + i; + indices[indiceIndex + 5] = topCycleBeginning + 1 + i; + } + } + + int bottomFaceCycleBeginning = bottomCycleBeginning + slices; + + //Bottom circle. + for( int i = 0; i < slices; i++, indiceIndex += 3 ) + { + indices[indiceIndex] = bottomFaceCycleBeginning; + indices[indiceIndex + 1] = bottomFaceCycleBeginning + i; + if( i == slices - 1 ) + { + //End, so loop around. + indices[indiceIndex + 2] = bottomFaceCycleBeginning; + } + else + { + indices[indiceIndex + 2] = bottomFaceCycleBeginning + i + 1; + } + } + } + else if( !coneTop || !coneBottom ) + { + //Top circle/edges. Start at index of first outer point and go around. + for( int i = 1; i <= slices; i++, indiceIndex += 3 ) + { + indices[indiceIndex] = 0; + indices[indiceIndex + 1] = i; + if( i == slices ) + { + //End, so loop around. + indices[indiceIndex + 2] = 1; + } + else + { + indices[indiceIndex + 2] = i + 1; + } + } + + //Bottom circle/edges. Start at index of first outer point and go around. + for( int i = 1; i <= slices; i++, indiceIndex += 3 ) + { + indices[indiceIndex] = 2 * slices + 1; + indices[indiceIndex + 1] = slices + i; + if( i == slices ) + { + //End, so loop around. + indices[indiceIndex + 2] = slices + 1; + } + else + { + indices[indiceIndex + 2] = slices + i + 1; + } + } + } +} + +void PrimitiveRenderer::ComputeCubeVertices( Vector& vertices, Vector3 dimensions ) +{ + int numVertices = 4 * 6; //Four per face. + int vertexIndex = 0; //Tracks progress through vertices. + float scaledX = 0.5 * dimensions.x; + float scaledY = 0.5 * dimensions.y; + float scaledZ = 0.5 * dimensions.z; + + vertices.Resize( numVertices ); + + Vector positions; //Stores vertex positions, which are shared between vertexes at the same position but with a different normal. + positions.Resize(8); + Vector normals; //Stores normals, which are shared between vertexes of the same face. + normals.Resize(6); + + positions[0] = Vector3( -scaledX, scaledY, -scaledZ ); + positions[1] = Vector3( scaledX, scaledY, -scaledZ ); + positions[2] = Vector3( scaledX, scaledY, scaledZ ); + positions[3] = Vector3( -scaledX, scaledY, scaledZ ); + positions[4] = Vector3( -scaledX, -scaledY, -scaledZ ); + positions[5] = Vector3( scaledX, -scaledY, -scaledZ ); + positions[6] = Vector3( scaledX, -scaledY, scaledZ ); + positions[7] = Vector3( -scaledX, -scaledY, scaledZ ); + + normals[0] = Vector3( 0, 1, 0 ); + normals[1] = Vector3( 0, 0, -1 ); + normals[2] = Vector3( 1, 0, 0 ); + normals[3] = Vector3( 0, 0, 1 ); + normals[4] = Vector3( -1, 0, 0 ); + normals[5] = Vector3( 0, -1, 0 ); + + //Top face, upward normals. + for( int i = 0; i < 4; i++, vertexIndex++ ) + { + vertices[vertexIndex].position = positions[i]; + vertices[vertexIndex].normal = normals[0]; + } + + //Top face, outward normals. + for( int i = 0; i < 4; i++, vertexIndex += 2 ) + { + vertices[vertexIndex].position = positions[i]; + vertices[vertexIndex].normal = normals[i + 1]; + + if( i == 3 ) + { + //End, so loop around. + vertices[vertexIndex + 1].position = positions[0]; + } + else + { + vertices[vertexIndex + 1].position = positions[i + 1]; + } + vertices[vertexIndex + 1].normal = normals[i + 1]; + } + + //Bottom face, outward normals. + for( int i = 0; i < 4; i++, vertexIndex += 2 ) + { + vertices[vertexIndex].position = positions[i + 4]; + vertices[vertexIndex].normal = normals[i + 1]; + + if( i == 3 ) + { + //End, so loop around. + vertices[vertexIndex + 1].position = positions[4]; + } + else + { + vertices[vertexIndex + 1].position = positions[i + 5]; + } + vertices[vertexIndex + 1].normal = normals[i + 1]; + } + + //Bottom face, downward normals. + for( int i = 0; i < 4; i++, vertexIndex++ ) + { + vertices[vertexIndex].position = positions[i + 4]; + vertices[vertexIndex].normal = normals[5]; + } + +} + +void PrimitiveRenderer::FormCubeTriangles( Vector& indices ) +{ + int numTriangles = 12; + int triangleIndex = 0; //Track progress through indices. + + indices.Resize( 3 * numTriangles ); + + //Top face. + indices[triangleIndex] = 0; + indices[triangleIndex + 1] = 1; + indices[triangleIndex + 2] = 2; + indices[triangleIndex + 3] = 2; + indices[triangleIndex + 4] = 3; + indices[triangleIndex + 5] = 0; + triangleIndex += 6; + + int topFaceStart = 4; + int bottomFaceStart = 12; + + //Side faces. + for( int i = 0; i < 8; i += 2, triangleIndex += 6 ) + { + indices[triangleIndex ] = i + topFaceStart; + indices[triangleIndex + 1] = i + bottomFaceStart + 1; + indices[triangleIndex + 2] = i + topFaceStart + 1; + indices[triangleIndex + 3] = i + topFaceStart; + indices[triangleIndex + 4] = i + bottomFaceStart; + indices[triangleIndex + 5] = i + bottomFaceStart + 1; + } + + //Bottom face. + indices[triangleIndex] = 20; + indices[triangleIndex + 1] = 21; + indices[triangleIndex + 2] = 22; + indices[triangleIndex + 3] = 22; + indices[triangleIndex + 4] = 23; + indices[triangleIndex + 5] = 20; +} + +void PrimitiveRenderer::ComputeOctahedronVertices( Vector& vertices, Vector3 dimensions, float smoothness ) +{ + int numVertices = 3 * 8; //Three per face + int vertexIndex = 0; //Tracks progress through vertices. + float scaledX = 0.5 * dimensions.x; + float scaledY = 0.5 * dimensions.y; + float scaledZ = 0.5 * dimensions.z; + + vertices.Resize( numVertices ); + + Vector positions; //Stores vertex positions, which are shared between vertexes at the same position but with a different normal. + positions.Resize(6); + Vector normals; //Stores normals, which are shared between vertexes of the same face. + normals.Resize(8); + Vector outerNormals; //Holds normals that point outwards at each vertex. + outerNormals.Resize( 6 ); + + positions[0] = Vector3( 0.0, scaledY, 0.0 ); + positions[1] = Vector3( -scaledX, 0.0, 0.0 ); + positions[2] = Vector3( 0.0, 0.0, -scaledZ ); + positions[3] = Vector3( scaledX, 0.0, 0.0 ); + positions[4] = Vector3( 0.0, 0.0, scaledZ ); + positions[5] = Vector3( 0.0, -scaledY, 0.0 ); + + normals[0] = Vector3( -1, 1, -1 ); + normals[1] = Vector3( 1, 1, -1 ); + normals[2] = Vector3( 1, 1, 1 ); + normals[3] = Vector3( -1, 1, 1 ); + normals[4] = Vector3( -1, -1, -1 ); + normals[5] = Vector3( 1, -1, -1 ); + normals[6] = Vector3( 1, -1, 1 ); + normals[7] = Vector3( -1, -1, 1 ); + + outerNormals[0] = Vector3( 0, 1, 0 ); + outerNormals[1] = Vector3( -1, 0, 0 ); + outerNormals[2] = Vector3( 0, 0, -1 ); + outerNormals[3] = Vector3( 1, 0, 0 ); + outerNormals[4] = Vector3( 0, 0, 1 ); + outerNormals[5] = Vector3( 0, -1, 0 ); + + //Loop through top faces. + for( int i = 0; i < 4; i++, vertexIndex += 3 ) + { + if( i == 3 ) + { + //End, so loop around. + vertices[vertexIndex ].position = positions[0]; + vertices[vertexIndex ].normal = outerNormals[0] * smoothness + normals[i] * (1 - smoothness); + vertices[vertexIndex + 1].position = positions[i + 1]; + vertices[vertexIndex + 1].normal = outerNormals[i + 1] * smoothness + normals[i] * (1 - smoothness); + vertices[vertexIndex + 2].position = positions[1]; + vertices[vertexIndex + 2].normal = outerNormals[1] * smoothness + normals[i] * (1 - smoothness); + } + else + { + vertices[vertexIndex ].position = positions[0]; + vertices[vertexIndex ].normal = outerNormals[0] * smoothness + normals[i] * (1 - smoothness); + vertices[vertexIndex + 1].position = positions[i + 1]; + vertices[vertexIndex + 1].normal = outerNormals[i + 1] * smoothness + normals[i] * (1 - smoothness); + vertices[vertexIndex + 2].position = positions[i + 2]; + vertices[vertexIndex + 2].normal = outerNormals[i + 2] * smoothness + normals[i] * (1 - smoothness); + } + } + + //Loop through bottom faces. + for( int i = 0; i < 4; i++, vertexIndex += 3 ) + { + if( i == 3 ) + { + //End, so loop around. + vertices[vertexIndex ].position = positions[5]; + vertices[vertexIndex ].normal = outerNormals[5] * smoothness + normals[i + 4] * (1 - smoothness); + vertices[vertexIndex + 1].position = positions[i + 1]; + vertices[vertexIndex + 1].normal = outerNormals[i + 1] * smoothness + normals[i + 4] * (1 - smoothness); + vertices[vertexIndex + 2].position = positions[1]; + vertices[vertexIndex + 2].normal = outerNormals[1] * smoothness + normals[i + 4] * (1 - smoothness); + } + else + { + vertices[vertexIndex ].position = positions[5]; + vertices[vertexIndex ].normal = outerNormals[5] * smoothness + normals[i + 4] * (1 - smoothness); + vertices[vertexIndex + 1].position = positions[i + 1]; + vertices[vertexIndex + 1].normal = outerNormals[i + 1] * smoothness + normals[i + 4] * (1 - smoothness); + vertices[vertexIndex + 2].position = positions[i + 2]; + vertices[vertexIndex + 2].normal = outerNormals[i + 2] * smoothness + normals[i + 4] * (1 - smoothness); + } + } +} + +void PrimitiveRenderer::FormOctahedronTriangles( Vector& indices ) +{ + int numTriangles = 8; + int numIndices = numTriangles * 3; + + indices.Resize( numIndices ); + + for( unsigned short i = 0; i < numIndices; i++ ) + { + indices[i] = i; + } +} + +void PrimitiveRenderer::ComputeBevelledCubeVertices( Vector& vertices, Vector3 dimensions, + float bevelPercentage, float bevelSmoothness ) +{ + int numPositions = 24; + int numFaces = 26; + int numOuterFaces = 6; + int numVertices = 6 * 4 + 12 * 4 + 8 * 3; //Six outer faces, 12 slanting rectangles, 8 slanting triangles. + int vertexIndex = 0; //Track progress through vertices. + int normalIndex = 0; //Track progress through normals, as vertices are calculated per face. + + float minDimension = std::min( std::min( dimensions.x, dimensions.y ), dimensions.z ); + float bevelScale = 1.0 - bevelPercentage; + float bevelAmount = 0.5 * bevelScale * minDimension; + + float outerX = 0.5 * dimensions.x; + float outerY = 0.5 * dimensions.y; + float outerZ = 0.5 * dimensions.z; + + float bevelX = outerX - ( 0.5 * minDimension - bevelAmount ); + float bevelY = outerY - ( 0.5 * minDimension - bevelAmount ); + float bevelZ = outerZ - ( 0.5 * minDimension - bevelAmount ); + + Vector positions; //Holds object points, to be shared between vertexes. + positions.Resize( numPositions ); + Vector normals; //Holds face normals, to be shared between vertexes. + normals.Resize( numFaces ); + Vector outerNormals; //Holds normals of the outermost faces specifically. + outerNormals.Resize( numOuterFaces ); + vertices.Resize( numVertices ); + + //Topmost face positions. + positions[0 ] = Vector3( -bevelX, outerY, -bevelZ ); + positions[1 ] = Vector3( bevelX, outerY, -bevelZ ); + positions[2 ] = Vector3( bevelX, outerY, bevelZ ); + positions[3 ] = Vector3( -bevelX, outerY, bevelZ ); + + //Second layer positions. + positions[4 ] = Vector3( -outerX, bevelY, -bevelZ ); + positions[5 ] = Vector3( -bevelX, bevelY, -outerZ ); + positions[6 ] = Vector3( bevelX, bevelY, -outerZ ); + positions[7 ] = Vector3( outerX, bevelY, -bevelZ ); + positions[8 ] = Vector3( outerX, bevelY, bevelZ ); + positions[9 ] = Vector3( bevelX, bevelY, outerZ ); + positions[10] = Vector3( -bevelX, bevelY, outerZ ); + positions[11] = Vector3( -outerX, bevelY, bevelZ ); + + //Third layer positions. + positions[12] = Vector3( -outerX, -bevelY, -bevelZ ); + positions[13] = Vector3( -bevelX, -bevelY, -outerZ ); + positions[14] = Vector3( bevelX, -bevelY, -outerZ ); + positions[15] = Vector3( outerX, -bevelY, -bevelZ ); + positions[16] = Vector3( outerX, -bevelY, bevelZ ); + positions[17] = Vector3( bevelX, -bevelY, outerZ ); + positions[18] = Vector3( -bevelX, -bevelY, outerZ ); + positions[19] = Vector3( -outerX, -bevelY, bevelZ ); + + //Bottom-most face positions. + positions[20] = Vector3( -bevelX, -outerY, -bevelZ ); + positions[21] = Vector3( bevelX, -outerY, -bevelZ ); + positions[22] = Vector3( bevelX, -outerY, bevelZ ); + positions[23] = Vector3( -bevelX, -outerY, bevelZ ); + + //Top face normal. + normals[0 ] = Vector3( 0, 1, 0 ); + + //Top slope normals. + normals[1 ] = Vector3( -1, 1, -1 ); + normals[2 ] = Vector3( 0, 1, -1 ); + normals[3 ] = Vector3( 1, 1, -1 ); + normals[4 ] = Vector3( 1, 1, 0 ); + normals[5 ] = Vector3( 1, 1, 1 ); + normals[6 ] = Vector3( 0, 1, 1 ); + normals[7 ] = Vector3( -1, 1, 1 ); + normals[8 ] = Vector3( -1, 1, 0 ); + + //Side normals. + normals[9 ] = Vector3( -1, 0, -1 ); + normals[10] = Vector3( 0, 0, -1 ); + normals[11] = Vector3( 1, 0, -1 ); + normals[12] = Vector3( 1, 0, 0 ); + normals[13] = Vector3( 1, 0, 1 ); + normals[14] = Vector3( 0, 0, 1 ); + normals[15] = Vector3( -1, 0, 1 ); + normals[16] = Vector3( -1, 0, 0 ); + + //Bottom slope normals. + normals[17] = Vector3( -1, -1, -1 ); + normals[18] = Vector3( 0, -1, -1 ); + normals[19] = Vector3( 1, -1, -1 ); + normals[20] = Vector3( 1, -1, 0 ); + normals[21] = Vector3( 1, -1, 1 ); + normals[22] = Vector3( 0, -1, 1 ); + normals[23] = Vector3( -1, -1, 1 ); + normals[24] = Vector3( -1, -1, 0 ); + + //Bottom face normal. + normals[25] = Vector3( 0, -1, 0 ); + + //Top, back, right, front, left and bottom faces, respectively. + outerNormals[0] = Vector3( 0, 1, 0 ); + outerNormals[1] = Vector3( 0, 0, -1 ); + outerNormals[2] = Vector3( 1, 0, 0 ); + outerNormals[3] = Vector3( 0, 0, 1 ); + outerNormals[4] = Vector3( -1, 0, 0 ); + outerNormals[5] = Vector3( 0, -1, 0 ); + + //Topmost face vertices. + for( int i = 0; i < 4; i++, vertexIndex++ ) + { + vertices[vertexIndex].position = positions[i]; + vertices[vertexIndex].normal = normals[normalIndex]; + } + + normalIndex++; + + //Top slope vertices. + for( int i = 0; i < 4; i++, vertexIndex += 7, normalIndex += 2 ) + { + //Triangle part + vertices[vertexIndex ].position = positions[i]; + vertices[vertexIndex ].normal = outerNormals[0] * bevelSmoothness + normals[normalIndex] * (1 - bevelSmoothness); + vertices[vertexIndex + 1].position = positions[2 * i + 4]; + vertices[vertexIndex + 1].normal = outerNormals[( i == 0 ) ? 4 : i] * bevelSmoothness + normals[normalIndex] * (1 - bevelSmoothness); + vertices[vertexIndex + 2].position = positions[2 * i + 5]; + vertices[vertexIndex + 2].normal = outerNormals[i + 1] * bevelSmoothness + normals[normalIndex] * (1 - bevelSmoothness); + + //Rectangle part + if( i == 3 ) + { + //End, so loop around. + vertices[vertexIndex + 3].position = positions[i]; + vertices[vertexIndex + 3].normal = outerNormals[0] * bevelSmoothness + normals[normalIndex + 1] * (1 - bevelSmoothness); + vertices[vertexIndex + 4].position = positions[0]; + vertices[vertexIndex + 4].normal = outerNormals[0] * bevelSmoothness + normals[normalIndex + 1] * (1 - bevelSmoothness); + vertices[vertexIndex + 5].position = positions[2 * i + 5]; + vertices[vertexIndex + 5].normal = outerNormals[i + 1] * bevelSmoothness + normals[normalIndex + 1] * (1 - bevelSmoothness); + vertices[vertexIndex + 6].position = positions[4]; + vertices[vertexIndex + 6].normal = outerNormals[i + 1] * bevelSmoothness + normals[normalIndex + 1] * (1 - bevelSmoothness); + } + else + { + vertices[vertexIndex + 3].position = positions[i]; + vertices[vertexIndex + 3].normal = outerNormals[0] * bevelSmoothness + normals[normalIndex + 1] * (1 - bevelSmoothness); + vertices[vertexIndex + 4].position = positions[i + 1]; + vertices[vertexIndex + 4].normal = outerNormals[0] * bevelSmoothness + normals[normalIndex + 1] * (1 - bevelSmoothness); + vertices[vertexIndex + 5].position = positions[2 * i + 5]; + vertices[vertexIndex + 5].normal = outerNormals[i + 1] * bevelSmoothness + normals[normalIndex + 1] * (1 - bevelSmoothness); + vertices[vertexIndex + 6].position = positions[2 * i + 6]; + vertices[vertexIndex + 6].normal = outerNormals[i + 1] * bevelSmoothness + normals[normalIndex + 1] * (1 - bevelSmoothness); + } + } + + int secondCycleBeginning = 4; + int thirdCycleBeginning = secondCycleBeginning + 8; + int bottomCycleBeginning = thirdCycleBeginning + 8; + + //Side vertices. + for( int i = 0; i < 8; i++, vertexIndex += 4, normalIndex++ ) + { + if( i == 7 ) + { + //End, so loop around. + vertices[vertexIndex ].position = positions[secondCycleBeginning + i]; + vertices[vertexIndex ].normal = normals[normalIndex]; + vertices[vertexIndex + 1].position = positions[secondCycleBeginning]; + vertices[vertexIndex + 1].normal = normals[normalIndex]; + vertices[vertexIndex + 2].position = positions[thirdCycleBeginning + i]; + vertices[vertexIndex + 2].normal = normals[normalIndex]; + vertices[vertexIndex + 3].position = positions[thirdCycleBeginning]; + vertices[vertexIndex + 3].normal = normals[normalIndex]; + } + else if( (i % 2) == 0 ) + { + //'even' faces are corner ones, and need smoothing. + vertices[vertexIndex ].position = positions[secondCycleBeginning + i]; + vertices[vertexIndex ].normal = outerNormals[( i == 0 ) ? 4 : i / 2] * bevelSmoothness + normals[normalIndex] * (1 - bevelSmoothness); + vertices[vertexIndex + 1].position = positions[secondCycleBeginning + i + 1]; + vertices[vertexIndex + 1].normal = outerNormals[i / 2 + 1] * bevelSmoothness + normals[normalIndex] * (1 - bevelSmoothness); + vertices[vertexIndex + 2].position = positions[thirdCycleBeginning + i]; + vertices[vertexIndex + 2].normal = outerNormals[( i == 0 ) ? 4 : i / 2] * bevelSmoothness + normals[normalIndex] * (1 - bevelSmoothness); + vertices[vertexIndex + 3].position = positions[thirdCycleBeginning + i + 1]; + vertices[vertexIndex + 3].normal = outerNormals[i / 2 + 1] * bevelSmoothness + normals[normalIndex] * (1 - bevelSmoothness); + } + else + { + //'odd' faces are outer ones, and so don't need smoothing. + vertices[vertexIndex ].position = positions[secondCycleBeginning + i]; + vertices[vertexIndex ].normal = normals[normalIndex]; + vertices[vertexIndex + 1].position = positions[secondCycleBeginning + i + 1]; + vertices[vertexIndex + 1].normal = normals[normalIndex]; + vertices[vertexIndex + 2].position = positions[thirdCycleBeginning + i]; + vertices[vertexIndex + 2].normal = normals[normalIndex]; + vertices[vertexIndex + 3].position = positions[thirdCycleBeginning + i + 1]; + vertices[vertexIndex + 3].normal = normals[normalIndex]; + } + } + + //Bottom slope vertices. + for( int i = 0; i < 4; i++, vertexIndex += 7, normalIndex += 2 ) + { + //Triangle part + vertices[vertexIndex ].position = positions[thirdCycleBeginning + 2 * i]; + vertices[vertexIndex ].normal = outerNormals[( i == 0 ) ? 4 : i] * bevelSmoothness + normals[normalIndex] * (1 - bevelSmoothness); + vertices[vertexIndex + 1].position = positions[thirdCycleBeginning + 2 * i + 1]; + vertices[vertexIndex + 1].normal = outerNormals[i + 1] * bevelSmoothness + normals[normalIndex] * (1 - bevelSmoothness); + vertices[vertexIndex + 2].position = positions[bottomCycleBeginning + i]; + vertices[vertexIndex + 2].normal = outerNormals[5] * bevelSmoothness + normals[normalIndex] * (1 - bevelSmoothness); + + //Rectangle part + if( i == 3 ) + { + //End, so loop around. + vertices[vertexIndex + 3].position = positions[thirdCycleBeginning + 2 * i + 1]; + vertices[vertexIndex + 3].normal = outerNormals[i + 1] * bevelSmoothness + normals[normalIndex + 1] * (1 - bevelSmoothness); + vertices[vertexIndex + 4].position = positions[thirdCycleBeginning]; + vertices[vertexIndex + 4].normal = outerNormals[i + 1] * bevelSmoothness + normals[normalIndex + 1] * (1 - bevelSmoothness); + vertices[vertexIndex + 5].position = positions[bottomCycleBeginning + i]; + vertices[vertexIndex + 5].normal = outerNormals[5] * bevelSmoothness + normals[normalIndex + 1] * (1 - bevelSmoothness); + vertices[vertexIndex + 6].position = positions[bottomCycleBeginning]; + vertices[vertexIndex + 6].normal = outerNormals[5] * bevelSmoothness + normals[normalIndex + 1] * (1 - bevelSmoothness); + } + else + { + vertices[vertexIndex + 3].position = positions[thirdCycleBeginning + 2 * i + 1]; + vertices[vertexIndex + 3].normal = outerNormals[i + 1] * bevelSmoothness + normals[normalIndex + 1] * (1 - bevelSmoothness); + vertices[vertexIndex + 4].position = positions[thirdCycleBeginning + 2 * i + 2]; + vertices[vertexIndex + 4].normal = outerNormals[i + 1] * bevelSmoothness + normals[normalIndex + 1] * (1 - bevelSmoothness); + vertices[vertexIndex + 5].position = positions[bottomCycleBeginning + i]; + vertices[vertexIndex + 5].normal = outerNormals[5] * bevelSmoothness + normals[normalIndex + 1] * (1 - bevelSmoothness); + vertices[vertexIndex + 6].position = positions[bottomCycleBeginning + i + 1]; + vertices[vertexIndex + 6].normal = outerNormals[5] * bevelSmoothness + normals[normalIndex + 1] * (1 - bevelSmoothness); + } + } + + //Bottom-most face vertices. + for( int i = 0; i < 4; i++, vertexIndex++ ) + { + vertices[vertexIndex].position = positions[ bottomCycleBeginning + i]; + vertices[vertexIndex].normal = normals[normalIndex]; + } + + normalIndex++; +} + +void PrimitiveRenderer::FormBevelledCubeTriangles( Vector& indices ) +{ + int numTriangles = 44; //(Going from top to bottom, that's 2 + 12 + 16 + 12 + 2) + int indiceIndex = 0; //Track progress through indices. + int vertexIndex = 0; //Track progress through vertices as they're processed. + + indices.Resize( 3 * numTriangles ); + + //Top face. + indices[indiceIndex ] = vertexIndex; + indices[indiceIndex + 1] = vertexIndex + 1; + indices[indiceIndex + 2] = vertexIndex + 2; + indices[indiceIndex + 3] = vertexIndex + 0; + indices[indiceIndex + 4] = vertexIndex + 2; + indices[indiceIndex + 5] = vertexIndex + 3; + indiceIndex += 6; + vertexIndex += 4; + + //Top slopes. + for( int i = 0; i < 4; i++, indiceIndex += 9, vertexIndex += 7 ) + { + //Triangle part. + indices[indiceIndex ] = vertexIndex; + indices[indiceIndex + 1] = vertexIndex + 1; + indices[indiceIndex + 2] = vertexIndex + 2; + + //Rectangle part. + indices[indiceIndex + 3] = vertexIndex + 3; + indices[indiceIndex + 4] = vertexIndex + 4; + indices[indiceIndex + 5] = vertexIndex + 5; + indices[indiceIndex + 6] = vertexIndex + 4; + indices[indiceIndex + 7] = vertexIndex + 5; + indices[indiceIndex + 8] = vertexIndex + 6; + } + + //Side faces. + for( int i = 0; i < 8; i++, indiceIndex += 6, vertexIndex += 4 ) + { + indices[indiceIndex ] = vertexIndex; + indices[indiceIndex + 1] = vertexIndex + 1; + indices[indiceIndex + 2] = vertexIndex + 2; + indices[indiceIndex + 3] = vertexIndex + 1; + indices[indiceIndex + 4] = vertexIndex + 2; + indices[indiceIndex + 5] = vertexIndex + 3; + } + + //Bottom slopes. + for( int i = 0; i < 4; i++, indiceIndex += 9, vertexIndex += 7 ) + { + //Triangle part. + indices[indiceIndex ] = vertexIndex; + indices[indiceIndex + 1] = vertexIndex + 1; + indices[indiceIndex + 2] = vertexIndex + 2; + + //Rectangle part. + indices[indiceIndex + 3] = vertexIndex + 3; + indices[indiceIndex + 4] = vertexIndex + 4; + indices[indiceIndex + 5] = vertexIndex + 5; + indices[indiceIndex + 6] = vertexIndex + 4; + indices[indiceIndex + 7] = vertexIndex + 5; + indices[indiceIndex + 8] = vertexIndex + 6; + } + + //Bottom face. + indices[indiceIndex ] = vertexIndex; + indices[indiceIndex + 1] = vertexIndex + 1; + indices[indiceIndex + 2] = vertexIndex + 2; + indices[indiceIndex + 3] = vertexIndex + 0; + indices[indiceIndex + 4] = vertexIndex + 2; + indices[indiceIndex + 5] = vertexIndex + 3; + indiceIndex += 6; + vertexIndex += 4; +} + +} // namespace Internal + +} // namespace Toolkit + +} // namespace Dali diff --git a/dali-toolkit/internal/controls/renderers/primitive/primitive-renderer.h b/dali-toolkit/internal/controls/renderers/primitive/primitive-renderer.h new file mode 100644 index 0000000..273bb36 --- /dev/null +++ b/dali-toolkit/internal/controls/renderers/primitive/primitive-renderer.h @@ -0,0 +1,352 @@ +#ifndef DALI_TOOLKIT_INTERNAL_PRIMITIVE_RENDERER_H +#define DALI_TOOLKIT_INTERNAL_PRIMITIVE_RENDERER_H + +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/* + * The geometry creation logic was based off similar methods provided by freeGLUT. + * Original copyright and licence information: + * + * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved. + * Written by Pawel W. Olszta, + * Creation date: Fri Dec 3 1999 + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +// INTERNAL INCLUDES +#include + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Internal +{ + +/** + * The renderer which renders a simple 3D shape to the control's quad + * + * The following properties are required to create a PrimitiveRender + * + * | %Property Name | Type | + * |-----------------|-------------| + * | shape | STRING | + * + * In addition, the following properties can be (optionally) supplied to modify the shape's parameters + * + * | %Property Name | Type | Shapes Affected | + * |-------------------|-------------|------------------------------------------| + * | color | VECTOR4 | all | + * | slices | INTEGER | sphere, cone, conical frustrum, cylinder | + * | stacks | INTEGER | sphere | + * | scaleTopRadius | FLOAT | conical frustrum | + * | scaleBottomRadius | FLOAT | cone, conical frustrum | + * | scaleHeight | FLOAT | cone, conical frustrum, cylinder | + * | scaleRadius | FLOAT | cylinder | + * | scaleDimensions | VECTOR3 | cube, octahedron, bevelled cube | + * | bevelPercentage | FLOAT | bevelled cube | + * | bevelSmoothness | FLOAT | bevelled cube | + * + * Note: slices and stacks both have an upper limit of 255. + * + * Finally, the following can be used to affect the renderer's shader + * + * | %Property Name | Type | Representing | + * |-----------------|-------------|-----------------------------------------| + * | uLightPosition | VECTOR3 | The position (on stage) of the light | + */ +class PrimitiveRenderer: public ControlRenderer +{ +public: + + /** + * @brief Constructor. + * + * @param[in] factoryCache A pointer pointing to the RendererFactoryCache object + */ + PrimitiveRenderer( RendererFactoryCache& factoryCache ); + + /** + * @brief A reference counted object may only be deleted by calling Unreference(). + */ + virtual ~PrimitiveRenderer(); + +public: // from ControlRenderer + + /** + * @copydoc ControlRenderer::SetSize + */ + virtual void SetSize( const Vector2& size ); + + /** + * @copydoc ControlRenderer::SetClipRect + */ + virtual void SetClipRect( const Rect& clipRect ); + + /** + * @copydoc ControlRenderer::SetOffset + */ + virtual void SetOffset( const Vector2& offset ); + + /** + * @copydoc ControlRenderer::CreatePropertyMap + */ + virtual void DoCreatePropertyMap( Property::Map& map ) const; + +protected: + + /** + * @copydoc ControlRenderer::DoInitialize + */ + virtual void DoInitialize( Actor& actor, const Property::Map& propertyMap ); + + /** + * @copydoc ControlRenderer::DoSetOnStage + */ + virtual void DoSetOnStage( Actor& actor ); + +private: + + enum PrimitiveType + { + SPHERE, + CONE, + CONICAL_FRUSTRUM, + CYLINDER, + CUBE, + OCTAHEDRON, + BEVELLED_CUBE + }; + + //Simple struct to store the position and normal of a single vertex. + struct Vertex + { + Vertex() + {} + + Vertex( const Vector3& position, const Vector3& normal, const Vector2& textureCoord ) + : position( position ), normal( normal ) + {} + + Vector3 position; + Vector3 normal; + }; + + /** + * @brief Initialize the renderer with the geometry and shader from the cache, if not available, create and save to the cache for sharing. + */ + void InitializeRenderer(); + + /** + * @brief Create a shader for the object to use. + */ + void CreateShader(); + + /** + * @brief Update shader related info, uniforms, etc. for the new shader. + */ + void UpdateShaderUniforms(); + + /** + * @brief Create the geometry of the given primitive type. + */ + void CreateGeometry(); + + /** + * @brief Compute the vertices and the triangles for a sphere. + * @param[in, out] vertices The vector of vertices. + * @param[in, out] indices The vector of triangles, consisting of groups of three vertex indices. + * @param[in] slices The number of slices as you go around the sphere. Affects the smoothness of the surface. + * @param[in] stacks The number of stacks as you go down the sphere. Affects the smoothness of the surface. + */ + void CreateSphere( Vector& vertices, Vector& indices, int slices, int stacks ); + + /** + * @brief Compute the vertices and the triangles for a conic shape. + * @param[in, out] vertices The vector of vertices. + * @param[in, out] indices The vector of triangles, consisting of groups of three vertex indices. + * @param[in] scaleTopRadius The scale of the radius of the top circle, compared to the other dimensions. + * @param[in] scaleBottomRadius The scale of the radius of the bottom circle, compared to the other dimensions. + * @param[in] scaleHeight The scale of the height of the object, compared to the other dimensions. + * @param[in] slices The number of slices as you go around the conic shape. Affects the smoothness of the surface. + */ + void CreateConic( Vector& vertices, Vector& indices, float scaleTopRadius, + float scaleBottomRadius, float scaleHeight, int slices ); + + /** + * @brief Compute the vertices and the triangles for a bevelled cube. + * @param[in, out] vertices The vector of vertices. + * @param[in, out] indices The vector of triangles, consisting of groups of three vertex indices. + * @Param[in] dimensions The dimensions of the object. Scales in the same fashion as a 9-patch image. + * @param[in] bevelPercentage The ratio of the outer face widths to the cube's width. Between 0.0 and 1.0. + * @param[in] bevelSmoothness The smoothness of the bevelled edges. Between 0.0 and 1.0. + */ + void CreateBevelledCube( Vector& vertices, Vector& indices, Vector3 dimensions, + float bevelPercentage, float bevelSmoothness ); + + /** + * @brief Computes look-up tables for sin and cos, over angle divisions of (2 * Pi) / divisions + * @param[in, out] sinTable The table of sin values. + * @param[in, out] cosTable The table of cos values. + * @param[in] divisions Determines the angle coverage of the table. E.g divisions of '4' will have the sin values 0 = sin(0), 1 = sin(Pi/2), 2 = sin(Pi), 3 = sin(3Pi/2) + * @Param[in] halfCircle If true, go from 0 to Pi instead of 0 to 2Pi. + */ + void ComputeCircleTables( Vector& sinTable, Vector& cosTable, int divisions, bool halfCircle ); + + /** + * @brief Compute the vertices for a sphere. + * @param[in, out] vertices The vector of vertices. + * @param[in] slices The number of slices as you go around the sphere. Affects the smoothness of the surface. + * @param[in] stacks The number of stacks as you go down the sphere. Affects the smoothness of the surface. + */ + void ComputeSphereVertices( Vector& vertices, int slices, int stacks ); + + /** + * @brief Compute the triangles for a sphere. + * @param[in, out] indices The vector of triangles, consisting of groups of three vertex indices. + * @param[in] slices The number of slices as you go around the sphere. Affects the smoothness of the surface. + * @param[in] stacks The number of stacks as you go down the sphere. Affects the smoothness of the surface. + */ + void FormSphereTriangles( Vector& indices, int slices, int stacks ); + + /** + * @brief Compute the vertices for a conical. + * @param[in, out] vertices The vector of vertices. + * @param[in] scaleTopRadius The scale of the radius of the top circle, compared to the other dimensions. + * @param[in] scaleBottomRadius The scale of the radius of the bottom circle, compared to the other dimensions. + * @param[in] scaleHeight The scale of the height of the object, compared to the other dimensions. + * @param[in] slices The number of slices as you go around the conical. Affects the smoothness of the surface. + */ + void ComputeConicVertices( Vector& vertices, float scaleTopRadius, float scaleBottomRadius, + float scaleHeight, int slices ); + + /** + * @brief Compute the triangles for a conic. + * @param[in, out] indices The vector of triangles, consisting of groups of three vertex indices. + * @param[in] coneTop True if the top circle has a radius of zero, i.e. the object is a complete cone. + * @param[in] coneBottom True if the bottom circle has a radius of zero, i.e. the object is an inverted complete cone. + * @param[in] slices The number of slices as you go around the conic. Affects the smoothness of the surface. + */ + void FormConicTriangles( Vector& indices, float scaleTopRadius, float scaleBottomRadius, + int slices ); + + /** + * @brief Compute the vertices for a cube. + * @param[in, out] vertices The vector of vertices. + * @Param[in] dimensions The dimensions of the object. + */ + void ComputeCubeVertices( Vector& vertices, Vector3 dimensions ); + + /** + * @brief Compute the triangles for a cube. + * @param[in, out] indices The vector of triangles, consisting of groups of three vertex indices. + */ + void FormCubeTriangles( Vector& indices ); + + /** + * @brief Compute the vertices for an octahedron (maximumly bevelled cube). + * @param[in, out] vertices The vector of vertices. + * @Param[in] dimensions The dimensions of the object. + * @Param[in] smoothness Defines how rounded the edges appear under lighting. Between 0.0 and 1.0. + */ + void ComputeOctahedronVertices( Vector& vertices, Vector3 dimensions, float smoothness ); + + /** + * @brief Compute the triangles for an octahedron. + * @param[in, out] indices The vector of triangles, consisting of groups of three vertex indices. + */ + void FormOctahedronTriangles( Vector& indices ); + + /** + * @brief Compute the vertices for a bevelled cube. + * @param[in, out] vertices The vector of vertices. + * @Param[in] dimensions The dimensions of the object. Scales in the same fashion as a 9-patch image. + * @param[in] bevelPercentage The ratio of the outer face widths to the cube's width. Between 0.0 and 1.0. + * @param[in] bevelSmoothness The smoothness of the bevelled edges. Between 0.0 and 1.0. + */ + void ComputeBevelledCubeVertices( Vector& vertices, Vector3 dimensions, float bevelPercentage, + float bevelSmoothness ); + + /** + * @brief Compute the triangles for a bevelled cube. + * @param[in, out] indices The vector of triangles, consisting of groups of three vertex indices. + */ + void FormBevelledCubeTriangles( Vector& indices ); + +private: + + // Undefined + PrimitiveRenderer( const PrimitiveRenderer& PrimitiveRenderer ); + + // Undefined + PrimitiveRenderer& operator=( const PrimitiveRenderer& PrimitiveRenderer ); + +private: + Shader mShader; + Geometry mGeometry; + + std::string mShape; //Shape to render, as string. + Vector4 mColor; //Color of shape. + Vector3 mObjectDimensions; //Dimensions of shape, scaled to be between 0.0 and 1.0. + + Vector3 mSceneCenter; + Vector3 mSceneSize; + + //Shader properties. + Vector3 mLightPosition; + + //Shape properties. + Vector3 mScaleDimensions; ///< Scale of dimensions of bevelled cube and sub-shapes. + float mScaleTopRadius; ///< Scale of radius of top circle, to use when creating certain objects. + float mScaleBottomRadius; ///< Scale of radius of bottom circle, to use when creating certain objects. + float mScaleHeight; ///< Scale of height, to use when creating certain objects. + float mScaleRadius; ///< Scale of radius, to use when creating certain objects. + float mBevelPercentage; ///< Used to determine bevel amount when creating certain objects. + float mBevelSmoothness; ///< Used to determine the smoothness of bevelled edges. + int mSlices; ///< Number of slices to use when creating certain objects. + int mStacks; ///< Number of stacks to use when creating certain objects. + + PrimitiveType mPrimitiveType; //Shape to render, as enum. +}; + +} // namespace Internal + +} // namespace Toolkit + +} // namespace Dali + +#endif /* DALI_TOOLKIT_INTERNAL_PRIMITIVE_RENDERER_H */ diff --git a/dali-toolkit/internal/controls/renderers/renderer-factory-cache.h b/dali-toolkit/internal/controls/renderers/renderer-factory-cache.h index f6fd573..8d5b18e 100644 --- a/dali-toolkit/internal/controls/renderers/renderer-factory-cache.h +++ b/dali-toolkit/internal/controls/renderers/renderer-factory-cache.h @@ -1,8 +1,8 @@ -#ifndef __DALI_TOOLKIT_RENDERER_FACTORY_CACHE_H__ -#define __DALI_TOOLKIT_RENDERER_FACTORY_CACHE_H__ +#ifndef DALI_TOOLKIT_RENDERER_FACTORY_CACHE_H +#define DALI_TOOLKIT_RENDERER_FACTORY_CACHE_H /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,9 +23,9 @@ // EXTERNAL INCLUDES #include #include -#include -#include -#include +#include +#include +#include #include #include @@ -231,4 +231,4 @@ private: } // namespace Dali -#endif /*__DALI_TOOLKIT_RENDERER_FACTORY_CACHE_H__ */ +#endif // DALI_TOOLKIT_RENDERER_FACTORY_CACHE_H diff --git a/dali-toolkit/internal/controls/renderers/renderer-factory-impl.cpp b/dali-toolkit/internal/controls/renderers/renderer-factory-impl.cpp index 6cb0aa0..e1c75a2 100644 --- a/dali-toolkit/internal/controls/renderers/renderer-factory-impl.cpp +++ b/dali-toolkit/internal/controls/renderers/renderer-factory-impl.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -103,6 +104,10 @@ RendererFactory::RendererType RendererFactory::GetRendererType( const Property:: { rendererType = MESH; } + else if( typeValue == PRIMITIVE_RENDERER ) + { + rendererType = PRIMITIVE; + } } // check the url if exist, to decide the renderer type @@ -187,6 +192,11 @@ Toolkit::ControlRenderer RendererFactory::CreateControlRenderer( const Property: rendererPtr = new MeshRenderer( *( mFactoryCache.Get() ) ); break; } + case PRIMITIVE: + { + rendererPtr = new PrimitiveRenderer( *( mFactoryCache.Get() ) ); + break; + } case UNDEFINED: default: { diff --git a/dali-toolkit/internal/controls/renderers/renderer-factory-impl.h b/dali-toolkit/internal/controls/renderers/renderer-factory-impl.h index 671c752..57f5f59 100644 --- a/dali-toolkit/internal/controls/renderers/renderer-factory-impl.h +++ b/dali-toolkit/internal/controls/renderers/renderer-factory-impl.h @@ -55,6 +55,7 @@ public: N_PATCH, SVG, MESH, + PRIMITIVE, UNDEFINED }; diff --git a/dali-toolkit/internal/controls/renderers/renderer-string-constants.cpp b/dali-toolkit/internal/controls/renderers/renderer-string-constants.cpp index 41fd6a7..baca920 100644 --- a/dali-toolkit/internal/controls/renderers/renderer-string-constants.cpp +++ b/dali-toolkit/internal/controls/renderers/renderer-string-constants.cpp @@ -28,15 +28,17 @@ namespace Internal { const char * const RENDERER_TYPE("rendererType"); -const char * const COLOR_RENDERER("color"); -const char * const BORDER_RENDERER("border"); -const char * const GRADIENT_RENDERER("gradient"); -const char * const IMAGE_RENDERER("image"); -const char * const MESH_RENDERER("mesh"); +const char * const COLOR_RENDERER("COLOR"); +const char * const BORDER_RENDERER("BORDER"); +const char * const GRADIENT_RENDERER("GRADIENT"); +const char * const IMAGE_RENDERER("IMAGE"); +const char * const MESH_RENDERER("MESH"); +const char * const PRIMITIVE_RENDERER( "PRIMITIVE" ); +const char * const DEBUG_RENDERER("DEBUG"); const char * const IMAGE_URL_NAME("url"); const char * const ATLAS_RECT_UNIFORM_NAME ( "uAtlasRect" ); -const char * const COLOR( "color" ); +const char * const LIGHT_POSITION_UNIFORM_NAME( "uLightPosition" ); //Mesh properties const char * const OBJECT_URL( "objectUrl" ); @@ -45,6 +47,19 @@ const char * const TEXTURES_PATH( "texturesPath" ); const char * const SHADER_TYPE( "shaderType" ); const char * const USE_MIPMAPPING( "useMipmapping" ); +//Primitive shape properties +const char * const PRIMITIVE_SHAPE( "shape" ); +const char * const SHAPE_COLOR( "color" ); +const char * const SLICES( "slices" ); +const char * const STACKS( "stacks" ); +const char * const SCALE_TOP_RADIUS( "scaleTopRadius" ); +const char * const SCALE_BOTTOM_RADIUS( "scaleBottomRadius" ); +const char * const SCALE_HEIGHT( "scaleHeight" ); +const char * const SCALE_RADIUS( "scaleRadius" ); +const char * const SCALE_DIMENSIONS( "scaleDimensions" ); +const char * const BEVEL_PERCENTAGE( "bevelPercentage" ); +const char * const BEVEL_SMOOTHNESS( "bevelSmoothness" ); + } // namespace Internal } // namespace Toolkit diff --git a/dali-toolkit/internal/controls/renderers/renderer-string-constants.h b/dali-toolkit/internal/controls/renderers/renderer-string-constants.h index 0bb7d45..ec3e161 100644 --- a/dali-toolkit/internal/controls/renderers/renderer-string-constants.h +++ b/dali-toolkit/internal/controls/renderers/renderer-string-constants.h @@ -33,10 +33,12 @@ extern const char * const BORDER_RENDERER; extern const char * const GRADIENT_RENDERER; extern const char * const IMAGE_RENDERER; extern const char * const MESH_RENDERER; +extern const char * const PRIMITIVE_RENDERER; +extern const char * const DEBUG_RENDERER; extern const char * const IMAGE_URL_NAME; extern const char * const ATLAS_RECT_UNIFORM_NAME; -extern const char * const COLOR; +extern const char * const LIGHT_POSITION_UNIFORM_NAME; //Mesh properties extern const char * const OBJECT_URL; @@ -45,6 +47,19 @@ extern const char * const TEXTURES_PATH; extern const char * const SHADER_TYPE; extern const char * const USE_MIPMAPPING; +//Primitive shape properties +extern const char * const PRIMITIVE_SHAPE; +extern const char * const SHAPE_COLOR; +extern const char * const SLICES; +extern const char * const STACKS; +extern const char * const SCALE_TOP_RADIUS; +extern const char * const SCALE_BOTTOM_RADIUS; +extern const char * const SCALE_HEIGHT; +extern const char * const SCALE_RADIUS; +extern const char * const SCALE_DIMENSIONS; +extern const char * const BEVEL_PERCENTAGE; +extern const char * const BEVEL_SMOOTHNESS; + } // namespace Internal } // namespace Toolkit diff --git a/dali-toolkit/internal/controls/renderers/svg/svg-rasterize-thread.h b/dali-toolkit/internal/controls/renderers/svg/svg-rasterize-thread.h index 556a7e6..cbdf376 100644 --- a/dali-toolkit/internal/controls/renderers/svg/svg-rasterize-thread.h +++ b/dali-toolkit/internal/controls/renderers/svg/svg-rasterize-thread.h @@ -1,5 +1,5 @@ -#ifndef __DALI_TOOLKIT_SVG_RASTERIZE_THREAD_H__ -#define __DALI_TOOLKIT_SVG_RASTERIZE_THREAD_H__ +#ifndef DALI_TOOLKIT_SVG_RASTERIZE_THREAD_H +#define DALI_TOOLKIT_SVG_RASTERIZE_THREAD_H /* * Copyright (c) 2016 Samsung Electronics Co., Ltd. @@ -18,16 +18,16 @@ */ // EXTERNAL INCLUDES +#include #include #include #include -#include -#include #include +#include #include #include #include -#include +#include struct NSVGimage; struct NSVGrasterizer; @@ -213,4 +213,4 @@ private: } // namespace Dali -#endif /* __DALI_TOOLKIT_SVG_RASTERIZE_THREAD_H__ */ +#endif // DALI_TOOLKIT_SVG_RASTERIZE_THREAD_H diff --git a/dali-toolkit/internal/controls/scrollable/bouncing-effect-actor.cpp b/dali-toolkit/internal/controls/scrollable/bouncing-effect-actor.cpp index c06e400..1b9c422 100644 --- a/dali-toolkit/internal/controls/scrollable/bouncing-effect-actor.cpp +++ b/dali-toolkit/internal/controls/scrollable/bouncing-effect-actor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,11 +21,11 @@ // EXTERNAL INCLUDES #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include namespace Dali { diff --git a/dali-toolkit/internal/controls/scrollable/bouncing-effect-actor.h b/dali-toolkit/internal/controls/scrollable/bouncing-effect-actor.h index 5261f60..1eb7725 100644 --- a/dali-toolkit/internal/controls/scrollable/bouncing-effect-actor.h +++ b/dali-toolkit/internal/controls/scrollable/bouncing-effect-actor.h @@ -1,8 +1,8 @@ -#ifndef __DALI_TOOLKIT_INTERNAL_BOUNCING_EFFECT_ACTOR_H__ -#define __DALI_TOOLKIT_INTERNAL_BOUNCING_EFFECT_ACTOR_H__ +#ifndef DALI_TOOLKIT_INTERNAL_BOUNCING_EFFECT_ACTOR_H +#define DALI_TOOLKIT_INTERNAL_BOUNCING_EFFECT_ACTOR_H /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -66,4 +66,4 @@ Actor CreateBouncingEffectActor( Property::Index& bouncePropertyIndex); } // namespace Dali -#endif /* __DALI_TOOLKIT_INTERNAL_BOUNCING_EFFECT_ACTOR_H__ */ +#endif // DALI_TOOLKIT_INTERNAL_BOUNCING_EFFECT_ACTOR_H diff --git a/dali-toolkit/internal/controls/super-blur-view/super-blur-view-impl.cpp b/dali-toolkit/internal/controls/super-blur-view/super-blur-view-impl.cpp index 47a0790..1e1ccad 100644 --- a/dali-toolkit/internal/controls/super-blur-view/super-blur-view-impl.cpp +++ b/dali-toolkit/internal/controls/super-blur-view/super-blur-view-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,10 +22,10 @@ #include #include #include -#include #include +#include #include -#include +#include #include #include diff --git a/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp b/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp index 4763884..8f7916c 100644 --- a/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp @@ -52,10 +52,11 @@ namespace // unnamed namespace { #if defined(DEBUG_ENABLED) - Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_CONTROLS"); +Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_CONTROLS"); #endif - const unsigned int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::Text::DEFAULT_RENDERING_BACKEND; +const unsigned int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::Text::DEFAULT_RENDERING_BACKEND; +const float DEFAULT_SCROLL_SPEED = 1200.f; ///< The default scroll speed for the text editor in pixels/second. } // unnamed namespace namespace @@ -928,10 +929,20 @@ void TextEditor::OnInitialize() mController->GetLayoutEngine().SetLayout( LayoutEngine::MULTI_LINE_BOX ); + // Enables the text input. mController->EnableTextInput( mDecorator ); + // Enables the vertical scrolling after the text input has been enabled. + mController->SetVerticalScrollEnabled( true ); + + // Disables the horizontal scrolling. + mController->SetHorizontalScrollEnabled( false ); + mController->SetMaximumNumberOfCharacters( std::numeric_limits::max() ); + // Enable the smooth handle panning. + mController->SetSmoothHandlePanEnabled( true ); + // Forward input events to controller EnableGestureDetection( static_cast( Gesture::Tap | Gesture::Pan | Gesture::LongPress ) ); GetTapGestureDetector().SetMaximumTapsRequired( 2 ); @@ -948,8 +959,11 @@ void TextEditor::OnInitialize() mDecorator->SetBoundingBox( Rect( 0.0f, 0.0f, stageSize.width, stageSize.height ) ); } - // Flip vertically the 'left' selection handle - mDecorator->FlipHandleVertically( LEFT_SELECTION_HANDLE, true ); + // Whether to flip the selection handles as soon as they cross. + mDecorator->FlipSelectionHandlesOnCrossEnabled( true ); + + // Set the default scroll speed. + mDecorator->SetScrollSpeed( DEFAULT_SCROLL_SPEED ); // Fill-parent area by default self.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH ); diff --git a/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp b/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp index 69776fa..32fe824 100644 --- a/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp @@ -1114,8 +1114,18 @@ void TextField::OnInitialize() mController->GetLayoutEngine().SetLayout( LayoutEngine::SINGLE_LINE_BOX ); + // Enables the text input. mController->EnableTextInput( mDecorator ); + // Enables the horizontal scrolling after the text input has been enabled. + mController->SetHorizontalScrollEnabled( true ); + + // Disables the vertical scrolling. + mController->SetVerticalScrollEnabled( false ); + + // Disable the smooth handle panning. + mController->SetSmoothHandlePanEnabled( false ); + // Forward input events to controller EnableGestureDetection( static_cast( Gesture::Tap | Gesture::Pan | Gesture::LongPress ) ); GetTapGestureDetector().SetMaximumTapsRequired( 2 ); diff --git a/dali-toolkit/internal/file.list b/dali-toolkit/internal/file.list index a33845e..b8730a6 100644 --- a/dali-toolkit/internal/file.list +++ b/dali-toolkit/internal/file.list @@ -28,6 +28,7 @@ toolkit_src_files = \ $(toolkit_src_dir)/controls/renderers/svg/svg-rasterize-thread.cpp \ $(toolkit_src_dir)/controls/renderers/svg/svg-renderer.cpp \ $(toolkit_src_dir)/controls/renderers/mesh/mesh-renderer.cpp \ + $(toolkit_src_dir)/controls/renderers/primitive/primitive-renderer.cpp \ $(toolkit_src_dir)/controls/alignment/alignment-impl.cpp \ $(toolkit_src_dir)/controls/bloom-view/bloom-view-impl.cpp \ $(toolkit_src_dir)/controls/bubble-effect/bubble-emitter-impl.cpp \ diff --git a/dali-toolkit/internal/filters/blur-two-pass-filter.cpp b/dali-toolkit/internal/filters/blur-two-pass-filter.cpp index 8d7fc12..b1dce92 100644 --- a/dali-toolkit/internal/filters/blur-two-pass-filter.cpp +++ b/dali-toolkit/internal/filters/blur-two-pass-filter.cpp @@ -24,10 +24,8 @@ #include #include #include +#include #include -#include - -// INTERNAL INCLUDES namespace Dali { diff --git a/dali-toolkit/internal/filters/emboss-filter.cpp b/dali-toolkit/internal/filters/emboss-filter.cpp index 275292c..d980708 100644 --- a/dali-toolkit/internal/filters/emboss-filter.cpp +++ b/dali-toolkit/internal/filters/emboss-filter.cpp @@ -24,8 +24,8 @@ #include #include #include +#include #include -#include // INTERNAL INCLUDES #include @@ -123,7 +123,7 @@ void EmbossFilter::Enable() customShader[ "fragmentShader" ] = COMPOSITE_FRAGMENT_SOURCE; rendererMap[ "shader"] = customShader; - rendererMap[ "rendererType"] = "image"; + rendererMap[ "rendererType"] = "IMAGE"; mRootActor.Add( mActorForComposite ); diff --git a/dali-toolkit/internal/text/clipping/text-clipper.cpp b/dali-toolkit/internal/text/clipping/text-clipper.cpp index 2286a5b..11a8fc9 100644 --- a/dali-toolkit/internal/text/clipping/text-clipper.cpp +++ b/dali-toolkit/internal/text/clipping/text-clipper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,7 +21,7 @@ // EXTERNAL INCLUDES #include #include -#include +#include namespace { diff --git a/dali-toolkit/internal/text/cursor-helper-functions.cpp b/dali-toolkit/internal/text/cursor-helper-functions.cpp index b3b7250..1fbca0d 100644 --- a/dali-toolkit/internal/text/cursor-helper-functions.cpp +++ b/dali-toolkit/internal/text/cursor-helper-functions.cpp @@ -33,6 +33,97 @@ namespace const Dali::Toolkit::Text::CharacterDirection LTR = false; ///< Left To Right direction. +struct FindWordData +{ + FindWordData( const Dali::Toolkit::Text::Character* const textBuffer, + Dali::Toolkit::Text::Length totalNumberOfCharacters, + Dali::Toolkit::Text::CharacterIndex hitCharacter, + bool isWhiteSpace, + bool isNewParagraph ) + : textBuffer( textBuffer ), + totalNumberOfCharacters( totalNumberOfCharacters ), + hitCharacter( hitCharacter ), + foundIndex( 0u ), + isWhiteSpace( isWhiteSpace ), + isNewParagraph( isNewParagraph ) + {} + + ~FindWordData() + {} + + const Dali::Toolkit::Text::Character* const textBuffer; + Dali::Toolkit::Text::Length totalNumberOfCharacters; + Dali::Toolkit::Text::CharacterIndex hitCharacter; + Dali::Toolkit::Text::CharacterIndex foundIndex; + bool isWhiteSpace : 1u; + bool isNewParagraph : 1u; +}; + +bool IsWhiteSpaceOrNewParagraph( Dali::Toolkit::Text::Character character, + bool isHitWhiteSpace, + bool isHitWhiteSpaceOrNewParagraph ) +{ + bool isWhiteSpaceOrNewParagraph = false; + if( isHitWhiteSpaceOrNewParagraph ) + { + if( isHitWhiteSpace ) + { + // Whether the current character is a white space. Note a new paragraph character is a white space as well but here is not wanted. + isWhiteSpaceOrNewParagraph = Dali::TextAbstraction::IsWhiteSpace( character ) && !Dali::TextAbstraction::IsNewParagraph( character ); + } + else + { + // Whether the current character is a new paragraph character. + isWhiteSpaceOrNewParagraph = Dali::TextAbstraction::IsNewParagraph( character ); + } + } + else + { + // Whether the current character is a white space or a new paragraph character (note the new paragraph character is a white space as well). + isWhiteSpaceOrNewParagraph = Dali::TextAbstraction::IsWhiteSpace( character ); + } + + return isWhiteSpaceOrNewParagraph; +} + +void FindStartOfWord( FindWordData& data ) +{ + const bool isHitWhiteSpaceOrNewParagraph = data.isWhiteSpace || data.isNewParagraph; + + for( data.foundIndex = data.hitCharacter; data.foundIndex > 0; --data.foundIndex ) + { + const Dali::Toolkit::Text::Character character = *( data.textBuffer + data.foundIndex - 1u ); + + const bool isWhiteSpaceOrNewParagraph = IsWhiteSpaceOrNewParagraph( character, + data.isWhiteSpace, + isHitWhiteSpaceOrNewParagraph ); + + if( isHitWhiteSpaceOrNewParagraph != isWhiteSpaceOrNewParagraph ) + { + break; + } + } +} + +void FindEndOfWord( FindWordData& data ) +{ + const bool isHitWhiteSpaceOrNewParagraph = data.isWhiteSpace || data.isNewParagraph; + + for( data.foundIndex = data.hitCharacter + 1u; data.foundIndex < data.totalNumberOfCharacters; ++data.foundIndex ) + { + const Dali::Toolkit::Text::Character character = *( data.textBuffer + data.foundIndex ); + + const bool isWhiteSpaceOrNewParagraph = IsWhiteSpaceOrNewParagraph( character, + data.isWhiteSpace, + isHitWhiteSpaceOrNewParagraph ); + + if( isHitWhiteSpaceOrNewParagraph != isWhiteSpaceOrNewParagraph ) + { + break; + } + } +} + } //namespace namespace Dali @@ -587,7 +678,7 @@ void GetCursorPosition( VisualModelPtr visualModel, ( isFirstPositionOfLine && !isRightToLeftParagraph ) ); cursorInfo.secondaryPosition.x = -glyphMetrics.xBearing + secondaryPosition.x + ( addGlyphAdvance ? glyphMetrics.advance : 0.f ); - cursorInfo.secondaryPosition.y = cursorInfo.lineOffset + cursorInfo.lineHeight - cursorInfo.secondaryCursorHeight - line.descender - ( glyphMetrics.fontHeight - glyphMetrics.ascender ); + cursorInfo.secondaryPosition.y = cursorInfo.lineOffset + cursorInfo.lineHeight - cursorInfo.secondaryCursorHeight; // Transform the cursor info from line's coords to text's coords. cursorInfo.secondaryPosition.x += line.alignmentOffset; @@ -595,7 +686,7 @@ void GetCursorPosition( VisualModelPtr visualModel, } } -void FindSelectionIndices( VisualModelPtr visualModel, +bool FindSelectionIndices( VisualModelPtr visualModel, LogicalModelPtr logicalModel, MetricsPtr metrics, float visualX, @@ -603,52 +694,122 @@ void FindSelectionIndices( VisualModelPtr visualModel, CharacterIndex& startIndex, CharacterIndex& endIndex ) { + +/* + Hit character Select +|-------------------------------------------------------|------------------------------------------| +| On a word | The word | +| On a single white space between words | The word before or after the white space | +| On one of the multiple contiguous white spaces | The white spaces | +| On a single white space which is in the position zero | The white space and the next word | +| On a new paragraph character | The word or group of white spaces before | +|-------------------------------------------------------|------------------------------------------| +*/ + CharacterIndex hitCharacter = Text::GetClosestCursorIndex( visualModel, logicalModel, metrics, visualX, visualY ); - DALI_ASSERT_DEBUG( hitCharacter <= logicalModel->mText.Count() && "GetClosestCursorIndex returned out of bounds index" ); - if( logicalModel->mText.Count() == 0 ) + const Length totalNumberOfCharacters = logicalModel->mText.Count(); + + DALI_ASSERT_DEBUG( ( hitCharacter <= totalNumberOfCharacters ) && "GetClosestCursorIndex returned out of bounds index" ); + + if( 0u == totalNumberOfCharacters ) { - return; // if model empty + // Nothing to do if the model is empty. + return false; } - if( hitCharacter >= logicalModel->mText.Count() ) + if( hitCharacter >= totalNumberOfCharacters ) { // Closest hit character is the last character. - if( hitCharacter == logicalModel->mText.Count() ) + if( hitCharacter == totalNumberOfCharacters ) { hitCharacter--; //Hit character index set to last character in logical model } else { // hitCharacter is out of bounds - return; + return false; } } + const Character* const textBuffer = logicalModel->mText.Begin(); + startIndex = hitCharacter; endIndex = hitCharacter; - bool isHitCharacterWhitespace = TextAbstraction::IsWhiteSpace( logicalModel->mText[hitCharacter] ); - // Find the start and end of the text - for( startIndex = hitCharacter; startIndex > 0; --startIndex ) + // Whether the hit character is a new paragraph character. + const bool isHitCharacterNewParagraph = TextAbstraction::IsNewParagraph( *( textBuffer + hitCharacter ) ); + + // Whether the hit character is a white space. Note a new paragraph character is a white space as well but here is not wanted. + const bool isHitCharacterWhiteSpace = TextAbstraction::IsWhiteSpace( *( textBuffer + hitCharacter ) ) && !isHitCharacterNewParagraph; + + FindWordData data( textBuffer, + totalNumberOfCharacters, + hitCharacter, + isHitCharacterWhiteSpace, + isHitCharacterNewParagraph ); + + if( isHitCharacterNewParagraph ) { - if( isHitCharacterWhitespace != TextAbstraction::IsWhiteSpace( logicalModel->mText[ startIndex-1 ] ) ) + // Find the first character before the hit one which is not a new paragraph character. + + if( hitCharacter > 0u ) { - break; + endIndex = hitCharacter - 1u; + for( ; endIndex > 0; --endIndex ) + { + const Dali::Toolkit::Text::Character character = *( data.textBuffer + endIndex ); + + if( !Dali::TextAbstraction::IsNewParagraph( character ) ) + { + break; + } + } } + + data.hitCharacter = endIndex; + data.isNewParagraph = false; + data.isWhiteSpace = TextAbstraction::IsWhiteSpace( *( textBuffer + data.hitCharacter ) ); } - const CharacterIndex pastTheEnd = logicalModel->mText.Count(); - for( endIndex = hitCharacter + 1u; endIndex < pastTheEnd; ++endIndex ) + + // Find the start of the word. + FindStartOfWord( data ); + startIndex = data.foundIndex; + + // Find the end of the word. + FindEndOfWord( data ); + endIndex = data.foundIndex; + + if( 1u == ( endIndex - startIndex ) ) { - if( isHitCharacterWhitespace != TextAbstraction::IsWhiteSpace( logicalModel->mText[ endIndex ] ) ) + if( isHitCharacterWhiteSpace ) { - break; + // Select the word before or after the white space + + if( 0u == hitCharacter ) + { + data.isWhiteSpace = false; + FindEndOfWord( data ); + endIndex = data.foundIndex; + } + else if( hitCharacter > 0u ) + { + // Find the start of the word. + data.hitCharacter = hitCharacter - 1u; + data.isWhiteSpace = false; + FindStartOfWord( data ); + startIndex = data.foundIndex; + + --endIndex; + } } } + + return true; } } // namespace Text diff --git a/dali-toolkit/internal/text/cursor-helper-functions.h b/dali-toolkit/internal/text/cursor-helper-functions.h index e89c335..5896b4d 100644 --- a/dali-toolkit/internal/text/cursor-helper-functions.h +++ b/dali-toolkit/internal/text/cursor-helper-functions.h @@ -128,8 +128,10 @@ void GetCursorPosition( VisualModelPtr visualModel, * @param[in] visualY The touch point 'y' in text's coords. * @param[out] startIndex Index to the first character of the selected word. * @param[out] endIndex Index to the last character of the selected word. + * + * @return @e true if the indices are found. */ -void FindSelectionIndices( VisualModelPtr visualModel, +bool FindSelectionIndices( VisualModelPtr visualModel, LogicalModelPtr logicalModel, MetricsPtr metrics, float visualX, diff --git a/dali-toolkit/internal/text/decorator/text-decorator.cpp b/dali-toolkit/internal/text/decorator/text-decorator.cpp index cc76691..281e43d 100644 --- a/dali-toolkit/internal/text/decorator/text-decorator.cpp +++ b/dali-toolkit/internal/text/decorator/text-decorator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,17 +20,15 @@ // EXTERNAL INCLUDES #include - -#include #include +#include #include #include #include #include #include - -#include -#include +#include +#include // INTERNAL INCLUDES #include @@ -49,12 +47,10 @@ namespace const char* VERTEX_SHADER = MAKE_SHADER( attribute mediump vec2 aPosition; uniform mediump mat4 uMvpMatrix; -uniform mediump vec3 uSize; void main() { mediump vec4 position = vec4( aPosition, 0.0, 1.0 ); - position.xyz *= uSize; gl_Position = uMvpMatrix * position; } ); @@ -93,17 +89,17 @@ const Dali::Vector4 LIGHT_BLUE( 0.75f, 0.96f, 1.f, 1.f ); // The text highlight const Dali::Vector4 HANDLE_COLOR( 0.0f, (183.0f / 255.0f), (229.0f / 255.0f), 1.0f ); -const unsigned int CURSOR_BLINK_INTERVAL = 500u; // Cursor blink interval -const float TO_MILLISECONDS = 1000.f; -const float TO_SECONDS = 1.f / TO_MILLISECONDS; +const unsigned int CURSOR_BLINK_INTERVAL = 500u; ///< Cursor blink interval in milliseconds. +const float TO_MILLISECONDS = 1000.f; ///< Converts from seconds to milliseconds. +const float TO_SECONDS = 1.f / TO_MILLISECONDS; ///< Converts from milliseconds to seconds. -const unsigned int SCROLL_TICK_INTERVAL = 50u; +const unsigned int SCROLL_TICK_INTERVAL = 50u; ///< Scroll interval in milliseconds. +const float SCROLL_THRESHOLD = 10.f; ///< Threshold in pixels close to the edges of the decorator boundaries from where the scroll timer starts to emit signals. +const float SCROLL_SPEED = 300.f; ///< The scroll speed in pixels/second. -const float SCROLL_THRESHOLD = 10.f; -const float SCROLL_SPEED = 300.f; -const float SCROLL_DISTANCE = SCROLL_SPEED * SCROLL_TICK_INTERVAL * TO_SECONDS; +const float SCROLL_DISTANCE = SCROLL_SPEED * SCROLL_TICK_INTERVAL * TO_SECONDS; ///< Distance in pixels scrolled in one second. -const float CURSOR_WIDTH = 1.f; +const float CURSOR_WIDTH = 1.f; ///< The cursor's width in pixels. /** * structure to hold coordinates of each quad, which will make up the mesh. @@ -208,6 +204,7 @@ struct Decorator::Impl : public ConnectionTracker { HandleImpl() : position(), + globalPosition(), size(), lineHeight( 0.0f ), grabDisplacementX( 0.f ), @@ -226,6 +223,7 @@ struct Decorator::Impl : public ConnectionTracker ImageView markerActor; Vector2 position; + Vector2 globalPosition; Size size; float lineHeight; ///< Not the handle height float grabDisplacementX; @@ -277,10 +275,12 @@ struct Decorator::Impl : public ConnectionTracker mFlipSelectionHandlesOnCross( false ), mFlipLeftSelectionHandleDirection( false ), mFlipRightSelectionHandleDirection( false ), - mHandlePanning( false ), - mHandleCurrentCrossed( false ), - mHandlePreviousCrossed( false ), - mNotifyEndOfScroll( false ) + mIsHandlePanning( false ), + mIsHandleCurrentlyCrossed( false ), + mIsHandlePreviouslyCrossed( false ), + mNotifyEndOfScroll( false ), + mHorizontalScrollingEnabled( false ), + mVerticalScrollingEnabled( false ) { mQuadVertexFormat[ "aPosition" ] = Property::VECTOR2; mHighlightShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER ); @@ -304,7 +304,10 @@ struct Decorator::Impl : public ConnectionTracker if( mPrimaryCursor ) { const CursorImpl& cursor = mCursor[PRIMARY_CURSOR]; - mPrimaryCursorVisible = ( cursor.position.x + mCursorWidth <= mControlSize.width ) && ( cursor.position.x >= 0.f ); + mPrimaryCursorVisible = ( ( cursor.position.x + mCursorWidth <= mControlSize.width ) && + ( cursor.position.x >= 0.f ) && + ( cursor.position.y + cursor.cursorHeight <= mControlSize.height ) && + ( cursor.position.y >= 0.f ) ); if( mPrimaryCursorVisible ) { mPrimaryCursor.SetPosition( cursor.position.x, @@ -316,7 +319,10 @@ struct Decorator::Impl : public ConnectionTracker if( mSecondaryCursor ) { const CursorImpl& cursor = mCursor[SECONDARY_CURSOR]; - mSecondaryCursorVisible = ( cursor.position.x + mCursorWidth <= mControlSize.width ) && ( cursor.position.x >= 0.f ); + mSecondaryCursorVisible = ( ( cursor.position.x + mCursorWidth <= mControlSize.width ) && + ( cursor.position.x >= 0.f ) && + ( cursor.position.y + cursor.cursorHeight <= mControlSize.height ) && + ( cursor.position.y >= 0.f ) ); if( mSecondaryCursorVisible ) { mSecondaryCursor.SetPosition( cursor.position.x, @@ -331,7 +337,10 @@ struct Decorator::Impl : public ConnectionTracker bool newGrabHandlePosition = false; if( grabHandle.active ) { - const bool isVisible = ( grabHandle.position.x + floor( 0.5f * mCursorWidth ) <= mControlSize.width ) && ( grabHandle.position.x >= 0.f ); + const bool isVisible = ( ( grabHandle.position.x + floor( 0.5f * mCursorWidth ) <= mControlSize.width ) && + ( grabHandle.position.x >= 0.f ) && + ( grabHandle.position.y <= mControlSize.height - grabHandle.lineHeight ) && + ( grabHandle.position.y >= 0.f ) ); if( isVisible ) { @@ -363,8 +372,14 @@ struct Decorator::Impl : public ConnectionTracker bool newSecondaryHandlePosition = false; if( primary.active || secondary.active ) { - const bool isPrimaryVisible = ( primary.position.x <= mControlSize.width ) && ( primary.position.x >= 0.f ); - const bool isSecondaryVisible = ( secondary.position.x <= mControlSize.width ) && ( secondary.position.x >= 0.f ); + const bool isPrimaryVisible = ( ( primary.position.x <= mControlSize.width ) && + ( primary.position.x >= 0.f ) && + ( primary.position.y <= mControlSize.height - primary.lineHeight ) && + ( primary.position.y >= 0.f ) ); + const bool isSecondaryVisible = ( ( secondary.position.x <= mControlSize.width ) && + ( secondary.position.x >= 0.f ) && + ( secondary.position.y <= mControlSize.height - secondary.lineHeight ) && + ( secondary.position.y >= 0.f ) ); if( isPrimaryVisible || isSecondaryVisible ) { @@ -844,8 +859,8 @@ struct Decorator::Impl : public ConnectionTracker // The grab handle position in world coords. // The active layer's world position is the center of the active layer. The origin of the // coord system of the handles is the top left of the active layer. - position.x = parentWorldPosition.x - 0.5f * mControlSize.width + handle.position.x; - position.y = parentWorldPosition.y - 0.5f * mControlSize.height + handle.position.y; + position.x = parentWorldPosition.x - 0.5f * mControlSize.width + handle.position.x + ( mSmoothHandlePanEnabled ? handle.grabDisplacementX : 0.f ); + position.y = parentWorldPosition.y - 0.5f * mControlSize.height + handle.position.y + ( mSmoothHandlePanEnabled ? handle.grabDisplacementY : 0.f ); } void SetGrabHandlePosition() @@ -877,8 +892,8 @@ struct Decorator::Impl : public ConnectionTracker if( grabHandle.actor ) { - grabHandle.actor.SetPosition( grabHandle.position.x + floor( 0.5f * mCursorWidth ), - yLocalPosition ); // TODO : Fix for multiline. + grabHandle.actor.SetPosition( grabHandle.position.x + floor( 0.5f * mCursorWidth ) + ( mSmoothHandlePanEnabled ? grabHandle.grabDisplacementX : 0.f ), + yLocalPosition + ( mSmoothHandlePanEnabled ? grabHandle.grabDisplacementY : 0.f ) ); } } @@ -903,18 +918,21 @@ struct Decorator::Impl : public ConnectionTracker // Whether to flip the handles if they are crossed. bool crossFlip = false; - if( mFlipSelectionHandlesOnCross || !mHandlePanning ) + if( mFlipSelectionHandlesOnCross || !mIsHandlePanning ) { - crossFlip = mHandleCurrentCrossed; + crossFlip = mIsHandleCurrentlyCrossed; } + // Whether the handle was crossed before start the panning. + const bool isHandlePreviouslyCrossed = mFlipSelectionHandlesOnCross ? false : mIsHandlePreviouslyCrossed; + // Does not flip if both conditions are true (double flip) - flipHandle = flipHandle != ( crossFlip || mHandlePreviousCrossed ); + flipHandle = flipHandle != ( crossFlip || isHandlePreviouslyCrossed ); // Will flip the handles vertically if the user prefers it. bool verticallyFlippedPreferred = handle.verticallyFlippedPreferred; - if( crossFlip || mHandlePreviousCrossed ) + if( crossFlip || isHandlePreviouslyCrossed ) { if( isPrimaryHandle ) { @@ -967,8 +985,8 @@ struct Decorator::Impl : public ConnectionTracker if( handle.actor ) { - handle.actor.SetPosition( handle.position.x, - yLocalPosition ); // TODO : Fix for multiline. + handle.actor.SetPosition( handle.position.x + ( mSmoothHandlePanEnabled ? handle.grabDisplacementX : 0.f ), + yLocalPosition + ( mSmoothHandlePanEnabled ? handle.grabDisplacementY : 0.f ) ); } } @@ -1022,8 +1040,8 @@ struct Decorator::Impl : public ConnectionTracker #ifdef DECORATOR_DEBUG mHighlightActor.SetName( "HighlightActor" ); #endif + mHighlightActor.SetParentOrigin( ParentOrigin::TOP_LEFT ); mHighlightActor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); - mHighlightActor.SetSize( 1.0f, 1.0f ); mHighlightActor.SetColor( mHighlightColor ); mHighlightActor.SetColorMode( USE_OWN_COLOR ); } @@ -1036,37 +1054,57 @@ struct Decorator::Impl : public ConnectionTracker { if ( mHighlightActor ) { - if( !mHighlightQuadList.empty() ) + // Sets the position of the highlight actor inside the decorator. + mHighlightActor.SetPosition( mHighlightPosition.x, + mHighlightPosition.y ); + + const unsigned int numberOfQuads = mHighlightQuadList.size(); + if( 0u != numberOfQuads ) { - Vector< Vector2 > vertices; - Vector< unsigned short> indices; - Vector2 vertex; + // Set the size of the highlighted text to the actor. + mHighlightActor.SetSize( mHighlightSize ); + + // Used to translate the vertices given in decorator's coords to the mHighlightActor's local coords. + const float offsetX = mHighlightPosition.x + 0.5f * mHighlightSize.width; + const float offsetY = mHighlightPosition.y + 0.5f * mHighlightSize.height; - std::vector::iterator iter = mHighlightQuadList.begin(); - std::vector::iterator endIter = mHighlightQuadList.end(); + Vector vertices; + Vector indices; - for( std::size_t v = 0; iter != endIter; ++iter,v+=4 ) + vertices.Reserve( 4u * numberOfQuads ); + indices.Reserve( 6u * numberOfQuads ); + + // Index to the vertex. + unsigned int v = 0u; + + // Traverse all quads. + for( std::vector::iterator it = mHighlightQuadList.begin(), + endIt = mHighlightQuadList.end(); + it != endIt; + ++it, v += 4u ) { - QuadCoordinates& quad = *iter; + QuadCoordinates& quad = *it; + + Vector2 vertex; // top-left (v+0) - vertex.x = quad.min.x; - vertex.y = quad.min.y; + vertex.x = quad.min.x - offsetX; + vertex.y = quad.min.y - offsetY; vertices.PushBack( vertex ); // top-right (v+1) - vertex.x = quad.max.x; - vertex.y = quad.min.y; + vertex.x = quad.max.x - offsetX; + vertex.y = quad.min.y - offsetY; vertices.PushBack( vertex ); // bottom-left (v+2) - vertex.x = quad.min.x; - vertex.y = quad.max.y; + vertex.x = quad.min.x - offsetX; + vertex.y = quad.max.y - offsetY; vertices.PushBack( vertex ); // bottom-right (v+3) - vertex.x = quad.max.x; - vertex.y = quad.max.y; + vertex.x = quad.max.x - offsetX; + vertex.y = quad.max.y - offsetY; vertices.PushBack( vertex ); // triangle A (3, 1, 0) @@ -1101,9 +1139,6 @@ struct Decorator::Impl : public ConnectionTracker } } - mHighlightActor.SetPosition( mHighlightPosition.x, - mHighlightPosition.y ); - mHighlightQuadList.clear(); if( mHighlightRenderer ) @@ -1118,32 +1153,52 @@ struct Decorator::Impl : public ConnectionTracker if( Gesture::Started == gesture.state ) { handle.grabDisplacementX = handle.grabDisplacementY = 0.f; + + handle.globalPosition.x = handle.position.x; + handle.globalPosition.y = handle.position.y; } handle.grabDisplacementX += gesture.displacement.x; handle.grabDisplacementY += ( handle.verticallyFlipped ? -gesture.displacement.y : gesture.displacement.y ); - const float x = handle.position.x + handle.grabDisplacementX; - const float y = handle.position.y + handle.lineHeight*0.5f + handle.grabDisplacementY; + const float x = handle.globalPosition.x + handle.grabDisplacementX; + const float y = handle.globalPosition.y + handle.grabDisplacementY + 0.5f * handle.lineHeight; + const float yVerticallyFlippedCorrected = y - ( handle.verticallyFlipped ? handle.lineHeight : 0.f ); - if( Gesture::Started == gesture.state || - Gesture::Continuing == gesture.state ) + if( ( Gesture::Started == gesture.state ) || + ( Gesture::Continuing == gesture.state ) ) { Vector2 targetSize; mController.GetTargetSize( targetSize ); - if( x < mScrollThreshold ) + if( mHorizontalScrollingEnabled && + ( x < mScrollThreshold ) ) { mScrollDirection = SCROLL_RIGHT; mHandleScrolling = type; StartScrollTimer(); } - else if( x > targetSize.width - mScrollThreshold ) + else if( mHorizontalScrollingEnabled && + ( x > targetSize.width - mScrollThreshold ) ) { mScrollDirection = SCROLL_LEFT; mHandleScrolling = type; StartScrollTimer(); } + else if( mVerticalScrollingEnabled && + ( yVerticallyFlippedCorrected < mScrollThreshold ) ) + { + mScrollDirection = SCROLL_TOP; + mHandleScrolling = type; + StartScrollTimer(); + } + else if( mVerticalScrollingEnabled && + ( yVerticallyFlippedCorrected + handle.lineHeight > targetSize.height - mScrollThreshold ) ) + { + mScrollDirection = SCROLL_BOTTOM; + mHandleScrolling = type; + StartScrollTimer(); + } else { mHandleScrolling = HANDLE_TYPE_COUNT; @@ -1151,10 +1206,10 @@ struct Decorator::Impl : public ConnectionTracker mController.DecorationEvent( type, HANDLE_PRESSED, x, y ); } - mHandlePanning = true; + mIsHandlePanning = true; } - else if( Gesture::Finished == gesture.state || - Gesture::Cancelled == gesture.state ) + else if( ( Gesture::Finished == gesture.state ) || + ( Gesture::Cancelled == gesture.state ) ) { if( mScrollTimer && ( mScrollTimer.IsRunning() || mNotifyEndOfScroll ) ) @@ -1175,7 +1230,7 @@ struct Decorator::Impl : public ConnectionTracker } handle.pressed = false; - mHandlePanning = false; + mIsHandlePanning = false; } } @@ -1201,20 +1256,22 @@ struct Decorator::Impl : public ConnectionTracker bool OnGrabHandleTouched( Actor actor, const TouchData& touch ) { + HandleImpl& grabHandle = mHandle[GRAB_HANDLE]; + // Switch between pressed/release grab-handle images if( touch.GetPointCount() > 0 && - mHandle[GRAB_HANDLE].actor ) + grabHandle.actor ) { const PointState::Type state = touch.GetState( 0 ); if( PointState::DOWN == state ) { - mHandle[GRAB_HANDLE].pressed = true; + grabHandle.pressed = true; } else if( ( PointState::UP == state ) || ( PointState::INTERRUPTED == state ) ) { - mHandle[GRAB_HANDLE].pressed = false; + grabHandle.pressed = false; } SetHandleImage( GRAB_HANDLE ); @@ -1226,22 +1283,24 @@ struct Decorator::Impl : public ConnectionTracker bool OnHandleOneTouched( Actor actor, const TouchData& touch ) { + HandleImpl& primarySelectionHandle = mHandle[LEFT_SELECTION_HANDLE]; + // Switch between pressed/release selection handle images if( touch.GetPointCount() > 0 && - mHandle[LEFT_SELECTION_HANDLE].actor ) + primarySelectionHandle.actor ) { const PointState::Type state = touch.GetState( 0 ); if( PointState::DOWN == state ) { - mHandle[LEFT_SELECTION_HANDLE].pressed = true; + primarySelectionHandle.pressed = true; } else if( ( PointState::UP == state ) || ( PointState::INTERRUPTED == state ) ) { - mHandle[LEFT_SELECTION_HANDLE].pressed = false; - mHandlePreviousCrossed = mHandleCurrentCrossed; - mHandlePanning = false; + primarySelectionHandle.pressed = false; + mIsHandlePreviouslyCrossed = mIsHandleCurrentlyCrossed; + mIsHandlePanning = false; } SetHandleImage( LEFT_SELECTION_HANDLE ); @@ -1253,22 +1312,24 @@ struct Decorator::Impl : public ConnectionTracker bool OnHandleTwoTouched( Actor actor, const TouchData& touch ) { + HandleImpl& secondarySelectionHandle = mHandle[RIGHT_SELECTION_HANDLE]; + // Switch between pressed/release selection handle images if( touch.GetPointCount() > 0 && - mHandle[RIGHT_SELECTION_HANDLE].actor ) + secondarySelectionHandle.actor ) { const PointState::Type state = touch.GetState( 0 ); if( PointState::DOWN == state ) { - mHandle[RIGHT_SELECTION_HANDLE].pressed = true; + secondarySelectionHandle.pressed = true; } else if( ( PointState::UP == state ) || ( PointState::INTERRUPTED == state ) ) { - mHandle[RIGHT_SELECTION_HANDLE].pressed = false; - mHandlePreviousCrossed = mHandleCurrentCrossed; - mHandlePanning = false; + secondarySelectionHandle.pressed = false; + mIsHandlePreviouslyCrossed = mIsHandleCurrentlyCrossed; + mIsHandlePanning = false; } SetHandleImage( RIGHT_SELECTION_HANDLE ); @@ -1646,10 +1707,39 @@ struct Decorator::Impl : public ConnectionTracker { if( HANDLE_TYPE_COUNT != mHandleScrolling ) { + float x = 0.f; + float y = 0.f; + + switch( mScrollDirection ) + { + case SCROLL_RIGHT: + { + x = mScrollDistance; + break; + } + case SCROLL_LEFT: + { + x = -mScrollDistance; + break; + } + case SCROLL_TOP: + { + y = mScrollDistance; + break; + } + case SCROLL_BOTTOM: + { + y = -mScrollDistance; + break; + } + default: + break; + } + mController.DecorationEvent( mHandleScrolling, HANDLE_SCROLLING, - mScrollDirection == SCROLL_RIGHT ? mScrollDistance : -mScrollDistance, - 0.f ); + x, + y ); } return true; @@ -1693,7 +1783,8 @@ struct Decorator::Impl : public ConnectionTracker Vector4 mBoundingBox; ///< The bounding box in world coords. Vector4 mHighlightColor; ///< Color of the highlight Vector2 mHighlightPosition; ///< The position of the highlight actor. - Vector2 mControlSize; ///< The control's size. Set by the Relayout. + Size mHighlightSize; ///< The size of the highlighted text. + Size mControlSize; ///< The control's size. Set by the Relayout. unsigned int mActiveCursor; unsigned int mCursorBlinkInterval; @@ -1715,10 +1806,13 @@ struct Decorator::Impl : public ConnectionTracker bool mFlipSelectionHandlesOnCross : 1; ///< Whether to flip the selection handles as soon as they cross. bool mFlipLeftSelectionHandleDirection : 1; ///< Whether to flip the left selection handle image because of the character's direction. bool mFlipRightSelectionHandleDirection : 1; ///< Whether to flip the right selection handle image because of the character's direction. - bool mHandlePanning : 1; ///< Whether any of the handles is moving. - bool mHandleCurrentCrossed : 1; ///< Whether the handles are crossed. - bool mHandlePreviousCrossed : 1; ///< Whether the handles where crossed at the last handle touch up. + bool mIsHandlePanning : 1; ///< Whether any of the handles is moving. + bool mIsHandleCurrentlyCrossed : 1; ///< Whether the handles are crossed. + bool mIsHandlePreviouslyCrossed : 1; ///< Whether the handles where crossed at the last handle touch up. bool mNotifyEndOfScroll : 1; ///< Whether to notify the end of the scroll. + bool mHorizontalScrollingEnabled : 1; ///< Whether the horizontal scrolling is enabled. + bool mVerticalScrollingEnabled : 1; ///< Whether the vertical scrolling is enabled. + bool mSmoothHandlePanEnabled : 1; ///< Whether to pan smoothly the handles. }; DecoratorPtr Decorator::New( ControllerInterface& controller, @@ -1762,18 +1856,22 @@ unsigned int Decorator::GetActiveCursor() const void Decorator::SetPosition( Cursor cursor, float x, float y, float cursorHeight, float lineHeight ) { - mImpl->mCursor[cursor].position.x = x; - mImpl->mCursor[cursor].position.y = y; - mImpl->mCursor[cursor].cursorHeight = cursorHeight; - mImpl->mCursor[cursor].lineHeight = lineHeight; + Impl::CursorImpl& cursorImpl = mImpl->mCursor[cursor]; + + cursorImpl.position.x = x; + cursorImpl.position.y = y; + cursorImpl.cursorHeight = cursorHeight; + cursorImpl.lineHeight = lineHeight; } void Decorator::GetPosition( Cursor cursor, float& x, float& y, float& cursorHeight, float& lineHeight ) const { - x = mImpl->mCursor[cursor].position.x; - y = mImpl->mCursor[cursor].position.y; - cursorHeight = mImpl->mCursor[cursor].cursorHeight; - lineHeight = mImpl->mCursor[cursor].lineHeight; + const Impl::CursorImpl& cursorImpl = mImpl->mCursor[cursor]; + + x = cursorImpl.position.x; + y = cursorImpl.position.y; + cursorHeight = cursorImpl.cursorHeight; + lineHeight = cursorImpl.lineHeight; } const Vector2& Decorator::GetPosition( Cursor cursor ) const @@ -1861,7 +1959,7 @@ void Decorator::SetHandleActive( HandleType handleType, bool active ) { if( ( LEFT_SELECTION_HANDLE == handleType ) || ( RIGHT_SELECTION_HANDLE == handleType ) ) { - mImpl->mHandlePreviousCrossed = false; + mImpl->mIsHandlePreviouslyCrossed = false; } // TODO: this is a work-around. @@ -1908,12 +2006,15 @@ void Decorator::SetPosition( HandleType handleType, float x, float y, float heig // Adjust handle's displacement Impl::HandleImpl& handle = mImpl->mHandle[handleType]; - handle.grabDisplacementX -= x - handle.position.x; - handle.grabDisplacementY -= y - handle.position.y; - handle.position.x = x; handle.position.y = y; handle.lineHeight = height; + + if( mImpl->mSmoothHandlePanEnabled ) + { + handle.grabDisplacementX = 0.f; + handle.grabDisplacementY = 0.f; + } } void Decorator::GetPosition( HandleType handleType, float& x, float& y, float& height ) const @@ -1947,7 +2048,7 @@ void Decorator::FlipSelectionHandlesOnCrossEnabled( bool enable ) void Decorator::SetSelectionHandleFlipState( bool indicesSwapped, bool left, bool right ) { - mImpl->mHandleCurrentCrossed = indicesSwapped; + mImpl->mIsHandleCurrentlyCrossed = indicesSwapped; mImpl->mFlipLeftSelectionHandleDirection = left; mImpl->mFlipRightSelectionHandleDirection = right; } @@ -1957,6 +2058,12 @@ void Decorator::AddHighlight( float x1, float y1, float x2, float y2 ) mImpl->mHighlightQuadList.push_back( QuadCoordinates(x1, y1, x2, y2) ); } +void Decorator::SetHighLightBox( const Vector2& position, const Size& size ) +{ + mImpl->mHighlightPosition = position; + mImpl->mHighlightSize = size; +} + void Decorator::ClearHighlights() { mImpl->mHighlightQuadList.clear(); @@ -2037,6 +2144,36 @@ void Decorator::NotifyEndOfScroll() mImpl->NotifyEndOfScroll(); } +void Decorator::SetHorizontalScrollEnabled( bool enable ) +{ + mImpl->mHorizontalScrollingEnabled = enable; +} + +bool Decorator::IsHorizontalScrollEnabled() const +{ + return mImpl->mHorizontalScrollingEnabled; +} + +void Decorator::SetVerticalScrollEnabled( bool enable ) +{ + mImpl->mVerticalScrollingEnabled = enable; +} + +bool Decorator::IsVerticalScrollEnabled() const +{ + return mImpl->mVerticalScrollingEnabled; +} + +void Decorator::SetSmoothHandlePanEnabled( bool enable ) +{ + mImpl->mSmoothHandlePanEnabled = enable; +} + +bool Decorator::IsSmoothHandlePanEnabled() const +{ + return mImpl->mSmoothHandlePanEnabled; +} + Decorator::~Decorator() { delete mImpl; diff --git a/dali-toolkit/internal/text/decorator/text-decorator.h b/dali-toolkit/internal/text/decorator/text-decorator.h index 4bcd012..a868958 100644 --- a/dali-toolkit/internal/text/decorator/text-decorator.h +++ b/dali-toolkit/internal/text/decorator/text-decorator.h @@ -284,7 +284,7 @@ public: /** * @brief Retrieves the blink-interval for a cursor. * - * @return The cursor blink-interval. + * @return The cursor blink-interval in seconds. */ float GetCursorBlinkInterval() const; @@ -298,7 +298,7 @@ public: /** * @brief Retrieves the blink-duration for a cursor. * - * @return The cursor blink-duration. + * @return The cursor blink-duration in seconds. */ float GetCursorBlinkDuration() const; @@ -435,7 +435,7 @@ public: void SetSelectionHandleFlipState( bool indicesSwapped, bool left, bool right ); /** - * @brief Adds a quad to the existing selection highlights. + * @brief Adds a quad to the existing selection highlights. Vertices are in decorator's coordinates. * * @param[in] x1 The top-left x position. * @param[in] y1 The top-left y position. @@ -445,6 +445,18 @@ public: void AddHighlight( float x1, float y1, float x2, float y2 ); /** + * @brief Sets the min 'x,y' coordinates and the size of the highlighted box. + * + * It's used to set the size and position of the highlight's actor and to translate each highlight quad from + * decorator's coordinates to the local coords of the highlight's actor. + * + * @param[in] position The position of the highlighted text in decorator's coords. + * @param[in] size The size of the highlighted text. + */ + void SetHighLightBox( const Vector2& position, + const Size& size ); + + /** * @brief Removes all of the previously added highlights. */ void ClearHighlights(); @@ -501,14 +513,14 @@ public: * It defines a square area inside the control, close to the edge. * When the cursor enters this area, the decorator starts to send scroll events. * - * @param[in] threshold The scroll threshold. + * @param[in] threshold The scroll threshold in pixels. */ void SetScrollThreshold( float threshold ); /** * @brief Retrieves the scroll threshold. * - * @retunr The scroll threshold. + * @retunr The scroll threshold in pixels. */ float GetScrollThreshold() const; @@ -517,14 +529,14 @@ public: * * Is the distance the text is going to be scrolled during a scroll interval. * - * @param[in] speed The scroll speed. + * @param[in] speed The scroll speed in pixels/second. */ void SetScrollSpeed( float speed ); /** * @brief Retrieves the scroll speed. * - * @return The scroll speed. + * @return The scroll speed in pixels/second. */ float GetScrollSpeed() const; @@ -533,6 +545,36 @@ public: */ void NotifyEndOfScroll(); + /** + * @copydoc Text::Controller::SetHorizontalScrollEnabled() + */ + void SetHorizontalScrollEnabled( bool enable ); + + /** + * @copydoc Text::Controller::IsHorizontalScrollEnabled() + */ + bool IsHorizontalScrollEnabled() const; + + /** + * @copydoc Text::Controller::SetVerticalScrollEnabled() + */ + void SetVerticalScrollEnabled( bool enable ); + + /** + * @copydoc Text::Controller::IsVerticalScrollEnabled() + */ + bool IsVerticalScrollEnabled() const; + + /** + * @copydoc Text::Controller::SetSmoothHandlePanEnabled() + */ + void SetSmoothHandlePanEnabled( bool enable ); + + /** + * @copydoc Text::Controller::IsSmoothHandlePanEnabled() + */ + bool IsSmoothHandlePanEnabled() const; + protected: /** diff --git a/dali-toolkit/internal/text/layouts/layout-engine.cpp b/dali-toolkit/internal/text/layouts/layout-engine.cpp index 8d9f8f5..cd51c8d 100644 --- a/dali-toolkit/internal/text/layouts/layout-engine.cpp +++ b/dali-toolkit/internal/text/layouts/layout-engine.cpp @@ -795,6 +795,10 @@ struct LayoutEngine::Impl } } + // Calculates the layout size. + UpdateLayoutSize( lines, + layoutSize ); + // Nothing else do if there are no glyphs to layout. return false; } diff --git a/dali-toolkit/internal/text/rendering/atlas/atlas-manager.h b/dali-toolkit/internal/text/rendering/atlas/atlas-manager.h index 5542dd0..00fdc7a 100644 --- a/dali-toolkit/internal/text/rendering/atlas/atlas-manager.h +++ b/dali-toolkit/internal/text/rendering/atlas/atlas-manager.h @@ -1,8 +1,8 @@ -#ifndef __DALI_TOOLKIT_ATLAS_MANAGER_H__ -#define __DALI_TOOLKIT_ATLAS_MANAGER_H__ +#ifndef DALI_TOOLKIT_ATLAS_MANAGER_H +#define DALI_TOOLKIT_ATLAS_MANAGER_H /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,8 +21,8 @@ #include #include #include +#include #include -#include namespace Dali { @@ -283,4 +283,4 @@ private: } // namespace Dali -#endif // __DALI_TOOLKIT_ATLAS_MANAGER_H__ +#endif // DALI_TOOLKIT_ATLAS_MANAGER_H diff --git a/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp b/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp index 3ee577f..5ba07ce 100644 --- a/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp +++ b/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,10 +19,10 @@ #include // EXTERNAL INCLUDES -#include -#include -#include +#include +#include #include +#include // INTERNAL INCLUDES #include @@ -176,7 +176,6 @@ struct AtlasRenderer::Impl TextCacheEntry textCacheEntry; mDepth = depth; - const Vector2& actorSize( view.GetControlSize() ); const Vector2& textSize( view.GetLayoutSize() ); const Vector2 halfTextSize( textSize * 0.5f ); const Vector2& shadowOffset( view.GetShadowOffset() ); @@ -393,6 +392,15 @@ struct AtlasRenderer::Impl // For each MeshData object, create a mesh actor and add to the renderable actor if( !meshContainer.empty() ) { + if( !mActor ) + { + // Create a container actor to act as a common parent for text and shadow, to avoid color inheritence issues. + mActor = Actor::New(); + mActor.SetParentOrigin( ParentOrigin::TOP_LEFT ); + mActor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + mActor.SetSize( textSize ); + } + for( std::vector< MeshRecord >::iterator it = meshContainer.begin(), endIt = meshContainer.end(); it != endIt; ++it ) @@ -401,8 +409,12 @@ struct AtlasRenderer::Impl Actor actor = CreateMeshActor( meshRecord, textSize ); + // Whether the actor has renderers. + const bool hasRenderer = actor.GetRendererCount() > 0u; + // Create an effect if necessary - if( style == STYLE_DROP_SHADOW ) + if( hasRenderer && + ( style == STYLE_DROP_SHADOW ) ) { // Change the color of the vertices. for( Vector::Iterator vIt = meshRecord.mMesh.mVertices.Begin(), @@ -415,39 +427,22 @@ struct AtlasRenderer::Impl vertex.mColor = shadowColor; } - // Create a container actor to act as a common parent for text and shadow, to avoid color inheritence issues. - Actor containerActor = Actor::New(); - containerActor.SetParentOrigin( ParentOrigin::CENTER ); - containerActor.SetSize( actorSize ); - Actor shadowActor = CreateMeshActor( meshRecord, textSize ); #if defined(DEBUG_ENABLED) shadowActor.SetName( "Text Shadow renderable actor" ); #endif // Offset shadow in x and y shadowActor.RegisterProperty("uOffset", shadowOffset ); - if( actor.GetRendererCount() ) - { - Dali::Renderer renderer( shadowActor.GetRendererAt( 0 ) ); - int depthIndex = renderer.GetProperty(Dali::Renderer::Property::DEPTH_INDEX); - renderer.SetProperty( Dali::Renderer::Property::DEPTH_INDEX, depthIndex - 1 ); - containerActor.Add( shadowActor ); - containerActor.Add( actor ); -#if defined(DEBUG_ENABLED) - containerActor.SetName("TextContainer"); -#endif - actor = containerActor; - } + Dali::Renderer renderer( shadowActor.GetRendererAt( 0 ) ); + int depthIndex = renderer.GetProperty(Dali::Renderer::Property::DEPTH_INDEX); + renderer.SetProperty( Dali::Renderer::Property::DEPTH_INDEX, depthIndex - 1 ); + mActor.Add( shadowActor ); } - if( mActor ) + if( hasRenderer ) { mActor.Add( actor ); } - else - { - mActor = actor; - } } } #if defined(DEBUG_ENABLED) diff --git a/dali-toolkit/internal/text/rendering/vector-based/glyphy-shader/glyphy-shader.h b/dali-toolkit/internal/text/rendering/vector-based/glyphy-shader/glyphy-shader.h index b3bbcf7..a7d2061 100644 --- a/dali-toolkit/internal/text/rendering/vector-based/glyphy-shader/glyphy-shader.h +++ b/dali-toolkit/internal/text/rendering/vector-based/glyphy-shader/glyphy-shader.h @@ -1,5 +1,5 @@ -#ifndef __DALI_TOOLKIT_TEXT_GLYPHY_SHADER_H__ -#define __DALI_TOOLKIT_TEXT_GLYPHY_SHADER_H__ +#ifndef DALI_TOOLKIT_TEXT_GLYPHY_SHADER_H +#define DALI_TOOLKIT_TEXT_GLYPHY_SHADER_H /* * Copyright (c) 2016 Samsung Electronics Co., Ltd. @@ -20,7 +20,7 @@ // INTERNEL INCLUDES #include -#include +#include namespace Dali { @@ -71,4 +71,4 @@ private: // Not intended for application developer } // namespace Dali -#endif // __DALI_TOOLKIT_TEXT_GLYPHY_SHADER_H__ +#endif // DALI_TOOLKIT_TEXT_GLYPHY_SHADER_H diff --git a/dali-toolkit/internal/text/rendering/vector-based/vector-based-renderer.cpp b/dali-toolkit/internal/text/rendering/vector-based/vector-based-renderer.cpp index 73fb666..b183524 100644 --- a/dali-toolkit/internal/text/rendering/vector-based/vector-based-renderer.cpp +++ b/dali-toolkit/internal/text/rendering/vector-based/vector-based-renderer.cpp @@ -19,10 +19,10 @@ #include // EXTERNAL INCLUDES -#include -#include -#include +#include +#include #include +#include // INTERNAL INCLUDES #include diff --git a/dali-toolkit/internal/text/rendering/vector-based/vector-blob-atlas.h b/dali-toolkit/internal/text/rendering/vector-based/vector-blob-atlas.h index 13b226d..14af3bb 100644 --- a/dali-toolkit/internal/text/rendering/vector-based/vector-blob-atlas.h +++ b/dali-toolkit/internal/text/rendering/vector-based/vector-blob-atlas.h @@ -1,5 +1,5 @@ -#ifndef __DALI_TOOLKIT_TEXT_VECTOR_BLOB_ATLAS_H__ -#define __DALI_TOOLKIT_TEXT_VECTOR_BLOB_ATLAS_H__ +#ifndef DALI_TOOLKIT_TEXT_VECTOR_BLOB_ATLAS_H +#define DALI_TOOLKIT_TEXT_VECTOR_BLOB_ATLAS_H /* * Copyright (c) 2016 Samsung Electronics Co., Ltd. @@ -18,10 +18,10 @@ */ // EXTERNAL INCLUDES -#include #include -#include -#include +#include +#include +#include #include // INTERNAL INCLUDES @@ -182,4 +182,4 @@ private: } // namespace Dali -#endif // __DALI_TOOLKIT_TEXT_VECTOR_BLOB_ATLAS_H__ +#endif // DALI_TOOLKIT_TEXT_VECTOR_BLOB_ATLAS_H diff --git a/dali-toolkit/internal/text/text-controller-impl.cpp b/dali-toolkit/internal/text/text-controller-impl.cpp index 0263b64..2c45d35 100644 --- a/dali-toolkit/internal/text/text-controller-impl.cpp +++ b/dali-toolkit/internal/text/text-controller-impl.cpp @@ -79,6 +79,7 @@ EventData::EventData( DecoratorPtr decorator ) mRightSelectionPosition( 0u ), mPreEditStartPosition( 0u ), mPreEditLength( 0u ), + mCursorHookPositionX( 0.f ), mIsShowingPlaceholderText( false ), mPreEditFlag( false ), mDecoratorUpdated( false ), @@ -86,11 +87,11 @@ EventData::EventData( DecoratorPtr decorator ) mGrabHandleEnabled( true ), mGrabHandlePopupEnabled( true ), mSelectionEnabled( true ), - mHorizontalScrollingEnabled( true ), - mVerticalScrollingEnabled( false ), mUpdateCursorPosition( false ), + mUpdateGrabHandlePosition( false ), mUpdateLeftSelectionPosition( false ), mUpdateRightSelectionPosition( false ), + mUpdateHighlightBox( false ), mScrollAfterUpdatePosition( false ), mScrollAfterDelete( false ), mAllTextSelected( false ), @@ -162,8 +163,7 @@ bool Controller::Impl::ProcessInputEvents() } if( mEventData->mUpdateCursorPosition || - mEventData->mUpdateLeftSelectionPosition || - mEventData->mUpdateRightSelectionPosition ) + mEventData->mUpdateHighlightBox ) { NotifyImfManager(); } @@ -173,9 +173,17 @@ bool Controller::Impl::ProcessInputEvents() { // Updates the cursor position and scrolls the text to make it visible. CursorInfo cursorInfo; + // Calculate the cursor position from the new cursor index. GetCursorPosition( mEventData->mPrimaryCursorPosition, cursorInfo ); + if( mEventData->mUpdateCursorHookPosition ) + { + // Update the cursor hook position. Used to move the cursor with the keys 'up' and 'down'. + mEventData->mCursorHookPositionX = cursorInfo.primaryPosition.x; + mEventData->mUpdateCursorHookPosition = false; + } + // Scroll first the text after delete ... if( mEventData->mScrollAfterDelete ) { @@ -185,7 +193,8 @@ bool Controller::Impl::ProcessInputEvents() // ... then, text can be scrolled to make the cursor visible. if( mEventData->mScrollAfterUpdatePosition ) { - ScrollToMakePositionVisible( cursorInfo.primaryPosition ); + const Vector2 currentCursorPosition( cursorInfo.primaryPosition.x, cursorInfo.lineOffset ); + ScrollToMakePositionVisible( currentCursorPosition, cursorInfo.lineHeight ); } mEventData->mScrollAfterUpdatePosition = false; mEventData->mScrollAfterDelete = false; @@ -194,36 +203,31 @@ bool Controller::Impl::ProcessInputEvents() mEventData->mDecoratorUpdated = true; mEventData->mUpdateCursorPosition = false; + mEventData->mUpdateGrabHandlePosition = false; } else { - bool leftScroll = false; - bool rightScroll = false; - CursorInfo leftHandleInfo; CursorInfo rightHandleInfo; - if( mEventData->mUpdateLeftSelectionPosition ) + if( mEventData->mUpdateHighlightBox ) { GetCursorPosition( mEventData->mLeftSelectionPosition, leftHandleInfo ); - if( mEventData->mScrollAfterUpdatePosition ) - { - ScrollToMakePositionVisible( leftHandleInfo.primaryPosition ); - leftScroll = true; - } - } - - if( mEventData->mUpdateRightSelectionPosition ) - { GetCursorPosition( mEventData->mRightSelectionPosition, rightHandleInfo ); - if( mEventData->mScrollAfterUpdatePosition ) + if( mEventData->mScrollAfterUpdatePosition && mEventData->mUpdateLeftSelectionPosition ) + { + const Vector2 currentCursorPosition( leftHandleInfo.primaryPosition.x, leftHandleInfo.lineOffset ); + ScrollToMakePositionVisible( currentCursorPosition, leftHandleInfo.lineHeight ); + } + + if( mEventData->mScrollAfterUpdatePosition && mEventData->mUpdateRightSelectionPosition ) { - ScrollToMakePositionVisible( rightHandleInfo.primaryPosition ); - rightScroll = true; + const Vector2 currentCursorPosition( rightHandleInfo.primaryPosition.x, rightHandleInfo.lineOffset ); + ScrollToMakePositionVisible( currentCursorPosition, rightHandleInfo.lineHeight ); } } @@ -234,6 +238,7 @@ bool Controller::Impl::ProcessInputEvents() SetPopupButtons(); mEventData->mDecoratorUpdated = true; + mEventData->mUpdateLeftSelectionPosition = false; } if( mEventData->mUpdateRightSelectionPosition ) @@ -243,20 +248,19 @@ bool Controller::Impl::ProcessInputEvents() SetPopupButtons(); mEventData->mDecoratorUpdated = true; + mEventData->mUpdateRightSelectionPosition = false; } - if( mEventData->mUpdateLeftSelectionPosition || mEventData->mUpdateRightSelectionPosition ) + if( mEventData->mUpdateHighlightBox ) { RepositionSelectionHandles(); mEventData->mUpdateLeftSelectionPosition = false; mEventData->mUpdateRightSelectionPosition = false; + mEventData->mUpdateHighlightBox = false; } - if( leftScroll || rightScroll ) - { - mEventData->mScrollAfterUpdatePosition = false; - } + mEventData->mScrollAfterUpdatePosition = false; } if( mEventData->mUpdateInputStyle ) @@ -1075,11 +1079,69 @@ void Controller::Impl::OnCursorKeyEvent( const Event& event ) } else if( Dali::DALI_KEY_CURSOR_UP == keyCode ) { - // TODO + // Get first the line index of the current cursor position index. + CharacterIndex characterIndex = 0u; + + if( mEventData->mPrimaryCursorPosition > 0u ) + { + characterIndex = mEventData->mPrimaryCursorPosition - 1u; + } + + const LineIndex lineIndex = mVisualModel->GetLineOfCharacter( characterIndex ); + + if( lineIndex > 0u ) + { + // Retrieve the cursor position info. + CursorInfo cursorInfo; + GetCursorPosition( mEventData->mPrimaryCursorPosition, + cursorInfo ); + + // Get the line above. + const LineRun& line = *( mVisualModel->mLines.Begin() + ( lineIndex - 1u ) ); + + // Get the next hit 'y' point. + const float hitPointY = cursorInfo.lineOffset - 0.5f * ( line.ascender - line.descender ); + + // Use the cursor hook position 'x' and the next hit 'y' position to calculate the new cursor index. + mEventData->mPrimaryCursorPosition = Text::GetClosestCursorIndex( mVisualModel, + mLogicalModel, + mMetrics, + mEventData->mCursorHookPositionX, + hitPointY ); + } } else if( Dali::DALI_KEY_CURSOR_DOWN == keyCode ) { - // TODO + // Get first the line index of the current cursor position index. + CharacterIndex characterIndex = 0u; + + if( mEventData->mPrimaryCursorPosition > 0u ) + { + characterIndex = mEventData->mPrimaryCursorPosition - 1u; + } + + const LineIndex lineIndex = mVisualModel->GetLineOfCharacter( characterIndex ); + + if( lineIndex + 1u < mVisualModel->mLines.Count() ) + { + // Retrieve the cursor position info. + CursorInfo cursorInfo; + GetCursorPosition( mEventData->mPrimaryCursorPosition, + cursorInfo ); + + // Get the line below. + const LineRun& line = *( mVisualModel->mLines.Begin() + lineIndex + 1u ); + + // Get the next hit 'y' point. + const float hitPointY = cursorInfo.lineOffset + cursorInfo.lineHeight + 0.5f * ( line.ascender - line.descender ); + + // Use the cursor hook position 'x' and the next hit 'y' position to calculate the new cursor index. + mEventData->mPrimaryCursorPosition = Text::GetClosestCursorIndex( mVisualModel, + mLogicalModel, + mMetrics, + mEventData->mCursorHookPositionX, + hitPointY ); + } } mEventData->mUpdateCursorPosition = true; @@ -1101,6 +1163,9 @@ void Controller::Impl::OnTapEvent( const Event& event ) const float xPosition = event.p2.mFloat - mScrollPosition.x; const float yPosition = event.p3.mFloat - mScrollPosition.y; + // Keep the tap 'x' position. Used to move the cursor. + mEventData->mCursorHookPositionX = xPosition; + mEventData->mPrimaryCursorPosition = Text::GetClosestCursorIndex( mVisualModel, mLogicalModel, mMetrics, @@ -1116,6 +1181,7 @@ void Controller::Impl::OnTapEvent( const Event& event ) } mEventData->mUpdateCursorPosition = true; + mEventData->mUpdateGrabHandlePosition = true; mEventData->mScrollAfterUpdatePosition = true; mEventData->mUpdateInputStyle = true; @@ -1142,27 +1208,27 @@ void Controller::Impl::OnPanEvent( const Event& event ) if( ( Gesture::Started == state ) || ( Gesture::Continuing == state ) ) { - const Vector2& actualSize = mVisualModel->GetLayoutSize(); - const Vector2 currentScroll = mScrollPosition; - - if( mEventData->mHorizontalScrollingEnabled ) + if( mEventData->mDecorator ) { - const float displacementX = event.p2.mFloat; - mScrollPosition.x += displacementX; + const Vector2& layoutSize = mVisualModel->GetLayoutSize(); + const Vector2 currentScroll = mScrollPosition; - ClampHorizontalScroll( actualSize ); - } + if( mEventData->mDecorator->IsHorizontalScrollEnabled() ) + { + const float displacementX = event.p2.mFloat; + mScrollPosition.x += displacementX; - if( mEventData->mVerticalScrollingEnabled ) - { - const float displacementY = event.p3.mFloat; - mScrollPosition.y += displacementY; + ClampHorizontalScroll( layoutSize ); + } - ClampVerticalScroll( actualSize ); - } + if( mEventData->mDecorator->IsVerticalScrollEnabled() ) + { + const float displacementY = event.p3.mFloat; + mScrollPosition.y += displacementY; + + ClampVerticalScroll( layoutSize ); + } - if( mEventData->mDecorator ) - { mEventData->mDecorator->UpdatePositions( mScrollPosition - currentScroll ); } } @@ -1189,6 +1255,7 @@ void Controller::Impl::OnHandleEvent( const Event& event ) const unsigned int state = event.p1.mUint; const bool handleStopScrolling = ( HANDLE_STOP_SCROLLING == state ); + const bool isSmoothHandlePanEnabled = mEventData->mDecorator->IsSmoothHandlePanEnabled(); if( HANDLE_PRESSED == state ) { @@ -1196,6 +1263,7 @@ void Controller::Impl::OnHandleEvent( const Event& event ) const float xPosition = event.p2.mFloat - mScrollPosition.x; const float yPosition = event.p3.mFloat - mScrollPosition.y; + // Need to calculate the handle's new position. const CharacterIndex handleNewPosition = Text::GetClosestCursorIndex( mVisualModel, mLogicalModel, mMetrics, @@ -1208,9 +1276,15 @@ void Controller::Impl::OnHandleEvent( const Event& event ) if( handleNewPosition != mEventData->mPrimaryCursorPosition ) { - mEventData->mPrimaryCursorPosition = handleNewPosition; + // Updates the cursor position if the handle's new position is different than the current one. mEventData->mUpdateCursorPosition = true; + // Does not update the grab handle position if the smooth panning is enabled. (The decorator does it smooth). + mEventData->mUpdateGrabHandlePosition = !isSmoothHandlePanEnabled; + mEventData->mPrimaryCursorPosition = handleNewPosition; } + + // Updates the decorator if the soft handle panning is enabled. It triggers a relayout in the decorator and the new position of the handle is set. + mEventData->mDecoratorUpdated = isSmoothHandlePanEnabled; } else if( Event::LEFT_SELECTION_HANDLE_EVENT == event.type ) { @@ -1219,10 +1293,15 @@ void Controller::Impl::OnHandleEvent( const Event& event ) if( ( handleNewPosition != mEventData->mLeftSelectionPosition ) && ( handleNewPosition != mEventData->mRightSelectionPosition ) ) { + // Updates the highlight box if the handle's new position is different than the current one. + mEventData->mUpdateHighlightBox = true; + // Does not update the selection handle position if the smooth panning is enabled. (The decorator does it smooth). + mEventData->mUpdateLeftSelectionPosition = !isSmoothHandlePanEnabled; mEventData->mLeftSelectionPosition = handleNewPosition; - - mEventData->mUpdateLeftSelectionPosition = true; } + + // Updates the decorator if the soft handle panning is enabled. It triggers a relayout in the decorator and the new position of the handle is set. + mEventData->mDecoratorUpdated = isSmoothHandlePanEnabled; } else if( Event::RIGHT_SELECTION_HANDLE_EVENT == event.type ) { @@ -1231,17 +1310,22 @@ void Controller::Impl::OnHandleEvent( const Event& event ) if( ( handleNewPosition != mEventData->mRightSelectionPosition ) && ( handleNewPosition != mEventData->mLeftSelectionPosition ) ) { + // Updates the highlight box if the handle's new position is different than the current one. + mEventData->mUpdateHighlightBox = true; + // Does not update the selection handle position if the smooth panning is enabled. (The decorator does it smooth). + mEventData->mUpdateRightSelectionPosition = !isSmoothHandlePanEnabled; mEventData->mRightSelectionPosition = handleNewPosition; - - mEventData->mUpdateRightSelectionPosition = true; } + + // Updates the decorator if the soft handle panning is enabled. It triggers a relayout in the decorator and the new position of the handle is set. + mEventData->mDecoratorUpdated = isSmoothHandlePanEnabled; } } // end ( HANDLE_PRESSED == state ) else if( ( HANDLE_RELEASED == state ) || handleStopScrolling ) { CharacterIndex handlePosition = 0u; - if( handleStopScrolling ) + if( handleStopScrolling || isSmoothHandlePanEnabled ) { // Convert from decorator's coords to text's coords. const float xPosition = event.p2.mFloat - mScrollPosition.x; @@ -1257,6 +1341,7 @@ void Controller::Impl::OnHandleEvent( const Event& event ) if( Event::GRAB_HANDLE_EVENT == event.type ) { mEventData->mUpdateCursorPosition = true; + mEventData->mUpdateGrabHandlePosition = true; mEventData->mUpdateInputStyle = true; if( !IsClipboardEmpty() ) @@ -1264,9 +1349,9 @@ void Controller::Impl::OnHandleEvent( const Event& event ) ChangeState( EventData::EDITING_WITH_PASTE_POPUP ); // Moving grabhandle will show Paste Popup } - if( handleStopScrolling ) + if( handleStopScrolling || isSmoothHandlePanEnabled ) { - mEventData->mScrollAfterUpdatePosition = mEventData->mPrimaryCursorPosition != handlePosition; + mEventData->mScrollAfterUpdatePosition = true; mEventData->mPrimaryCursorPosition = handlePosition; } } @@ -1274,12 +1359,15 @@ void Controller::Impl::OnHandleEvent( const Event& event ) { ChangeState( EventData::SELECTING ); - if( handleStopScrolling ) + mEventData->mUpdateHighlightBox = true; + mEventData->mUpdateLeftSelectionPosition = true; + + if( handleStopScrolling || isSmoothHandlePanEnabled ) { - mEventData->mUpdateLeftSelectionPosition = ( mEventData->mRightSelectionPosition != handlePosition ); - mEventData->mScrollAfterUpdatePosition = mEventData->mUpdateLeftSelectionPosition; + mEventData->mScrollAfterUpdatePosition = true; - if( mEventData->mUpdateLeftSelectionPosition ) + if( ( handlePosition != mEventData->mRightSelectionPosition ) && + ( handlePosition != mEventData->mLeftSelectionPosition ) ) { mEventData->mLeftSelectionPosition = handlePosition; } @@ -1289,11 +1377,14 @@ void Controller::Impl::OnHandleEvent( const Event& event ) { ChangeState( EventData::SELECTING ); - if( handleStopScrolling ) + mEventData->mUpdateHighlightBox = true; + mEventData->mUpdateRightSelectionPosition = true; + + if( handleStopScrolling || isSmoothHandlePanEnabled ) { - mEventData->mUpdateRightSelectionPosition = ( mEventData->mLeftSelectionPosition != handlePosition ); - mEventData->mScrollAfterUpdatePosition = mEventData->mUpdateRightSelectionPosition; - if( mEventData->mUpdateRightSelectionPosition ) + mEventData->mScrollAfterUpdatePosition = true; + if( ( handlePosition != mEventData->mRightSelectionPosition ) && + ( handlePosition != mEventData->mLeftSelectionPosition ) ) { mEventData->mRightSelectionPosition = handlePosition; } @@ -1305,12 +1396,15 @@ void Controller::Impl::OnHandleEvent( const Event& event ) else if( HANDLE_SCROLLING == state ) { const float xSpeed = event.p2.mFloat; - const Vector2& actualSize = mVisualModel->GetLayoutSize(); + const float ySpeed = event.p3.mFloat; + const Vector2& layoutSize = mVisualModel->GetLayoutSize(); const Vector2 currentScrollPosition = mScrollPosition; mScrollPosition.x += xSpeed; + mScrollPosition.y += ySpeed; - ClampHorizontalScroll( actualSize ); + ClampHorizontalScroll( layoutSize ); + ClampVerticalScroll( layoutSize ); bool endOfScroll = false; if( Vector2::ZERO == ( currentScrollPosition - mScrollPosition ) ) @@ -1324,6 +1418,7 @@ void Controller::Impl::OnHandleEvent( const Event& event ) // Set the position of the handle. const bool scrollRightDirection = xSpeed > 0.f; + const bool scrollBottomDirection = ySpeed > 0.f; const bool leftSelectionHandleEvent = Event::LEFT_SELECTION_HANDLE_EVENT == event.type; const bool rightSelectionHandleEvent = Event::RIGHT_SELECTION_HANDLE_EVENT == event.type; @@ -1331,10 +1426,22 @@ void Controller::Impl::OnHandleEvent( const Event& event ) { ChangeState( EventData::GRAB_HANDLE_PANNING ); + // Get the grab handle position in decorator coords. Vector2 position = mEventData->mDecorator->GetPosition( GRAB_HANDLE ); - // Position the grag handle close to either the left or right edge. - position.x = scrollRightDirection ? 0.f : mVisualModel->mControlSize.width; + if( mEventData->mDecorator->IsHorizontalScrollEnabled() ) + { + // Position the grag handle close to either the left or right edge. + position.x = scrollRightDirection ? 0.f : mVisualModel->mControlSize.width; + } + + if( mEventData->mDecorator->IsVerticalScrollEnabled() ) + { + position.x = mEventData->mCursorHookPositionX; + + // Position the grag handle close to either the top or bottom edge. + position.y = scrollBottomDirection ? 0.f : mVisualModel->mControlSize.height; + } // Get the new handle position. // The grab handle's position is in decorator's coords. Need to transforms to text's coords. @@ -1344,22 +1451,38 @@ void Controller::Impl::OnHandleEvent( const Event& event ) position.x - mScrollPosition.x, position.y - mScrollPosition.y ); - mEventData->mUpdateCursorPosition = mEventData->mPrimaryCursorPosition != handlePosition; - mEventData->mScrollAfterUpdatePosition = mEventData->mUpdateCursorPosition; - mEventData->mPrimaryCursorPosition = handlePosition; + if( mEventData->mPrimaryCursorPosition != handlePosition ) + { + mEventData->mUpdateCursorPosition = true; + mEventData->mUpdateGrabHandlePosition = !isSmoothHandlePanEnabled; + mEventData->mScrollAfterUpdatePosition = true; + mEventData->mPrimaryCursorPosition = handlePosition; + } mEventData->mUpdateInputStyle = mEventData->mUpdateCursorPosition; + + // Updates the decorator if the soft handle panning is enabled. + mEventData->mDecoratorUpdated = isSmoothHandlePanEnabled; } else if( leftSelectionHandleEvent || rightSelectionHandleEvent ) { - // TODO: This is recalculating the selection box every time the text is scrolled with the selection handles. - // Think if something can be done to save power. - ChangeState( EventData::SELECTION_HANDLE_PANNING ); + // Get the selection handle position in decorator coords. Vector2 position = mEventData->mDecorator->GetPosition( leftSelectionHandleEvent ? Text::LEFT_SELECTION_HANDLE : Text::RIGHT_SELECTION_HANDLE ); - // Position the selection handle close to either the left or right edge. - position.x = scrollRightDirection ? 0.f : mVisualModel->mControlSize.width; + if( mEventData->mDecorator->IsHorizontalScrollEnabled() ) + { + // Position the selection handle close to either the left or right edge. + position.x = scrollRightDirection ? 0.f : mVisualModel->mControlSize.width; + } + + if( mEventData->mDecorator->IsVerticalScrollEnabled() ) + { + position.x = mEventData->mCursorHookPositionX; + + // Position the grag handle close to either the top or bottom edge. + position.y = scrollBottomDirection ? 0.f : mVisualModel->mControlSize.height; + } // Get the new handle position. // The selection handle's position is in decorator's coords. Need to transform to text's coords. @@ -1372,18 +1495,23 @@ void Controller::Impl::OnHandleEvent( const Event& event ) if( leftSelectionHandleEvent ) { const bool differentHandles = ( mEventData->mLeftSelectionPosition != handlePosition ) && ( mEventData->mRightSelectionPosition != handlePosition ); - mEventData->mUpdateLeftSelectionPosition = endOfScroll || differentHandles; - if( differentHandles ) + + if( differentHandles || endOfScroll ) { + mEventData->mUpdateHighlightBox = true; + mEventData->mUpdateLeftSelectionPosition = !isSmoothHandlePanEnabled; + mEventData->mUpdateRightSelectionPosition = isSmoothHandlePanEnabled; mEventData->mLeftSelectionPosition = handlePosition; } } else { const bool differentHandles = ( mEventData->mRightSelectionPosition != handlePosition ) && ( mEventData->mLeftSelectionPosition != handlePosition ); - mEventData->mUpdateRightSelectionPosition = endOfScroll || differentHandles; - if( differentHandles ) + if( differentHandles || endOfScroll ) { + mEventData->mUpdateHighlightBox = true; + mEventData->mUpdateRightSelectionPosition = !isSmoothHandlePanEnabled; + mEventData->mUpdateLeftSelectionPosition = isSmoothHandlePanEnabled; mEventData->mRightSelectionPosition = handlePosition; } } @@ -1392,7 +1520,7 @@ void Controller::Impl::OnHandleEvent( const Event& event ) { RepositionSelectionHandles(); - mEventData->mScrollAfterUpdatePosition = true; + mEventData->mScrollAfterUpdatePosition = !isSmoothHandlePanEnabled; } } mEventData->mDecoratorUpdated = true; @@ -1416,12 +1544,6 @@ void Controller::Impl::OnSelectEvent( const Event& event ) // Calculates the logical position from the x,y coords. RepositionSelectionHandles( xPosition, yPosition ); - - mEventData->mUpdateLeftSelectionPosition = true; - mEventData->mUpdateRightSelectionPosition = true; - mEventData->mUpdateCursorPosition = false; - - mEventData->mScrollAfterUpdatePosition = ( mEventData->mLeftSelectionPosition != mEventData->mRightSelectionPosition ); } } @@ -1437,12 +1559,15 @@ void Controller::Impl::OnSelectAllEvent() if( mEventData->mSelectionEnabled ) { + ChangeState( EventData::SELECTING ); + mEventData->mLeftSelectionPosition = 0u; mEventData->mRightSelectionPosition = mLogicalModel->mText.Count(); mEventData->mScrollAfterUpdatePosition = true; mEventData->mUpdateLeftSelectionPosition = true; mEventData->mUpdateRightSelectionPosition = true; + mEventData->mUpdateHighlightBox = true; } } @@ -1563,8 +1688,6 @@ void Controller::Impl::RepositionSelectionHandles() const CharacterIndex* const glyphToCharacterBuffer = mVisualModel->mGlyphsToCharacters.Begin(); const CharacterDirection* const modelCharacterDirectionsBuffer = ( 0u != mLogicalModel->mCharacterDirections.Count() ) ? mLogicalModel->mCharacterDirections.Begin() : NULL; - // TODO: Better algorithm to create the highlight box. - const bool isLastCharacter = selectionEnd >= mLogicalModel->mText.Count(); const CharacterDirection startDirection = ( ( NULL == modelCharacterDirectionsBuffer ) ? false : *( modelCharacterDirectionsBuffer + selectionStart ) ); const CharacterDirection endDirection = ( ( NULL == modelCharacterDirectionsBuffer ) ? false : *( modelCharacterDirectionsBuffer + ( selectionEnd - ( isLastCharacter ? 1u : 0u ) ) ) ); @@ -1605,11 +1728,21 @@ void Controller::Impl::RepositionSelectionHandles() selectionBoxInfo->minX = MAX_FLOAT; selectionBoxInfo->maxX = MIN_FLOAT; + // Keep the min and max 'x' position to calculate the size and position of the highlighed text. + float minHighlightX = std::numeric_limits::max(); + float maxHighlightX = std::numeric_limits::min(); + Size highLightSize; + Vector2 highLightPosition; // The highlight position in decorator's coords. + // Retrieve the first line and get the line's vertical offset, the line's height and the index to the last glyph. // The line's vertical offset of all the lines before the line where the first glyph is laid-out. selectionBoxInfo->lineOffset = CalculateLineOffset( mVisualModel->mLines, firstLineIndex ); + + // Transform to decorator's (control) coords. + selectionBoxInfo->lineOffset += mScrollPosition.y; + lineRun += firstLineIndex; // The line height is the addition of the line ascender and the line descender. @@ -1651,7 +1784,7 @@ void Controller::Impl::RepositionSelectionHandles() const float xPosition = lineRun->alignmentOffset + position.x - glyph.xBearing + mScrollPosition.x + glyphAdvance * static_cast( isCurrentRightToLeft ? ( numberOfCharactersStart - interGlyphIndex - numberOfCharacters ) : interGlyphIndex ); const float xPositionAdvance = xPosition + static_cast( numberOfCharacters ) * glyphAdvance; - const float yPosition = selectionBoxInfo->lineOffset + mScrollPosition.y; + const float yPosition = selectionBoxInfo->lineOffset; // Store the min and max 'x' for each line. selectionBoxInfo->minX = std::min( selectionBoxInfo->minX, xPosition ); @@ -1683,7 +1816,7 @@ void Controller::Impl::RepositionSelectionHandles() const float xPosition = lineRun->alignmentOffset + position.x - glyph.xBearing + mScrollPosition.x + ( isCurrentRightToLeft ? ( glyphAdvance * static_cast( numberOfCharacters ) ) : 0.f ); const float xPositionAdvance = xPosition + static_cast( interGlyphIndex ) * glyphAdvance; - const float yPosition = selectionBoxInfo->lineOffset + mScrollPosition.y; + const float yPosition = selectionBoxInfo->lineOffset; // Store the min and max 'x' for each line. selectionBoxInfo->minX = std::min( selectionBoxInfo->minX, xPosition ); @@ -1700,7 +1833,7 @@ void Controller::Impl::RepositionSelectionHandles() const float xPosition = lineRun->alignmentOffset + position.x - glyph.xBearing + mScrollPosition.x; const float xPositionAdvance = xPosition + glyph.advance; - const float yPosition = selectionBoxInfo->lineOffset + mScrollPosition.y; + const float yPosition = selectionBoxInfo->lineOffset; // Store the min and max 'x' for each line. selectionBoxInfo->minX = std::min( selectionBoxInfo->minX, xPosition ); @@ -1723,23 +1856,41 @@ void Controller::Impl::RepositionSelectionHandles() ++lineIndex; if( lineIndex < firstLineIndex + numberOfLines ) { - // Get the selection box info for the next line. + // Keep the offset and height of the current selection box. const float currentLineOffset = selectionBoxInfo->lineOffset; + const float currentLineHeight = selectionBoxInfo->lineHeight; + + // Get the selection box info for the next line. ++selectionBoxInfo; selectionBoxInfo->minX = MAX_FLOAT; selectionBoxInfo->maxX = MIN_FLOAT; + // Update the line's vertical offset. + selectionBoxInfo->lineOffset = currentLineOffset + currentLineHeight; + // The line height is the addition of the line ascender and the line descender. // However, the line descender has a negative value, hence the subtraction. selectionBoxInfo->lineHeight = lineRun->ascender - lineRun->descender; - - // Update the line's vertical offset. - selectionBoxInfo->lineOffset = currentLineOffset + selectionBoxInfo->lineHeight; } } } + // Traverses all the lines and updates the min and max 'x' positions and the total height. + // The final width is calculated after 'boxifying' the selection. + for( Vector::ConstIterator it = selectionBoxLinesInfo.Begin(), + endIt = selectionBoxLinesInfo.End(); + it != endIt; + ++it ) + { + const SelectionBoxInfo& info = *it; + + // Update the size of the highlighted text. + highLightSize.height += selectionBoxInfo->lineHeight; + minHighlightX = std::min( minHighlightX, info.minX ); + maxHighlightX = std::max( maxHighlightX, info.maxX ); + } + // Add extra geometry to 'boxify' the selection. if( 1u < numberOfLines ) @@ -1758,6 +1909,9 @@ void Controller::Impl::RepositionSelectionHandles() firstSelectionBoxLineInfo.lineOffset, firstSelectionBoxLineInfo.minX, firstSelectionBoxLineInfo.lineOffset + firstSelectionBoxLineInfo.lineHeight ); + + // Update the size of the highlighted text. + minHighlightX = 0.f; } if( boxifyEnd ) @@ -1767,6 +1921,9 @@ void Controller::Impl::RepositionSelectionHandles() firstSelectionBoxLineInfo.lineOffset, mVisualModel->mControlSize.width, firstSelectionBoxLineInfo.lineOffset + firstSelectionBoxLineInfo.lineHeight ); + + // Update the size of the highlighted text. + maxHighlightX = mVisualModel->mControlSize.width; } // Boxify the central lines. @@ -1789,6 +1946,10 @@ void Controller::Impl::RepositionSelectionHandles() mVisualModel->mControlSize.width, info.lineOffset + info.lineHeight ); } + + // Update the size of the highlighted text. + minHighlightX = 0.f; + maxHighlightX = mVisualModel->mControlSize.width; } // Boxify the last line. @@ -1805,6 +1966,9 @@ void Controller::Impl::RepositionSelectionHandles() lastSelectionBoxLineInfo.lineOffset, lastSelectionBoxLineInfo.minX, lastSelectionBoxLineInfo.lineOffset + lastSelectionBoxLineInfo.lineHeight ); + + // Update the size of the highlighted text. + minHighlightX = 0.f; } if( boxifyEnd ) @@ -1814,30 +1978,46 @@ void Controller::Impl::RepositionSelectionHandles() lastSelectionBoxLineInfo.lineOffset, mVisualModel->mControlSize.width, lastSelectionBoxLineInfo.lineOffset + lastSelectionBoxLineInfo.lineHeight ); + + // Update the size of the highlighted text. + maxHighlightX = mVisualModel->mControlSize.width; } } + // Sets the highlight's size and position. In decorator's coords. + // The highlight's height has been calculated above (before 'boxifying' the highlight). + highLightSize.width = maxHighlightX - minHighlightX; + + highLightPosition.x = minHighlightX; + const SelectionBoxInfo& firstSelectionBoxLineInfo = *( selectionBoxLinesInfo.Begin() ); + highLightPosition.y = firstSelectionBoxLineInfo.lineOffset; + + mEventData->mDecorator->SetHighLightBox( highLightPosition, highLightSize ); + + if( !mEventData->mDecorator->IsSmoothHandlePanEnabled() ) + { + CursorInfo primaryCursorInfo; + GetCursorPosition( mEventData->mLeftSelectionPosition, + primaryCursorInfo ); - CursorInfo primaryCursorInfo; - GetCursorPosition( mEventData->mLeftSelectionPosition, - primaryCursorInfo ); + const Vector2 primaryPosition = primaryCursorInfo.primaryPosition + mScrollPosition; - CursorInfo secondaryCursorInfo; - GetCursorPosition( mEventData->mRightSelectionPosition, - secondaryCursorInfo ); + mEventData->mDecorator->SetPosition( LEFT_SELECTION_HANDLE, + primaryPosition.x, + primaryCursorInfo.lineOffset + mScrollPosition.y, + primaryCursorInfo.lineHeight ); - const Vector2 primaryPosition = primaryCursorInfo.primaryPosition + mScrollPosition; - const Vector2 secondaryPosition = secondaryCursorInfo.primaryPosition + mScrollPosition; + CursorInfo secondaryCursorInfo; + GetCursorPosition( mEventData->mRightSelectionPosition, + secondaryCursorInfo ); - mEventData->mDecorator->SetPosition( LEFT_SELECTION_HANDLE, - primaryPosition.x, - primaryCursorInfo.lineOffset + mScrollPosition.y, - primaryCursorInfo.lineHeight ); + const Vector2 secondaryPosition = secondaryCursorInfo.primaryPosition + mScrollPosition; - mEventData->mDecorator->SetPosition( RIGHT_SELECTION_HANDLE, - secondaryPosition.x, - secondaryCursorInfo.lineOffset + mScrollPosition.y, - secondaryCursorInfo.lineHeight ); + mEventData->mDecorator->SetPosition( RIGHT_SELECTION_HANDLE, + secondaryPosition.x, + secondaryCursorInfo.lineOffset + mScrollPosition.y, + secondaryCursorInfo.lineHeight ); + } // Cursor to be positioned at end of selection so if selection interrupted and edit mode restarted the cursor will be at end of selection mEventData->mPrimaryCursorPosition = ( indicesSwapped ) ? mEventData->mLeftSelectionPosition : mEventData->mRightSelectionPosition; @@ -1872,24 +2052,40 @@ void Controller::Impl::RepositionSelectionHandles( float visualX, float visualY // Find which word was selected CharacterIndex selectionStart( 0 ); CharacterIndex selectionEnd( 0 ); - FindSelectionIndices( mVisualModel, - mLogicalModel, - mMetrics, - visualX, - visualY, - selectionStart, - selectionEnd ); + const bool indicesFound = FindSelectionIndices( mVisualModel, + mLogicalModel, + mMetrics, + visualX, + visualY, + selectionStart, + selectionEnd ); DALI_LOG_INFO( gLogFilter, Debug::Verbose, "%p selectionStart %d selectionEnd %d\n", this, selectionStart, selectionEnd ); - if( selectionStart == selectionEnd ) + if( indicesFound ) { - ChangeState( EventData::EDITING ); - // Nothing to select. i.e. a white space, out of bounds - return; + ChangeState( EventData::SELECTING ); + + mEventData->mLeftSelectionPosition = selectionStart; + mEventData->mRightSelectionPosition = selectionEnd; + + mEventData->mUpdateLeftSelectionPosition = true; + mEventData->mUpdateRightSelectionPosition = true; + mEventData->mUpdateHighlightBox = true; + + mEventData->mScrollAfterUpdatePosition = ( mEventData->mLeftSelectionPosition != mEventData->mRightSelectionPosition ); } + else + { + // Nothing to select. i.e. a white space, out of bounds + ChangeState( EventData::EDITING ); + + mEventData->mPrimaryCursorPosition = selectionEnd; - mEventData->mLeftSelectionPosition = selectionStart; - mEventData->mRightSelectionPosition = selectionEnd; + mEventData->mUpdateCursorPosition = true; + mEventData->mUpdateGrabHandlePosition = true; + mEventData->mScrollAfterUpdatePosition = true; + mEventData->mUpdateInputStyle = true; + } } void Controller::Impl::SetPopupButtons() @@ -2219,6 +2415,9 @@ CharacterIndex Controller::Impl::CalculateNewCursorIndex( CharacterIndex index ) cursorIndex += numberOfCharacters; } + // Will update the cursor hook position. + mEventData->mUpdateCursorHookPosition = true; + return cursorIndex; } @@ -2242,11 +2441,14 @@ void Controller::Impl::UpdateCursorPosition( const CursorInfo& cursorInfo ) cursorInfo.lineHeight ); DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Primary cursor position: %f,%f\n", cursorPosition.x, cursorPosition.y ); - // Sets the grab handle position. - mEventData->mDecorator->SetPosition( GRAB_HANDLE, - cursorPosition.x, - cursorInfo.lineOffset + mScrollPosition.y, - cursorInfo.lineHeight ); + if( mEventData->mUpdateGrabHandlePosition ) + { + // Sets the grab handle position. + mEventData->mDecorator->SetPosition( GRAB_HANDLE, + cursorPosition.x, + cursorInfo.lineOffset + mScrollPosition.y, + cursorInfo.lineHeight ); + } if( cursorInfo.isSecondaryCursor ) { @@ -2301,13 +2503,13 @@ void Controller::Impl::UpdateSelectionHandle( HandleType handleType, mEventData->mAllTextSelected = ( startOfSelection == 0 ) && ( endOfSelection == mLogicalModel->mText.Count() ); } -void Controller::Impl::ClampHorizontalScroll( const Vector2& actualSize ) +void Controller::Impl::ClampHorizontalScroll( const Vector2& layoutSize ) { // Clamp between -space & 0. - if( actualSize.width > mVisualModel->mControlSize.width ) + if( layoutSize.width > mVisualModel->mControlSize.width ) { - const float space = ( actualSize.width - mVisualModel->mControlSize.width ); + const float space = ( layoutSize.width - mVisualModel->mControlSize.width ); mScrollPosition.x = ( mScrollPosition.x < -space ) ? -space : mScrollPosition.x; mScrollPosition.x = ( mScrollPosition.x > 0.f ) ? 0.f : mScrollPosition.x; @@ -2319,12 +2521,12 @@ void Controller::Impl::ClampHorizontalScroll( const Vector2& actualSize ) } } -void Controller::Impl::ClampVerticalScroll( const Vector2& actualSize ) +void Controller::Impl::ClampVerticalScroll( const Vector2& layoutSize ) { // Clamp between -space & 0. - if( actualSize.height > mVisualModel->mControlSize.height ) + if( layoutSize.height > mVisualModel->mControlSize.height ) { - const float space = ( actualSize.height - mVisualModel->mControlSize.height ); + const float space = ( layoutSize.height - mVisualModel->mControlSize.height ); mScrollPosition.y = ( mScrollPosition.y < -space ) ? -space : mScrollPosition.y; mScrollPosition.y = ( mScrollPosition.y > 0.f ) ? 0.f : mScrollPosition.y; @@ -2336,24 +2538,37 @@ void Controller::Impl::ClampVerticalScroll( const Vector2& actualSize ) } } -void Controller::Impl::ScrollToMakePositionVisible( const Vector2& position ) +void Controller::Impl::ScrollToMakePositionVisible( const Vector2& position, float lineHeight ) { - const float cursorWidth = mEventData->mDecorator ? mEventData->mDecorator->GetCursorWidth() : 0.f; + const float cursorWidth = mEventData->mDecorator ? static_cast( mEventData->mDecorator->GetCursorWidth() ) : 0.f; // position is in actor's coords. - const float positionEnd = position.x + cursorWidth; + const float positionEndX = position.x + cursorWidth; + const float positionEndY = position.y + lineHeight; // Transform the position to decorator coords. - const float decoratorPositionBegin = position.x + mScrollPosition.x; - const float decoratorPositionEnd = positionEnd + mScrollPosition.x; + const float decoratorPositionBeginX = position.x + mScrollPosition.x; + const float decoratorPositionEndX = positionEndX + mScrollPosition.x; - if( decoratorPositionBegin < 0.f ) + const float decoratorPositionBeginY = position.y + mScrollPosition.y; + const float decoratorPositionEndY = positionEndY + mScrollPosition.y; + + if( decoratorPositionBeginX < 0.f ) { mScrollPosition.x = -position.x; } - else if( decoratorPositionEnd > mVisualModel->mControlSize.width ) + else if( decoratorPositionEndX > mVisualModel->mControlSize.width ) + { + mScrollPosition.x = mVisualModel->mControlSize.width - positionEndX; + } + + if( decoratorPositionBeginY < 0.f ) + { + mScrollPosition.y = -position.y; + } + else if( decoratorPositionEndY > mVisualModel->mControlSize.height ) { - mScrollPosition.x = mVisualModel->mControlSize.width - positionEnd; + mScrollPosition.y = mVisualModel->mControlSize.height - positionEndY; } } @@ -2364,11 +2579,13 @@ void Controller::Impl::ScrollTextToMatchCursor( const CursorInfo& cursorInfo ) // Calculate the offset to match the cursor position before the character was deleted. mScrollPosition.x = currentCursorPosition.x - cursorInfo.primaryPosition.x; + mScrollPosition.y = currentCursorPosition.y - cursorInfo.lineOffset; ClampHorizontalScroll( mVisualModel->GetLayoutSize() ); + ClampVerticalScroll( mVisualModel->GetLayoutSize() ); // Makes the new cursor position visible if needed. - ScrollToMakePositionVisible( cursorInfo.primaryPosition ); + ScrollToMakePositionVisible( cursorInfo.primaryPosition, cursorInfo.lineHeight ); } void Controller::Impl::RequestRelayout() diff --git a/dali-toolkit/internal/text/text-controller-impl.h b/dali-toolkit/internal/text/text-controller-impl.h index 003aec5..68659b6 100644 --- a/dali-toolkit/internal/text/text-controller-impl.h +++ b/dali-toolkit/internal/text/text-controller-impl.h @@ -126,6 +126,8 @@ struct EventData CharacterIndex mPreEditStartPosition; ///< Used to remove the pre-edit text if necessary. Length mPreEditLength; ///< Used to remove the pre-edit text if necessary. + float mCursorHookPositionX; ///< Used to move the cursor with the keys or when scrolling the text vertically with the handles. + bool mIsShowingPlaceholderText : 1; ///< True if the place-holder text is being displayed. bool mPreEditFlag : 1; ///< True if the model contains text in pre-edit state. bool mDecoratorUpdated : 1; ///< True if the decorator was updated during event processing. @@ -133,11 +135,12 @@ struct EventData bool mGrabHandleEnabled : 1; ///< True if grab handle is enabled. bool mGrabHandlePopupEnabled : 1; ///< True if the grab handle popu-up should be shown. bool mSelectionEnabled : 1; ///< True if selection handles, highlight etc. are enabled. - bool mHorizontalScrollingEnabled : 1; ///< True if horizontal scrolling is enabled. - bool mVerticalScrollingEnabled : 1; ///< True if vertical scrolling is enabled. + bool mUpdateCursorHookPosition : 1; ///< True if the cursor hook position must be updated. Used to move the cursor with the keys 'up' and 'down'. bool mUpdateCursorPosition : 1; ///< True if the visual position of the cursor must be recalculated. + bool mUpdateGrabHandlePosition : 1; ///< True if the visual position of the grab handle must be recalculated. bool mUpdateLeftSelectionPosition : 1; ///< True if the visual position of the left selection handle must be recalculated. bool mUpdateRightSelectionPosition : 1; ///< True if the visual position of the right selection handle must be recalculated. + bool mUpdateHighlightBox : 1; ///< True if the text selection high light box must be updated. bool mScrollAfterUpdatePosition : 1; ///< Whether to scroll after the cursor position is updated. bool mScrollAfterDelete : 1; ///< Whether to scroll after delete characters. bool mAllTextSelected : 1; ///< True if the selection handles are selecting all the text. @@ -630,16 +633,16 @@ struct Controller::Impl /** * @biref Clamps the horizontal scrolling to get the control always filled with text. * - * @param[in] actualSize The size of the laid out text. + * @param[in] layoutSize The size of the laid out text. */ - void ClampHorizontalScroll( const Vector2& actualSize ); + void ClampHorizontalScroll( const Vector2& layoutSize ); /** * @biref Clamps the vertical scrolling to get the control always filled with text. * - * @param[in] actualSize The size of the laid out text. + * @param[in] layoutSize The size of the laid out text. */ - void ClampVerticalScroll( const Vector2& actualSize ); + void ClampVerticalScroll( const Vector2& layoutSize ); /** * @brief Scrolls the text to make a position visible. @@ -647,11 +650,12 @@ struct Controller::Impl * @pre mEventData must not be NULL. (there is a text-input or selection capabilities). * * @param[in] position A position in text coords. + * @param[in] lineHeight The line height for the given position. * * This method is called after inserting text, moving the cursor with the grab handle or the keypad, * or moving the selection handles. */ - void ScrollToMakePositionVisible( const Vector2& position ); + void ScrollToMakePositionVisible( const Vector2& position, float lineHeight ); /** * @brief Scrolls the text to make the cursor visible. diff --git a/dali-toolkit/internal/text/text-controller.cpp b/dali-toolkit/internal/text/text-controller.cpp index 9e1d0dc..643c8b8 100644 --- a/dali-toolkit/internal/text/text-controller.cpp +++ b/dali-toolkit/internal/text/text-controller.cpp @@ -93,6 +93,7 @@ FontDescriptionRun& UpdateSelectionFontStyleRun( EventData* eventData, // Recalculate the selection highlight as the metrics may have changed. eventData->mUpdateLeftSelectionPosition = true; eventData->mUpdateRightSelectionPosition = true; + eventData->mUpdateHighlightBox = true; return fontDescriptionRun; } @@ -143,7 +144,7 @@ void Controller::SetAutoScrollEnabled( bool enable ) mImpl->mOperationsPending = static_cast( mImpl->mOperationsPending | LAYOUT | ALIGN | - UPDATE_ACTUAL_SIZE | + UPDATE_LAYOUT_SIZE | UPDATE_DIRECTION | REORDER ); @@ -154,7 +155,7 @@ void Controller::SetAutoScrollEnabled( bool enable ) mImpl->mOperationsPending = static_cast( mImpl->mOperationsPending | LAYOUT | ALIGN | - UPDATE_ACTUAL_SIZE | + UPDATE_LAYOUT_SIZE | REORDER ); } @@ -193,6 +194,69 @@ float Controller::GetAutoScrollLineAlignment() const return offset; } +void Controller::SetHorizontalScrollEnabled( bool enable ) +{ + if( ( NULL != mImpl->mEventData ) && + mImpl->mEventData->mDecorator ) + { + mImpl->mEventData->mDecorator->SetHorizontalScrollEnabled( enable ); + } +} + +bool Controller::IsHorizontalScrollEnabled() const +{ + if( ( NULL != mImpl->mEventData ) && + mImpl->mEventData->mDecorator ) + { + return mImpl->mEventData->mDecorator->IsHorizontalScrollEnabled(); + } + + return false; +} + +void Controller::SetVerticalScrollEnabled( bool enable ) +{ + if( ( NULL != mImpl->mEventData ) && + mImpl->mEventData->mDecorator ) + { + if( mImpl->mEventData->mDecorator ) + { + mImpl->mEventData->mDecorator->SetVerticalScrollEnabled( enable ); + } + } +} + +bool Controller::IsVerticalScrollEnabled() const +{ + if( ( NULL != mImpl->mEventData ) && + mImpl->mEventData->mDecorator ) + { + return mImpl->mEventData->mDecorator->IsVerticalScrollEnabled(); + } + + return false; +} + +void Controller::SetSmoothHandlePanEnabled( bool enable ) +{ + if( ( NULL != mImpl->mEventData ) && + mImpl->mEventData->mDecorator ) + { + mImpl->mEventData->mDecorator->SetSmoothHandlePanEnabled( enable ); + } +} + +bool Controller::IsSmoothHandlePanEnabled() const +{ + if( ( NULL != mImpl->mEventData ) && + mImpl->mEventData->mDecorator ) + { + return mImpl->mEventData->mDecorator->IsSmoothHandlePanEnabled(); + } + + return false; +} + void Controller::SetText( const std::string& text ) { DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Controller::SetText\n" ); @@ -861,7 +925,7 @@ void Controller::SetInputFontFamily( const std::string& fontFamily ) SHAPE_TEXT | GET_GLYPH_METRICS | LAYOUT | - UPDATE_ACTUAL_SIZE | + UPDATE_LAYOUT_SIZE | REORDER | ALIGN ); mImpl->mRecalculateNaturalSize = true; @@ -874,6 +938,7 @@ void Controller::SetInputFontFamily( const std::string& fontFamily ) // As the font changes, recalculate the handle positions is needed. mImpl->mEventData->mUpdateLeftSelectionPosition = true; mImpl->mEventData->mUpdateRightSelectionPosition = true; + mImpl->mEventData->mUpdateHighlightBox = true; mImpl->mEventData->mScrollAfterUpdatePosition = true; } } @@ -934,7 +999,7 @@ void Controller::SetInputFontWeight( FontWeight weight ) SHAPE_TEXT | GET_GLYPH_METRICS | LAYOUT | - UPDATE_ACTUAL_SIZE | + UPDATE_LAYOUT_SIZE | REORDER | ALIGN ); mImpl->mRecalculateNaturalSize = true; @@ -947,6 +1012,7 @@ void Controller::SetInputFontWeight( FontWeight weight ) // As the font might change, recalculate the handle positions is needed. mImpl->mEventData->mUpdateLeftSelectionPosition = true; mImpl->mEventData->mUpdateRightSelectionPosition = true; + mImpl->mEventData->mUpdateHighlightBox = true; mImpl->mEventData->mScrollAfterUpdatePosition = true; } } @@ -987,7 +1053,7 @@ void Controller::SetInputFontWidth( FontWidth width ) SHAPE_TEXT | GET_GLYPH_METRICS | LAYOUT | - UPDATE_ACTUAL_SIZE | + UPDATE_LAYOUT_SIZE | REORDER | ALIGN ); mImpl->mRecalculateNaturalSize = true; @@ -1000,6 +1066,7 @@ void Controller::SetInputFontWidth( FontWidth width ) // As the font might change, recalculate the handle positions is needed. mImpl->mEventData->mUpdateLeftSelectionPosition = true; mImpl->mEventData->mUpdateRightSelectionPosition = true; + mImpl->mEventData->mUpdateHighlightBox = true; mImpl->mEventData->mScrollAfterUpdatePosition = true; } } @@ -1040,7 +1107,7 @@ void Controller::SetInputFontSlant( FontSlant slant ) SHAPE_TEXT | GET_GLYPH_METRICS | LAYOUT | - UPDATE_ACTUAL_SIZE | + UPDATE_LAYOUT_SIZE | REORDER | ALIGN ); mImpl->mRecalculateNaturalSize = true; @@ -1053,6 +1120,7 @@ void Controller::SetInputFontSlant( FontSlant slant ) // As the font might change, recalculate the handle positions is needed. mImpl->mEventData->mUpdateLeftSelectionPosition = true; mImpl->mEventData->mUpdateRightSelectionPosition = true; + mImpl->mEventData->mUpdateHighlightBox = true; mImpl->mEventData->mScrollAfterUpdatePosition = true; } } @@ -1092,7 +1160,7 @@ void Controller::SetInputFontPointSize( float size ) SHAPE_TEXT | GET_GLYPH_METRICS | LAYOUT | - UPDATE_ACTUAL_SIZE | + UPDATE_LAYOUT_SIZE | REORDER | ALIGN ); mImpl->mRecalculateNaturalSize = true; @@ -1105,6 +1173,7 @@ void Controller::SetInputFontPointSize( float size ) // As the font might change, recalculate the handle positions is needed. mImpl->mEventData->mUpdateLeftSelectionPosition = true; mImpl->mEventData->mUpdateRightSelectionPosition = true; + mImpl->mEventData->mUpdateHighlightBox = true; mImpl->mEventData->mScrollAfterUpdatePosition = true; } } @@ -1413,7 +1482,7 @@ Controller::UpdateTextType Controller::Relayout( const Size& size ) mImpl->mOperationsPending = static_cast( mImpl->mOperationsPending | LAYOUT | ALIGN | - UPDATE_ACTUAL_SIZE | + UPDATE_LAYOUT_SIZE | REORDER ); // Set the update info to relayout the whole text. mImpl->mTextUpdateInfo.mFullRelayoutNeeded = true; @@ -1636,6 +1705,9 @@ bool Controller::DoRelayout( const Size& size, const CharacterIndex startIndex = mImpl->mTextUpdateInfo.mParagraphCharacterIndex; const Length requestedNumberOfCharacters = mImpl->mTextUpdateInfo.mRequestedNumberOfCharacters; + // Get the current layout size. + layoutSize = mImpl->mVisualModel->GetLayoutSize(); + if( NO_OPERATION != ( LAYOUT & operations ) ) { DALI_LOG_INFO( gLogFilter, Debug::Verbose, "-->Controller::DoRelayout LAYOUT & operations\n"); @@ -1657,7 +1729,7 @@ bool Controller::DoRelayout( const Size& size, if( 0u == totalNumberOfGlyphs ) { - if( NO_OPERATION != ( UPDATE_ACTUAL_SIZE & operations ) ) + if( NO_OPERATION != ( UPDATE_LAYOUT_SIZE & operations ) ) { mImpl->mVisualModel->SetLayoutSize( Size::ZERO ); } @@ -1703,14 +1775,18 @@ bool Controller::DoRelayout( const Size& size, layoutParameters.estimatedNumberOfLines = mImpl->mTextUpdateInfo.mEstimatedNumberOfLines; // Update the visual model. + Size newLayoutSize; viewUpdated = mImpl->mLayoutEngine.LayoutText( layoutParameters, glyphPositions, mImpl->mVisualModel->mLines, - layoutSize ); + newLayoutSize ); + viewUpdated = viewUpdated || ( newLayoutSize != layoutSize ); if( viewUpdated ) { + layoutSize = newLayoutSize; + if ( NO_OPERATION != ( UPDATE_DIRECTION & operations ) ) { mImpl->mAutoScrollDirectionRTL = false; @@ -1757,8 +1833,8 @@ bool Controller::DoRelayout( const Size& size, } } // REORDER - // Sets the actual size. - if( NO_OPERATION != ( UPDATE_ACTUAL_SIZE & operations ) ) + // Sets the layout size. + if( NO_OPERATION != ( UPDATE_LAYOUT_SIZE & operations ) ) { mImpl->mVisualModel->SetLayoutSize( layoutSize ); } @@ -1767,10 +1843,6 @@ bool Controller::DoRelayout( const Size& size, // Store the size used to layout the text. mImpl->mVisualModel->mControlSize = size; } - else - { - layoutSize = mImpl->mVisualModel->GetLayoutSize(); - } if( NO_OPERATION != ( ALIGN & operations ) ) { @@ -1804,7 +1876,7 @@ void Controller::SetMultiLineEnabled( bool enable ) // Set the flags to redo the layout operations const OperationsMask layoutOperations = static_cast( LAYOUT | - UPDATE_ACTUAL_SIZE | + UPDATE_LAYOUT_SIZE | ALIGN | REORDER ); @@ -2313,6 +2385,7 @@ void Controller::TapEvent( unsigned int tapCount, float x, float y ) } else { + // Show cursor and grabhandle on first tap, this matches the behaviour of tapping when already editing mImpl->ChangeState( EventData::EDITING_WITH_GRAB_HANDLE ); } relayoutNeeded = true; @@ -2363,7 +2436,6 @@ void Controller::TapEvent( unsigned int tapCount, float x, float y ) } void Controller::PanEvent( Gesture::State state, const Vector2& displacement ) - // Show cursor and grabhandle on first tap, this matches the behaviour of tapping when already editing { DALI_ASSERT_DEBUG( mImpl->mEventData && "Unexpected PanEvent" ); @@ -2425,8 +2497,6 @@ void Controller::SelectEvent( float x, float y, bool selectAll ) if( NULL != mImpl->mEventData ) { - mImpl->ChangeState( EventData::SELECTING ); - if( selectAll ) { Event event( Event::SELECT_ALL ); @@ -2854,7 +2924,7 @@ void Controller::ClearFontData() SHAPE_TEXT | GET_GLYPH_METRICS | LAYOUT | - UPDATE_ACTUAL_SIZE | + UPDATE_LAYOUT_SIZE | REORDER | ALIGN ); } diff --git a/dali-toolkit/internal/text/text-controller.h b/dali-toolkit/internal/text/text-controller.h index 8517ca5..ad5c09a 100644 --- a/dali-toolkit/internal/text/text-controller.h +++ b/dali-toolkit/internal/text/text-controller.h @@ -82,7 +82,7 @@ public: SHAPE_TEXT = 0x0040, GET_GLYPH_METRICS = 0x0080, LAYOUT = 0x0100, - UPDATE_ACTUAL_SIZE = 0x0200, + UPDATE_LAYOUT_SIZE = 0x0200, REORDER = 0x0400, ALIGN = 0x0800, COLOR = 0x1000, @@ -188,6 +188,48 @@ public: float GetAutoScrollLineAlignment() const; /** + * @brief Enables the horizontal scrolling. + * + * @param[in] enable Whether to enable the horizontal scrolling. + */ + void SetHorizontalScrollEnabled( bool enable ); + + /** + * @brief Retrieves whether the horizontal scrolling is enabled. + * + * @return @e true if the horizontal scrolling is enabled, otherwise it returns @e false. + */ + bool IsHorizontalScrollEnabled() const; + + /** + * @brief Enables the vertical scrolling. + * + * @param[in] enable Whether to enable the vertical scrolling. + */ + void SetVerticalScrollEnabled( bool enable ); + + /** + * @brief Retrieves whether the verticall scrolling is enabled. + * + * @return @e true if the vertical scrolling is enabled, otherwise it returns @e false. + */ + bool IsVerticalScrollEnabled() const; + + /** + * @brief Enables the smooth handle panning. + * + * @param[in] enable Whether to enable the smooth handle panning. + */ + void SetSmoothHandlePanEnabled( bool enable ); + + /** + * @brief Retrieves whether the smooth handle panning is enabled. + * + * @return @e true if the smooth handle panning is enabled. + */ + bool IsSmoothHandlePanEnabled() const; + + /** * @brief Replaces any text previously set. * * @note This will be converted into UTF-32 when stored in the text model. diff --git a/dali-toolkit/internal/text/text-scroller.cpp b/dali-toolkit/internal/text/text-scroller.cpp index 605e5b1..d1a5d2f 100644 --- a/dali-toolkit/internal/text/text-scroller.cpp +++ b/dali-toolkit/internal/text/text-scroller.cpp @@ -19,15 +19,15 @@ #include // EXTERNAL INCLUDES -#include -#include -#include -#include -#include -#include #include #include #include +#include +#include +#include +#include +#include +#include // INTERNAL INCLUDES #include diff --git a/dali-toolkit/internal/transition-effects/cube-transition-effect-impl.h b/dali-toolkit/internal/transition-effects/cube-transition-effect-impl.h index 8d1760e..5eda6b2 100644 --- a/dali-toolkit/internal/transition-effects/cube-transition-effect-impl.h +++ b/dali-toolkit/internal/transition-effects/cube-transition-effect-impl.h @@ -1,8 +1,8 @@ -#ifndef __DALI_TOOLKIT_INTERNAL_CUBE_TRANSITION_EFFECT_H__ -#define __DALI_TOOLKIT_INTERNAL_CUBE_TRANSITION_EFFECT_H__ +#ifndef DALI_TOOLKIT_INTERNAL_CUBE_TRANSITION_EFFECT_H +#define DALI_TOOLKIT_INTERNAL_CUBE_TRANSITION_EFFECT_H /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ // EXTERNAL INCLUDES #include -#include +#include // INTERNAL INCLUDES #include @@ -262,4 +262,4 @@ inline const Internal::CubeTransitionEffect& GetImpl(const Dali::Toolkit::CubeTr } // namespace Dali -#endif /* __DALI_TOOLKIT_INTERNAL_CUBE_TRANSITION_EFFECT_H__ */ +#endif // DALI_TOOLKIT_INTERNAL_CUBE_TRANSITION_EFFECT_H diff --git a/dali-toolkit/public-api/controls/control-impl.cpp b/dali-toolkit/public-api/controls/control-impl.cpp index 0a2c3c8..e47001a 100644 --- a/dali-toolkit/public-api/controls/control-impl.cpp +++ b/dali-toolkit/public-api/controls/control-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,9 +25,9 @@ #include #include #include -#include #include -#include +#include +#include #include #include diff --git a/dali-toolkit/public-api/controls/control-impl.h b/dali-toolkit/public-api/controls/control-impl.h index 4779d58..2353cea 100644 --- a/dali-toolkit/public-api/controls/control-impl.h +++ b/dali-toolkit/public-api/controls/control-impl.h @@ -1,8 +1,8 @@ -#ifndef __DALI_TOOLKIT_CONTROL_IMPL_H__ -#define __DALI_TOOLKIT_CONTROL_IMPL_H__ +#ifndef DALI_TOOLKIT_CONTROL_IMPL_H +#define DALI_TOOLKIT_CONTROL_IMPL_H /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -698,4 +698,4 @@ DALI_IMPORT_API const Internal::Control& GetImplementation( const Dali::Toolkit: } // namespace Dali -#endif // __DALI_TOOLKIT_CONTROL_IMPL_H__ +#endif // DALI_TOOLKIT_CONTROL_IMPL_H diff --git a/dali-toolkit/public-api/dali-toolkit-version.cpp b/dali-toolkit/public-api/dali-toolkit-version.cpp index d087913..0f27e3b 100644 --- a/dali-toolkit/public-api/dali-toolkit-version.cpp +++ b/dali-toolkit/public-api/dali-toolkit-version.cpp @@ -31,7 +31,7 @@ namespace Toolkit const unsigned int TOOLKIT_MAJOR_VERSION = 1; const unsigned int TOOLKIT_MINOR_VERSION = 1; -const unsigned int TOOLKIT_MICRO_VERSION = 42; +const unsigned int TOOLKIT_MICRO_VERSION = 43; const char * const TOOLKIT_BUILD_DATE = __DATE__ " " __TIME__; #ifdef DEBUG_ENABLED diff --git a/dali-toolkit/styles/480x800/dali-toolkit-default-theme.json b/dali-toolkit/styles/480x800/dali-toolkit-default-theme.json index 725a71a..87c22af 100644 --- a/dali-toolkit/styles/480x800/dali-toolkit-default-theme.json +++ b/dali-toolkit/styles/480x800/dali-toolkit-default-theme.json @@ -98,7 +98,7 @@ "popupIconColor":[1.0,1.0,1.0,1.0], "popupPressedColor":[0.24,0.72,0.8,0.11], "background": { - "rendererType": "image", + "rendererType": "IMAGE", "url": "{DALI_IMAGE_DIR}selection-popup-bg.9.png" }, "popupFadeInDuration":0.25, diff --git a/dali-toolkit/styles/720x1280/dali-toolkit-default-theme.json b/dali-toolkit/styles/720x1280/dali-toolkit-default-theme.json index 3297e51..029dcbd 100644 --- a/dali-toolkit/styles/720x1280/dali-toolkit-default-theme.json +++ b/dali-toolkit/styles/720x1280/dali-toolkit-default-theme.json @@ -98,7 +98,7 @@ "popupIconColor":[1.0,1.0,1.0,1.0], "popupPressedColor":[0.24,0.72,0.8,0.11], "background": { - "rendererType": "image", + "rendererType": "IMAGE", "url": "{DALI_IMAGE_DIR}selection-popup-bg.9.png" }, "popupFadeInDuration":0.25, diff --git a/docs/content/example-code/properties.cpp b/docs/content/example-code/properties.cpp index 300d276..69248b9 100644 --- a/docs/content/example-code/properties.cpp +++ b/docs/content/example-code/properties.cpp @@ -66,7 +66,7 @@ public: // Set another property to set the image-map Property::Map imageMap; - imageMap[ "rendererType" ] = "image"; + imageMap[ "rendererType" ] = "IMAGE"; imageMap[ "url" ] = IMAGE_CARDS; imageMap[ "desiredWidth" ] = 100; imageMap[ "desiredHeight" ] = 100; diff --git a/docs/content/images/renderers/bevelled-cube-high.png b/docs/content/images/renderers/bevelled-cube-high.png new file mode 100644 index 0000000..d6676db Binary files /dev/null and b/docs/content/images/renderers/bevelled-cube-high.png differ diff --git a/docs/content/images/renderers/bevelled-cube-low.png b/docs/content/images/renderers/bevelled-cube-low.png new file mode 100644 index 0000000..d76c836 Binary files /dev/null and b/docs/content/images/renderers/bevelled-cube-low.png differ diff --git a/docs/content/images/renderers/cone.png b/docs/content/images/renderers/cone.png new file mode 100644 index 0000000..6437a0e Binary files /dev/null and b/docs/content/images/renderers/cone.png differ diff --git a/docs/content/images/renderers/conical-frustrum.png b/docs/content/images/renderers/conical-frustrum.png new file mode 100644 index 0000000..000c74b Binary files /dev/null and b/docs/content/images/renderers/conical-frustrum.png differ diff --git a/docs/content/images/renderers/cube.png b/docs/content/images/renderers/cube.png new file mode 100644 index 0000000..af04b30 Binary files /dev/null and b/docs/content/images/renderers/cube.png differ diff --git a/docs/content/images/renderers/cylinder.png b/docs/content/images/renderers/cylinder.png new file mode 100644 index 0000000..d4efd00 Binary files /dev/null and b/docs/content/images/renderers/cylinder.png differ diff --git a/docs/content/images/renderers/octahedron.png b/docs/content/images/renderers/octahedron.png new file mode 100644 index 0000000..9ad5704 Binary files /dev/null and b/docs/content/images/renderers/octahedron.png differ diff --git a/docs/content/images/renderers/slices.png b/docs/content/images/renderers/slices.png new file mode 100644 index 0000000..8747577 Binary files /dev/null and b/docs/content/images/renderers/slices.png differ diff --git a/docs/content/images/renderers/sphere.png b/docs/content/images/renderers/sphere.png new file mode 100644 index 0000000..3efd4a0 Binary files /dev/null and b/docs/content/images/renderers/sphere.png differ diff --git a/docs/content/images/renderers/stacks.png b/docs/content/images/renderers/stacks.png new file mode 100644 index 0000000..fb3cb84 Binary files /dev/null and b/docs/content/images/renderers/stacks.png differ diff --git a/docs/content/programming-guide/background.h b/docs/content/programming-guide/background.h index c157a18..ef2d933 100644 --- a/docs/content/programming-guide/background.h +++ b/docs/content/programming-guide/background.h @@ -62,7 +62,7 @@ then the above image will look like: The background can be set to use a specified renderer, e.g the border renderer @code Property::Map renderer; -renderer.Insert("rendererType","border"); +renderer.Insert("rendererType","BORDER"); renderer.Insert("borderColor",COLOR::RED); renderer.Insert("borderSize",20.f); diff --git a/docs/content/programming-guide/image-view.h b/docs/content/programming-guide/image-view.h index 9b18dfc..27a8574 100644 --- a/docs/content/programming-guide/image-view.h +++ b/docs/content/programming-guide/image-view.h @@ -47,7 +47,7 @@ * * @code * Property::Map renderer; - * renderer.Insert("rendererType","border"); + * renderer.Insert("rendererType","BORDER"); * renderer.Insert("borderColor",COLOR::RED); * renderer.Insert("borderSize",20.f); * diff --git a/docs/content/programming-guide/properties.h b/docs/content/programming-guide/properties.h index 1033b5f..cc15da1 100644 --- a/docs/content/programming-guide/properties.h +++ b/docs/content/programming-guide/properties.h @@ -231,7 +231,7 @@ imageView.parentOrigin = dali.CENTER; // Set an image view property imageView.image = { - "rendererType" : "image", + "rendererType" : "IMAGE", "url": "images/icon-0.png", "desiredWidth" : 100, "desiredHeight" : 100 @@ -260,7 +260,7 @@ This is a basic example of a button defined in JSON by setting the default prope "position": [0, 0, 0], "image": { - "rendererType" : "image", + "rendererType" : "IMAGE", "url" : "images/icon-0.png", "desiredWidth" : 100, "desiredHeight" : 100 diff --git a/docs/content/shared-javascript-and-cpp-documentation/control-renderers.md b/docs/content/shared-javascript-and-cpp-documentation/control-renderers.md index 6930b03..010a385 100644 --- a/docs/content/shared-javascript-and-cpp-documentation/control-renderers.md +++ b/docs/content/shared-javascript-and-cpp-documentation/control-renderers.md @@ -15,6 +15,7 @@ DALi provides the following renderers: + [Image](@ref image-renderers) + [Border](@ref border-renderer) + [Mesh](@ref mesh-renderer) + + [Primitive](@ref primitive-renderer) Controls can provide properties that allow users to specify the renderer type. Setting renderer properties are done via a property map. @@ -31,7 +32,7 @@ Renders a solid color to the control's quad. ### Properties Supported -**RendererType:** "color" +**RendererType:** "COLOR" | Property Name | Type | Required | Description | |---------------|:-------:|:--------:|---------------------------| @@ -44,7 +45,7 @@ Renders a solid color to the control's quad. Dali::Toolkit::Control control = Dali::Toolkit::Control::New(); Dali::Property::Map map; -map[ "rendererType" ] = "color"; +map[ "rendererType" ] = "COLOR"; map[ "mixColor" ] = Color::RED; control.SetProperty( Dali::Toolkit::Control::Property::BACKGROUND, map ); @@ -56,7 +57,7 @@ var control = new dali.Control( "Control" ); control.background = { - rendererType : "color", + rendererType : "COLOR", mixColor : dali.COLOR_RED }; ~~~ @@ -74,18 +75,18 @@ Both Linear and Radial gradients are supported. ### Properties Supported -**RendererType:** "gradient" +**RendererType:** "GRADIENT" -| Property Name | Type | Required | Description | -|--------------------------------------------------------------|:----------------:|:----------:|-------------------------------------------------------------------------| -| startPosition | VECTOR2 | For Linear | The start position of the linear gradient. | -| endPosition | VECTOR2 | For Linear | The end position of the linear gradient. | -| center | VECTOR2 | For Radial | The center point of the gradient. | -| radius | FLOAT | For Radial | The size of the radius. | -| stopOffset | ARRAY of FLOAT | No | All the stop offsets. If not supplied default is 0.0 and 1.0 | -| stopColor | ARRAY of VECTOR4 | Yes | The color at those stop offsets. At least 2 required to show a gradient | -| [gradientUnits](@ref gradient-renderer-units) | STRING | No | *objectBoundingBox* or *userSpace*. Default: *objectBoundingBox*. | -| [gradientSpreadMethod](@ref gradient-renderer-spread-method) | STRING | No | *pad*, *repeat* or *reflect*. Default: *pad* | +| Property Name | Type | Required | Description | +|------------------------------------------------------|:----------------:|:----------:|--------------------------------------------------------------------------| +| startPosition | VECTOR2 | For Linear | The start position of the linear gradient. | +| endPosition | VECTOR2 | For Linear | The end position of the linear gradient. | +| center | VECTOR2 | For Radial | The center point of the gradient. | +| radius | FLOAT | For Radial | The size of the radius. | +| stopOffset | ARRAY of FLOAT | No | All the stop offsets. If not supplied default is 0.0 and 1.0. | +| stopColor | ARRAY of VECTOR4 | Yes | The color at those stop offsets. At least 2 required to show a gradient. | +| [units](@ref gradient-renderer-units) | STRING | No | *OBJECT_BOUNDING_BOX* or *USER_SPACE*. Default: *OBJECT_BOUNDING_BOX*. | +| [spreadMethod](@ref gradient-renderer-spread-method) | STRING | No | *PAD*, *REFLECT* or *REPEAT*. Default: *PAD*. | If the *stopOffset* and *stopColor* arrays do not have the same number of elements, then the minimum of the two is used as the stop points. @@ -95,10 +96,10 @@ Defines the coordinate system for the attributes: + Start (x1, y1) and End (x2 and y2) points of a line if using a linear gradient. + Center point (cx, cy) and radius (r) of a circle if using a radial gradient. -| Value | Description | -|-------------------|------------------------------------------------------------------------------------------------------------------------------------------------| -| objectBoundingBox | *Default*. Uses the normals for the start, end & center points, i.e. top-left is (-0.5, -0.5) and bottom-right it (0.5, 0.5). | -| userSpace | Uses the user coordinates for the start, end & center points, i.e. in a 200 by 200 control, top-left is (0, 0) and bottom-right is (200, 200). | +| Value | Description | +|---------------------|------------------------------------------------------------------------------------------------------------------------------------------------| +| OBJECT_BOUNDING_BOX | *Default*. Uses the normals for the start, end & center points, i.e. top-left is (-0.5, -0.5) and bottom-right is (0.5, 0.5). | +| USER_SPACE | Uses the user coordinates for the start, end & center points, i.e. in a 200 by 200 control, top-left is (0, 0) and bottom-right is (200, 200). | ### Spread Method {#gradient-renderer-spread-method} @@ -106,9 +107,9 @@ Indicates what happens if the gradient starts or ends inside the bounds of the t | Value | Description | |---------|------------------------------------------------------------------------------------------------------| -| pad | *Default*. Uses the terminal colors of the gradient to fill the remainder of the quad. | -| reflect | Reflect the gradient pattern start-to-end, end-to-start, start-to-end etc. until the quad is filled. | -| repeat | Repeat the gradient pattern start-to-end, start-to-end, start-to-end until the quad is filled. | +| PAD | *Default*. Uses the terminal colors of the gradient to fill the remainder of the quad. | +| REFLECT | Reflect the gradient pattern start-to-end, end-to-start, start-to-end etc. until the quad is filled. | +| REPEAT | Repeat the gradient pattern start-to-end, start-to-end, start-to-end etc. until the quad is filled. | ### Usage @@ -118,7 +119,7 @@ Indicates what happens if the gradient starts or ends inside the bounds of the t Dali::Toolkit::Control control = Dali::Toolkit::Control::New(); Dali::Property::Map map; -map[ "rendererType" ] = "gradient"; +map[ "rendererType" ] = "GRADIENT"; map[ "startPosition" ] = Vector2( 0.5f, 0.5f ); map[ "endPosition" ] = Vector2( -0.5f, -0.5f ); @@ -147,7 +148,7 @@ var control = new dali.Control( "Control" ); control.background = { - rendererType : "gradient", + rendererType : "GRADIENT", startPosition : [ 0.5, 0.5 ], endPosition : [ -0.5, -0.5 ], stopOffset : [ 0.0, 0.3, 0.6, 0.8, 1.0 ], @@ -167,7 +168,7 @@ control.background = Dali::Toolkit::Control control = Dali::Toolkit::Control::New(); Dali::Property::Map map; -map[ "rendererType" ] = "gradient"; +map[ "rendererType" ] = "GRADIENT"; map[ "center" ] = Vector2( 0.5f, 0.5f ); map[ "radius" ] = 1.414f; @@ -196,7 +197,7 @@ var control = new dali.Control( "Control" ); control.background = { - rendererType : "gradient", + rendererType : "GRADIENT", center : [ 0.5, 0.5 ], radius : 1.414, stopOffset : [ 0.0, 0.3, 0.6, 0.8, 1.0 ], @@ -232,15 +233,15 @@ Renders a raster image ( jpg, png etc.) into the control's quad. #### Properties Supported -**RendererType:** "image" +**RendererType:** "IMAGE" -| Property Name | Type | Required | Description | -|--------------------|:--------:|:--------:|-------------------------------------------------------------------------------------------------------------------------------------------------| -| url | STRING | Yes | The URL of the image. | -| [fittingMode](@ref resourceimagescaling-fittingmode) | STRING | No | *SHRINK_TO_FIT*, *SCALE_TO_FILL*, *FIT_WIDTH* or *FIT_HEIGHT*. Default: *SHRINK_TO_FIT*. | -| [samplingMode](@ref resourceimagescaling-scaling) | STRING | No | *BOX*, *NEAREST*, *LINEAR*, *BOX_THEN_NEAREST*, *BOX_THEN_LINEAR*, *NO_FILTERr* or *DONT_CARE*. Default: *BOX*. | -| desiredWidth | INT | No | The desired image width. Will use actual image width if not specified. | -| desiredHeight | INT | No | The desired image height. Will use actual image height if not specified. | +| Property Name | Type | Required | Description | +|------------------------------------------------------|:--------:|:--------:|----------------------------------------------------------------------------------------------------------------| +| url | STRING | Yes | The URL of the image. | +| [fittingMode](@ref resourceimagescaling-fittingmode) | STRING | No | *SHRINK_TO_FIT*, *SCALE_TO_FILL*, *FIT_WIDTH* or *FIT_HEIGHT*. Default: *SHRINK_TO_FIT*. | +| [samplingMode](@ref resourceimagescaling-scaling) | STRING | No | *BOX*, *NEAREST*, *LINEAR*, *BOX_THEN_NEAREST*, *BOX_THEN_LINEAR*, *NO_FILTER* or *DONT_CARE*. Default: *BOX*. | +| desiredWidth | INT | No | The desired image width. Will use actual image width if not specified. | +| desiredHeight | INT | No | The desired image height. Will use actual image height if not specified. | #### Usage @@ -249,7 +250,7 @@ Renders a raster image ( jpg, png etc.) into the control's quad. Dali::Toolkit::Control control = Dali::Toolkit::Control::New(); Dali::Property::Map map; -map[ "rendererType" ] = "image"; +map[ "rendererType" ] = "IMAGE"; map[ "url" ] = "path-to-image.jpg"; control.SetProperty( Dali::Toolkit::Control::Property::BACKGROUND, map ); @@ -261,7 +262,7 @@ var control = new dali.Control( "Control" ); control.background = { - rendererType : "image", + rendererType : "IMAGE", url : "path-to-image.jpg" }; ~~~ @@ -276,7 +277,7 @@ Renders an n-patch or a 9-patch image into the control's quad. #### Properties Supported -**RendererType:** "image" +**RendererType:** "IMAGE" | Property Name | Type | Required | Description | |---------------|:-------:|:--------:|----------------------------------| @@ -291,7 +292,7 @@ Dali::Toolkit::Control control = Dali::Toolkit::Control::New(); Dali::Property::Map map; -map[ "rendererType" ] = "image"; +map[ "rendererType" ] = "IMAGE"; map[ "url" ] = "path-to-image.9.png"; control.SetProperty( Dali::Toolkit::Control::Property::BACKGROUND, map ); @@ -303,7 +304,7 @@ var control = new dali.Control( "Control" ); control.background = { - rendererType : "image", + rendererType : "IMAGE", url : "path-to-image.9.png" }; ~~~ @@ -347,7 +348,7 @@ Renders a svg image into the control's quad. #### Properties Supported -**RendererType:** "image" +**RendererType:** "IMAGE" | Property Name | Type | Required | Description | |---------------|:-------:|:--------:|----------------------------------| @@ -361,7 +362,7 @@ Dali::Toolkit::Control control = Dali::Toolkit::Control::New(); Dali::Property::Map map; -map[ "rendererType" ] = "image"; +map[ "rendererType" ] = "IMAGE"; map[ "url" ] = "path-to-image.svg"; control.SetSize( 200.f, 200.f ); @@ -374,7 +375,7 @@ var control = new dali.Control( "Control" ); control.background = { - rendererType : "image", + rendererType : "IMAGE", url : "path-to-image.svg" }; ~~~ @@ -389,7 +390,7 @@ Renders a solid color as an internal border to the control's quad. ### Properties Supported -**RendererType:** "border" +**RendererType:** "BORDER" | Property Name | Type | Required | Description | |---------------|:-------:|:--------:|--------------------------------------------------| @@ -405,7 +406,7 @@ Dali::Toolkit::Control control = Dali::Toolkit::Control::New(); Dali::Property::Map map; -map[ "rendererType" ] = "border"; +map[ "rendererType" ] = "BORDER"; map[ "borderColor" ] = Color::BLUE; map[ "borderSize" ] = 5.0f; @@ -418,7 +419,7 @@ var control = new dali.Control( "Control" ); control.background = { - rendererType : "border", + rendererType : "BORDER", borderColor : dali.COLOR_BLUE, borderSize = 5 }; @@ -435,14 +436,26 @@ Renders a mesh using a .obj file, optionally with textures provided by a mtl fil ### Properties Supported -**RendererType** "mesh" +**RendererType** "MESH" -| Property Name | Type | Required | Description | -|---------------|:-------:|:------------------:|----------------------------------------------------------------------| -| objectUrl | STRING | Yes | The location of the .obj file. | -| materialUrl | STRING | No | The location of the .mtl file. Leave blank for a textureless object. | -| texturesPath | STRING | If using material | Path to the directory textures (including gloss and normal) are stored in. | -| shaderType | STRING | No | Sets the type of shader to be used with the mesh. Note that if anything the shader requires is missing, it will use a simpler one that it can handle with what has been supplied.\n Possible values: "textureless", "diffuseTexture", "allTextures". | +| Property Name | Type | Required | Description | +|----------------------------------------------|:-------:|:------------------:|--------------------------------------------------------------------------------| +| objectUrl | STRING | Yes | The location of the ".obj" file. | +| materialUrl | STRING | No | The location of the ".mtl" file. Leave blank for a textureless object. | +| texturesPath | STRING | If using material | Path to the directory the textures (including gloss and normal) are stored in. | +| [shaderType](@ref mesh-renderer-shader-type) | STRING | No | Sets the type of shader to be used with the mesh. | + +### Shader Type {#mesh-renderer-shader-type} + +When specifying the shader type, if anything the shader requires is missing, a simpler type that can be handled with what has been supplied will be used instead. + +**Possible values:** + +| String Value | Description | +|-----------------|------------------------------------------------| +| TEXTURELESS | *Simplest*. A flat color with shading is used. | +| DIFFUSE_TEXTURE | Textured. | +| ALL_TEXTURES | Has a gloss, normal map and texture map. | ### Usage @@ -452,7 +465,7 @@ Dali::Toolkit::Control control = Dali::Toolkit::Control::New(); Dali::Property::Map map; -map[ "rendererType" ] = "mesh"; +map[ "rendererType" ] = "MESH"; map[ "objectUrl" ] = "home/models/Dino.obj"; map[ "materialUrl" ] = "home/models/Dino.mtl"; map[ "texturesPath" ] = "home/images/"; @@ -460,6 +473,134 @@ map[ "texturesPath" ] = "home/images/"; control.SetProperty( Dali::Toolkit::Control::Property::BACKGROUND, map ); ~~~ +___________________________________________________________________________________________________ + +## Primitive Renderer {#primitive-renderer} + +Renders a simple 3D shape, such as a cube or sphere. Scaled to fit the control. + +![ ](../assets/img/renderers/cube.png) +![ ](renderers/cube.png) + +### Properties Supported + +**RendererType** "PRIMITIVE" + +| Property Name | Type | Description | Default Value | Range | +|---------------------------------------|:-------:|---------------------------------------------------------------------------------|:--------------------:|:------------------------------:| +| [shape](@ref shape-details) | STRING | The specific shape to render. | "SPHERE" | [See list](@ref shape-details) | +| color | VECTOR4 | The color of the shape. | (0.5, 0.5, 0.5, 1.0) | 0.0 - 1.0 for each | +| [slices](@ref slices-details) | INT | The number of slices as you go around the shape. | 128 | 1 - 255 | +| [stacks](@ref stacks-details) | INT | The number of stacks as you go down the shape. | 128 | 1 - 255 | +| scaleTopRadius | FLOAT | The scale of the radius of the top circle of a conical frustrum. | 1.0 | ≥ 0.0 | +| scaleBottomRadius | FLOAT | The scale of the radius of the bottom circle of a conical frustrum. | 1.5 | ≥ 0.0 | +| scaleHeight | FLOAT | The scale of the height of a conic. | 3.0 | > 0.0 | +| scaleRadius | FLOAT | The scale of the radius of a cylinder. | 1.0 | > 0.0 | +| scaleDimensions | VECTOR3 | The dimensions of a cuboid. Scales in the same fashion as a 9-patch image. | (1.0, 1.0, 1.0) | > 0.0 for each | +| [bevelPercentage](@ref bevel-details) | FLOAT | Determines how bevelled the cuboid should be, based off the smallest dimension. | 0.0 (no bevel) | 0.0 - 1.0 | +| bevelSmoothness | FLOAT | Defines how smooth the bevelled edges should be. | 0.0 (sharp edges) | 0.0 - 1.0 | +| uLightPosition | VECTOR3 | The position, in stage space, of the point light that applies lighting to the model. This is based off the stage's dimensions, so using the width and height of the stage halved will correspond to the center, and using all zeroes will place the light at the upper left back corner. Note that this corresponds to a shader property, so it can be registered and set in the actor as well. | (Offset outwards from the center of the screen.) | Unlimited | + +### Shapes {#shape-details} + +There are six shapes that can be chosen, some of which are simplified specialisations of another. + +| Value | Description | Parameters | +|------------------|-----------------------------------------------------------------------------------|---------------------------------------------------------------| +| SPHERE | *Default*. | color, slices, stacks | +| CONICAL_FRUSTRUM | The area bound between two circles, i.e. a cone with the tip removed. | color, scaleTopRadius, scaleBottomRadius, scaleHeight, slices | +| CONE | Equivalent to a conical frustrum with top radius of zero. | color, scaleBottomRadius, scaleHeight, slices | +| CYLINDER | Equivalent to a conical frustrum with equal radii for the top and bottom circles. | color, scaleRadius, scaleHeight, slices | +| CUBE | Equivalent to a bevelled cube with a bevel percentage of zero. | color, scaleDimensions | +| OCTAHEDRON | Equivalent to a bevelled cube with a bevel percentage of one. | color, scaleDimensions | +| BEVELLED_CUBE | A cube/cuboid with all edges flattened to some degree. | color, scaleDimensions, bevelPercentage, bevelSmoothness | + +Examples below: + +**sphere:** + +![ ](../assets/img/renderers/sphere.png) +![ ](renderers/sphere.png) + +**conics:** + +| Frustrum | Cone | Cylinder | +|----------|------|----------| +| ![ ](../assets/img/renderers/conical-frustrum.png) ![ ](renderers/conical-frustrum.png) | ![ ](../assets/img/renderers/cone.png) ![ ](renderers/cone.png) | ![ ](../assets/img/renderers/cylinder.png) ![ ](renderers/cylinder.png) | + +### Bevel {#bevel-details} + +Bevel percentage ranges from 0.0 to 1.0. It affects the ratio of the outer face widths to the width of the overall cube, as shown: + +| 0.0 ( cube) | 0.3 | 0.7 | 1.0 (octahedron) | +|-------------|-----|-----|------------------| +| ![ ](../assets/img/renderers/cube.png) ![ ](renderers/cube.png) | ![ ](../assets/img/renderers/bevelled-cube-low.png) ![ ](renderers/bevelled-cube-low.png) | ![ ](../assets/img/renderers/bevelled-cube-high.png) ![ ](renderers/bevelled-cube-high.png) | ![ ](../assets/img/renderers/octahedron.png) ![ ](renderers/octahedron.png) | + +### Slices {#slices-details} + +For spheres and conical frustrums, 'slices' determines how many divisions there are as you go around the object. Note that spheres are rendered along the Z-axis, and so will appear rotated. + +![ ](../assets/img/renderers/slices.png) +![ ](renderers/slices.png) + +### Stacks {#stacks-details} + +For spheres, 'stacks' determines how many layers there are as you go down the object. Note that spheres are rendered along the Z-axis, and so will appear rotated. + +![ ](../assets/img/renderers/stacks.png) +![ ](renderers/stacks.png) + +### Usage + +**sphere** + +~~~{.cpp} +// C++ +Dali::Toolkit::Control control = Dali::Toolkit::Control::New(); + +Dali::Property::Map map; + +map[ "rendererType" ] = "PRIMITIVE"; +map[ "shape" ] = "SPHERE"; +map[ "color" ] = Vector4( 1.0, 0.5, 0.0, 1.0 ); + +control.SetProperty( Dali::Toolkit::Control::Property::BACKGROUND, map ); +~~~ + +**conical frustrum** + +~~~{.cpp} +// C++ +Dali::Toolkit::Control control = Dali::Toolkit::Control::New(); + +Dali::Property::Map map; + +map[ "rendererType" ] = "PRIMITIVE"; +map[ "shape" ] = "CONICAL_FRUSTRUM"; +map[ "color" ] = Vector4( 1.0, 0.5, 0.0, 1.0 ); +map[ "scaleTopRadius" ] = 1.0f; +map[ "scaleBottomRadius" ] = 1.5f; +map[ "scaleHeight" ] = 3.0f; + +control.SetProperty( Dali::Toolkit::Control::Property::BACKGROUND, map ); +~~~ + +**bevelled cube** + +~~~{.cpp} +// C++ +Dali::Toolkit::Control control = Dali::Toolkit::Control::New(); + +Dali::Property::Map map; + +map[ "rendererType" ] = "PRIMITIVE"; +map[ "shape" ] = "BEVELLED_CUBE"; +map[ "color" ] = Vector4( 1.0, 0.5, 0.0, 1.0 ); +map[ "bevelPercentage" ] = 0.4f; + +control.SetProperty( Dali::Toolkit::Control::Property::BACKGROUND, map ); +~~~ + @class _Guide_Control_Renderers */ diff --git a/node-addon/examples/scripts/item-template.json b/node-addon/examples/scripts/item-template.json index 2016ea7..2871198 100644 --- a/node-addon/examples/scripts/item-template.json +++ b/node-addon/examples/scripts/item-template.json @@ -15,7 +15,7 @@ "type":"ImageView", "image": { - "rendererType" : "image", + "rendererType" : "IMAGE", "url": "{icon_path}" }, "position":[20.0, 0.0, 0.0], @@ -59,7 +59,7 @@ "type":"ImageView", "image": { - "rendererType" : "image", + "rendererType" : "IMAGE", "url": "{icon_path}" }, "position":[0.0, -10.0, 0.0], diff --git a/node-addon/item-template.json b/node-addon/item-template.json index 2016ea7..2871198 100644 --- a/node-addon/item-template.json +++ b/node-addon/item-template.json @@ -15,7 +15,7 @@ "type":"ImageView", "image": { - "rendererType" : "image", + "rendererType" : "IMAGE", "url": "{icon_path}" }, "position":[20.0, 0.0, 0.0], @@ -59,7 +59,7 @@ "type":"ImageView", "image": { - "rendererType" : "image", + "rendererType" : "IMAGE", "url": "{icon_path}" }, "position":[0.0, -10.0, 0.0], diff --git a/packaging/dali-toolkit.spec b/packaging/dali-toolkit.spec index 3dae332..fead10f 100644 --- a/packaging/dali-toolkit.spec +++ b/packaging/dali-toolkit.spec @@ -1,6 +1,6 @@ Name: dali-toolkit Summary: The OpenGLES Canvas Core Library Toolkit -Version: 1.1.42 +Version: 1.1.43 Release: 1 Group: System/Libraries License: Apache-2.0 and BSD-2-Clause and MIT diff --git a/plugins/dali-script-v8/docs/content/animation.js b/plugins/dali-script-v8/docs/content/animation.js index fbff9bd..e5a3da4 100644 --- a/plugins/dali-script-v8/docs/content/animation.js +++ b/plugins/dali-script-v8/docs/content/animation.js @@ -190,7 +190,7 @@ var imageView = createImageView(); var shader = createColorShiftAndZoomEffect(); var image = { - "rendererType" : "image", + "rendererType" : "IMAGE", "url" : getImageDirectory()+"gallery-medium-50.jpg", "shader" : shader }; diff --git a/plugins/dali-script-v8/docs/content/image-view.js b/plugins/dali-script-v8/docs/content/image-view.js index 3b61fc2..e0b0f48 100644 --- a/plugins/dali-script-v8/docs/content/image-view.js +++ b/plugins/dali-script-v8/docs/content/image-view.js @@ -45,7 +45,7 @@ imageView.size = imageViewSize; // If not set, it will use either the natural im dali.stage.add( imageView ); var image = { - "rendererType" : "image", + "rendererType" : "IMAGE", "url" : "myImage.jpg", "desiredWidth" : desiredWidth, // The desired image width while loading (optional but preferable to set for efficiency) "desiredHeight" : desiredHeight, // The desired image height while loading (optional but preferable to set for efficiency) diff --git a/plugins/dali-script-v8/docs/content/item-factory.js b/plugins/dali-script-v8/docs/content/item-factory.js index 8f0c3ed..9643c3e 100644 --- a/plugins/dali-script-v8/docs/content/item-factory.js +++ b/plugins/dali-script-v8/docs/content/item-factory.js @@ -30,7 +30,7 @@ "type":"ImageView", "image": { - "rendererType" : "image", + "rendererType" : "IMAGE", "url": "{icon_path}" }, "position":[20.0, 0.0, 0.0], diff --git a/plugins/dali-script-v8/src/constants/constants-wrapper.cpp b/plugins/dali-script-v8/src/constants/constants-wrapper.cpp index eab1614..15252da 100644 --- a/plugins/dali-script-v8/src/constants/constants-wrapper.cpp +++ b/plugins/dali-script-v8/src/constants/constants-wrapper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,8 +33,8 @@ #include #include #include -#include -#include +#include +#include #include #include diff --git a/plugins/dali-script-v8/src/object/property-buffer-api.h b/plugins/dali-script-v8/src/object/property-buffer-api.h index 39b1707..c76607c 100644 --- a/plugins/dali-script-v8/src/object/property-buffer-api.h +++ b/plugins/dali-script-v8/src/object/property-buffer-api.h @@ -1,8 +1,8 @@ -#ifndef __DALI_V8PLUGIN_PROPERTY_BUFFER_API_H__ -#define __DALI_V8PLUGIN_PROPERTY_BUFFER_API_H__ +#ifndef DALI_V8PLUGIN_PROPERTY_BUFFER_API_H +#define DALI_V8PLUGIN_PROPERTY_BUFFER_API_H /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ // EXTERNAL INCLUDES #include -#include +#include namespace Dali @@ -61,10 +61,10 @@ namespace PropertyBufferApi */ void SetData( const v8::FunctionCallbackInfo< v8::Value >& args ); -}; // namespace PropertyBufferApi +} // namespace PropertyBufferApi } // namespace V8Plugin } // namespace Dali -#endif // header __DALI_V8PLUGIN_PROPERTY_BUFFER_API_H__ +#endif // DALI_V8PLUGIN_PROPERTY_BUFFER_API_H diff --git a/plugins/dali-script-v8/src/object/property-buffer-wrapper.h b/plugins/dali-script-v8/src/object/property-buffer-wrapper.h index 7cb8b84..914b9a9 100644 --- a/plugins/dali-script-v8/src/object/property-buffer-wrapper.h +++ b/plugins/dali-script-v8/src/object/property-buffer-wrapper.h @@ -1,8 +1,8 @@ -#ifndef __DALI_V8PLUGIN_PROPERTY_BUFFER_WRAPPER_H__ -#define __DALI_V8PLUGIN_PROPERTY_BUFFER_WRAPPER_H__ +#ifndef DALI_V8PLUGIN_PROPERTY_BUFFER_WRAPPER_H +#define DALI_V8PLUGIN_PROPERTY_BUFFER_WRAPPER_H /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ // EXTERNAL INCLUDES #include -#include +#include // INTERNAL INCLUDES #include @@ -54,7 +54,7 @@ public: */ virtual ~PropertyBufferWrapper() { - }; + } /** * @brief Creates a new PropertyBuffer wrapped inside a Javascript Object. @@ -92,4 +92,4 @@ private: } // namespace Dali -#endif // __DALI_V8PLUGIN_PROPERTY_BUFFER_WRAPPER_H__ +#endif // DALI_V8PLUGIN_PROPERTY_BUFFER_WRAPPER_H diff --git a/plugins/dali-script-v8/src/rendering/geometry-api.h b/plugins/dali-script-v8/src/rendering/geometry-api.h index 2a8778f..6b994fb 100644 --- a/plugins/dali-script-v8/src/rendering/geometry-api.h +++ b/plugins/dali-script-v8/src/rendering/geometry-api.h @@ -1,8 +1,8 @@ -#ifndef __DALI_V8PLUGIN_GEOMETRY_API_H__ -#define __DALI_V8PLUGIN_GEOMETRY_API_H__ +#ifndef DALI_V8PLUGIN_GEOMETRY_API_H +#define DALI_V8PLUGIN_GEOMETRY_API_H /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ // EXTERNAL INCLUDES #include -#include +#include namespace Dali @@ -70,4 +70,4 @@ namespace GeometryApi } // namespace Dali -#endif // header __DALI_V8PLUGIN_GEOMETRY_API_H__ +#endif // DALI_V8PLUGIN_GEOMETRY_API_H diff --git a/plugins/dali-script-v8/src/rendering/geometry-wrapper.cpp b/plugins/dali-script-v8/src/rendering/geometry-wrapper.cpp index f57abfe..e4f6498 100644 --- a/plugins/dali-script-v8/src/rendering/geometry-wrapper.cpp +++ b/plugins/dali-script-v8/src/rendering/geometry-wrapper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/plugins/dali-script-v8/src/rendering/geometry-wrapper.h b/plugins/dali-script-v8/src/rendering/geometry-wrapper.h index 6272ffc..8608d92 100644 --- a/plugins/dali-script-v8/src/rendering/geometry-wrapper.h +++ b/plugins/dali-script-v8/src/rendering/geometry-wrapper.h @@ -1,8 +1,8 @@ -#ifndef __DALI_V8PLUGIN_GEOMETRY_WRAPPER_H__ -#define __DALI_V8PLUGIN_GEOMETRY_WRAPPER_H__ +#ifndef DALI_V8PLUGIN_GEOMETRY_WRAPPER_H +#define DALI_V8PLUGIN_GEOMETRY_WRAPPER_H /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ // EXTERNAL INCLUDES #include -#include +#include // INTERNAL INCLUDES #include @@ -104,4 +104,4 @@ private: } // namespace Dali -#endif // __DALI_V8PLUGIN_GEOMETRY_WRAPPER_H__ +#endif // DALI_V8PLUGIN_GEOMETRY_WRAPPER_H diff --git a/plugins/dali-script-v8/src/rendering/renderer-api.h b/plugins/dali-script-v8/src/rendering/renderer-api.h index 033729d..e65d3d8 100644 --- a/plugins/dali-script-v8/src/rendering/renderer-api.h +++ b/plugins/dali-script-v8/src/rendering/renderer-api.h @@ -1,8 +1,8 @@ -#ifndef __DALI_V8PLUGIN_RENDERER_API_H__ -#define __DALI_V8PLUGIN_RENDERER_API_H__ +#ifndef DALI_V8PLUGIN_RENDERER_API_H +#define DALI_V8PLUGIN_RENDERER_API_H /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ // EXTERNAL INCLUDES #include -#include +#include namespace Dali @@ -68,4 +68,4 @@ namespace RendererApi } // namespace Dali -#endif // header __DALI_V8PLUGIN_RENDERER_API_H__ +#endif // DALI_V8PLUGIN_RENDERER_API_H diff --git a/plugins/dali-script-v8/src/rendering/renderer-wrapper.h b/plugins/dali-script-v8/src/rendering/renderer-wrapper.h index d03669a..c5e676a 100644 --- a/plugins/dali-script-v8/src/rendering/renderer-wrapper.h +++ b/plugins/dali-script-v8/src/rendering/renderer-wrapper.h @@ -1,8 +1,8 @@ -#ifndef __DALI_V8PLUGIN_RENDERER_WRAPPER_H__ -#define __DALI_V8PLUGIN_RENDERER_WRAPPER_H__ +#ifndef DALI_V8PLUGIN_RENDERER_WRAPPER_H +#define DALI_V8PLUGIN_RENDERER_WRAPPER_H /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ // EXTERNAL INCLUDES #include -#include +#include // INTERNAL INCLUDES #include @@ -104,4 +104,4 @@ private: } // namespace Dali -#endif // __DALI_V8PLUGIN_RENDERER_WRAPPER_H__ +#endif // DALI_V8PLUGIN_RENDERER_WRAPPER_H diff --git a/plugins/dali-script-v8/src/rendering/sampler-api.h b/plugins/dali-script-v8/src/rendering/sampler-api.h index 1eac960..8cb5aa9 100644 --- a/plugins/dali-script-v8/src/rendering/sampler-api.h +++ b/plugins/dali-script-v8/src/rendering/sampler-api.h @@ -1,8 +1,8 @@ -#ifndef __DALI_V8PLUGIN_SAMPLER_API_H__ -#define __DALI_V8PLUGIN_SAMPLER_API_H__ +#ifndef DALI_V8PLUGIN_SAMPLER_API_H +#define DALI_V8PLUGIN_SAMPLER_API_H /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ // EXTERNAL INCLUDES #include -#include +#include namespace Dali { @@ -64,4 +64,4 @@ namespace SamplerApi } // namespace Dali -#endif // header __DALI_V8PLUGIN_SAMPLER_API_H__ +#endif // DALI_V8PLUGIN_SAMPLER_API_H diff --git a/plugins/dali-script-v8/src/rendering/sampler-wrapper.h b/plugins/dali-script-v8/src/rendering/sampler-wrapper.h index 5f2df3c..42c6300 100644 --- a/plugins/dali-script-v8/src/rendering/sampler-wrapper.h +++ b/plugins/dali-script-v8/src/rendering/sampler-wrapper.h @@ -1,8 +1,8 @@ -#ifndef __DALI_V8PLUGIN_SAMPLER_WRAPPER_H__ -#define __DALI_V8PLUGIN_SAMPLER_WRAPPER_H__ +#ifndef DALI_V8PLUGIN_SAMPLER_WRAPPER_H +#define DALI_V8PLUGIN_SAMPLER_WRAPPER_H /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ // EXTERNAL INCLUDES #include -#include +#include // INTERNAL INCLUDES #include @@ -100,4 +100,4 @@ private: } // namespace Dali -#endif // __DALI_V8PLUGIN_SAMPLER_WRAPPER_H__ +#endif // DALI_V8PLUGIN_SAMPLER_WRAPPER_H diff --git a/plugins/dali-script-v8/src/rendering/shader-api.h b/plugins/dali-script-v8/src/rendering/shader-api.h index 1c9e1a2..230e789 100644 --- a/plugins/dali-script-v8/src/rendering/shader-api.h +++ b/plugins/dali-script-v8/src/rendering/shader-api.h @@ -1,8 +1,8 @@ -#ifndef __DALI_V8PLUGIN_SHADER_API_H__ -#define __DALI_V8PLUGIN_SHADER_API_H__ +#ifndef DALI_V8PLUGIN_SHADER_API_H +#define DALI_V8PLUGIN_SHADER_API_H /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ // EXTERNAL INCLUDES #include -#include +#include namespace Dali @@ -55,4 +55,4 @@ namespace ShaderApi } // namespace Dali -#endif // header __DALI_V8PLUGIN_SHADER_API_H__ +#endif // DALI_V8PLUGIN_SHADER_API_H diff --git a/plugins/dali-script-v8/src/rendering/shader-wrapper.h b/plugins/dali-script-v8/src/rendering/shader-wrapper.h index b4cb2a0..a5833f9 100644 --- a/plugins/dali-script-v8/src/rendering/shader-wrapper.h +++ b/plugins/dali-script-v8/src/rendering/shader-wrapper.h @@ -1,8 +1,8 @@ -#ifndef __DALI_V8PLUGIN_SHADER_WRAPPER_H__ -#define __DALI_V8PLUGIN_SHADER_WRAPPER_H__ +#ifndef DALI_V8PLUGIN_SHADER_WRAPPER_H +#define DALI_V8PLUGIN_SHADER_WRAPPER_H /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ // EXTERNAL INCLUDES #include -#include +#include // INTERNAL INCLUDES #include @@ -104,4 +104,4 @@ private: } // namespace Dali -#endif // __DALI_V8PLUGIN_SHADER_WRAPPER_H__ +#endif // DALI_V8PLUGIN_SHADER_WRAPPER_H__ diff --git a/plugins/dali-script-v8/src/rendering/texture-set-api.h b/plugins/dali-script-v8/src/rendering/texture-set-api.h index c5dc357..8b4159d 100644 --- a/plugins/dali-script-v8/src/rendering/texture-set-api.h +++ b/plugins/dali-script-v8/src/rendering/texture-set-api.h @@ -1,5 +1,5 @@ -#ifndef __DALI_V8PLUGIN_TEXURE_SET_API_H__ -#define __DALI_V8PLUGIN_TEXURE_SET_API_H__ +#ifndef DALI_V8PLUGIN_TEXURE_SET_API_H +#define DALI_V8PLUGIN_TEXURE_SET_API_H /* * Copyright (c) 2016 Samsung Electronics Co., Ltd. @@ -20,7 +20,7 @@ // EXTERNAL INCLUDES #include -#include +#include namespace Dali @@ -66,4 +66,4 @@ namespace TextureSetApi } // namespace Dali -#endif // header __DALI_V8PLUGIN_TEXURE_SET_API_H__ +#endif // DALI_V8PLUGIN_TEXURE_SET_API_H diff --git a/plugins/dali-script-v8/src/rendering/texture-set-wrapper.h b/plugins/dali-script-v8/src/rendering/texture-set-wrapper.h index 9e0426a..aaf8ecc 100644 --- a/plugins/dali-script-v8/src/rendering/texture-set-wrapper.h +++ b/plugins/dali-script-v8/src/rendering/texture-set-wrapper.h @@ -1,5 +1,5 @@ -#ifndef __DALI_V8PLUGIN_TEXTURE_SET_WRAPPER_H__ -#define __DALI_V8PLUGIN_TEXTURE_SET_WRAPPER_H__ +#ifndef DALI_V8PLUGIN_TEXTURE_SET_WRAPPER_H +#define DALI_V8PLUGIN_TEXTURE_SET_WRAPPER_H /* * Copyright (c) 2016 Samsung Electronics Co., Ltd. @@ -20,7 +20,7 @@ // EXTERNAL INCLUDES #include -#include +#include // INTERNAL INCLUDES #include @@ -104,4 +104,4 @@ private: } // namespace Dali -#endif // __DALI_V8PLUGIN_TEXTURE_SET_WRAPPER_H__ +#endif // DALI_V8PLUGIN_TEXTURE_SET_WRAPPER_H