Sorry it has been awhile, but good news! I got a job! I was dealing with all the onboarding stuff, but things should slightly return to normal for a while. Also because I got a job schedule is going to change somewhat. I will now be getting my kid one night a week, and every other weekend. So on the weekends that I have my son I might not be doing work, and the night I have it, I for sure wont be doing work. I'll be getting him either on Tuesday or Thursday, so only one open source day a week.
Also for my game, I've just been going over tutorials so I haven't been writing any blog posts about that. I'm going to keep going over tutorials for the next few weeks till I feel good to start. Hopefully by that time I have my new computer up and running so I can stream. I would prefer to stream the whole process from start to finish, I think that would be pretty rad.
Anyways, let's get into what work happened today. Made some good progress on my Alarm Clock
today! It's almost functional, I got alarms showing up, but it's sloppy and I don't like it. I ended up just removing the code and instead of using Icon Balloons I'm just going to create a new window. Not only do I don't have to worry about the balloon just going away, but it should make dealing with all the thread stuff of the sound player easier. To bad I already spend a good chunk of time getting the threading stuff working, oops.
Okay, so what did I work on. Hmmm honestly just a bunch of little things. First let's start here.
public static string PickFile()
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "audio files (*.mp3;*.wma;*.wav)|*.mp3;*.wma;*.wav|All files (*.*)|*.*";
if (ofd.ShowDialog() == true)
So I needed a file selector. I forgot when I was making all the alarm windows, I need both an alarm sound and alarm text. That way you can have a sound notify you, and text to remind you of what the alarm was about. So for the file picker we used this OpenFileDialog class. It's part of the Win32 stuff, so it's part of windows itself. So once we make a new OpenFileDialog object, we filter what files to use, and then just grab the file path and return that back. I'm not going to be showing every single line of code that was changed, cause that will get messy, so if you want to look around, I already linked the github project. Anyways, for the filtering of files, we only want someone to use an audio file. I had a hard time finding exactly what was supported in the MediaPlayer class I use, but I know these three for sure work. I tested it out, and if you use some kind of other file, it just wont do anything, so that's good.
So on the three different alarm window classes, I added a spot for slecting/removing an audio file, and a text box for the alarm text. Some some basic xmal stuff really. I also added a way that when a new alarm window is open, you can't open the main window. I did this by just enabling and disabling the context menu that opens the main window. I also added the stuff to add/edit/open alarm text and sound file path.
Also on the TimeForAlarm parent class added two new properties for text and file path. As well as to the datagrid xaml so that info shows up on the mainwindow as well.
private void timerTriggered(object sender, ElapsedEventArgs e)
foreach (var item in TimeForAlarms)
if (item.AlarmTriggered() && !item.getTriggered())
Okay so moving to triggering the alarm itself. If you recall I already showed some of this. All that was really changed was that AlarmWentOff returns an alarm, and we call show alarm.
public void ShowAlarm(TimeForAlarm alarm)
//using a balloon is a mess, going to just make a new window instead
string text = alarm.AlarmText;
if (text == "")
text = "Alarm Went Off";
Window.NotifyIcon.ShowBalloonTip("Alarm Went Off", text,
Window.NotifyIcon.TrayBalloonTipShown += (sender, e) => OpenBalloon(sender, e, alarm.GetAlarmSound());
Window.NotifyIcon.TrayBalloonTipClosed += (sender, e) => CloseBalloon(sender, e);
Okay here is where we do trigger the alarm. Although this code will end up being scrapped it's cool to go over. So I found out if you have an empty string as the text in a balloon it wont show up. So first we just make sure we have some sort of text to show. Then we trigger the balloon and if there is a sound file attached we add some events to the balloon open and closing. Now I already said the balloon closes on it's own sometimes, but another reason I want to move it to it's window thing is because that way it will handle more then one alarm at a time. Granted you most likely wouldn't want a pile of alarms going off at the same time, and even more so don't want them all to have audio ques, but maybe you do. I don't judge.
private void OpenBalloon(object sender, EventArgs e, string sound)
SoundPlayer = new MediaPlayer();
SoundPlayer.MediaEnded += LoopAlarm;
private void CloseBalloon(object sender, EventArgs e)
private void LoopAlarm(object sender, EventArgs e)
MediaPlayer player = (MediaPlayer)sender;
player.Position = TimeSpan.Zero;
player.Volume -= 5;
This is all the events from the previous method. We have opening and closing of the balloon which are pretty straight forward, but we also have this LoopAlarm event. Well we wouldn't want a sound for an alarm to just go off once, but I also don't want it to go off forever. So what we do is every time the media finishes, we set the position back to 0 and play it again, the key is we lower the sound every time it loops. I could also set it up so it goes a set number of times, or set length of time, but whatever, small changes if needed. Also I guess wrap that all around an if statement where it checks if volume is 0, just so it's not trying to play it over and over and be wasteful.
I guess that's really it for today. We are pretty close to done, I can think of 3 main things that need to be finished. First, move the whole balloon business to a window. Second, have saving and loading so if you close the program, or restart your computer, it will load up all your alarms. Finally, need to get an installer working, so people can just download an setup exe and install it instead of downloading the source code and running it out of the bin file. Well see you next time!