diff --git a/src/calculator/main.rs b/src/calculator/main.rs
index cfd5032add09723e1a51d2347fa99765d28b828c..4466ebd915ae81497a3db0520c5def4878140597 100644
--- a/src/calculator/main.rs
+++ b/src/calculator/main.rs
@@ -278,7 +278,7 @@ fn eval(input: &str) -> String {
 }
 
 fn main(){
-    let window = Window::new(Rect::new(100, 100, 148, 210), "Calculator");
+    let mut window = Window::new(Rect::new(100, 100, 148, 210), "Calculator");
 
     {
         let text_box = TextBox::new();
diff --git a/src/file_manager/main.rs b/src/file_manager/main.rs
index 22117b463e5d90b6f97a5bfbca4e0d7777d517e3..d56bb0268501a69e14c4a3e2efc50f27cc46023c 100644
--- a/src/file_manager/main.rs
+++ b/src/file_manager/main.rs
@@ -4,6 +4,7 @@
 extern crate orbclient;
 extern crate orbimage;
 extern crate orbfont;
+extern crate orbtk;
 
 use std::{cmp, env, fs};
 use std::collections::BTreeMap;
@@ -11,10 +12,13 @@ use std::path::{Path, PathBuf};
 use std::process::Command;
 use std::string::{String, ToString};
 use std::vec::Vec;
+use std::sync::mpsc::{channel, Sender, Receiver};
+use std::sync::Arc;
 
-use orbclient::{event, Color, EventOption, MouseEvent, Renderer, Window};
+use orbclient::{Color, Renderer};
 use orbimage::Image;
-use orbfont::Font;
+
+use orbtk::{Window, Point, Rect, List, Entry, Label, Place, Text, Click};
 
 const ICON_SIZE: i32 = 32;
 
@@ -193,15 +197,7 @@ impl FileTypesInfo {
 enum FileManagerCommand {
     ChangeDir(String),
     Execute(String),
-    Redraw(DrawCommand),
-    Quit,
-}
-
-enum DrawCommand {
-    Everything,
-    Nothing,
-    Rows(Vec<usize>),
-    ScrollButtons,
+    ChangeSort(usize),
 }
 
 #[derive(PartialEq)]
@@ -236,16 +232,14 @@ struct Column {
 pub struct FileManager {
     file_types_info: FileTypesInfo,
     files: Vec<FileInfo>,
-    selected: isize,
     columns: [Column; 3],
+    column_labels: Vec<Arc<Label>>,
     sort_predicate: SortPredicate,
     sort_direction: SortDirection,
-    last_mouse_event: MouseEvent,
     window: Window,
-    font: Font,
-    row_limit: usize,
-    row_offset: usize,
-    scroll_selected: usize,
+    list_widget_index: Option<usize>,
+    tx: Sender<FileManagerCommand>,
+    rx: Receiver<FileManagerCommand>,
 }
 
 fn load_icon(path: &Path) -> Image {
@@ -264,10 +258,11 @@ fn load_icon(path: &Path) -> Image {
 
 impl FileManager {
     pub fn new() -> Self {
+        let (tx, rx) = channel();
+
         FileManager {
             file_types_info: FileTypesInfo::new(),
             files: Vec::new(),
-            selected: -1,
             columns: [
                 Column {
                     name: "Name",
@@ -288,114 +283,13 @@ impl FileManager {
                     sort_predicate: SortPredicate::Type,
                 },
             ],
+            column_labels: Vec::new(),
             sort_predicate: SortPredicate::Name,
             sort_direction: SortDirection::Asc,
-            last_mouse_event: MouseEvent {
-                x: 0,
-                y: 0,
-                left_button: false,
-                middle_button: false,
-                right_button: false,
-            },
-            window: Window::new(-1, -1, 0, 0, "").unwrap(),
-            font: Font::find(None, None, None).unwrap(),
-            row_limit: 7,
-            row_offset: 0,
-            scroll_selected: usize::max_value()
-        }
-    }
-
-    fn draw_content(&mut self, redraw_info: DrawCommand) {
-        let mut rows_to_redraw: Vec<usize> = (0..self.files.len()).collect();
-
-        match redraw_info {
-            DrawCommand::Everything => {
-                self.window.set(Color::rgb(255, 255, 255));
-                self.draw_header_row();
-                if self.files.len() > self.row_limit {
-                    self.draw_scroll_buttons();
-                }
-            },
-            DrawCommand::Rows(rows) => {
-                rows_to_redraw = rows;
-            },
-            DrawCommand::Nothing => return,
-            DrawCommand::ScrollButtons => {
-                if self.files.len() > self.row_limit {
-                    self.draw_scroll_buttons();
-                }
-            },
-        }
-
-        self.draw_file_list_range(rows_to_redraw);
-        self.window.sync();
-    }
-
-    fn draw_header_row(&mut self) {
-        for column in self.columns.iter() {
-            let text_y = 8;
-
-            self.font.render(column.name, 16.0).draw(&mut self.window, column.x, text_y, Color::rgb(0, 0, 0));
-            if column.sort_predicate == self.sort_predicate {
-                let arrow = match self.sort_direction {
-                    SortDirection::Asc => self.font.render("↓", 16.0),
-                    SortDirection::Desc => self.font.render("↑", 16.0),
-                };
-                let arrow_x = column.x + column.width - arrow.width() as i32 - 4;
-                arrow.draw(&mut self.window, arrow_x, text_y, Color::rgb(140, 140, 140));
-            }
-        }
-    }
-
-    fn draw_file_list_range(&mut self, rows_to_redraw: Vec<usize>) {
-        for i in rows_to_redraw {
-            if self.files.len() <= self.row_limit
-                    || i < self.row_limit {
-                if let Some(file) = self.files.get(i + self.row_offset) {
-                    let y = ICON_SIZE * i as i32 + 32; // Plus 32 because the header row is 32 pixels
-
-                    let width = self.window.width();
-                    let text_color = if i as isize == self.selected {
-                        self.window.rect(0, y, width, 32, Color::rgb(0x52, 0x94, 0xE2));
-                        Color::rgb(255, 255, 255)
-                    } else {
-                        self.window.rect(0, y, width, 32, Color::rgb(255, 255, 255));
-                        Color::rgb(0, 0, 0)
-                    };
-
-                    {
-                        let icon = self.file_types_info.icon_for(&file.name);
-                        icon.draw(&mut self.window, 4, y);
-                    }
-
-                    self.font.render(&file.name, 16.0).draw(&mut self.window, self.columns[0].x, y + 8, text_color);
-                    self.font.render(&file.size_str, 16.0).draw(&mut self.window, self.columns[1].x, y + 8, text_color);
-
-                    let description = self.file_types_info.description_for(&file.name);
-                    self.font.render(&description, 16.0).draw(&mut self.window, self.columns[2].x, y + 8, text_color);
-                }
-            }
-        }
-    }
-
-    fn draw_scroll_buttons(&mut self) {
-        // text_y = header (32) + row_limit * row height (ICON_SIZE)
-        let text_y = 32 + (self.row_limit * ICON_SIZE as usize) as i32;
-        let width = (self.columns[2].x + self.columns[2].width) as u32;
-        self.window.rect(0, text_y, width, 16, Color::rgb(70, 70, 70));
-        let center = (width / 2) as i32;
-
-        if self.scroll_selected == 0 {
-            self.window.rect(0, text_y, center as u32, 16, Color::rgb(128, 128, 255));
-            self.font.render("scroll down", 16.0).draw(&mut self.window, 0, text_y, Color::rgb(0, 0, 0));
-            self.font.render("scroll up", 16.0).draw(&mut self.window, center, text_y, Color::rgb(255, 255, 255));
-        } else if self.scroll_selected == 1 {
-            self.font.render("scroll down", 16.0).draw(&mut self.window, 0, text_y, Color::rgb(255, 255, 255));
-            self.window.rect(center, text_y, center as u32, 16, Color::rgb(128, 128, 255));
-            self.font.render("scroll up", 16.0).draw(&mut self.window, center, text_y, Color::rgb(0, 0, 0));
-        } else {
-            self.font.render("scroll down", 16.0).draw(&mut self.window, 0, text_y, Color::rgb(255, 255, 255));
-            self.font.render("scroll up", 16.0).draw(&mut self.window, center, text_y, Color::rgb(255, 255, 255));
+            window: Window::new(Rect::new(-1, -1, 0, 0),  ""),
+            list_widget_index: None,
+            tx: tx,
+            rx: rx,
         }
     }
 
@@ -440,6 +334,115 @@ impl FileManager {
         self.files.push(file_info);
     }
 
+    fn update_headers(&mut self) {
+        for (i, column) in self.columns.iter().enumerate() {
+            if let None = self.column_labels.get(i * 2) {
+                // header text
+                let mut label = Label::new();
+                self.window.add(&label);
+                label.bg.set(Color::rgba(255, 255, 255, 0));
+                label.text_offset.set(Point::new(0, 8));
+
+                let tx = self.tx.clone();
+                label.on_click(move |_, _| {
+                    tx.send(FileManagerCommand::ChangeSort(i)).unwrap();
+                });
+                self.column_labels.push(label);
+
+                // sort arrow
+                label = Label::new();
+                self.window.add(&label);
+                label.bg.set(Color::rgba(255, 255, 255, 0));
+                label.fg.set(Color::rgb(140, 140, 140));
+                label.text_offset.set(Point::new(0, 8));
+                self.column_labels.push(label);
+            }
+
+            if let Some(label) = self.column_labels.get(i * 2) {
+                label.position(column.x, 0).size(column.width as u32, 32).text(column.name.clone());
+            }
+
+            if let Some(label) = self.column_labels.get(i * 2 + 1) {
+                if column.sort_predicate == self.sort_predicate {
+                    let arrow = match self.sort_direction {
+                        SortDirection::Asc => "↓",
+                        SortDirection::Desc => "↑",
+                    };
+
+                    label.position(column.x + column.width - 12, 0).size(16, 32).text(arrow);
+                } else {
+                    label.text("");
+                }
+            }
+        }
+    }
+
+    fn update_list(&mut self) {
+        let w = (self.columns[2].x + self.columns[2].width) as u32;
+        let count = cmp::min(self.files.len(), 7);
+        let h = if self.files.len() < 8 {
+            (count * ICON_SIZE as usize) as u32 + 32 // +32 for the header row
+        } else {
+            (7 * ICON_SIZE as usize) as u32 + 32 - 16 // +32 for the header row, -16 to indicate scrolling
+        };
+
+        let list = List::new();
+        list.position(0, 32).size(w, h - 32);
+
+        {
+            for file in self.files.iter() {
+                let entry = Entry::new(ICON_SIZE as u32);
+
+                let path = file.full_path.clone();
+                let tx = self.tx.clone();
+
+                entry.on_click(move |_, _| {
+                    if path.ends_with('/') {
+                        tx.send(FileManagerCommand::ChangeDir(path.clone())).unwrap();
+                    } else {
+                        tx.send(FileManagerCommand::Execute(path.clone())).unwrap();
+                    }
+                });
+
+                {
+                    let icon = self.file_types_info.icon_for(&file.name);
+                    let image = orbtk::Image::from_image((*icon).clone());
+                    image.position(4, 0);
+                    entry.add(&image);
+                }
+
+                let mut label = Label::new();
+                label.position(self.columns[0].x, 0).size(w, ICON_SIZE as u32).text(file.name.clone());
+                label.text_offset.set(Point::new(0, 8));
+                label.bg.set(Color::rgba(255, 255, 255, 0));
+                entry.add(&label);
+
+                label = Label::new();
+                label.position(self.columns[1].x, 0).size(w, ICON_SIZE as u32).text(file.size_str.clone());
+                label.text_offset.set(Point::new(0, 8));
+                label.bg.set(Color::rgba(255, 255, 255, 0));
+                entry.add(&label);
+
+                let description = self.file_types_info.description_for(&file.name);
+                label = Label::new();
+                label.position(self.columns[2].x, 0).size(w, ICON_SIZE as u32).text(description);
+                label.text_offset.set(Point::new(0, 8));
+                label.bg.set(Color::rgba(255, 255, 255, 0));
+                entry.add(&label);
+
+                list.push(&entry);
+            }
+        }
+
+        if let Some(i) = self.list_widget_index {
+            let mut widgets = self.window.widgets.borrow_mut();
+            widgets.remove(i);
+            widgets.insert(i, list);
+        } else {
+            self.list_widget_index = Some(self.window.add(&list));
+        }
+    }
+
     fn set_path(&mut self, path: &str) {
         for column in self.columns.iter_mut() {
             column.width = (column.name.len() * 8) as i32 + 16;
@@ -490,29 +493,29 @@ impl FileManager {
             },
         }
 
-        self.sort_files();
-
         self.columns[0].x = ICON_SIZE + 8;
         self.columns[1].x = self.columns[0].x + self.columns[0].width;
         self.columns[2].x = self.columns[1].x + self.columns[1].width;
 
-        // TODO: HACK ALERT - should use resize whenver that gets added
-        self.window.sync_path();
-
-        let x = self.window.x();
-        let y = self.window.y();
         let w = (self.columns[2].x + self.columns[2].width) as u32;
-        let h = if self.files.len() <= self.row_limit {
-            (self.files.len() * ICON_SIZE as usize) as u32 + 32 // +32 for the header row
+        let count = cmp::min(self.files.len(), 7);
+        let h = if self.files.len() < 8 {
+            (count * ICON_SIZE as usize) as u32 + 32 // +32 for the header row
         } else {
-            // +32 for the header row
-            // +16 for the next/prev/expand/contract text buttons
-            (self.row_limit * ICON_SIZE as usize) as u32 + 32 + 16
+            (7 * ICON_SIZE as usize) as u32 + 32 - 16 // +32 for the header row, -16 to indicate scrolling
         };
 
-        self.window = Window::new(x, y, w, h, &path).unwrap();
+        self.window.set_size(w, h);
+        self.window.set_title(&path);
+        self.window.bg.set(Color::rgb(255, 255, 255));
+
+        self.sort_files();
+
+        self.update_headers();
+
+        self.update_list();
 
-        self.draw_content(DrawCommand::Everything);
+        self.window.needs_redraw();
     }
 
     fn sort_files(&mut self) {
@@ -536,222 +539,6 @@ impl FileManager {
         }
     }
 
-    fn event_loop(&mut self) -> Vec<FileManagerCommand> {
-        let mut commands = Vec::new();
-        for event in self.window.events() {
-            match event.to_option() {
-                EventOption::Key(key_event) => {
-                    if key_event.pressed {
-                        match key_event.scancode {
-                            event::K_ESC => commands.push(FileManagerCommand::Quit),
-                            event::K_HOME => {
-                                commands.push(
-                                    FileManagerCommand::Redraw(
-                                        DrawCommand::Rows(
-                                            [0, self.selected as usize].to_vec()
-                                        )
-                                    )
-                                );
-                                self.selected = 0;
-                            },
-                            event::K_UP => {
-                                if self.selected > 0 {
-                                    commands.push(
-                                        FileManagerCommand::Redraw(
-                                            DrawCommand::Rows(
-                                                [(self.selected - 1) as usize, self.selected as usize].to_vec()
-                                            )
-                                        )
-                                    );
-                                    self.selected -= 1;
-                                }
-                            },
-                            event::K_END => {
-                                let new_selected = self.files.len() as isize - 1;
-                                commands.push(
-                                    FileManagerCommand::Redraw(
-                                        DrawCommand::Rows(
-                                            [new_selected as usize, self.selected as usize].to_vec()
-                                        )
-                                    )
-                                );
-                                self.selected = new_selected;
-                            },
-                            event::K_DOWN => {
-                                if self.selected < self.files.len() as isize - 1 {
-                                    commands.push(
-                                        FileManagerCommand::Redraw(
-                                            DrawCommand::Rows(
-                                                [(self.selected + 1) as usize, self.selected as usize].to_vec()
-                                            )
-                                        )
-                                    );
-                                    self.selected += 1;
-                                }
-                            },
-                            _ => {
-                                match key_event.character {
-                                    '\0' => (),
-                                    '\n' => {
-                                        if self.selected >= 0 &&
-                                           self.selected < self.files.len() as isize {
-                                            match self.files.get(self.selected as usize) {
-                                                Some(file) => {
-                                                    if file.full_path.ends_with('/') {
-                                                        commands.push(FileManagerCommand::ChangeDir(file.full_path.clone()));
-                                                    } else {
-                                                        commands.push(FileManagerCommand::Execute(file.full_path.clone()));
-                                                    }
-                                                }
-                                                None => (),
-                                            }
-                                        }
-                                    }
-                                    _ => {
-                                        // The index of the first matching file
-                                        let mut result_first: Option<isize> = None;
-                                        // The index of the next matching file relative to the current selection
-                                        let mut result_next: Option<isize> = None;
-
-                                        for (i, file) in self.files.iter().enumerate() {
-                                            if file.name.to_lowercase().starts_with(key_event.character) {
-                                                if result_first.is_none() {
-                                                    result_first = Some(i as isize);
-                                                }
-
-                                                if i as isize > self.selected {
-                                                    result_next = Some(i as isize);
-                                                    break;
-                                                }
-                                            }
-                                        }
-
-                                        commands.push(FileManagerCommand::Redraw(DrawCommand::Everything));
-                                        self.selected = result_next.or(result_first).unwrap_or(-1);
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-                EventOption::Mouse(mouse_event) => {
-                    let row_number = (mouse_event.y - 32) / ICON_SIZE;
-
-                    if row_number >= 0 && self.files.get(row_number as usize).is_some() {
-                        if row_number as isize != self.selected {
-                            commands.push(
-                                FileManagerCommand::Redraw(
-                                    DrawCommand::Rows(
-                                        [row_number as usize, self.selected as usize].to_vec()
-                                    )
-                                )
-                            );
-                            self.selected = row_number as isize;
-                        }
-                    }
-
-                    if self.files.len() > self.row_limit {
-                        if mouse_event.y >= (32 + self.row_limit as i32 * ICON_SIZE)
-                                && mouse_event.y < (32 + self.row_limit as i32 * ICON_SIZE + 16) {
-                            if mouse_event.x < (self.columns[2].x + self.columns[2].width)
-                                    / 2 {
-                                self.scroll_selected = 0;
-                            }
-                            else {
-                                self.scroll_selected = 1;
-                            }
-                        } else {
-                            self.scroll_selected = usize::max_value();
-                        }
-                        commands.push(
-                            FileManagerCommand::Redraw(
-                                DrawCommand::ScrollButtons
-                            )
-                        );
-                    }
-
-
-                    if ! mouse_event.left_button && self.last_mouse_event.left_button {
-                        if mouse_event.y < ICON_SIZE { // Header row clicked
-                            if mouse_event.x < self.columns[1].x as i32 {
-                                if self.sort_predicate != SortPredicate::Name {
-                                    self.sort_predicate = SortPredicate::Name;
-                                } else {
-                                    self.sort_direction.invert();
-                                }
-                            } else if mouse_event.x < self.columns[2].x as i32 {
-                                if self.sort_predicate != SortPredicate::Size {
-                                    self.sort_predicate = SortPredicate::Size;
-                                } else {
-                                    self.sort_direction.invert();
-                                }
-                            } else {
-                                if self.sort_predicate != SortPredicate::Type {
-                                    self.sort_predicate = SortPredicate::Type;
-                                } else {
-                                    self.sort_direction.invert();
-                                }
-                            }
-                            self.sort_files();
-                            commands.push(FileManagerCommand::Redraw(DrawCommand::Everything));
-                        } else if self.files.len() > self.row_limit
-                                && mouse_event.y >= 32 + self.row_limit as i32 * ICON_SIZE {
-                            if self.scroll_selected == 0 {
-                                // scroll down pressed
-                                if self.row_offset + self.row_limit < self.files.len() - 1 {
-                                    self.row_offset += 2;
-                                } else if self.row_offset + self.row_limit < self.files.len() {
-                                    self.row_offset += 1;
-                                }
-                            } else if self.scroll_selected == 1 {
-                                // scroll up pressed
-                                if self.row_offset > 1 {
-                                    self.row_offset -= 2;
-                                } else if self.row_offset > 0 {
-                                    self.row_offset -= 1;
-                                }
-                            }
-                        } else if self.last_mouse_event.x == mouse_event.x &&
-                                  self.last_mouse_event.y == mouse_event.y {
-                            if self.selected >= 0 && self.selected < self.files.len() as isize {
-                                if let Some(file) = self.files.get(self.selected as usize + self.row_offset) {
-                                    if file.full_path.ends_with('/') {
-                                        commands.push(FileManagerCommand::ChangeDir(file.full_path.clone()));
-                                    } else {
-                                        commands.push(FileManagerCommand::Execute(file.full_path.clone()));
-                                    }
-                                }
-                            }
-                        }
-                    }
-                    self.last_mouse_event = mouse_event;
-                },
-                EventOption::Scroll(scroll_event) => {
-                    if scroll_event.y <= -1 {
-                        // scroll down pressed
-                        if self.row_offset + self.row_limit < self.files.len() - 1 {
-                            self.row_offset += 2;
-                        } else if self.row_offset + self.row_limit < self.files.len() {
-                            self.row_offset += 1;
-                        }
-                        commands.push(FileManagerCommand::Redraw(DrawCommand::Everything));
-                    } else if scroll_event.y >= 1  {
-                        // scroll up pressed
-                        if self.row_offset > 1 {
-                            self.row_offset -= 2;
-                        } else if self.row_offset > 0 {
-                            self.row_offset -= 1;
-                        }
-                        commands.push(FileManagerCommand::Redraw(DrawCommand::Everything));
-                    }
-                },
-                EventOption::Quit(_) => commands.push(FileManagerCommand::Quit),
-                _ => (),
-            }
-        }
-        commands
-    }
-
     fn main(&mut self, path: &str) {
         // Filter out invalid paths
         let mut path = match fs::canonicalize(path.to_owned()) {
@@ -764,25 +551,43 @@ impl FileManager {
 
         println!("main path: {}", path);
         self.set_path(&path);
-        self.draw_content(DrawCommand::Everything);
-        'events: loop {
-            let mut redraw_info = DrawCommand::Nothing;
-            for event in self.event_loop() {
+        self.window.draw_if_needed();
+
+        while self.window.running.get() {
+
+            self.window.step();
+
+            while let Ok(event) = self.rx.try_recv() {
+
                 match event {
                     FileManagerCommand::ChangeDir(dir) => {
-                        self.selected = 0;
                         self.set_path(&dir);
-                        self.row_offset = 0;
                     }
                     FileManagerCommand::Execute(cmd) => {
                         Command::new(LAUNCH_COMMAND).arg(&cmd).spawn().unwrap();
                     },
-                    FileManagerCommand::Redraw(ri) => redraw_info = ri,
-                    FileManagerCommand::Quit => break 'events,
-                };
+                    FileManagerCommand::ChangeSort(i) => {
+                        let predicate = match i {
+                            0 => SortPredicate::Name,
+                            1 => SortPredicate::Size,
+                            2 => SortPredicate::Type,
+                            _ => return
+                        };
+
+                        if self.sort_predicate != predicate {
+                            self.sort_predicate = predicate;
+                        } else {
+                            self.sort_direction.invert();
+                        }
+
+                        self.update_headers();
+                        self.sort_files();
+                        self.update_list();
+                    },
+                }
             }
 
-            self.draw_content(redraw_info);
+            self.window.draw_if_needed();
         }
     }
 }