Why my scroll view does not scroll to the bottom when adding two sentences consecutively? - scrollview

I created a scroll window like this, hoping it will auto scroll to the bottom when text continuously come:
public class LogWindow : MonoBehaviour
{
public Text logText;
Queue<string> textQueue = new Queue<string>();
public ScrollRect scrollRect;
public Scrollbar scrollbar;
void RefreshText()
{
string buffer = "";
foreach(string text in textQueue)
{
buffer += text;
buffer += '\n';
}
logText.text = buffer;
scrollRect.verticalNormalizedPosition = 0.0f;
scrollbar.value = 0.0f;
}
public void Log(string text, string color = "white")
{
text = String.Format("<color={0}>{1}</color>", color, text);
textQueue.Enqueue(text);
RefreshText();
}
}
It works fine when I call RefreshText once at a time. But when I do this:
Log("something 1");
Log("something 2");
I see that the log window is only scrolled down so that "something 1" is shown. I have to drag it manually to see "something 2".
My settings on the Text is:
I suppose there is something wrong in RefreshText. Can anyone tell me where did I go wrong?
Thank you!

Related

PagerAdapter always getting called two times in ViewPager

I am trying to make a slider between TouchImageView and PlayerView (Exoplayer) but I am unable to catch up with certain issues that are persisting even after several changes. All the suggestions and answers are welcome. Pardon my questioning skills and please let me know if more inputs are needed for your analysis. Kindly also let me know if there is any other alternative to successfully meet my expectations of properly implementing views smoothly in ViewPager.
Problem description:-
Issues related to click on view :-
When the image is clicked, the audio of next video (if any) starts playing in background.
The same issue is with PlayerView. When the video thumbnail is clicked, the audio of clicked video as well as next video plays together.
Issues related to slider :-
When an we slide and reach to an image preceding to a video, the audio starts playing in background. However, after sliding once toward video and sliding again in forward or backward direction from video for once, the audio stops. But this issue persists after viewing more than one images in forward or backward direction of video.
Attempts made by me to solve this issue :-
I tried to use playerView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {...}) method in PagerAdapter to handle player states while sliding between views. Unfortunately, I was unable to grasp to use different player states.
I also tried to use viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {...} method in StatusViewer class.
StatusViewer Java class (Setting PagerAdapter class object inViewPager) :-
modelFeedArrayList = (ArrayList<File>) getIntent().getSerializableExtra("modelFeedArrayList");
position = intent.getIntExtra("position", 0);
ImageSlideAdapter imageSlideAdapter = new ImageSlideAdapter(this,modelFeedArrayList,position);
viewPager.setAdapter(imageSlideAdapter);
viewPager.setCurrentItem(position);
viewPager.setOffscreenPageLimit(0);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
File currentFile = modelFeedArrayList.get(position);
String filePath = currentFile.toString();
if (filePath.endsWith(".jpg") || currentPage == position){
currentPage = position;
ImageSlideAdapter.player.pause();
}
else {
currentPage = position;
ImageSlideAdapter.player.play();
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
ImageSliderAdapter (PagerAdapter) (code mentioned below is inside instantiateItem):-
File currentFile = modelFeedArrayList.get(position);
String filePath = currentFile.toString();
if (currentFile.getAbsolutePath().endsWith(".mp4")) {
statusImageView.setVisibility(View.GONE);
playerView.setVisibility(View.VISIBLE);
player = new ExoPlayer.Builder(context).build();
MediaItem mediaItem = MediaItem.fromUri(filePath);
player.addMediaItem(mediaItem);
playerView.setPlayer(player);
player.prepare();
playerView.setBackgroundColor(context.getResources().getColor(android.R.color.black));
playerView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
#Override
public void onViewAttachedToWindow(View v) {
Log.d("Filepath", filePath);
Log.d("Position", "" + position);
}
#Override
public void onViewDetachedFromWindow(View v) {
if (filePath.endsWith(".jpg") || currentPage == position || modelFeedArrayList.get(currentPage).getAbsolutePath().endsWith(".jpg")){
currentPage = position;
player.pause();
Objects.requireNonNull(playerView.getPlayer()).pause();
}
else {
player.release();
Objects.requireNonNull(playerView.getPlayer()).release();
}
}
});
} else {
playerView.setVisibility(View.GONE);
statusImageView.setVisibility(View.VISIBLE);
Glide.with(context).load(modelFeedArrayList.get(position)).into(statusImageView);
statusImageView.setBackgroundColor(context.getResources().getColor(android.R.color.black));
}
Objects.requireNonNull(container).addView(itemView);
return itemView;
}
#Override
public void destroyItem(#NonNull #NotNull ViewGroup container, int position, #NonNull #NotNull Object object) {
container.removeView((ConstraintLayout) object);
}
Thank you StackOverflow community for viewing this question. I resolved the above issue by below mentioned modifications :-
Changes in ImageSliderAdapter (PagerAdapter) :-
-> Below mentioned code was added in onViewAttachedToWindow(View v) :-
if (filePath.endsWith(".jpg") || currentPage == position || modelFeedArrayList.get(currentPage).getAbsolutePath().endsWith(".jpg")){
currentPage = position;
player.pause();
Objects.requireNonNull(playerView.getPlayer()).pause();
}
else {
player.pause();
Objects.requireNonNull(playerView.getPlayer()).pause();
if (filePath.endsWith(".mp4")){
player.pause();
Objects.requireNonNull(playerView.getPlayer()).pause();
}
else {
player.play();
Objects.requireNonNull(playerView.getPlayer()).play();
}
}
-> Below mentioned code was added in onViewDetachedFromWindow(View v) :-
if (filePath.endsWith(".mp4")){
player.release();
Objects.requireNonNull(playerView.getPlayer()).release();
}
-> player.play() was added after player.prepare().
Changes in StatusViewer Java class :-
-> The below changes cured the issue of player malfunctioning and player's play state and release state. I used the smoothScroll: false in setCurrentItem.
viewPager.setCurrentItem(position,false);

