diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ChatActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ChatActivity.kt
index 19cf45c49e248c5c87d31ed1e7f239e634f4f60e..42b7c8edde245950d0c3b43557eb0b305e27188a 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ChatActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ChatActivity.kt
@@ -112,7 +112,6 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
         findViewById(R.id.autocomplete_list),
         findViewById(R.id.autocomplete_list_expanded)
       ),
-      findViewById(R.id.formatting_menu),
       findViewById(R.id.formatting_toolbar),
       appearanceSettings,
       autoCompleteSettings,
@@ -279,6 +278,12 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
       recreate()
     }
     super.onStart()
+    editor.onStart()
+  }
+
+  override fun onStop() {
+    editor.onStop()
+    super.onStop()
   }
 
   data class AutoCompletionState(
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/Editor.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/Editor.kt
index 94dba8dc1f0df78551557bb5fcd3ae42feb43797..b02c6fb18cd2266bb42c7bb1e9c60b6bf544d91a 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/Editor.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/Editor.kt
@@ -7,19 +7,16 @@ import android.support.v7.widget.*
 import android.text.Editable
 import android.text.InputType
 import android.text.TextWatcher
-import android.view.GestureDetector
-import android.view.KeyEvent
-import android.view.MenuItem
-import android.view.MotionEvent
+import android.view.*
 import android.view.inputmethod.EditorInfo
+import butterknife.BindView
+import butterknife.ButterKnife
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.settings.AppearanceSettings
 import de.kuschku.quasseldroid.settings.AutoCompleteSettings
 import de.kuschku.quasseldroid.ui.chat.ChatActivity
-import de.kuschku.quasseldroid.util.helper.lastWordIndices
-import de.kuschku.quasseldroid.util.helper.lineSequence
-import de.kuschku.quasseldroid.util.helper.retint
-import de.kuschku.quasseldroid.util.helper.visibleIf
+import de.kuschku.quasseldroid.util.helper.*
+import de.kuschku.quasseldroid.util.ui.EditTextSelectionChange
 import de.kuschku.quasseldroid.viewmodel.data.AutoCompleteItem
 import io.reactivex.Observable
 import io.reactivex.subjects.BehaviorSubject
@@ -31,11 +28,10 @@ class Editor(
   private val autoCompleteData: LiveData<Pair<String, List<AutoCompleteItem>>>,
   lastWordContainer: BehaviorSubject<Observable<Pair<String, IntRange>>>,
   // Views
-  val chatline: AppCompatEditText,
+  val chatline: EditTextSelectionChange,
   send: AppCompatImageButton,
   tabComplete: AppCompatImageButton,
   autoCompleteLists: List<RecyclerView>,
-  formattingMenu: ActionMenuView,
   formattingToolbar: Toolbar,
   // Settings
   private val appearanceSettings: AppearanceSettings,
@@ -49,7 +45,7 @@ class Editor(
       panelStateCallback(true)
       true
     }
-    else                      -> formatHandler.onMenuItemClick(item)
+    else                      -> false
   }
 
   private val lastWord = BehaviorSubject.createDefault(Pair("", IntRange.EMPTY))
@@ -78,6 +74,8 @@ class Editor(
       }
 
       lastWord.onNext(next ?: Pair("", IntRange.EMPTY))
+
+      updateButtons(chatline.selection)
     }
 
     override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) = Unit
