NSMutableAttributedString can not change the text color when calling addAttribute method - nsmutableattributedstring

i want to change the text color based on the 3rd part lib which is "TTTAttributedLabel" , but it does not make sense. Here is my code:
TTTAttributedLabel *priceInfoLabel.frame = [[TTTAttributedLabel alloc] initWithFrame:CGRectMake(self.view.width-12-realSize.width-priceSize.width, 15, realSize.width+priceSize.width, 18)];
priceInfoLabel.centerY = nameView.height/2;
priceInfoLabel.textColor = kRealPriceColor;
[priceInfoLabel setText:[NSString stringWithFormat:#"%#%#",realPriceText,priceText] afterInheritingLabelAttributesAndConfiguringWithBlock:^NSMutableAttributedString *(NSMutableAttributedString *mutableAttributedString) {
NSRange priceStringRange = [[mutableAttributedString string] rangeOfString:priceText options:NSCaseInsensitiveSearch];
[mutableAttributedString addAttribute:NSFontAttributeName value:[UIFont fontWithName:nil size:12] range:priceStringRange];
[mutableAttributedString addAttribute:UITextAttributeTextColor
value:colorWithIntegerValue(195, 195, 195) range:priceStringRange];
return mutableAttributedString;
}];

Try using:
[mutableAttributedString addAttribute:(NSString *)kCTForegroundColorAttributeName
value:colorWithIntegerValue(195, 195, 195) range:priceStringRange];

Related

Getting "Out of Stack space" error inconsistently