Change the backcolor of current line of caret position [duplicate]

I have uploaded a image of what i want to achive...
So as you can see i want to highlight the line i click on [And update it on _textchanged event!
Is there any possible way of doing this in any colour... doesnt have to be yellow. I have searched alot but i cant understand how to get the starting length and end length and all of that.
It has confused me alot and i don;'t understand and would require some help.
Thanks for all help that is given in this thread. Also it is windows form. Im making a notepad app like notepad++ or some other notepad app... .NET Windows Form C# RichTextBox
You'll need to create your own control that inherits from RichTextBox and use that control on your form. Since the RichTextBox does not support owner drawing, you will have to listen for the WM_PAINT message and then do your work in there. Here is an example that works fairly well, though the line height is hard coded right now:
public class HighlightableRTB : RichTextBox
{
// You should probably find a way to calculate this, as each line could have a different height.
private int LineHeight = 15;
public HighlightableRTB()
{
HighlightColor = Color.Yellow;
}
[Category("Custom"),
Description("Specifies the highlight color.")]
public Color HighlightColor { get; set; }
protected override void OnSelectionChanged(EventArgs e)
{
base.OnSelectionChanged(e);
this.Invalidate();
}
private const int WM_PAINT = 15;
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_PAINT)
{
var selectLength = this.SelectionLength;
var selectStart = this.SelectionStart;
this.Invalidate();
base.WndProc(ref m);
if (selectLength > 0) return; // Hides the highlight if the user is selecting something
using (Graphics g = Graphics.FromHwnd(this.Handle))
{
Brush b = new SolidBrush(Color.FromArgb(50, HighlightColor));
var line = this.GetLineFromCharIndex(selectStart);
var loc = this.GetPositionFromCharIndex(this.GetFirstCharIndexFromLine(line));
g.FillRectangle(b, new Rectangle(loc, new Size(this.Width, LineHeight)));
}
}
else
{
base.WndProc(ref m);
}
}
}

Show a toast message when a text is recognized from camera