@@ -88,6 +86,30 @@ class Editor(
 
   private var autocompletionState: ChatActivity.AutoCompletionState? = null
 
+  @BindView(R.id.action_format_bold)
+  lateinit var boldButton: View
+
+  @BindView(R.id.action_format_italic)
+  lateinit var italicButton: View
+
+  @BindView(R.id.action_format_underline)
+  lateinit var underlineButton: View
+
+  @BindView(R.id.action_format_strikethrough)
+  lateinit var strikethroughButton: View
+
+  @BindView(R.id.action_format_monospace)
+  lateinit var monospaceButton: View
+
+  @BindView(R.id.action_format_foreground)
+  lateinit var foregroundButton: View
+
+  @BindView(R.id.action_format_background)
+  lateinit var backgroundButton: View
+
+  @BindView(R.id.action_format_clear)
+  lateinit var clearButton: View
+
   init {
     send.setOnClickListener {
       send()
@@ -121,8 +143,6 @@ class Editor(
       )
     }.fold(0, Int::or)
 
-    chatline.addTextChangedListener(textWatcher)
-
     val autocompleteAdapter = AutoCompleteAdapter(
       // This is still broken when mixing tab complete and UI auto complete
       formatHandler::autoComplete
@@ -168,13 +188,75 @@ class Editor(
 
     lastWordContainer.onNext(lastWord)
 
-    activity.menuInflater.inflate(formatHandler.menu, formattingMenu.menu)
-    formattingMenu.menu.retint(activity)
-    formattingMenu.setOnMenuItemClickListener(this)
-
     activity.menuInflater.inflate(R.menu.editor, formattingToolbar.menu)
     formattingToolbar.menu.retint(activity)
     formattingToolbar.setOnMenuItemClickListener(this)
+
+    ButterKnife.bind(this, formattingToolbar)
+
+    boldButton.setOnClickListener {
+      formatHandler.toggleBold(chatline.selection)
+      updateButtons(chatline.selection)
+    }
+    italicButton.setOnClickListener {
+      formatHandler.toggleItalic(chatline.selection)
+      updateButtons(chatline.selection)
+    }
+    underlineButton.setOnClickListener {
+      formatHandler.toggleUnderline(chatline.selection)
+      updateButtons(chatline.selection)
+    }
+    strikethroughButton.setOnClickListener {
+      formatHandler.toggleStrikethrough(chatline.selection)
+      updateButtons(chatline.selection)
+    }
+    monospaceButton.setOnClickListener {
+      formatHandler.toggleMonospace(chatline.selection)
+      updateButtons(chatline.selection)
+    }
+    clearButton.setOnClickListener {
+      formatHandler.clearFormatting(chatline.selection)
+      updateButtons(chatline.selection)
+    }
+
+    chatline.setOnKeyListener { _, keyCode, event ->
+      if (event.isCtrlPressed && !event.isAltPressed) when (keyCode) {
+        KeyEvent.KEYCODE_B -> {
+          formatHandler.toggleBold(chatline.selection)
+          updateButtons(chatline.selection)
+          true
+        }
+        KeyEvent.KEYCODE_I -> {
+          formatHandler.toggleItalic(chatline.selection)
+          updateButtons(chatline.selection)
+          true
+        }
+        KeyEvent.KEYCODE_U -> {
+          formatHandler.toggleUnderline(chatline.selection)
+          updateButtons(chatline.selection)
+          true
+        }
+        else               -> false
+      } else false
+    }
+  }
+
+  fun updateButtons(selection: IntRange) {
+    boldButton.isSelected = formatHandler.isBold(selection)
+    italicButton.isSelected = formatHandler.isItalic(selection)
+    underlineButton.isSelected = formatHandler.isUnderline(selection)
+    strikethroughButton.isSelected = formatHandler.isStrikethrough(selection)
+    monospaceButton.isSelected = formatHandler.isMonospace(selection)
+  }
+
+  fun onStart() {
+    chatline.addTextChangedListener(textWatcher)
+    chatline.setSelectionChangeListener(::updateButtons)
+  }
+
+  fun onStop() {
+    chatline.removeTextChangedListener(textWatcher)
+    chatline.removeSelectionChangeListener()
   }
 
   private fun send() {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/FormatHandler.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/FormatHandler.kt
index 770e01905b5fbff73547d38bb7772752c4b26c79..f7c0d85470757bb824389a4fb78d23c153f56657 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/FormatHandler.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/FormatHandler.kt
@@ -1,7 +1,6 @@
 package de.kuschku.quasseldroid.ui.chat.input
 
 import android.graphics.Typeface
-import android.support.annotation.MenuRes
 import android.text.Editable
 import android.text.SpannableString
 import android.text.Spanned
@@ -9,13 +8,12 @@ import android.text.style.StrikethroughSpan
 import android.text.style.StyleSpan
 import android.text.style.TypefaceSpan
 import android.text.style.UnderlineSpan
-import android.view.MenuItem
 import android.widget.EditText
-import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.ui.chat.ChatActivity
 import de.kuschku.quasseldroid.util.helper.lastWordIndices
 import de.kuschku.quasseldroid.util.helper.lineSequence
 import de.kuschku.quasseldroid.util.helper.selection
+import de.kuschku.quasseldroid.util.helper.without
 import de.kuschku.quasseldroid.util.irc.format.IrcFormatSerializer
 import de.kuschku.quasseldroid.util.irc.format.spans.*
 
@@ -42,14 +40,13 @@ class FormatHandler(
       text
     }
 
-  @MenuRes
-  val menu: Int = R.menu.formatting
+  fun isBold(range: IntRange) = editText.text.hasSpans<StyleSpan>(range) {
+    it.style == Typeface.BOLD || it.style == Typeface.BOLD_ITALIC
+  }
 
   fun toggleBold(range: IntRange, createNew: Boolean = true) {
-    if (range.isEmpty())
-      return
-
-    val exists = editText.text.removeSpans<StyleSpan, IrcBoldSpan>(range) { span ->
+    val bold = isBold(range)
+    editText.text.removeSpans<StyleSpan, IrcBoldSpan>(range) { span ->
       when {
         span is IrcBoldSpan         -> span
         span.style == Typeface.BOLD -> IrcBoldSpan()
@@ -57,18 +54,21 @@ class FormatHandler(
       }
     }
 
-    if (!exists && createNew) {
+    if (!bold && createNew) {
       editText.text.setSpan(
-        IrcBoldSpan(), range.start, range.endInclusive + 1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE
+        IrcBoldSpan(), range.start, range.endInclusive + 1, Spanned.SPAN_INCLUSIVE_INCLUSIVE
       )
     }
   }
 
+  fun isItalic(range: IntRange) = editText.text.hasSpans<StyleSpan>(range) {
+    it.style == Typeface.ITALIC || it.style == Typeface.BOLD_ITALIC
+  }
+
   fun toggleItalic(range: IntRange, createNew: Boolean = true) {
-    if (range.isEmpty())
-      return
+    val italic = isItalic(range)
 
-    val exists = editText.text.removeSpans<StyleSpan, IrcItalicSpan>(range) { span ->
+    editText.text.removeSpans<StyleSpan, IrcItalicSpan>(range) { span ->
       when {
         span is IrcItalicSpan         -> span
         span.style == Typeface.ITALIC -> IrcItalicSpan()
@@ -76,55 +76,60 @@ class FormatHandler(
       }
     }
 
-    if (!exists && createNew) {
+    if (!italic && createNew) {
       editText.text.setSpan(
-        IrcItalicSpan(), range.start, range.endInclusive + 1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE
+        IrcItalicSpan(), range.start, range.endInclusive + 1, Spanned.SPAN_INCLUSIVE_INCLUSIVE
       )
     }
   }
 
+  fun isUnderline(range: IntRange) = editText.text.hasSpans<UnderlineSpan>(range)
+
   fun toggleUnderline(range: IntRange, createNew: Boolean = true) {
-    if (range.isEmpty())
-      return
+    val underline = isUnderline(range)
 
-    val exists = editText.text.removeSpans<UnderlineSpan, IrcUnderlineSpan>(range) { span ->
+    editText.text.removeSpans<UnderlineSpan, IrcUnderlineSpan>(range) { span ->
       when (span) {
         is IrcUnderlineSpan -> span
         else                -> IrcUnderlineSpan()
       }
     }
 
-    if (!exists && createNew) {
+    if (!underline && createNew) {
       editText.text.setSpan(
-        IrcUnderlineSpan(), range.start, range.endInclusive + 1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE
+        IrcUnderlineSpan(), range.start, range.endInclusive + 1, Spanned.SPAN_INCLUSIVE_INCLUSIVE
       )
     }
   }
 
+  fun isStrikethrough(range: IntRange) = editText.text.hasSpans<StrikethroughSpan>(range)
+
   fun toggleStrikethrough(range: IntRange, createNew: Boolean = true) {
-    if (range.isEmpty())
-      return
+    val strikethrough = isStrikethrough(range)
 
-    val exists = editText.text.removeSpans<StrikethroughSpan, IrcStrikethroughSpan>(range) { span ->
+    editText.text.removeSpans<StrikethroughSpan, IrcStrikethroughSpan>(range) { span ->
       when (span) {
         is IrcStrikethroughSpan -> span
         else                    -> IrcStrikethroughSpan()
       }
     }
 
-    if (!exists && createNew) {
+    if (!strikethrough && createNew) {
       editText.text.setSpan(
         IrcStrikethroughSpan(), range.start, range.endInclusive + 1,
-        Spanned.SPAN_INCLUSIVE_EXCLUSIVE
+        Spanned.SPAN_INCLUSIVE_INCLUSIVE
       )
     }
   }
 
+  fun isMonospace(range: IntRange) = editText.text.hasSpans<TypefaceSpan>(range) {
+    it.family == "monospace"
+  }
+
   fun toggleMonospace(range: IntRange, createNew: Boolean = true) {
-    if (range.isEmpty())
-      return
+    val monospace = isMonospace(range)
 
-    val exists = editText.text.removeSpans<TypefaceSpan, IrcMonospaceSpan>(range) { span ->
+    editText.text.removeSpans<TypefaceSpan, IrcMonospaceSpan>(range) { span ->
       when {
         span is IrcMonospaceSpan   -> span
         span.family == "monospace" -> IrcMonospaceSpan()
@@ -132,17 +137,14 @@ class FormatHandler(
       }
     }
 
-    if (!exists && createNew) {
+    if (!monospace && createNew) {
       editText.text.setSpan(
-        IrcMonospaceSpan(), range.start, range.endInclusive + 1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE
+        IrcMonospaceSpan(), range.start, range.endInclusive + 1, Spanned.SPAN_INCLUSIVE_INCLUSIVE
       )
     }
   }
 
   fun clearFormatting(range: IntRange) {
-    if (range.isEmpty())
-      return
-
     toggleBold(range, false)
     toggleItalic(range, false)
     toggleUnderline(range, false)
@@ -150,40 +152,24 @@ class FormatHandler(
     toggleMonospace(range, false)
   }
 
-  fun onMenuItemClick(item: MenuItem?) = when (item?.itemId) {
-    R.id.format_bold          -> {
-      toggleBold(editText.selection)
-      true
+  private inline fun <reified U> Spanned.hasSpans(range: IntRange) =
+    getSpans(range.start, range.endInclusive + 1, U::class.java).any {
+      getSpanFlags(it) and Spanned.SPAN_COMPOSING == 0 &&
+      (getSpanEnd(it) != range.start ||
+       getSpanFlags(it) and 0x02 != 0)
     }
-    R.id.format_italic        -> {
-      toggleItalic(editText.selection)
-      true
-    }
-    R.id.format_underline     -> {
-      toggleUnderline(editText.selection)
-      true
-    }
-    R.id.format_strikethrough -> {
-      toggleStrikethrough(editText.selection)
-      true
-    }
-    R.id.format_monospace     -> {
-      toggleMonospace(editText.selection)
-      true
-    }
-    R.id.format_clear         -> {
-      clearFormatting(editText.selection)
-      true
+
+  private inline fun <reified U> Spanned.hasSpans(range: IntRange, f: (U) -> Boolean) =
+    getSpans(range.start, range.last + 1, U::class.java).any {
+      f(it) &&
+      getSpanFlags(it) and Spanned.SPAN_COMPOSING == 0 &&
+      (getSpanEnd(it) != range.start ||
+       getSpanFlags(it) and 0x02 != 0)
     }
-    else                      -> false
-  }
 
   private inline fun <reified U, T> Editable.removeSpans(
-    range: IntRange, removeInvalid: Boolean = false, f: (U) -> T?): Boolean where T : Copyable<T> {
-    if (range.isEmpty())
-      return false
-
-    var removedAny = false
+    range: IntRange, removeInvalid: Boolean = false, f: (U) -> T?
+  ) where T : Copyable<T> {
 
     for (raw in getSpans<U>(range.start, range.endInclusive + 1, U::class.java)) {
       val spanFlags = getSpanFlags(raw)
@@ -199,36 +185,20 @@ class FormatHandler(
       } else {
         removeSpan(raw)
 
-        val endIsIn = spanEnd in range
-        val endIsAfter = spanEnd > range.endInclusive + 1
-
-        val startIsIn = spanStart in range
-        val startIsBefore = spanStart < range.start
-
-        if (endIsIn && startIsIn) {
-          removedAny = true
-        } else if (endIsIn) {
-          setSpan(span, spanStart, range.start, spanFlags)
-          removedAny = true
-        } else if (startIsIn) {
-          setSpan(span, range.endInclusive + 1, spanEnd, spanFlags)
-          removedAny = true
-        } else if (startIsBefore && endIsAfter) {
-          setSpan(span, spanStart, range.start, spanFlags)
-          setSpan(span.copy(), range.endInclusive + 1, spanEnd, spanFlags)
-          removedAny = true
-        } else if (startIsBefore) {
-          setSpan(span, spanStart, range.start, spanFlags)
-          removedAny = true
+        for (spanRange in spanStart until spanEnd without range) {
+          setSpan(
+            span.copy(),
+            spanRange.start,
+            spanRange.endInclusive + 1,
+            (spanFlags and 0x03.inv()) or 0x01
+          )
         }
       }
     }
-
-    return removedAny
   }
 
   fun autoComplete(text: CharSequence) {
-    val range = editText.text.lastWordIndices(editText.selectionStart, true)
+    val range = editText.text.lastWordIndices(editText.selection.start, true)
     val replacement = if (range?.start == 0) {
       "$text: "
     } else {
@@ -268,4 +238,4 @@ class FormatHandler(
     editText.setText(text)
     editText.setSelection(editText.text.length)
   }
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/helper/IntRangeHelper.kt b/app/src/main/java/de/kuschku/quasseldroid/util/helper/IntRangeHelper.kt
new file mode 100644
index 0000000000000000000000000000000000000000..fc62e431eb013fa6519c3e0cb6d91d550dda9763
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/helper/IntRangeHelper.kt
@@ -0,0 +1,13 @@
+package de.kuschku.quasseldroid.util.helper
+
+import clamp
+
+infix fun IntRange.without(other: IntRange): Iterable<IntRange> {
+  val otherStart = minOf(other.start, other.last + 1).clamp(this.start, this.last + 1)
+  val otherLast = maxOf(other.start, other.last + 1).clamp(this.start, this.last + 1)
+
+  val startingFragment: IntRange = this.start until otherStart
+  val endingFragment: IntRange = otherLast + 1 until this.last + 1
+
+  return listOf(startingFragment, endingFragment).filter { it.last >= it.start }
+}
\ No newline at end of file
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/helper/SelectionHelper.kt b/app/src/main/java/de/kuschku/quasseldroid/util/helper/SelectionHelper.kt
index 67924afdc5d8d1742d66e86ff1fa71b1ba0ae69d..6d107d6f5ea6d515ae59a883ec7e8043ecb5cf8f 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/helper/SelectionHelper.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/helper/SelectionHelper.kt
@@ -4,7 +4,12 @@ import android.text.Selection
 import android.widget.EditText
 
 val CharSequence.selection: IntRange
-  get() = Selection.getSelectionStart(this) until Selection.getSelectionEnd(this)
+  get() {
+    val start = Selection.getSelectionStart(this)
+    val end = Selection.getSelectionEnd(this)
+
+    return minOf(start, end) until maxOf(start, end)
+  }
 
 val EditText.selection: IntRange
   get() = text.selection
\ No newline at end of file
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ui/EditTextSelectionChange.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ui/EditTextSelectionChange.kt
new file mode 100644
index 0000000000000000000000000000000000000000..ad316e498111d10fdcc73628c5c15eb73edace88
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/EditTextSelectionChange.kt
@@ -0,0 +1,27 @@
+package de.kuschku.quasseldroid.util.ui
+
+import android.content.Context
+import android.support.v7.widget.AppCompatEditText
+import android.util.AttributeSet
+
+class EditTextSelectionChange : AppCompatEditText {
+  constructor(context: Context?) : super(context)
+  constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
+  constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) :
+    super(context, attrs, defStyleAttr)
+
+  private var selectionChangeListener: ((IntRange) -> Unit)? = null
+
+  fun setSelectionChangeListener(f: (IntRange) -> Unit) {
+    selectionChangeListener = f
+  }
+
+  fun removeSelectionChangeListener() {
+    selectionChangeListener = null
+  }
+
+  override fun onSelectionChanged(selStart: Int, selEnd: Int) {
+    super.onSelectionChanged(selStart, selEnd)
+    selectionChangeListener?.invoke(selStart until selEnd)
+  }
+}
\ No newline at end of file
diff --git a/app/src/main/res/drawable-de/ic_format_bold.xml b/app/src/main/res/drawable-de/ic_format_bold.xml
deleted file mode 100644
index f14946cf3f9b4787c234f1511c50769ea48249a6..0000000000000000000000000000000000000000
--- a/app/src/main/res/drawable-de/ic_format_bold.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-  android:width="24dp"
-  android:height="24dp"
-  android:viewportHeight="24"
-  android:viewportWidth="24">
-  <path
-    android:fillColor="#000"
-    android:pathData="M 16.509807,12.423077 H 11.0675 V 18 H 7.6924995 V 4.0000001 H 17.057884 V 6.605769 H 11.0675 v 3.2211544 h 5.442307 z" />
-</vector>
diff --git a/app/src/main/res/drawable-de/ic_format_italic.xml b/app/src/main/res/drawable-de/ic_format_italic.xml
deleted file mode 100644
index c6232c77aa08da45f42e98f5442748cd4786b325..0000000000000000000000000000000000000000
--- a/app/src/main/res/drawable-de/ic_format_italic.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-  android:width="24dp"
-  android:height="24dp"
-  android:viewportHeight="24"
-  android:viewportWidth="24">
-  <path
-    android:fillColor="#000"
-    android:pathData="m10.3 12-2.41 1.7-1.87 4.3h-2.37l6.16-14h2.39l-2.86 6.4 7.96-6.4h3.1l-7.9 6.3 1.8 7.7h-2.64z" />
-</vector>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_format_foreground.xml b/app/src/main/res/drawable/ic_format_foreground.xml
index d0f11e7e5165001b3cfcb67685afc6d4f446e0f2..f529befb6e35015f25d1227233758569d51131fe 100644
--- a/app/src/main/res/drawable/ic_format_foreground.xml
+++ b/app/src/main/res/drawable/ic_format_foreground.xml
@@ -5,5 +5,5 @@
   android:viewportWidth="24">
   <path
     android:fillColor="#000"
-    android:pathData="M18,4V3A1,1 0 0,0 17,2H5A1,1 0 0,0 4,3V7A1,1 0 0,0 5,8H17A1,1 0 0,0 18,7V6H19V10H9V21A1,1 0 0,0 10,22H12A1,1 0 0,0 13,21V12H21V4H18Z" />
+    android:pathData="M9.62,12L12,5.67L14.37,12M11,3L5.5,17H7.75L8.87,14H15.12L16.25,17H18.5L13,3H11Z" />
 </vector>
diff --git a/app/src/main/res/layout/layout_editor.xml b/app/src/main/res/layout/layout_editor.xml
index 898de974f20c5daf0c41129e40d2cefa11b2551f..b74c913372b659d4dc258bc103e773bfec172b67 100644
--- a/app/src/main/res/layout/layout_editor.xml
+++ b/app/src/main/res/layout/layout_editor.xml
@@ -13,9 +13,9 @@
     android:background="?attr/selectableItemBackgroundBorderless"
     android:padding="12dp"
     android:scaleType="fitXY"
-    app:tint="?attr/colorTextSecondary"
     app:layout_constraintStart_toStartOf="parent"
-    app:srcCompat="@drawable/ic_tab" />
+    app:srcCompat="@drawable/ic_tab"
+    app:tint="?attr/colorTextSecondary" />
 
   <ScrollView
     android:id="@+id/chatline_scroller"
@@ -27,7 +27,7 @@
     app:layout_constraintStart_toEndOf="@+id/tab_complete"
     app:layout_constraintTop_toTopOf="parent">
 
-    <android.support.v7.widget.AppCompatEditText
+    <de.kuschku.quasseldroid.util.ui.EditTextSelectionChange
       android:id="@+id/chatline"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
@@ -54,9 +54,9 @@
     android:background="?attr/selectableItemBackgroundBorderless"
     android:padding="12dp"
     android:scaleType="fitXY"
-    app:tint="?attr/colorAccent"
     app:layout_constraintEnd_toEndOf="parent"
-    app:srcCompat="@drawable/ic_send" />
+    app:srcCompat="@drawable/ic_send"
+    app:tint="?attr/colorAccent" />
 
   <de.kuschku.quasseldroid.util.ui.AutoCompleteRecyclerView
     android:id="@+id/autocomplete_list_expanded"
@@ -82,11 +82,7 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent">
 
-        <android.support.v7.widget.ActionMenuView
-          android:id="@+id/formatting_menu"
-          android:layout_width="wrap_content"
-          android:layout_height="match_parent"
-          android:theme="?attr/formatBarTheme" />
+        <include layout="@layout/widget_formatting" />
       </HorizontalScrollView>
     </android.support.v7.widget.Toolbar>
   </android.support.design.widget.AppBarLayout>
diff --git a/app/src/main/res/layout/widget_formatting.xml b/app/src/main/res/layout/widget_formatting.xml
new file mode 100644
index 0000000000000000000000000000000000000000..00c1af122add435c92c9899a523c0f1a795e4c19
--- /dev/null
+++ b/app/src/main/res/layout/widget_formatting.xml
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+  xmlns:app="http://schemas.android.com/apk/res-auto"
+  android:layout_width="wrap_content"
+  android:layout_height="match_parent"
+  android:padding="2dp">
+
+  <android.support.v7.widget.AppCompatImageButton
+    android:id="@+id/action_format_bold"
+    style="@style/Widget.Button.Format"
+    app:srcCompat="@drawable/ic_format_bold"
+    app:tint="?colorTextPrimary" />
+
+  <Space
+    android:layout_width="2dp"
+    android:layout_height="match_parent" />
+
+  <android.support.v7.widget.AppCompatImageButton
+    android:id="@+id/action_format_italic"
+    style="@style/Widget.Button.Format"
+    app:srcCompat="@drawable/ic_format_italic"
+    app:tint="?colorTextPrimary" />
+
+  <Space
+    android:layout_width="2dp"
+    android:layout_height="match_parent" />
+
+  <android.support.v7.widget.AppCompatImageButton
+    android:id="@+id/action_format_underline"
+    style="@style/Widget.Button.Format"
+    app:srcCompat="@drawable/ic_format_underline"
+    app:tint="?colorTextPrimary" />
+
+  <Space
+    android:layout_width="2dp"
+    android:layout_height="match_parent" />
+
+  <android.support.v7.widget.AppCompatImageButton
+    android:id="@+id/action_format_strikethrough"
+    style="@style/Widget.Button.Format"
+    app:srcCompat="@drawable/ic_format_strikethrough"
+    app:tint="?colorTextPrimary" />
+
+  <Space
+    android:layout_width="2dp"
+    android:layout_height="match_parent" />
+
+  <android.support.v7.widget.AppCompatImageButton
+    android:id="@+id/action_format_monospace"
+    style="@style/Widget.Button.Format"
+    app:srcCompat="@drawable/ic_format_monospace"
+    app:tint="?colorTextPrimary" />
+
+  <Space
+    android:layout_width="2dp"
+    android:layout_height="match_parent" />
+
+  <FrameLayout
+    android:layout_width="48dp"
+    android:layout_height="48dp"
+    android:layout_gravity="center">
+
+    <android.support.v7.widget.AppCompatImageButton
+      android:id="@+id/action_format_foreground"
+      android:layout_width="match_parent"
+      android:layout_height="match_parent"
+      android:background="?backgroundMenuItem"
+      android:paddingBottom="4dp"
+      app:srcCompat="@drawable/ic_format_foreground"
+      app:tint="?colorTextPrimary" />
+
+    <View
+      android:id="@+id/ic_format_foreground_preview"
+      android:layout_width="match_parent"
+      android:layout_height="4dp"
+      android:layout_gravity="center_horizontal|bottom"
+      android:layout_margin="8dp"
+      android:background="?colorTextPrimary" />
+
+  </FrameLayout>
+
+  <Space
+    android:layout_width="2dp"
+    android:layout_height="match_parent" />
+
+  <FrameLayout
+    android:layout_width="48dp"
+    android:layout_height="48dp"
+    android:layout_gravity="center">
+
+    <android.support.v7.widget.AppCompatImageButton
+      android:id="@+id/action_format_background"
+      android:layout_width="match_parent"
+      android:layout_height="match_parent"
+      android:background="?backgroundMenuItem"
+      android:paddingBottom="4dp"
+      app:srcCompat="@drawable/ic_format_background"
+      app:tint="?colorTextPrimary" />
+
+    <View
+      android:id="@+id/ic_format_background_preview"
+      android:layout_width="match_parent"
+      android:layout_height="4dp"
+      android:layout_gravity="center_horizontal|bottom"
+      android:layout_margin="8dp"
+      android:background="?colorTextPrimary" />
+
+  </FrameLayout>
+
+  <Space
+    android:layout_width="2dp"
+    android:layout_height="match_parent" />
+
+  <android.support.v7.widget.AppCompatImageButton
+    android:id="@+id/action_format_clear"
+    style="@style/Widget.Button.Format"
+    app:srcCompat="@drawable/ic_format_clear"
+    app:tint="?colorTextPrimary" />
+</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/menu/formatting.xml b/app/src/main/res/menu/formatting.xml
deleted file mode 100644
index 3add5e54ebb575acc1bd45651ab500e74edca737..0000000000000000000000000000000000000000
--- a/app/src/main/res/menu/formatting.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<menu xmlns:android="http://schemas.android.com/apk/res/android"
-  xmlns:app="http://schemas.android.com/apk/res-auto">
-  <item
-    android:id="@+id/format_bold"
-    android:icon="@drawable/ic_format_bold"
-    android:title="@string/label_bold"
-    app:showAsAction="always" />
-  <item
-    android:id="@+id/format_italic"
-    android:icon="@drawable/ic_format_italic"
-    android:title="@string/label_italic"
-    app:showAsAction="always" />
-  <item
-    android:id="@+id/format_underline"
-    android:icon="@drawable/ic_format_underline"
-    android:title="@string/label_underline"
-    app:showAsAction="always" />
-  <item
-    android:id="@+id/format_strikethrough"
-    android:icon="@drawable/ic_format_strikethrough"
-    android:title="@string/label_strikethrough"
-    app:showAsAction="always" />
-  <item
-    android:id="@+id/format_monospace"
-    android:icon="@drawable/ic_format_monospace"
-    android:title="@string/label_monospace"
-    app:showAsAction="always" />
-  <item
-    android:id="@+id/format_foreground"
-    android:icon="@drawable/ic_format_foreground"
-    android:title="@string/label_foreground"
-    app:showAsAction="always" />
-  <item
-    android:id="@+id/format_background"
-    android:icon="@drawable/ic_format_background"
-    android:title="@string/label_background"
-    app:showAsAction="always" />
-  <item
-    android:id="@+id/format_clear"
-    android:icon="@drawable/ic_format_clear"
-    android:title="@string/label_clear_formatting"
-    app:showAsAction="always" />
-</menu>
\ No newline at end of file
diff --git a/app/src/main/res/values/styles_widgets.xml b/app/src/main/res/values/styles_widgets.xml
index 7bcd0a5707fd9642cf0f6a644817e98e4af85fde..3d7def74e09c12501bf49fd87743b77d092c68f2 100644
--- a/app/src/main/res/values/styles_widgets.xml
+++ b/app/src/main/res/values/styles_widgets.xml
@@ -63,6 +63,13 @@
 
   <style name="Widget.DialogTheme.Light" parent="Theme.AppCompat.Light.Dialog.Alert" />
 
+  <style name="Widget.Button.Format" parent="">
+    <item name="android:layout_width">48dp</item>
+    <item name="android:layout_height">48dp</item>
+    <item name="android:layout_gravity">center</item>
+    <item name="android:background">?backgroundMenuItem</item>
+  </style>
+
   <!-- NavigationDrawerLayout -->
   <declare-styleable name="NavigationDrawerLayout">
     <attr name="insetBackground" />
diff --git a/lib/src/main/java/de/kuschku/libquassel/util/helpers/MathHelper.kt b/lib/src/main/java/de/kuschku/libquassel/util/helpers/MathHelper.kt
index bedb3827a980c885716a997c5fcc901ccb70a844..2335af048431608733b4229411a87f47ffdf3623 100644
--- a/lib/src/main/java/de/kuschku/libquassel/util/helpers/MathHelper.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/util/helpers/MathHelper.kt
@@ -1,2 +1,4 @@
-inline fun Int.clamp(lowerBound: Int, upperBound: Int): Int = maxOf(lowerBound,
-                                                                    minOf(this, upperBound))
+inline fun Int.clamp(lowerBound: Int, upperBound: Int): Int =
+  maxOf(lowerBound, minOf(this, upperBound))
+
+inline fun Int.clamp(range: IntRange): Int = clamp(range.start, range.last)
\ No newline at end of file