On every page of my workbook, I have a status bar made of status boxes. There are three statuses -- "Tab Started", "Design Updated", and "Configurations Complete". Originally I had these boxes called out on every page (and using absolute references), but I recently tried to improve the efficiency and flexibility of the workbook by moving that code to a separate module and calling it on every workbook page near the top (+ setting variables using "Find" rather than absolute references).
However, while this works 90% of the time or more, occasionally I get an error message "Out of Stack Space". Reading on the MSDN, none of the examples that might trigger this error seem to apply to my code (e.g. the code doesn't call itself).
See below for code.
'This function is called by all workbook tabs and controls the status boxes
Sub StatusBars(ByVal Target As Range)
Dim TabStarted1 As Range
Set TabStarted1 = ActiveSheet.Range("A4:Z5").Find("Tab Started")
Dim TabStarted As Range
Set TabStarted = TabStarted1.Offset(0, 1)
Dim Design1 As Range
Set Design1 = ActiveSheet.Range("A6:Z7").Find("Design Updated")
Dim Design As Range
Set Design = Design1.Offset(0, 1)
Dim Configurations1 As Range
Set Configurations1 = ActiveSheet.Range("A8:Z9").Find("Configurations Complete")
Dim Configurations As Range
Set Configurations = Configurations1.Offset(0, 1)
If Not Intersect(Target, TabStarted) Is Nothing Then
If Target.Cells.Count = 2 Then
If WorksheetFunction.CountA(Target) = 0 Then 'If box is empty, then add an X, format it, change the box color and the tab color
TabStarted.Value = "X"
TabStarted.HorizontalAlignment = xlCenter
TabStarted.Font.Size = 25
TabStarted.Interior.Color = RGB(255, 255, 0)
Design.Interior.Color = RGB(255, 255, 255)
Design.Value = ""
Configurations.Interior.Color = RGB(255, 255, 255)
Configurations.Value = ""
ActiveSheet.Tab.Color = RGB(255, 255, 0)
Else 'if box is already checked clear, the X, the color, and the tab color
TabStarted.Interior.Color = RGB(255, 255, 255)
TabStarted.Value = ""
ActiveSheet.Tab.ColorIndex = xlColorIndexNone
End If
End If
End If
If Not Intersect(Target, Design) Is Nothing Then
If Target.Cells.Count = 2 Then
If WorksheetFunction.CountA(Target) = 0 Then
Design.Value = "X"
Design.HorizontalAlignment = xlCenter
Design.Font.Size = 25
Design.Interior.Color = RGB(0, 112, 192)
TabStarted.Interior.Color = RGB(255, 255, 255)
TabStarted.Value = ""
Configurations.Interior.Color = RGB(255, 255, 255)
Configurations.Value = ""
ActiveSheet.Tab.Color = RGB(0, 112, 192)
Else
Design.Interior.Color = RGB(255, 255, 255)
Design.Value = ""
ActiveSheet.Tab.ColorIndex = xlColorIndexNone
End If
End If
End If
If Not Intersect(Target, Configurations) Is Nothing Then
If Target.Cells.Count = 2 Then
If WorksheetFunction.CountA(Target) = 0 Then
Configurations.Value = "X"
Configurations.HorizontalAlignment = xlCenter
Configurations.Font.Size = 25
Configurations.Interior.Color = RGB(0, 176, 80)
TabStarted.Interior.Color = RGB(255, 255, 255)
TabStarted.Value = ""
Design.Interior.Color = RGB(255, 255, 255)
Design.Value = ""
ActiveSheet.Tab.Color = RGB(0, 176, 80)
Else
Configurations.Interior.Color = RGB(255, 255, 255)
Configurations.Value = ""
ActiveSheet.Tab.ColorIndex = xlColorIndexNone
End If
End If
End If
End Sub
EDIT:
An example of the code that calls this function:
'Remove Case Sensitivity
Option Compare Text
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Application.ScreenUpdating = False
Dim var1 As Variant
Dim var2 As Variant
Dim var3 As Variant
Dim PlusTemplates As Range
Set PlusTemplates = Range("A14:Z15").Find("+")
Call StatusBars(Target)
[rest of the code]
Application.ScreenUpdating = True
End Sub
Activesheet is a global variable. When you set tabstarted1 etc. with Activesheet, because activesheet is on stack and did not disposed, your other variables like tabstarted1, design1 stays on stack memory. Try to get activesheet as parameter to your function.
I think the error is because your code changes the sheet and thus a new event is called. To make sure that this is the case, do the following - insert a STOP on the event like this:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Application.ScreenUpdating = False
Stop
Dim var1 As Variant
'rest of your code.
End Sub
The first time you have a selection change you will stop on the stop. Then press F5 and continue. If you stop again, then it is a recursion error.
The easiest way to fix it is with Application.EnableEvents = False at the beginning of the event and Application.EnableEvents = True at the end of the code.

IDL: Button Widget stops updating after one push

I'm pretty new to IDL and as a way to learn I have tried to create a number guessing game. I have a Widget with three buttons: One that tells the program the number you are thinking of is larger than the one the computer asks about, one if it's smaller and one if it's correct.
My problem is that once you have pushed i.e. the larger button, if you press it again it won't do anything. E.g. the program starts to guess 500, if I press larger it guesses 750. If I now press larger again, the program doesn't respond.
My code is like this:
PRO test1_event, ev
WIDGET_CONTROL, ev.top, GET_UVALUE = stash
minimum = 0
maximum = 1000
IF (ev.Id EQ largerbutton) THEN BEGIN
minimum = (minimum+maximum)/2
maximum = maximum
ENDIF
IF (ev.Id EQ smallerbutton) THEN BEGIN
maximum = (minimum+maximum)/2
minimum = minimum
ENDIF
IF (ev.Id EQ correctbutton) THEN BEGIN
help2 = string('I got it!') ;This prints to a text widget
ENDIF
END
PRO test1
wBase = WIDGET_BASE(X_SCROLL_SIZE = 512, Y_SCROLL_SIZE = 512)
;wDraw = WIDGET_WINDOW(wBase, X_SCROLL_SIZE = 512, Y_SCROLL_SIZE = 512)
Lower = WIDGET_BUTTON(wBase, VALUE = 'Smaller', XOFFSET = 60, YOFFSET = 250)
Higher = WIDGET_BUTTON(wBase, VALUE = 'Larger', XOFFSET = 225, YOFFSET = 250)
Correct = WIDGET_BUTTON(wBase, VALUE = 'Correct', XOFFSET = 380, YOFFSET = 250)
minimum = 0
maximum = 1000
help1 = string('Please think of a number between' + string(minimum) + ' and ' + string(maximum))
help2 = string('Is your number ' + string((minimum + maximum)/2) + '?')
wText = WIDGET_TEXT(wBase, VALUE = ['Welcome to my little game. I will now try and guess a number you are thinking of.'], XSIZE = 63,XOFFSET = 50, YOFFSET = 100)
wText1 = WIDGET_TEXT(wBase, VALUE = help1, XSIZE = 63,XOFFSET = 50, YOFFSET = 120)
wText2 = WIDGET_TEXT(wBase, VALUE = help2, XSIZE = 63,XOFFSET = 50, YOFFSET = 140)
stash = {text1:wText, text2:wText1, text3:wText2, $
lower:Lower, higher:Higher, correct:Correct, minimum:minimum, maximum:maximum}
WIDGET_CONTROL, wBase, SET_UVALUE = stash, /REALIZE
XMANAGER, 'test1', wBase
end
I have tried using a while loop and also REPEAT, but then the program just goes right up to 999 if I press the larger button and to 0 if I press the smaller.
Any ideas to what I can do?
EDIT: Added the rest of the program
I think the buttons are working fine but your event handler doesn't actually do anything. First, I needed to change largerbutton, smallerbutton, and correctbutton to be stash.higher, stash.lower, stash.correct. Then, your code calculates the new minimum & maximum but it doesn't actually do anything with them.
I put a print statement into the event code and it's definitely getting the button presses.
In your event handler you probably want to use widget_control to update the text box with the new guess.

Changes from 3.5 to 4.0

I need to help to port my 3.5 rc.lua to 4.0. I try to set one progressbar.
It used to be :
mybacklight = awful.widget.progressbar()
mybacklight:set_width(12)
mybacklight:set_height(10)
mybacklight:set_vertical(true)
mybacklight:set_background_color("#131211")
mybacklight:set_border_color(nil)
The new version should be :
mybacklight = wibox.widget.progressbar {
max_value = 1,
value = brightness_new,
forced_width = 12,
forced_height = 10,
background_color = "#131211",
border_color = nil,
color = {type="linear", from = {0, 0}, to = {0, 20},
stops = { {0, "#F6F6F6"}, {0.5,
"#bdbdbd"}, {1.0, "#3b3b3b"} } },
widget = wibox.widget.progressbar,
direction = 'east',
layout = wibox.container.rotate
}
The 3.5 version works (no errors) but does no more give the expected result, it should be a vertical progressbar, it is, but the progression itself is horizontal.
The 4.0 version makes no error, except that it takes all the place with red (default ?) colors.
First of all, the imperative syntax isn't gone, you can still do it "the old way". It is fully supported and the declarative one is "compiled to" the old one.
Now, to answer the question, the code should look like (untested):
mybacklight = wibox.widget {
{
max_value = 1,
value = brightness_new,
background_color = "#131211",
color = {type="linear", from = {0, 0}, to = {0, 20},
stops = { {0, "#F6F6F6"}, {0.5,
"#bdbdbd"}, {1.0, "#3b3b3b"} }
},
widget = wibox.widget.progressbar,
},
forced_width = 12,
forced_height = 10,
direction = 'east',
layout = wibox.container.rotate
}
Changes:
The composite widget constructor is wibox.widget. You used the progressbar constructor to contruct a rotate container
Indentation to make the code more readable
You had 2 widget in the same block, this isn't supported.
Reference https://awesomewm.org/apidoc/classes/wibox.widget.progressbar.html#

IniRead array and pass to download function with progress bar

so i'm trying to work out how to get a downloader function working in a tool i'm working on, basically theres a tab with 3 download buttons, based on what button is clicked in the tab i'd like it to pass to one function, the downloder that will read the links from the ini file, with a progress bar in the tab I'll post the code bellow so you'll get an understanding
So it will download the files absolutely fine the only problem is when I start the app the download for the first file in the array starts automatically even though I didn't click the label in the tab, nor does the rest of the GUI function, I can't switch tabs as it just "freezes" then the download starts all over again if i comment out the case dwitch for $modlabel1 like so ";Case $modlabel1" it allows me to switch tabs etc just fine and I can switch tabs and click on the other 2 buttons and they will download as intended but the GUI stays on the mod tab till its finished, another small issue I have is i need the files to download with the same as the source file name, is that possible to do with InetGet?
Downloads Tab
Func _mods_gui()
$modsgui = GUICreate("Mods", 1270, 610, 5, 105, BitOR($ws_popup, $ws_border), $ws_ex_mdichild, $maingui)
GUISetBkColor(3487029)
DllCall("user32.dll", "int", "AnimateWindow", "hwnd", $setgui, "int", 250, "long", 524288)
$progressbar1 = GUICtrlCreateProgress(10, 200, 1250, 50, $PBS_MARQUEE)
$modlabel1 = GUICtrlCreateLabel("Download" & #CRLF & "DayZ Epoch 1.0.5.1", 50, 50, 350, 100, $ss_center)
GUICtrlSetFont(-1, 30, 700, 0, "Segeo UI", 4)
GUICtrlSetBkColor(-1, 3825)
GUICtrlSetColor(-1, 16777215)
_guictrl_setonhover(-1, "_Hover", "_Hover_Leave")
$modlabel2 = GUICtrlCreateLabel("Download" & #CRLF & "DayZ Overwatch 0.2.5", 450, 50, 350, 100, $ss_center)
GUICtrlSetFont(-1, 30, 700, 0, "Segeo UI", 4)
GUICtrlSetBkColor(-1, 3825)
GUICtrlSetColor(-1, 16777215)
_guictrl_setonhover(-1, "_Hover", "_Hover_Leave")
$modlabel3 = GUICtrlCreateLabel("Download" & #CRLF & "Namalsk 0.75", 850, 50, 350, 100, $ss_center)
GUICtrlSetFont(-1, 30, 700, 0, "Segeo UI", 4)
GUICtrlSetBkColor(-1, 3825)
GUICtrlSetColor(-1, 16777215)
_guictrl_setonhover(-1, "_Hover", "_Hover_Leave")
$modsgr2 = GUICtrlCreateGraphic(0, 25, 1270, 250)
GUICtrlSetState(-1, $gui_disable)
GUICtrlSetGraphic(-1, $gui_gr_color, 0, 2368548)
GUICtrlSetGraphic(-1, $gui_gr_rect, 0, 0, 1270, 250)
GUISetState(#SW_SHOW, $modsgui)
EndFunc
While Switch Case
Case $modsgui
Switch $nmsg[0]
Case $modlabel1
_downloadmod(0)
Case $modlabel2
_downloadmod(1)
Case $modlabel3
_downloadmod(2)
EndSwitch
Download Array
Func _downloadmod($mod)
$modarrayread[3] = [IniRead(#ScriptDir & "\LauncherFiles\data\XGLConfig.cfg", "mod_links", "mod_epoch", Default), IniRead(#ScriptDir & "\LauncherFiles\data\XGLConfig.cfg", "mod_links", "mod_overwatch", Default), IniRead(#ScriptDir & "\LauncherFiles\data\XGLConfig.cfg", "mod_links", "mod_namalsk", Default)]
$dwnmod = InetGet($modarrayread[$mod], #ScriptDir & "\Mods\$name.zip", 1, 1)
Do
Sleep(50)
$prc = Round(InetGetInfo($dwnmod, 0) / (InetGetInfo($dwnmod, 1)) * 100)
GUICtrlSetData($progressbar1, $prc)
Until InetGetInfo($dwnmod, $INET_DOWNLOADCOMPLETE)
EndFunc
INI
[mod_links]
mod_epoch=http://files.xexgaming.com/mods/#DayZ_Epoch1051.zip
mod_overwatch=http://files.xexgaming.com/mods/#DayZOverwatch.zip
mod_namalsk=http://files.xexgaming.com/mods/#Namalsk.zip
Credits to Trojan for the help with the array, worked out how to get the parameters using his example
I worked with the example script in the help for GUICtrlCreateProgress as base and wrote a script which hopefully does what u wanted it to do.
If you have any questions feel free to ask :)
#include <GUIConstantsEx.au3>
#include <ProgressConstants.au3>
#include <MsgBoxConstants.au3>
#include <InetConstants.au3>
Example()
Func Example()
Local $progressbar1, $button1, $button2, $button3
Local $downarrayread[3] = [IniRead(#ScriptDir & "\Files\data\Config.cfg", "links", "link_1", Default), IniRead(#ScriptDir & "\Files\data\Config.cfg", "links", "link_2", Default), IniRead(#ScriptDir & "\Files\data\Config.cfg", "links", "link_3", Default)]
GUICreate("Downloads", 220, 100, 100, 200)
$progressbar1 = GUICtrlCreateProgress(10, 40, 200, 20, $PBS_SMOOTH)
$button1 = GUICtrlCreateButton("Start 1", 5, 70, 70, 20)
$button2 = GUICtrlCreateButton("Start 2", 75, 70, 70, 20)
$button3 = GUICtrlCreateButton("Start 3", 145, 70, 70, 20)
GUISetState(#SW_SHOW)
While 1
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
ExitLoop
Case $button1
$hDownload = InetGet($downarrayread[1], #ScriptDir & "/Downloads/File1", $INET_FORCERELOAD, $INET_DOWNLOADBACKGROUND)
Do
Sleep(250)
GUICtrlSetData($progressbar1,((InetGetInfo($hDownload,$INET_DOWNLOADSIZE )/InetGetInfo($hDownload, $INET_DOWNLOADREAD))*100)/3)
Until InetGetInfo($hDownload, $INET_DOWNLOADCOMPLETE)
Case $button2
$hDownload = InetGet($downarrayread[2], #ScriptDir & "/Downloads/File2", $INET_FORCERELOAD, $INET_DOWNLOADBACKGROUND)
Do
Sleep(250)
GUICtrlSetData($progressbar1,((InetGetInfo($hDownload,$INET_DOWNLOADSIZE )/InetGetInfo($hDownload, $INET_DOWNLOADREAD))*100)/3+33.33)
Until InetGetInfo($hDownload, $INET_DOWNLOADCOMPLETE)
Case $button3
$hDownload = InetGet($downarrayread[3], #ScriptDir & "/Downloads/File3", $INET_FORCERELOAD, $INET_DOWNLOADBACKGROUND)
Do
Sleep(250)
GUICtrlSetData($progressbar1,((InetGetInfo($hDownload,$INET_DOWNLOADSIZE )/InetGetInfo($hDownload, $INET_DOWNLOADREAD))*100)/3+66.66)
Until InetGetInfo($hDownload, $INET_DOWNLOADCOMPLETE)
EndSwitch
WEnd
EndFunc ;==>Example

.NET: How to change the value in a DataTable

In ADO.NET i'm using GetSchemaTable to return the schema table for a results set.
DataTable schema = rdr.GetSchemaTable();
gridSchema.DataSource = schema;
gridSchema.DataBind();
Unfortunatly the "ProviderType" value is displaying as an integer, rather than the OleDbType enumeration value that it is:
ProviderType Desired Display Value
============ =====================
129 Char
3 Integer
129 Char
129 Char
3 Integer
3 Integer
129 Char
135 DBTimeStamp
129 Char
129 Char
...
All these integers are the the enumeration values for the OleDbType enumeration:
public enum OleDbType
{
Empty = 0,
SmallInt = 2,
Integer = 3,
Single = 4,
Double = 5,
Currency = 6,
Date = 7,
BSTR = 8,
IDispatch = 9,
Error = 10,
Boolean = 11,
Variant = 12,
IUnknown = 13,
Decimal = 14,
TinyInt = 16,
UnsignedTinyInt = 17,
UnsignedSmallInt = 18,
UnsignedInt = 19,
BigInt = 20,
UnsignedBigInt = 21,
Filetime = 64,
Guid = 72,
Binary = 128,
Char = 129,
WChar = 130,
Numeric = 131,
DBDate = 133,
DBTime = 134,
DBTimeStamp = 135,
PropVariant = 138,
VarNumeric = 139,
VarChar = 200,
LongVarChar = 201,
VarWChar = 202,
LongVarWChar = 203,
VarBinary = 204,
LongVarBinary = 205,
}
i want to display the data type as something human readable, rather than an integer.
i've tried looping through the schema DataTable and modify the values inside the DataTable:
DataTable schema = rdr.GetSchemaTable();
//Change providerType column to be readable
foreach (DataRow row in schema.Rows)
{
OleDbType t = (OleDbType)row["ProviderType"];
row["ProviderType"] = t.ToString();
}
gridSchema.DataSource = schema;
gridSchema.DataBind();
But that throws an exception:
Column 'ProviderType' is read only.
i even looked at the GridView's RowDataBound event, thinking i could change the value as it is rendered:
protected void gridSchema_RowDataBound(object sender, GridViewRowEventArgs e)
{
//todo: magic
//e.Row["ProviderType"]
}
But it doesn't look like you can play with rendered values.
Can anyone suggest a nice way to much with the value of the ProviderType column so that it is human readable when i display it to humans?
Update
The workaround i'm using right now is tack an extra column on the end:
DataTable schema = rdr.GetSchemaTable();
schema.Columns.Add("OleDbDataType", typeof(String));
schema.Columns.Add("CLRDataType", typeof(String));
foreach (DataRow row in schema.Rows)
{
//Show the actual provider type
OleDbType t = (OleDbType)row["ProviderType"];
row["OleDbDataType"] = t.ToString();
//Show the corresponding CLR type while we're doing a hack
row["CLRDataType"] = row["DataType"].ToString();
}
gridSchema.DataSource = schema;
gridSchema.DataBind();
I might be completely off here, but can't you just set the ReadOnly property of the column to false? Like:
schema.Columns["ProviderType"].ReadOnly = false;
Afterwards you might get a columntype problem as you're trying to put a string value into a integer column. But this should get you into the right direction.
edit:
Solving the columntype issue:
DataTable newTable = schema.Clone();
newTable.Columns["ProviderType"].DataType = typeof(string);
foreach (DataRow dr in schema.Rows)
{
DataRow newRow = newTable.NewRow();
// fill newRow with correct data and newly formatted providertype
newTable.Rows.Add(newRow);
}
Or you could create an object with all the fields from the datatable, pass all the data into your object and modify it or create a read only field that returns the string acording to the integer given.
GridView and other also accept object arrays as datasources so it is automatic.

Resources