diff --git a/Classes/LinphoneUI/UILinphone.h b/Classes/LinphoneUI/UILinphone.h index 7eec97b7a..ae4232c73 100644 --- a/Classes/LinphoneUI/UILinphone.h +++ b/Classes/LinphoneUI/UILinphone.h @@ -26,7 +26,7 @@ - (UIColor *)adjustHue:(float)hm saturation:(float)sm brightness:(float)bm alpha:(float)am; -- (UIColor *)multColor:(float)mult; +- (UIColor *)lumColor:(float)mult; - (UIColor *)lighterColor; diff --git a/Classes/LinphoneUI/UILinphone.m b/Classes/LinphoneUI/UILinphone.m index 0c151bf99..595b27cd9 100644 --- a/Classes/LinphoneUI/UILinphone.m +++ b/Classes/LinphoneUI/UILinphone.m @@ -18,35 +18,75 @@ */ #import "UILinphone.h" +#import "ColorSpaceUtilities.h" +#import "Utils.h" @implementation UIColor (LightAndDark) -- (UIColor *)multColor:(float)mult { - float h, s, b, a; - if ([self getHue:&h saturation:&s brightness:&b alpha:&a]) - return [UIColor colorWithHue:h - saturation:s - brightness:MIN(MAX(b * mult, 0.0), 1.0) - alpha:a]; - return nil; +- (UIColor *)lumColor:(float)mult { + float hsbH, hsbS, hsbB; + float rgbaR, rgbaG, rgbaB, rgbaA; + + // Get RGB + CGColorRef cgColor = [self CGColor]; + CGColorSpaceRef cgColorSpace = CGColorGetColorSpace(cgColor); + if(CGColorSpaceGetModel(cgColorSpace) != kCGColorSpaceModelRGB) { + [LinphoneLogger log:LinphoneLoggerWarning format:@"Can't convert not RGB color"]; + return self; + } else { + const float *colors = CGColorGetComponents(cgColor); + rgbaR = colors[0]; + rgbaG = colors[1]; + rgbaB = colors[2]; + rgbaA = CGColorGetAlpha(cgColor); + } + + RGB2HSL(rgbaR, rgbaG, rgbaB, &hsbH, &hsbS, &hsbB); + + hsbB = MIN(MAX(hsbB * mult, 0.0), 1.0); + + HSL2RGB(hsbH, hsbS, hsbB, &rgbaR, &rgbaG, &rgbaB); + + return [UIColor colorWithRed:rgbaR green:rgbaG blue:rgbaB alpha:rgbaA]; } - (UIColor *)adjustHue:(float)hm saturation:(float)sm brightness:(float)bm alpha:(float)am { - float h, s, b, a; - if ([self getHue:&h saturation:&s brightness:&b alpha:&a]) - return [UIColor colorWithHue:MIN(MAX(h + hm, 0.0), 1.0) - saturation:MIN(MAX(s + sm, 0.0), 1.0) - brightness:MIN(MAX(b + bm, 0.0), 1.0) - alpha:MIN(MAX(a + am, 0.0), 1.0)]; - return nil; + float hsbH, hsbS, hsbB; + float rgbaR, rgbaG, rgbaB, rgbaA; + + + // Get RGB + CGColorRef cgColor = [self CGColor]; + CGColorSpaceRef cgColorSpace = CGColorGetColorSpace(cgColor); + if(CGColorSpaceGetModel(cgColorSpace) != kCGColorSpaceModelRGB) { + [LinphoneLogger log:LinphoneLoggerWarning format:@"Can't convert not RGB color"]; + return self; + } else { + const float *colors = CGColorGetComponents(cgColor); + rgbaR = colors[0]; + rgbaG = colors[1]; + rgbaB = colors[2]; + rgbaA = CGColorGetAlpha(cgColor); + } + + RGB2HSL(rgbaR, rgbaG, rgbaB, &hsbH, &hsbS, &hsbB); + + hsbH = MIN(MAX(hsbH + hm, 0.0), 1.0); + hsbS = MIN(MAX(hsbS + sm, 0.0), 1.0); + hsbB = MIN(MAX(hsbB + bm, 0.0), 1.0); + rgbaA = MIN(MAX(rgbaA + am, 0.0), 1.0); + + HSL2RGB(hsbH, hsbS, hsbB, &rgbaR, &rgbaG, &rgbaB); + + return [UIColor colorWithRed:rgbaR green:rgbaG blue:rgbaB alpha:rgbaA]; } - (UIColor *)lighterColor { - return [self multColor:1.3]; + return [self lumColor:1.3]; } - (UIColor *)darkerColor { - return [self multColor:0.75]; + return [self lumColor:0.75]; } @end \ No newline at end of file diff --git a/Classes/SettingsViewController.m b/Classes/SettingsViewController.m index 8580eec38..be5ae481e 100644 --- a/Classes/SettingsViewController.m +++ b/Classes/SettingsViewController.m @@ -126,6 +126,11 @@ return self; } +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + [super tableView:tableView didSelectRowAtIndexPath:indexPath]; + [tableView deselectRowAtIndexPath:indexPath animated:YES]; // Fix IOS4 issue +} + - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell * cell = [super tableView:tableView cellForRowAtIndexPath:indexPath]; diff --git a/Classes/Utils/ColorSpaceUtilites.m b/Classes/Utils/ColorSpaceUtilites.m new file mode 100644 index 000000000..5f845a428 --- /dev/null +++ b/Classes/Utils/ColorSpaceUtilites.m @@ -0,0 +1,142 @@ +/* + ColorConverter + + you can use it to convert color from RGB space to HSL space and back. + + HSL2RGB copied from GLPaint Apple sample: http://developer.apple.com/library/ios/#samplecode/GLPaint/Introduction/Intro.html + + RGB2HSL translated from http://www.geekymonkey.com/Programming/CSharp/RGB2HSL_HSL2RGB.htm + + From: https://github.com/alessani/ColorConverter + */ + +void HSL2RGB(float h, float s, float l, float* outR, float* outG, float* outB) +{ + float temp1, + temp2; + float temp[3]; + int i; + + // Check for saturation. If there isn't any just return the luminance value for each, which results in gray. + if(s == 0.0) { + if(outR) + *outR = l; + if(outG) + *outG = l; + if(outB) + *outB = l; + return; + } + + // Test for luminance and compute temporary values based on luminance and saturation + if(l < 0.5) + temp2 = l * (1.0 + s); + else + temp2 = l + s - l * s; + temp1 = 2.0 * l - temp2; + + // Compute intermediate values based on hue + temp[0] = h + 1.0 / 3.0; + temp[1] = h; + temp[2] = h - 1.0 / 3.0; + + for(i = 0; i < 3; ++i) { + + // Adjust the range + if(temp[i] < 0.0) + temp[i] += 1.0; + if(temp[i] > 1.0) + temp[i] -= 1.0; + + + if(6.0 * temp[i] < 1.0) + temp[i] = temp1 + (temp2 - temp1) * 6.0 * temp[i]; + else { + if(2.0 * temp[i] < 1.0) + temp[i] = temp2; + else { + if(3.0 * temp[i] < 2.0) + temp[i] = temp1 + (temp2 - temp1) * ((2.0 / 3.0) - temp[i]) * 6.0; + else + temp[i] = temp1; + } + } + } + + // Assign temporary values to R, G, B + if(outR) + *outR = temp[0]; + if(outG) + *outG = temp[1]; + if(outB) + *outB = temp[2]; +} + + +void RGB2HSL(float r, float g, float b, float* outH, float* outS, float* outL) +{ + /*r = r/255.0f; + g = g/255.0f; + b = b/255.0f;*/ + + + float h,s, l, v, m, vm, r2, g2, b2; + + h = 0; + s = 0; + l = 0; + + v = MAX(r, g); + v = MAX(v, b); + m = MIN(r, g); + m = MIN(m, b); + + l = (m+v)/2.0f; + + if (l <= 0.0){ + if(outH) + *outH = h; + if(outS) + *outS = s; + if(outL) + *outL = l; + return; + } + + vm = v - m; + s = vm; + + if (s > 0.0f){ + s/= (l <= 0.5f) ? (v + m) : (2.0 - v - m); + }else{ + if(outH) + *outH = h; + if(outS) + *outS = s; + if(outL) + *outL = l; + return; + } + + r2 = (v - r)/vm; + g2 = (v - g)/vm; + b2 = (v - b)/vm; + + if (r == v){ + h = (g == m ? 5.0f + b2 : 1.0f - g2); + }else if (g == v){ + h = (b == m ? 1.0f + r2 : 3.0 - b2); + }else{ + h = (r == m ? 3.0f + g2 : 5.0f - r2); + } + + h/=6.0f; + + if(outH) + *outH = h; + if(outS) + *outS = s; + if(outL) + *outL = l; + +} \ No newline at end of file diff --git a/Classes/Utils/ColorSpaceUtilities.h b/Classes/Utils/ColorSpaceUtilities.h new file mode 100644 index 000000000..7f2ff1b70 --- /dev/null +++ b/Classes/Utils/ColorSpaceUtilities.h @@ -0,0 +1,14 @@ +/* + ColorConverter + + you can use it to convert color from RGB space to HSL space and back. + + HSL2RGB copied from GLPaint Apple sample: http://developer.apple.com/library/ios/#samplecode/GLPaint/Introduction/Intro.html + + RGB2HSL translated from http://www.geekymonkey.com/Programming/CSharp/RGB2HSL_HSL2RGB.htm + + From: https://github.com/alessani/ColorConverter +*/ + +void HSL2RGB(float h, float s, float l, float* outR, float* outG, float* outB); +void RGB2HSL(float r, float g, float b, float* outH, float* outS, float* outL); \ No newline at end of file diff --git a/linphone.xcodeproj/project.pbxproj b/linphone.xcodeproj/project.pbxproj index b0ec8549a..34c686e93 100755 --- a/linphone.xcodeproj/project.pbxproj +++ b/linphone.xcodeproj/project.pbxproj @@ -644,6 +644,8 @@ D380800315C2894A005BE9BC /* IASKTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = D3807FE715C2894A005BE9BC /* IASKTextField.m */; }; D380800515C28A7A005BE9BC /* UILinphone.m in Sources */ = {isa = PBXBuildFile; fileRef = D380800415C28A7A005BE9BC /* UILinphone.m */; }; D380800615C28A7A005BE9BC /* UILinphone.m in Sources */ = {isa = PBXBuildFile; fileRef = D380800415C28A7A005BE9BC /* UILinphone.m */; }; + D380801315C299D0005BE9BC /* ColorSpaceUtilites.m in Sources */ = {isa = PBXBuildFile; fileRef = D380801215C299D0005BE9BC /* ColorSpaceUtilites.m */; }; + D380801415C299D0005BE9BC /* ColorSpaceUtilites.m in Sources */ = {isa = PBXBuildFile; fileRef = D380801215C299D0005BE9BC /* ColorSpaceUtilites.m */; }; D38327F31580FE3A00FA0D23 /* contacts_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D38327EB1580FE3A00FA0D23 /* contacts_default.png */; }; D38327F41580FE3A00FA0D23 /* contacts_selected.png in Resources */ = {isa = PBXBuildFile; fileRef = D38327EC1580FE3A00FA0D23 /* contacts_selected.png */; }; D38327F51580FE3A00FA0D23 /* dialer_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D38327ED1580FE3A00FA0D23 /* dialer_default.png */; }; @@ -1403,6 +1405,8 @@ D3807FE615C2894A005BE9BC /* IASKTextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IASKTextField.h; sourceTree = ""; }; D3807FE715C2894A005BE9BC /* IASKTextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IASKTextField.m; sourceTree = ""; }; D380800415C28A7A005BE9BC /* UILinphone.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UILinphone.m; sourceTree = ""; }; + D380801115C29984005BE9BC /* ColorSpaceUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ColorSpaceUtilities.h; path = Utils/ColorSpaceUtilities.h; sourceTree = ""; }; + D380801215C299D0005BE9BC /* ColorSpaceUtilites.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ColorSpaceUtilites.m; path = Utils/ColorSpaceUtilites.m; sourceTree = ""; }; D38327EB1580FE3A00FA0D23 /* contacts_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = contacts_default.png; path = Resources/contacts_default.png; sourceTree = ""; }; D38327EC1580FE3A00FA0D23 /* contacts_selected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = contacts_selected.png; path = Resources/contacts_selected.png; sourceTree = ""; }; D38327ED1580FE3A00FA0D23 /* dialer_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = dialer_default.png; path = Resources/dialer_default.png; sourceTree = ""; }; @@ -2529,6 +2533,8 @@ D326483415887D4400930C67 /* Utils */ = { isa = PBXGroup; children = ( + D380801215C299D0005BE9BC /* ColorSpaceUtilites.m */, + D380801115C29984005BE9BC /* ColorSpaceUtilities.h */, D38935F715A6D06800A3A3AA /* CPAnimation */, D3807FB615C28940005BE9BC /* DCRoundSwitch */, D32B9DFA15A2F131000B6DEC /* FastAddressBook.h */, @@ -3480,6 +3486,7 @@ D380800015C2894A005BE9BC /* IASKSwitch.m in Sources */, D380800215C2894A005BE9BC /* IASKTextField.m in Sources */, D380800515C28A7A005BE9BC /* UILinphone.m in Sources */, + D380801315C299D0005BE9BC /* ColorSpaceUtilites.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3574,6 +3581,7 @@ D380800115C2894A005BE9BC /* IASKSwitch.m in Sources */, D380800315C2894A005BE9BC /* IASKTextField.m in Sources */, D380800615C28A7A005BE9BC /* UILinphone.m in Sources */, + D380801415C299D0005BE9BC /* ColorSpaceUtilites.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; };