I am trying to detect a text with a specific format from a live camera feed and show a toast message when that text is detected automatically.
I was able to detect the text and put a box around it. But I'm having a hard time showing that toast message.
This is the receiveDetections method from the Processor
#Override
public void receiveDetections(Detector.Detections<TextBlock> detections) {
mGraphicOverlay.clear();
SparseArray<TextBlock> items = detections.getDetectedItems();
for (int i = 0; i < items.size(); ++i) {
TextBlock item = items.valueAt(i);
if (item != null && item.getValue() != null) {
Log.d("OcrDetectorProcessor", "Text detected! " + item.getValue());
// Check if it is the correct format
if (item.getValue().matches("^\\d{3} \\d{3} \\d{4} \\d{4}")){
OcrGraphic graphic = new OcrGraphic(mGraphicOverlay, item);
mGraphicOverlay.add(graphic);
// Show the toast message
}
}
}
}
-> Showing a toast is not my end goal, If I'm able to fix that I'll fix the main problem.
-> I'm building on top of the code labs tutorial for the text vision api
First pass context to OcrDetectorProcessor class from OcrCaptureActivity and runUiThread from that context. This piece of code show all text at once. If you want to show words one by one you need to split from TextBlock items.
Context context;
OcrDetectorProcessor(GraphicOverlay<OcrGraphic> ocrGraphicOverlay, Context context) {
mGraphicOverlay = ocrGraphicOverlay;
this.context = context;
}
#Override
public void receiveDetections(Detector.Detections<TextBlock> detections) {
mGraphicOverlay.clear();
final String result;
String detectedText = "";
SparseArray<TextBlock> items = detections.getDetectedItems();
for (int i = 0; i < items.size(); ++i) {
final TextBlock item = items.valueAt(i);
OcrGraphic graphic = new OcrGraphic(mGraphicOverlay, item);
mGraphicOverlay.add(graphic);
detectedText += item.getValue();
}
result = detectedText;
((OcrCaptureActivity)context).runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(context, result, Toast.LENGTH_SHORT).show();
}
});
}

how to set xaml mapcontrol mapicon always visible

I'm fairly new to programming in XAML and I'm making a test application on windows phone 8.1 emulator with a MapControl.
I wanted to add a MapIcon to my map but the icon doesn't appear when the map is zoomed out. I've searched the internet and couldn't find anything regarding my problem.
I want my zoomlevel 12 and show the mapicon on that zoomlevel.
namespace TEST.APPLICATION
{
public partial class MapView : Page
{
Geolocator geo = null;
public MapView()
{
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
HardwareButtons.BackPressed += HardwareButtons_BackPressed;
}
void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
{
if (Frame.CanGoBack)
{
e.Handled = true;
Frame.GoBack();
}
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
map.Center = new Geopoint(new BasicGeoposition()
{
Latitude = 51.5856935784736,
Longitude = 4.79448171225132
});
map.ZoomLevel = 12;
displaySightings();
}
private void displaySightings()
{
MapIcon sighting1 = new MapIcon();
sighting1.Location = new Geopoint(new BasicGeoposition()
{
Latitude = 51.5940,
Longitude = 4.7795
});
//sighting1.NormalizedAnchorPoint = new Point(0.5, 1.0);
sighting1.Title = "VVV";
map.MapElements.Add(sighting1);
}
}
Is there any way to make the MapIcon always visible?
The MapIcon is not guaranteed to be shown. It may be hidden when it obscures other elements or labels on the map.
For some stupid reason, Microsoft thought that labels and other map elements should outrank map icons when rendering the display. So, if you're making an app displaying the locations of all the nearby Starbucks, the name of the high school across the street from the Starbucks is more important than the pushpin, according to them.
You'll need to render the pushpins using XAML instead.

Telerik Mail Merge - Friendly Names (using RadRichTextBox)

I think i'm missing something obvious...
I'm using the Telerik Rad controls for WPF but i assume that the Rich text box uses some similar implementation for the mail merge functionality.
I want to have some friendly names on my mail merge fields. (namely spaces in the field names)
So i have a class for instance
Public Class someclass
{
<DisplayName("This is the complex description of the field")>
Public property thisfieldnamehasacomplexdescription as string
Public property anothercomplexfield as string
}
This is the only way i know to get "Friendly" names in the dropdown that is the mail merge.
So the two fields turn up okay as :
"This is the complex description of the field"
"anothercomplexfield"
but only anothercomplexfield actually populates with data when you do the merge.
Am i going to have to template the raddropdownbutton that holds the mail merge fields?
Is there an example of this somewhere?
Also a sub question. How do i add a scroll bar on these things?
(also i know this board is not a TELERIK specific board (duh!) but this might be useful to someone in the future. So i'll copy the answer i get from Telerik into here!
http://www.telerik.com/community/forums/wpf/richtextbox/558428-radrichtextbox-mailmerge---using-displayname-to-create-a-friendly-name-with-spaces.aspx )
This is what telerik gave me:
With the default MergeFields, it is not possible to change the display name fragment of the field in order to achieve a more friendly look. This should be possible if you implement a custom MergeField by deriving from the MergeField class. Here is a sample implementation that shows how this can be done:
public class CustomMergeField : MergeField
{
private const string CustomFieldName = "CustomField";
static CustomMergeField()
{
CodeBasedFieldFactory.RegisterFieldType(CustomMergeField.CustomFieldName, () => { return new CustomMergeField(); });
}
public override string FieldTypeName
{
get
{
return CustomMergeField.CustomFieldName;
}
}
public override Field CreateInstance()
{
return new CustomMergeField();
}
protected override DocumentFragment GetDisplayNameFragment()
{
return base.CreateFragmentFromText(string.Format(Field.DisplayNameFragmentFormat, this.GetFriendlyFieldName(this.PropertyPath)));
}
private string GetFriendlyFieldName(string fieldName)
{
int lettersInEnglishAlphabet = 26;
List<char> separators = new List<char>(lettersInEnglishAlphabet);
for (int i = 0; i < lettersInEnglishAlphabet; i++)
{
separators.Add((char)('A' + i));
}
StringBuilder newFieldName = new StringBuilder();
int previousIndex = 0;
for (int i = 1; i < fieldName.Length; i++)
{
if (separators.Contains(fieldName[i]))
{
if (previousIndex > 0)
{
newFieldName.Append(" ");
}
newFieldName.Append(fieldName.Substring(previousIndex, i - previousIndex));
previousIndex = i;
}
}
newFieldName.Append(" " + fieldName.Substring(previousIndex));
return newFieldName.ToString();
}
}
Note that the fragment that is shown when the DisplayMode is Code cannot be changed.
As for your other question, you can change the content of the dropdown button to show the friendly name of the fields and to include a scrollbar in the following way:
1. First, remove the binding of the button to the InsertMergeFieldEmptyCommand from XAML and give it a name (e.g. insertMergeField).
2. Next, add the following code in code-behind:
AddMergeFieldsInDropDownContent(this.insertMergeFieldButton);
private void AddMergeFieldsInDropDownContent(RadRibbonDropDownButton radRibbonDropDownButton)
{
Grid grid = new Grid();
grid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(100, GridUnitType.Pixel) });
ScrollViewer scrollViewer = new ScrollViewer();
scrollViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
StackPanel stackPanel = new StackPanel();
foreach (string fieldName in this.editor.Document.MailMergeDataSource.GetColumnNames())
{
RadRibbonButton fieldButton = new RadRibbonButton()
{
Text = this.GetFriendlyFieldName(fieldName),
Size = ButtonSize.Medium,
HorizontalAlignment = HorizontalAlignment.Stretch,
HorizontalContentAlignment = HorizontalAlignment.Left
};
fieldButton.Command = this.editor.Commands.InsertFieldCommand;
fieldButton.CommandParameter = new MergeField() { PropertyPath = fieldName };
//or
//fieldButton.CommandParameter = new CustomMergeField() { PropertyPath = fieldName };
stackPanel.Children.Add(fieldButton);
}
stackPanel.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
scrollViewer.Content = stackPanel;
grid.Children.Add(scrollViewer);
radRibbonDropDownButton.DropDownContent = grid;
}
You can, of course optimize the code of the GetFriendlyName method and add it in a way that will be available by both classes.